Šotek - předběžná analýza Zápočtový projekt, IB013 Logické programování Jiří Mauritz, Tomáš Effenberger 12. dubna 2013
Obsah 1 Úvod 2 1.1 Charakteristika programu............................... 2 1.2 Vstupní podmínky................................... 2 2 Rozhraní 3 2.1 Uživatelské rozhraní.................................. 3 2.2 Prováděné modifikace................................. 3 2.3 Konfigurační soubor.................................. 4 2.4 Korpusy......................................... 4 3 Implementace 6 3.1 Zavedení korpusů do programové databáze...................... 6 3.2 Analýza vstupního textu................................ 6 3.2.1 Předzpracování vstupního textu....................... 6 3.2.2 Rozdělení vstupního textu na jednotlivá slova a věty............ 6 3.2.3 Analýza četnosti výskytu slov......................... 6 3.2.4 Rozeznání slovních druhů........................... 6 3.3 Zpracování konfiguračního souboru.......................... 7 3.4 Modifikace textu.................................... 7 3.4.1 Negace vět (negate/2)............................. 7 3.4.2 Záměna podmětu a předmětu (swap/2)................... 8 3.4.3 Náhrada podstatných jmen podle konfiguračního souboru (replace/2).. 8 3.4.4 Náhrada přídavných jmen jejich antonymy (makeantonyms/2)....... 8 3.4.5 Přidání přídavných jmen (addadjectives/2)................ 9 4 Příklad vstupu a výstupu 10 4.1 Ukázka fungování predikátu trolltext/2...................... 10 4.2 Ukázka fungování predikátu trollfile/2...................... 10 1
Kapitola 1 Úvod 1.1 Charakteristika programu Program Šotek modifikuje zadaný text tak, že změní význam vět, ale gramatická správnost zůstane zachována. Modifikace lze řídit pomocí konfiguračního souboru. 1.2 Vstupní podmínky Šotek pracuje s textem v angličtině bez neobvyklých gramatických jevů. Text nesmí obsahovat stažené tvary s výjimkou slovesa to be a slova n t. Text by neměl obsahovat taková podstatná jména v množném čísle, která se tvoří nepravidelně (např. mice, men). 2
Kapitola 2 Rozhraní 2.1 Uživatelské rozhraní K modifikaci textu lze použít predikáty trolltext/2 a trollfile/2. trolltext(-inputtext, +OutputText) -InputText - řetězec znaků reprezentující vstupní text, který má být změněn +OutputText - řetězec znaků reprezentující modifikovaný text trollfile(-inputfile, +OutputFile) -InputFile - řetězec znaků reprezentující jméno vstupní souboru, ve kterém je text, který má být změněn +OutputFile - řetězec znaků reprezentující jméno výstupního sobouru, do kterého se zapíše modifikovaný text 2.2 Prováděné modifikace Program bude umožňovat provádět tyto modifikace: negace vět, záměna podmětu a předmětu, náhrada podstatných jmen za jiná (podle konfiguračního souboru), náhrada přídavných jmen jejich antonymy a přidávání přídavných jmen. Tabulka 2.1: Příklady prováděných modifikací Modifikace Negace Záměna Náhrada Antonyma Přidávání Příklad vstup: Professor Slovak thinks the proof is obvious. výstup: Professor Slovak doesn t think the proof is obvious. vstup: Professor Slovak thinks the proof is obvious. výstup: The proof thinks professor Slovak is obvious. vstup: Professor Slovak thinks the proof is obvious. výstup: Bachelor Slovak thinks the proof is obvious. vstup: Professor Slovak thinks the proof is obvious. výstup: Professor Slovak thinks the proof is unclear. vstup: Professor Slovak thinks the proof is obvious. výstup: Sad professor Slovak thinks the happy proof is obvious. 3
2.3 Konfigurační soubor Chování programu je řízeno konfiguračním souborem, který se skládá se ze tří částí vzájemně oddělených řádkem obsahujícím pouze znak @. 1. Příznaky modifikací, které se mají provádět. Tabulka 2.2: Význam jednotlivých příznaků. Příznak negation. swap. replacement. antonym. add. Význam negace vět záměna podmětu a předmětu náhrada podstatných jmen za jiná náhrada přídavných jmen jejich antonymy přidávání přídavných jmen 2. Výčet slov, která mají být nahrazována (pokud je přítomen příznak Replacement.) Každý řádek reprezentuje jednu dvojici slov, kde první slovo se bude nahrazovat za druhé. Třetí parametr udává, z kolika procent se má náhrada provést. Např. řádek chair. table. 0.3 udává, že 30% ze všech slov chair ve vstupním textu bude nahrazeno slovem table. 3. Seznam přídavných jmen, která se mají přidávat do textu (pokud je přítomen příznak Add.) Na každém řádku bude právě jedno přídavné jméno následované tečkou. Textový soubor 1 Příklad konfiguračního souboru. negation. replacement. swap. antonym. add. @ yesterday. tomorow. 0.7 chair. table. 0.3 chair. window. 0.4 computer. girl. 0.5 half. quarter. 0.9 java. prolog. 1 telephone. mobile. 0.85 language. tongue. 0.71 @ easy. happy. difficult. 2.4 Korpusy K určování slovních druhů budeme potřebovat korpusy podstatných jmen, sloves v infinitivu (bez TO), nepravidelných sloves v 2. a 3. tvaru, přídavných jmen a determinantů. Korpusy budou upraveny pro jednoduché použití v Prologu, tj. na každém řádku bude jedno slovo následované tečkou. Pro náhradu přídavných jmen jejich antonymy budeme potřebovat korpus antonym, který na každém řádku obsahuje přídavné jméno a jeho anonymum, kde obě dvě slova jsou ukončena tečkou.
Pro účely negace vět budeme potřebovat korpus pomocných sloves, která nemohou být i významová, a všech tvarů slovesa být. Tato slovesa budeme negovat prostým přidáním slova not. Textový soubor 2 Příklad korpusu antonym. clever.stupid. good.bad. fast.slow. far.near. rich.poor. general.specific. Textový soubor 3 Příklad korpusu čistě pomocných sloves a tvarů slovesa být will. shall. can. could. should. may. might. am. are. is. was. were.
Kapitola 3 Implementace 3.1 Zavedení korpusů do programové databáze Pro každý z korpusů vytvoříme příslušný predikát noun/1, adjective/1, verb/1, irregular_verb/1, determiner/1, antonyms/2 a auxiliary_verb/1. Například pro každé slovo W z korpusu podstatných jmen přidáme do programové databáze fakt noun(w). Z korpusu antonym načteme vždy dva termy A a B a do programové databáze přidáme fakt antonyms(a,b). 3.2 Analýza vstupního textu 3.2.1 Předzpracování vstupního textu Odstranění stažených tvarů slovesa to be, tj. re nahradíme za are, m za am a s za is. Nahrazení -n t za not. 3.2.2 Rozdělení vstupního textu na jednotlivá slova a věty divideintowordsandsentences(-undividedtext, +DividedText) -UndividedText - řetězec znaků reprezentující vstupní text +DividedText - seznam vět, kde každá věta je reprezentována seznamem slov, kde každé slovo je řetězcem znaků Slova jsou oddělovány na základě mezer, věty podle znaků.,?,!. 3.2.3 Analýza četnosti výskytu slov countwords(-text) -Text - výstup predikátu divideintowordsandsentences/2 (seznam vět, kde každá věta je reprezentována seznamem slov, kde každé slovo je řetězcem znaků) Vytvoří fakta wordcount/2 v programové databázi, jejichž první atribut je slovo (řetězec znaků) a druhý je počet výskytu tohoto slova textu. 3.2.4 Rozeznání slovních druhů tagtext(-text, +TaggedText) -Text - výstup predikátu divideintowordsandsentences/2 (seznam vět, kde každá věta je reprezentována seznamem slov, kde každé slovo je řetězcem znaků) 6
+TaggedText - seznam vět, kde každá věta je reprezentována seznamem otagovaných slov, kde každé slovo je reprezentováno termem word/3, jehož první atribut je dané slovo jako řetězec znaků, druhý atribut je řetězec znaků, které v původní větě byly mezi tímto a následujicím znakem (např., nebo? nebo - ) a třetí atribut je tag, který označuje slovní druh. Tagem může být některá z konstant z tabulky 3.1. Tabulka 3.1: Význam jednotlivých tagů Tag noun adjective verb determiner other Význam podstatné jméno přídavné jméno sloveso determinant (členy, přivlastňovací a ukazovací zájmena, kvantifikátory, číslovky) ostatní + nejednoznačné Rozpoznávání slovního druhu budou vykonávat predikáty isnoun/1, isadjective/1, isverb/1 a isdeterminer/1, které budou využívat výše zmíněné predikáty noun/1, adjective/1, verb/1, a determiner/1. 3.3 Zpracování konfiguračního souboru 1. Do programové databáze zavedeme nulární predikáty odpovídájící příznákům pro prováděné modifikace z konfiguračního souboru. 2. Vytvoříme množinu faktů replacementrecord/3, jejichž první atribut je slovo, které má být nahrazováno, druhý atribut je slovo, za které se bude nahrazovat, a třetí udává počet výskytů, u kterých dojde k nahrazení. Tento počet získáme vynásobením údaje o procentuálním počtu nahrazení (3. argument v konfiguračním souboru) a počtu výskytu tohoto slova získaného predikátem countwords/2 (viz sekce 3.2.3). 3. Vytvoříme množinu faktů adjectivetoadd/1 pro každé přídavné jméno z poslední části konfiguračního souboru. 3.4 Modifikace textu Modifikace každé věty probíhá nezávisle na modifikaci ostatních vět. Proto si zavedeme predikát modifytext/2, který aplikuje predikát modifysentence/2 na každou větu. Predikát modifysentence/2 aplikuje na větu ty modifikace, které byly udány v první sekci konfiguračním souboru. 3.4.1 Negace vět (negate/2) Nejprve najdeme první sloveso v dané větě, dále negace probíhá odlišně pro různé případy: 1. první sloveso je pomocné sloveso nebo sloveso to be Jak zjistíme, že se jedná o pomocné sloveso: Bud je to sloveso, které nemůže být významové (popř. sloveso to be), což zjistíme predikátem auxiliary_verb/1. Existují ale i pomocná slovesa, která můžou být i významová (do, have). Budeme řešit pouze sloveso have (has, had), protože minulý čas prostý (did, dind t) se neguje komplikovaně. Musíme rozpoznat, zda sloveso have zde vystupuje jako pomocné. To zjistíme podle toho, že za ním bezprostředně (popř. po slově not) následuje další sloveso. (a) záporná věta (sloveso je následováno slovem not) - vrátíme původní větu bez not. (b) kladná věta - přidáme slovo not za dané pomocné sloveso
2. věta v přítomném čase prostém (a) záporná - odstraníme do not nebo does not. (b) kladná - přidáme don t nebo doesn t před dané sloveso (3. osobu poznáme podle toho, že sloveso končí na -s nebo -es, a tuto koncovku odstraníme) 3.4.2 Záměna podmětu a předmětu (swap/2) Swap bude využívat predikátu findsubjectandobject/6, který rozdělí zadanou větu na pět částí, z nichž jedna bude podmět a jedna předmět, a tyto dvě části pak pouze prohodí. findsubjectandobject(-sentence, +Before, +Subject, +Between, +Object, +After). -Sentence - zadaná věta +Before - vše před podmětem +Subject - podmětná část (podmět včetně slov před ním, které se k němu váží - např. přídavná jména a determinanty) +Between - vše mezi podmětem a předmětovou částí +Object - předmětná část (předmět včetně slov před ním, které se k němu váží - např. přídavná jména a determinanty) +After - vše za předmětem Podmětnou částí bude první podstatné jméno před prvním slovesem, včetně všeho, co se k němu váže - to zjistíme predikátem finddependentpart/3, který zadanou posloupnost slov rozdělí na dvě části, kde druhá část je celá závislá na posledním slově. Podívejme se na konkrétní příklad práce predikátu finddependentpart/3: vstup: In my opinion the most beautiful girl výstup: In my opinion, the most beautiful girl Předmětnou částí je pak první podstatné jméno za slovesem včetně všeho, co se k němu váže, což opět zjistíme pomocí predikátu finddependentpart/3. Následuje příklad: vstup: is the charming subdean výstup: is, the charming subdean Celkové rozdělení na 5 částí predikátem findsubjectandobject/6 by tedy pro větu In my opinion the most beautiful girl is the charming subdean who teaches Prolog dopadlo takto: In my opinion, the most beautiful girl, is, the charming subdean, who teaches Prolog. Po prohození podmětné a předmětné části pak dostáváme In my opinion the charming subdean is the most beautiful girl who teaches Prolog 3.4.3 Náhrada podstatných jmen podle konfiguračního souboru (replace/2) Pro každé slovo W textu zjistíme predikátem replacementrecord(w, WordToReplace, Count), jestli se má nahradit a za které slovo. Provedeme náhradu a následně vymažeme tento fakt z programové databáze. Pokud Count mělo větší hodnotu než 1, přidáme do programové databáze fakt replacementrecord(w, WordToReplace, Count1), kde Count1 is Count - 1. 3.4.4 Náhrada přídavných jmen jejich antonymy (makeantonyms/2) Pro každé slovo W zjistíme predikátem antonyms(w, Antonym) respektive antonyms(antonym, W) 1, jestli je to přídavné jméno, ke kterému existuje antonymum a pokud ano, tak ho tímto antonymem nahradíme. 1 antonyms(a, B) uspěje, pokud A, B jsou antonyma, viz sekce 3.1
3.4.5 Přidání přídavných jmen (addadjectives/2) Před každé podstatné jméno 2 (zjistíme predikátem isnoun) vstupní věty přidáme přídavné jméno zjištěné predikátem AdjectiveToAdd(A). Tento fakt odstraníme z programové databáze a pak ho přidáme na konec, takže při příštím volání predikátu AdjectiveToAdd/1 nám bude vráceno jiné přídavné jméno. 2 přesněji: před každé podstatné jméno, kterému nepředchází jiné podstatné jméno
Kapitola 4 Příklad vstupu a výstupu Budeme uvažovat konfigurační soubor uvedený výše (oddíl 2.3), korpus antonym uvedený výše (oddíl 2.4) a rozsáhlé korpusy podstatných jmen, sloves, přídavných jmen a determinantů (rozsáhlé znamená obsahující všechna slova, která jsou použita v příkladu). 4.1 Ukázka fungování predikátu trolltext/2?- trolltext("yesterday, love was such an easy game to play.", OutputText). OutputText = "Easy tomorow, an easy difficult game was not such happy love to play." 4.2 Ukázka fungování predikátu trollfile/2?- trolltext("vstup.txt", "vystup.txt"). Textový soubor 4 vstup.txt Yesterday, all my troubles seemed so far away. Now it looks as though they re here to stay. Oh, I believe in yesterday. Suddenly I m not half the man I used to be. There s a shadow hanging over me. Oh, yesterday came suddenly. Textový soubor 5 vystup.txt Easy tomorow, all my happy troubles seemed so near away. Now it doesn t look as though they are here to stay. Oh, I don t believe in difficult tomorow. Suddenly I am not quarter the easy man I used to be. There is not a happy shadow hanging over me. Oh, difficult yesterday came suddenly. 10