Source code for alex.components.nlg.tectotpl.tool.lexicon.cs

#!/usr/bin/env python
# coding=utf-8
#
# Czech lexicon related functions
#
from __future__ import unicode_literals

import re
import codecs
import os.path

NUMBER_FOR_NUMERAL = {
        'nula': 0, 'jedna': 1, 'jeden': 1, 'dva': 2, 'tři': 3, 'čtyři': 4,
        'pět': 5, 'šest': 6, 'sedm': 7, 'osm': 8, 'devět': 9, 'deset': 10,
        'jedenáct': 11, 'dvanáct': 12, 'třináct': 13, 'čtrnáct': 14,
        'patnáct': 15, 'šestnáct': 16, 'sedmnáct': 17, 'osmnáct': 18,
        'devatenáct': 19, 'dvacet': 20, 'třicet': 30, 'čtyřicet': 40,
        'padesát': 50, 'šedesát': 60, 'sedmdesát': 70, 'osmdesát': 80,
        'devadesát': 90, 'sto': 100, 'tisíc': 1000, 'milión': 1000000,
        'milion': 1000000, 'miliarda': 1000000000,

        # fractions
        'půl': 1.0 / 2, 'polovina': 1.0 / 2, 'třetina': 1.0 / 3,
        'čtvrt': 1.0 / 4, 'čtvrtina': 1.0 / 4, 'pětina': 1.0 / 5,
        'šestina': 1.0 / 6, 'sedmina': 1.0 / 7, 'osmina': 1.0 / 8,
        'devítina': 1.0 / 9, 'desetina': 1.0 / 10, 'jedenáctina': 1.0 / 11,
        'dvanáctina': 1.0 / 12, 'třináctina': 1.0 / 13, 'čtrnáctina': 1.0 / 14,
        'patnáctina': 1.0 / 15, 'šestnáctina': 1.0 / 16,
        'sedmnáctina': 1.0 / 17, 'osmnáctina': 1.0 / 18,
        'devatenáctina': 1.0 / 19, 'dvacetina': 1.0 / 20,
        'třicetina': 1.0 / 30, 'čtyřicetina': 1.0 / 40, 'padesátina': 1.0 / 50,
        'šedesátina': 1.0 / 60, 'sedmdesátina': 1.0 / 70,
        'osmdesátina': 1.0 / 80, 'devadesátina': 1.0 / 90,
        'setina': 1.0 / 100, 'tisícina': 1.0 / 1000,
        'milióntina': 1.0 / 1000000, 'miliontina': 1.0 / 1000000,

        # other
        'tucet': 12, 'kopa': 60, 'veletucet': 144,
        }

INDEFINITE_NUMERALS = r'^((ne|pře)?mnoho|(ně|bůhví|kdoví|nevím)?kolik' + \
                      r'|tolik|méně|míň|více?|moc|málo|hodně)$'

SYNTH_FUTURE = r'^(běžet|být|hrnout|jet|jít|letět|lézt|nést|růst|téci|vézt)$'

# endings of by/aby/kdyby for different number and person
CONDITIONAL_INFLECT = {('S', '1'): 'ch',
                       ('S', '2'): 's',
                       ('P', '1'): 'chom',
                       ('P', '2'): 'ste'}

# list of verbs that use expletives in 'že'-clauses
EXPLETIVE_VERBS = {'upozorňovat': 'na_to',
                   'zdůvodňovat': 'tím',
                   'uvažovat': 'o_tom',
                   'pochybovat': 'o_tom',
                   'poukazovat': 'na_to',
                   'spočívat': 'v_tom',
                   'nasvědčovat': 'tomu',
                   'vést': 'k_tomu',
                   'argumentovat': 'tím',
                   'souhlasit': 's_tím',
                   'rozhodnout': 'o_tom',
                   'mluvit': 'o_tom',
                   'shodnout_se': 'na_tom',
                   'zdůvodnit': 'tím',
                   'dojít': 'k_tomu',
                   #    'věřit': 'tomu',
                   #    'tajit': 'tím',
                   'přesvědčit': 'o_tom',
                   'přesvědčit_se': 'o_tom',
                   'vycházet': 'z_toho',
                   'trvat': 'na_tom',
                   'počítat': 's_tím',
                   'shodovat_se': 'v_tom',
                   'dopustit_se': 'tím',
                    #    'jít': 'o_to',
                    'hovořit': 'o_tom',
                    #    'moci': 'to',
                    'svědčit': 'o_tom'}

