Domácí úkol 12: Zpracování přirozeného jazyka Hlavní oblasti použití jazyka Prolog jsou umělá inteligence a zpracování přirozeného jazyka. Zjednodušené zpracování přirozeného jazyka si můžete vyzkoušet v této úloze. Vaším úkolem bude napsat program v jazyce Prolog, který o zadaném řetězci rozhodne, jestli se jedná o správně utvořenou větu. Pro účely tohoto úkolu považujeme za správně utvořenou větu posloupnost slov a čárek oddělených mezerami, která splňuje následující pravidla: • Věta je posloupnost slov, která se skládá z podmětu, slovesa a předmětu. • Vedlejší věta je posloupnost slov, která začíná slovem "ktera", po kterém následuje sloveso a předmět. • Podmět je podstatné jméno v prvním pádě, za kterým může následovat vedlejší věta oddělená z obou stran čárkami. • Předmět je podstatné jméno ve čtvrtém pádě, kterému může předcházet libovolný počet přídavných jmen a za kterým může následovat čárka a vedlejší věta. • Podstatné jméno v prvním pádě je jedno ze slov "zena", "ruze", "pisen" a "kost". • Podstatné jméno ve čtvrtém pádě je jedno ze slov "zenu", "ruzi", "pisen" a "kost". • Přídavné jméno je jedno ze slov "krasnou", "tvrdou" a "ostrou". • Sloveso je jedno ze slov "zpiva", "vidi" a "vari". Formálněji řečeno, správně utvořené věty je možné generovat bezkontextovou gramatikou s kořenovým neterminálem V a následující množinou pravidel: P = { V → Podmět Sloveso Předmět W → ktera Sloveso Předmět Podmět → Kdo | Kdo , W, Předmět → Koho | Koho , W | Jakou Předmět Kdo → zena | ruze | pisen | kost Koho → zenu | ruzi | pisen | kost Jakou → krasnou | tvrdou | ostrou Sloveso → zpiva | vidi | vari }. Tedy správně utvořené věty jsou například: • "zena vidi ruzi" • "zena , ktera zpiva pisen , vidi ruzi" • "zena , ktera zpiva krasnou pisen , vidi ostrou ruzi" • "zena , ktera zpiva krasnou pisen , vidi ostrou krasnou ostrou ruzi" • "zena , ktera zpiva krasnou pisen , vidi ostrou ruzi , ktera vari tvrdou kost" • "zena , ktera zpiva krasnou pisen , vidi krasnou zenu , ktera vidi krasnou zenu , ktera vari tvrdou kost " • "ruze , ktera vari tvrdou zenu , vidi ruzi , ktera zpiva tvrdou ostrou kost" Naopak následující věty správně utvořené nejsou: • "zena" • "zena vidi" • "krasna zena vidi ruzi" • "zena vidi ruzi , ktera vidi" • "zena vidi ruzi , kterou vidi zena" • "zena vidi ruzi , ktera vidi zena" Zadání Napiště predikát isCorrectSentence/1, který pro zadaný řetězec uspěje právě tehdy, když je tento řetězec správně utvořenou větou podle výše zmíněných pravidel. Tedy například ?- isCorrectSentence("zena vidi ruzi"). true. ?- isCorrectSentence("zena , ktera zpiva krasnou pisen , vidi ostrou ruzi"). true. 1 ?- isCorrectSentence("zena , ktera zpiva krasnou pisen , vidi zenu , ktera vidi zenu"). true. ?- isCorrectSentence("zena"). false. ?- isCorrectSentence("zena vidi"). false. ?- isCorrectSentence("zena vidi ruzi , ktera vidi zena"). false. Váš predikát má fungovat v módu isCorrectSentence(+String); případy, kdy argument není instanciovaný nebo není řetězec, nemusíte řešit. Můžete předpokládat, že všechna slova a čárky ve vstupním řetězci jsou od sebe oddělené mezerami. Můžete také předpokládat, že vstupní řetězec neobsahuje více mezer po sobě. Všimněte si, že v žádném případě interpret jazyka Prolog nenabízí žádné další řešení. Vaše řešení by se mělo chovat stejně, pokud má být ohodnoceno plným počtem bodů. Nápověda Pokud si chcete ulehčit život, doporučujeme rozdělit si úkol na dva podúkoly. Nejprve naprogramujte predikát splitString/2, který do druhého argumentu unifikuje seznam všech slov a čárek, které se vyskytují v řetězci v prvním argumentu. Například: ?- splitString("zena , ktera zpiva krasnou pisen , vidi ostrou ruzi", X). X = ["zena", ",", "ktera", "zpiva", "krasnou", "pisen", ",", "vidi", "ostrou", "ruzi"]. Při programování predikátu splitString se vám můžou hodit predikáty na práci s řetězci. Ty můžete vyhledat dotazem ?- apropos(string).. Poté naprogramujte predikát v/1, který uspěje právě tehdy, když je seznam slov a čárek správně utvořená věta. Například: ?- v(["zena", ",", "ktera", "zpiva", "krasnou", "pisen", ",", "zpiva", "ruzi"]). true. Poté vyjádřit predikát isCorrectSentence pomocí těchto predikátů už bude jednoduché. Odevzdávání a bodování Váš program odevzdávejte do příslušné odevzdávárny1 . Odevzdávejte jeden soubor s příponou .pl, který obsahuje okomentovaný zdrojový kód. Do komentářů slovně popište, jak jste při řešení příkladu postupovali. Čas na vypracování úkolu je do středy 21. prosince (včetně). Za celou úlohu můžete dostat dva body. První bod je za funkčnost kódu, druhý bod je za jeho čitelnost, smysluplnost a slovní popis. Je možné získat i desetinné body, pokud bude řešení jen částečně správně. Oba body uděluje cvičící. 1https://is.muni.cz/auth/el/1433/podzim2016/IB015/ode/ode_hw12/ 2