COORD_CONJS = {
        'a': 'N', 'ale': 'Y', 'ani': 'Y', 'anebo': 'N', 'nebo': 'N',
        'buď': 'N', 'avšak': 'Y', 'však': 'Y', 'dokonce': 'Y',
        'jenže': 'Y', 'či': 'N', 'proto': 'Y', 'neboť': 'Y',
        'totiž': 'Y', 'vždyť': 'Y', 'sice': 'N', 'tudíž': 'Y'
        }

NAMED_ENTITY_LABELS = {
        'agentura': 'I', 'automobil': 'I', 'bar': 'I', 'brožura': 'I',
        'cup': 'I', 'Cup': 'I', 'časopis': 'I', 'dílo': 'I', 'divize': 'I',
        'dům': 'I', 'film': 'I', 'firma': 'I', 'fond': 'I', 'fotka': 'I',
        'foto': 'I', 'fotografie': 'I', 'hit': 'I', 'informace': 'I',
        'kancelář': 'I', 'kauza': 'I', 'klub': 'I', 'kniha': 'I',
        'konference': 'I', 'kraj': 'I', 'lázně': 'I', 'model': 'I',
        'motel': 'I', 'motocykl': 'I', 'nakladatelství': 'I', 'noviny': 'I',
        'obrázek': 'I', 'oddělení': 'I', 'okres': 'I', 'palác': 'I',
        'penzión': 'I', 'píseň': 'I', 'písnička': 'I', 'počítač': 'I',
        'podnik': 'I', 'rádio': 'I', 'rotačka': 'I', 'rubrika': 'I',
        'řada': 'I', 'seriál': 'I', 'série': 'I', 'skladba': 'I',
        'skupina': 'I', 'snímek': 'I', 'software': 'I', 'soutěž': 'I',
        'spis': 'I', 'společnost': 'I', 'stadion': 'I', 'stanice': 'I',
        'symfonie': 'I', 'sympózium': 'I', 'telenovela': 'I', 'televize': 'I',
        'třída': 'I', 'úřad': 'I', 'ústav': 'I', 'vůz': 'I', 'výstava': 'I',
        'výstaviště': 'I', 'veletrh': 'I', 'vydavatelství': 'I',
        'zařízení': 'I', 'závod': 'I', 'hora': 'C', 'hrad': 'C', 'hrádek': 'C',
        'kopec': 'C', 'legenda': 'C', 'městečko': 'C', 'město': 'C',
        'metropole': 'C', 'obec': 'C', 'osobnost': 'C', 'řeka': 'C',
        'ves': 'C', 'vesnice': 'C', 'vesnička': 'C', 'víska': 'C'
        }

PERSONAL_ROLES = set([
        'abbé', 'absolvent', 'absolventka', 'adresa', 'advokát',
        'advokátka', 'agent', 'agentura', 'akademik', 'aktivista',
        'amatér', 'analytička', 'analytik', 'anděl', 'archeolog',
        'architekt', 'arcibiskup', 'asistence', 'asistent',
        'asistentka', 'astronom', 'atlet', 'auditor', 'automechanik',
        'autor', 'autorka', 'baba', 'babička', 'banjista', 'banka',
        'bankéř', 'baron', 'barytonista', 'basista', 'basketbalista',
        'baskytarista', 'básník', 'básnířka', 'beran', 'běžec',
        'bibliofil', 'biochemik', 'biolog', 'biskup', 'blokařka', 'bohemista',
        'bojovník', 'botanik', 'boxer', 'brácha', 'branka', 'brankář',
        'bratr', 'bratranec', 'bratříček', 'bubeník', 'budovatel',
        'car', 'čaroděj', 'cellista', 'černoch', 'cestovatel', 'chargé',
        'chemik', 'chirurg', 'chirurgie', 'chlap', 'chlapec',
        'choreograf', 'choť', 'chudák', 'činovník', 'císař', 'číšník',
        'cizinec', 'člen', 'členka', 'člověk', 'čtenář', 'čtyřhra',
        'cvičitelka', 'cyklista', 'dáma', 'dcera', 'dealer', 'dědeček',
        'dědic', 'dědička', 'dějepisec', 'děkan', 'delegát', 'dělník',
        'desetibojař', 'diplomat', 'dirigent', 'divadelník', 'divák',
        'dívka', 'dobrodruh', 'docent', 'dodavatel', 'dohoda', 'doktor',
        'doktorka', 'dopisovatel', 'dozorce', 'dramatička', 'dramatik',
        'dramaturg', 'dramaturgyně', 'držitel', 'držitelka',
        'důchodce', 'důchodkyně', 'důstojník', 'dvojice', 'edice', 'editor',
        'ekolog', 'ekonom', 'ekonomka', 'elektrotechnik', 'emigrant'
        'epidemiolog', 'estetik', 'etnograf', 'etnolog', 'exmanželka',
        'exministr', 'expert', 'expozice', 'expremiér', 'farář', 'farářka',
        'farmář', 'favorit', 'filolog', 'filozof', 'finalista',
        'finalistka', 'flétnista', 'fořt', 'fotbalista', 'fotograf',
        'fotografka', 'frontman', 'funkcionář', 'fyzik', 'garant',
        'generál', 'generálmajor', 'génius', 'geograf', 'geolog',
        'gólman', 'grafik', 'guvernér', 'gynekolog', 'harfenistka', 'herec',
        'historička', 'historik', 'hlasatel', 'hlava', 'hoch',
        'hokejista', 'horník', 'horolezec', 'hospodář', 'hospodyně', 'host',
        'hostinský', 'houslista', 'houslistka', 'hraběnka', 'hráč',
        'hráčka', 'hrdina', 'hrdinka', 'hudebník', 'hvězda', 'hygienik',
        'idol', 'ikona', 'ilustrátor', 'imitátor', 'iniciátor', 'inspektor',
        'instalatér', 'internista', 'investor', 'inženýr', 'jednatel',
        'jednatelka', 'jezdec', 'jinoch', 'kacíř', 'kadeřnice', 'kamarád',
        'kamelot', 'kameník', 'kamera', 'kameraman', 'kancelář',
        'kancléř', 'kandidát', 'kandidátka', 'kanoista', 'kanonýr',
        'kapelník', 'kapitán', 'kaplan', 'kardinál', 'kardiolog', 'kat',
        'keramik', 'kladivář', 'klasik', 'klávesista', 'klavírista',
        'klavíristka', 'kluk', 'kněz', 'kněžna', 'knihovník', 'kočí', 'kolega',
        'kolegyně', 'komentátor', 'komik', 'komisař', 'komisařka',
        'komisionář', 'komorník', 'komunista', 'konstruktér',
        'kontrabasista', 'konzultant', 'koordinátor', 'koordinátorka',
        'koproducent', 'kosmonaut', 'kostelník', 'kouč', 'koulař',
        'kovář', 'krajina', 'krajkářka', 'král', 'královna', 'krejčí',
        'kreslíř', 'křesťan', 'kritik', 'kuchař', 'kuchařka', 'kulak',
        'kurátor', 'kurátorka', 'kvestor', 'kytarista', 'láma', 'laureát',
        'laureátka', 'lazar', 'leader', 'legionář', 'lékař', 'lékařka',
        'lektor', 'lesák', 'lesník', 'lidovec', 'lídr', 'likvidátor',
        'lingvista', 'literát', 'literatura', 'lord', 'loutkář', 'lukostřelec',
        'majitel', 'majitelka', 'major', 'makléř', 'malíř', 'malířka',
        'máma', 'maminka', 'manažer', 'manažerka', 'manžel',
        'manželka', 'markýz', 'maršál', 'masér', 'matematik', 'matka',
        'mecenáš', 'medik', 'meteorolog', 'metropolita',
        'mezzosopranistka', 'miláček', 'milenec', 'milenka', 'milionář',
        'milovník', 'mim', 'ministr', 'ministryně', 'miss',
        'místopředseda', 'místopředsedkyně', 'místostarosta', 'místostarostka',
        'mistr', 'mistryně', 'mladík', 'mluvčí', 'mnich', 'modelka',
        'moderátor', 'moderátorka', 'mořeplavec', 'mučedník', 'muslim',
        'muž', 'mužík', 'muzikant', 'muzikolog', 'myslitel', 'myslivec',
        'náčelnice', 'náčelník', 'nacista', 'nadace', 'náhradnice',
        'náhradník', 'nájemce', 'nájemník', 'nakladatel', 'náměstek',
        'náměstkyně', 'námořník', 'nástupce', 'navrátilec', 'návrhář',
        'návštěvník', 'nestor', 'neteř', 'nositel', 'nositelka'
        'nováček', 'novinář', 'novinářka', 'novinka', 'občan', 'obchodník',
        'obdivovatel', 'oběť', 'obhájce', 'obhájkyně', 'objevitel',
        'obránce', 'obuvník', 'obyvatel', 'ochránce', 'odborář',
        'odbornice', 'odborník', 'odchovanec', 'operace', 'organizátor',
        'ošetřovatelka', 'osobnost', 'oštěpař', 'otec', 'pamětník',
        'pan', 'pán', 'paní', 'panna', 'papež', 'papoušek', 'partner',
        'pastýř', 'páter', 'patriarcha', 'patron', 'pedagog', 'pekař',
        'perkusista', 'pěvec', 'pěvkyně', 'pianista', 'pilot', 'písničkář',
        'plavkyně', 'playboy', 'plukovník', 'pochop', 'podnikatel'
        'podnikatelka', 'pokladník', 'pokračovatel', 'policajt',
        'policista', 'politik', 'politolog', 'pomocník', 'pořadatel',
        'poradce', 'poradkyně', 'poručík', 'poslanec', 'poslankyně',
        'posluchač', 'posluchačka', 'postava', 'potomek', 'poutník',
        'pověřenec', 'pozorovatel', 'pracovnice', 'pracovník',
        'právník', 'pravnuk', 'předák', 'předchůdce', 'přednosta',
        'předseda', 'předsedkyně', 'představitel', 'představitelka',
        'překážkář', 'překladatel', 'překladatelka', 'premiér',
        'přemožitel', 'prezident', 'prezident', 'prezidentka', 'příbuzný',
        'primář', 'primářka', 'primátor', 'princ', 'princezna', 'principál',
        'příručí', 'příslušník', 'přítel', 'privatizace', 'příznivec'
        'prodavač', 'prodavačka', 'prodejna', 'proděkan', 'producent',
        'producentka', 'profesionál', 'profesor', 'profesorka', 'programátor',
        'projektant', 'prokurista', 'proletář', 'propagátor', 'prorok',
        'protagonista', 'protagonistka', 'provozovatel', 'provozovatelka',
        'prozaik', 'průkopník', 'průmyslník', 'průvodce', 'průvodkyně',
        'psychiatr', 'psycholog', 'publicista', 'publicistka',
        'purkrabí', 'rada', 'rádce', 'radikál', 'radní', 'radnice', 'redaktor',
        'redaktorka', 'ředitel', 'ředitelka', 'referent', 'referentka',
        'rekordman', 'rektor', 'reportér', 'reprezentant', 'reprezentantka',
        'republikán', 'restaurátor', 'režisér', 'režisérka', 'řezník',
        'řidič', 'rodák', 'rodič', 'rolník', 'rozehrávač', 'rozhodčí',
        'rybář', 'rytíř', 'šašek', 'saxofonista', 'sběratel', 'sbormistr',
        'scenárista', 'scenáristka', 'scénograf', 'sedlák', 'šéf',
        'šéfdirigent', 'šéfka', 'šéfkuchař', 'šéfredaktor',
        'šéfredaktorka', 'šéftrenér', 'sekretář', 'sekretářka',
        'semifinalistka', 'senátor', 'senátorka', 'šerif', 'seržant',
        'sestra', 'sestřenice', 'sexuolog', 'signatář', 'sir', 'skaut',
        'skinhead', 'skladatel', 'skladba', 'skupina', 'slávista', 'slečna',
        'sluha', 'smečařka', 'sněmovna', 'sochař', 'sochařka',
        'socialista', 'sociolog', 'sólista', 'sólistka', 'sopranistka',
        'soudce', 'soudruh', 'soukromník', 'soupeř', 'sourozenec',
        'soused', 'soutěž', 'specialista', 'specialistka', 'spisovatel',
        'spisovatelka', 'spojenec', 'spojka', 'společník', 'spoluautor',
        'spoluautorka', 'spoluhráč', 'spolujezdec', 'spolumajitel',
        'spolumajitelka', 'spolupracovnice', 'spolupracovník', 'spolutvůrce',
        'spolužák', 'spoluzakladatel', 'sponzor', 'správce',
        'starosta', 'statkář', 'státník', 'stavbyvedoucí', 'stavitel',
        'stoper', 'stoupenec', 'stratég', 'strážce', 'střelec', 'strůjce',
        'strýc', 'student', 'studentka', 'stvořitel', 'superhvězda',
        'surrealista', 'švagr', 'švec', 'svědek', 'svoboda', 'symfonie', 'syn',
        'synovec', 'tajemnice', 'tajemník', 'tanečnice', 'tanečník',
        'táta', 'tatínek', 'tchán', 'teatrolog', 'technik',
        'technolog', 'tenista', 'tenistka', 'tenor', 'tenorista',
        'tenorsaxofonista', 'teolog', 'teoretik', 'tesař', 'teta',
        'textař', 'tlumočnice', 'tlumočník', 'továrník', 'trenér', 'trenérka',
        'trojskokanka', 'trombonista', 'truhlář', 'trumpetista',
        'tvůrce', 'účastnice', 'účastník', 'učenec', 'účetní',
        'učitel', 'učitelka', 'uhlíř', 'uklízečka', 'umělec', 'úprava',
        'uprchlík', 'úřednice', 'úředník', 'útočník', 'varhaník',
        'vdova', 'vědec', 'vedoucí', 'velitel', 'velmistr', 'velvyslanec',
        'velvyslankyně', 'verbíř', 'veterán', 'veteránka', 'vévoda',
        'vězeň', 'vibrafonista', 'viceguvernér', 'vicemistr',
        'vicepremiér', 'viceprezident', 'viceprezidentka', 'violista',
        'violoncellista', 'vítěz', 'vítězka', 'vladyka', 'vlastník',
        'vnuk', 'voják', 'vrah', 'vrátný', 'vrstevník', 'vůdce', 'výčepní',
        'vychovatelka', 'vydavatel', 'vyjednavač', 'vynálezce',
        'výrobce', 'vyšetřovatel', 'vyslanec', 'výstava', 'výtvarnice',
        'výtvarník', 'vyznavač', 'vzpoura', 'zahradník', 'žák', 'zakladatel',
        'zakladatelka', 'žákyně', 'záložník', 'zámečník',
        'zaměstnanec', 'zapisovatel', 'zapisovatelka', 'zastánce', 'zástupce',
        'zástupkyně', 'závodník', 'zedník', 'železničář', 'zemědělec',
        'žena', 'žid', 'živnostník', 'zločinec', 'zloděj', 'zmocněnec',
        'znalec', 'známý', 'zoolog', 'zpěvák', 'zplnomocněnec',
        ])


[docs]class Lexicon(object): def __init__(self): self.POSSESSIVE_FOR_NOUN = {} pass
[docs] def number_for(self, numeral): "Given a Czech numeral, returns the corresponding number." if re.match(r'^\d+$', numeral): return int(numeral) return NUMBER_FOR_NUMERAL.get(numeral)
[docs] def is_incongruent_numeral(self, numeral): """Return True if the given lemma belongs to a Czech numeral that takes a genitive attribute instead of being an attribute itself""" re.sub('[_\s]', '', numeral) # check whole numbers and numbers written as words number = self.number_for(numeral) if number is not None and (number < 1 or number > 4): return True # check decimal point numbers and indefinite numerals if re.match('^\d+[,.]\d+$', numeral) or \ re.match(INDEFINITE_NUMERALS, numeral): return True return False
[docs] def load_possessive_adj_dict(self, data_dir): """\ Read the possessive-adjective-to-noun conversion file and save it to the database. """ with codecs.open(os.path.join(data_dir, 'lexicon/cs/possessive_adjectives.tsv'), 'r', 'UTF-8') as handle: for line in handle: line = line.rstrip('\r\n') # skip comments if '##' in line: continue try: adj_lemma, count = line.split('\t') if int(count) < 2: continue # match long Czech possessive adjective lemma match = re.search(r'^([^_]+)_.*\/(\(.+\)\_)?' + r'\((\^UV)?\*(\d+)(.*)\)', adj_lemma) # divide it into parts adj, chars_to_del, new_suffix = \ match.group(1), match.group(4), match.group(5) # create the corresponding noun lemma noun = adj[:-int(chars_to_del)] + new_suffix adj = re.sub(r'-.+', r'', adj) noun = re.sub(r'-.+', r'', noun) # store it into dictionary self.POSSESSIVE_FOR_NOUN[noun] = adj except: continue
[docs] def get_possessive_adj_for(self, noun_lemma): """\ Given a noun lemma, this returns a possessive adjective if it's in the database. """ return self.POSSESSIVE_FOR_NOUN.get(noun_lemma)
[docs] def has_synthetic_future(self, verb_lemma): """Returns True if the verb builds a synthetic future tense form with the prefix 'po-'/'pů-'.""" verb_lemma = re.sub(r'_s[ei]$', '', verb_lemma) if re.match(SYNTH_FUTURE, verb_lemma): return True return False
[docs] def inflect_conditional(self, lemma, number, person): "Return inflected form of a conditional particle/conjunction" ending = CONDITIONAL_INFLECT.get((number, person), '') return lemma + ending
[docs] def has_expletive(self, lemma): """\ Return an expletive for a 'že'-clause that this verb governs, or False. Lemmas must include reflexive particles for reflexiva tantum. """ return EXPLETIVE_VERBS.get(lemma, False)
[docs] def is_coord_conj(self, lemma): """Return 'Y'/'N' if the given lemma is a coordinating conjunction (depending on whether one should write a comma directly in front).""" return COORD_CONJS.get(lemma, False)
[docs] def is_personal_role(self, lemma): "Return true if the given lemma is a personal role." return lemma in PERSONAL_ROLES
[docs] def is_named_entity_label(self, lemma): """Return 'I'/'C' if the given lemma is a named entity label (used as congruent/incongruent attribute).""" return NAMED_ENTITY_LABELS.get(lemma, False)