Praktikum z logického programování (kombi) -Cvičeni c. 1 KOMBINOVANÉ: ÚVOD A ZÁKLADY Organizace •4x cvičení v pátky od cca 8h v učebně B3a •15. 3., 26. 4., 10. 5., 24. 5. •Ukončení: zápočet •Podmínky zápočtu: •Povinná účast na cvičení min. 75 % (3 z 4) •Aktivní práce na cvičeních •Písemná forma ověření studijních výsledků PRAKTIKUM Z LOGICKÉHO PROGRAMOVÁNÍ (LÉTO 2024) 2 Co je to Prolog? 1. Logický programovací jazyk: 1. Prolog je logický programovací jazyk, který se zaměřuje na popis cílů výpočtu. 2. Programátor specifikuje, co chce dosáhnout, a systém se snaží najít odpovídající řešení. 2. Deklarativní charakter: 1. Prolog patří mezi deklarativní jazyky. 2. Programátor popisuje, co chce, aniž by specifikoval konkrétní postup výpočtu. 3Jednoduchá syntaxe: 1. Syntaxe Prologu je snadno čitelná a použitelná. 2. Umožňuje specifikovat fakta, pravidla a dotazy. 4. Využití v umělé inteligenci a lingvistice: 1. Prolog se často používá v oblasti umělé inteligence, prohledávání databází a zpracování přirozeného jazyka. 5. Původ názvu: 1. Název „Prolog" pochází z francouzského „PROgrammation en LOGique" („logické programování"). PRAKTIKUM Z LOGICKÉHO PROGRAMOVÁNÍ (LÉTO 2024) 3 Zápis klauzulí v Prologu •Program v Prologu je konečná neprázdná množina Hornových klauzulí • Klauzule s nejvýše jedním pozitivním literálem •Dva druhy klauzulí: fakty - tvrzení bez předpokladů, je to obdoba toho, co jsme měli v předchozí kapitole jako speciální axiomy • pravidla - obecná tvrzení ve tvaru „Závěr platí, pokud platí všechny jeho předpoklady zároveň/' Používání programu spočívá v zadávání dotazů (cílových klauzulí) - Hornových klauzulí bez pozitivních literálů. Prolog dotazy vyhodnocuje podle programu a podle vnitřních pravidel (obdoba logických axiomů). PRAKTIKUM Z LOGICKÉHO PROGRAMOVÁNÍ (LÉTO 2024) Zápis klauzulí v Prologu Příkazy se ukončují tečkou •Pravidla jsou tvaru hlava pravidla:- tělo pravidla. •Pro klausulární logiku antecedent konsekvent • Antecedent === tělo pravidla v prologu • Konsekvent === hlava pravidla v prologu •Výzva pro dotaz má tvar ?- dotaz. Klauzulární logika Predikátová klauzule Zápis v Prologu Pravidlo B,C,D A A V ->B V ->C V ->D A:-B,C,D. Fakt A A A. Dotaz B,C,D^ ^BV^CV ->D ?- B, C, D. PRAKTIKUM Z LOGICKÉHO PROGRAMOVÁNÍ (LÉTO 2024) 5 Zápis klauzulí v Prologu •Disjunkce (OR) v těle pravidla (; středník mezi atomy) •koupit(X) :-snedeno(X); vypito(X). • Dle vztahu v klauzulární logice (Fl OR F2 -> K) <=> ((Fl -> K) AND (F2 -> K)) je ekvivalentní pro dvě pravidla: • koupit(X):- snedeno(X). • koupit(X):- vypito(X). •Konjunkce (AND) v hlavě pravidla (, čárka mezi atomy) • Nepoužívá se v Prologu! <- Hornovy klauzule! • Převod dle vztahu v klauzulární logice (A -> Fl AND F2) <=> ((A -> Fl) AND (A -> F2)) na dvě pravidla! PRAKTIKUM Z LOGICKÉHO PROGRAMOVÁNÍ (LÉTO 2024) 6 Zápis elementů •Proměnné zapisujeme velkým počátečním písmem Proměnna, X, Auto •Konstanty zapisujeme malým počátečním písmenem konstanta, zíuta, jan, 8, "Petr", 'Alice' •predikat/2: predikat(parametrl, parametr2) otecfjan, klara). •Pravidla: závěr:- předpokladl, předpoklad2,... I ovi (Kdo, Koho) :- kocka (Kdo), mys(Koho). V predikátové logice: kocka (Kdo) & mys(Koho) -> lovi(Kdo, Koho) PRAKTIKUM Z LOGICKÉHO PROGRAMOVÁNÍ (LÉTO 2024) 7 Prolog a klausulární logika •Klauzule: hlava :- tělo. vs. antecedent -> konsekvent •Atomy a spojky (čárka AND a středník OR) • Hornovy klauzule - maximálně jeden atom v hlavě (konsekventu) •Fakta: pouze_hlava. •Dotaz: ?- pouze_telo. • Pravidlo: hlava :- telo. •Atom (atomická formule) •Logická konstanta (true, false) • Predikát s danou aritou (počet argumentů - termů) • Uživatelsky definované nebo vestavěné • predikat/2: predikat(terml, term2). • Vrací true nebo false PRAKTIKUM Z LOGICKÉHO PROGRAMOVÁNÍ (LÉTO 2024) 8 Prolog a klausulární logika •Term •Proměnná: X <- vždy počáteční velké písmeno •Anonymní proměnná: _1,... <- začíná podtržítkem, náhrada za existenční termy •Konstanta: eva, "Jan", 'ALÍK', 8 <- malé počáteční písmeno nebo apostrof/uvozovky nebo číslo (integer i float) • Funktor s danou aritou (počet argumentů - termů) • Uživatelsky definované nebo vestavěné • funktor/2: funktor(terml, term2). • Vrací hodnotu! • Infixová A + B nebo prefixová +(A,B) notace <- podobně u predikátů (atomů) PRAKTIKUM Z LOGICKÉHO PROGRAMOVÁNÍ (LÉTO 2024) 9 Prolog a klausulární logika •Bázový atom - atom, jehož parametry (termy) jsou bázové termy •Bázový term - term, který neobsahuje proměnnou (ani anonymní!) PRAKTIKUM Z LOGICKÉHO PROGRAMOVÁNÍ (LÉTO 2024) 10 Příklad - převod z klauzulemi logiky 1. „Jahoda je červená/' Klauzulární logika: ? Prolog: ? 2. „Psi mají čtyři nohy/' Klauzulární logika: ? Prolog: ? 3. „Děti mají rády sladká jídla/' Klauzulární logika: ? Prolog: ? PRAKTIKUM Z LOGICKÉHO PROGRAMOVÁNÍ (LÉTO 2024) 11 Příklad - převod z klauzulární logiky 1. „Jahoda je červená/' Klauzulární logika: -> barva(jahoda, červena) Prolog: ? 2. „Psi mají čtyři nohy/' Klauzulární logika: pes(X) -> pocet_nohou(X, 4) Prolog: ? 3. „Děti mají rády sladká jídla/' Klauzulární logika: dite(X), jidlo(Y ), chut(Y, sladký) -> ma_rad(X, Y) Prolog: ? PRAKTIKUM Z LOGICKÉHO PROGRAMOVÁNÍ (LÉTO 2024) 12 Příklad - převod z klauzulární logiky 1. „Jahoda je červená/' Klauzulární logika: -> barvaQahoda, červena) Prolog: barvaQahoda,červena). 2. „Psi mají čtyři nohy/' Klauzulární logika: pes(X) -> pocet_nohou(X, 4) Prolog: pocet_nohou(X,4) :- pes(X). 3. „Děti mají rády sladká jídla/' Klauzulární logika: dite(X), jidlo(Y ), chut(Y, sladký) -> ma_rad(X, Y) Prolog: ma_rad(X,Y) :- dite(X), jidlo(Y), chut(Y,sladky). PRAKTIKUM Z LOGICKÉHO PROGRAMOVÁNÍ (LÉTO 2024) 13 Znalostní báze •Množina tvrzení (pravidel) o uzavřeném modelovaném světě mezi nimiž je vztah konjunkce (AND) •Pravidla jsou tvaru hlava pravidla :- tělo pravidla. •Skládá se z: •fakta - množina elementů, která má prázdné tělo a neprázdnou hlavu (ekvivalent v klausulární logice je true -> Konsekvent) • pes(azor). • pravidla - množina elementů, která nemá prázdné ani tělo ani hlavu (v klasulární logice Anteceden -> Konsekvent) • ma_prázdniny(X):- skolak(X), obdobi(leto). PRAKTIKUM Z LOGICKÉHO PROGRAMOVÁNÍ (LÉTO 2024) 14 Pravidla pro sestavování znalostní báze •předem si promyslíme názvy predikátů a konstant tak, aby byly citelné pro uživatele, připadne můžeme přidávat komentáře, •pokud se proměnná vyskytuje v klauzuli pouze jednou, použijeme anonymní proměnnou, •funktory používáme jen tehdy, když je to opravdu nutné a bereme na vědomí, že funktor lze používat spíše jen jako argument predikátu, •v bázi uvedeme nejdřív fakty a pak pravidla, zvláště vjořípadě, že některá pravidla mají v hlave shodný predikát s příslušným faktem, •jestliže se v pravidle vyskytuje rekurze, toto pravidlo uvedeme jako poslední ze všech klauzuli, které mají v hlavě tentýž predikát, •pokud je v klauzuli atom negovaný predikátem not, pak tento atom uvádíme v klauzuli jako poslední, •všímáme si také nepřímé rekurze PRAKTIKUM Z LOGICKÉHO PROGRAMOVÁNÍ (LÉTO 2024) 15 ?- Dotazy •Zajímá nás pravdivost predikátu - všechny atomy jsou bazove ?- prchafmicka, zoubek), true •Zajímají nás všechny kombinace pro které je dotaz splnitelný - proměnná ?- prcha[X, zoubek). X = micka •Existuje hodnota, kterou lze dosadit - anonymní proměnná ?- prcha(_, zoubek). true PRAKTIKUM Z LOGICKÉHO PROGRAMOVÁNÍ (LÉTO 2024) 16 Zvýraznění syntaxe •jasně červené jsou predikáty, které jsou použity pouze v klauzulích typu fakt nebo v hlavách klauzulí odpovídajících pravidlům (v predikátové nebo kauzulární logice by byly jen „za implikací"), •tučné černé jsou predikáty nacházející se v hlavách klauzulí, které se vyskytují i v tělech jiných klauzulí, •netučné černé jsou predikáty v tělech klauzulí, •modré jsou operátory a některé vestavěné predikáty (například write/1), •červenohnědé jsou proměnné, tučné tmavé červené jsou chyby, •zelené jsou komentáře (komentářovým symbolem je procento). PRAKTIKUM Z LOGICKÉHO PROGRAMOVÁNÍ (LÉTO 2024) 17 Zvýraznění syntaxe •Proč Prolog zabarvuje predikáty v hlavách klauzulí (a ve faktech) některé jasně červenou a jiné černou barvou? •Protože ty černé se v jiných klauzulích nacházejí na opačné straně implikace, a tedy je možné použít je jako „spojovací materiál" při unifikaci a následné rezoluci, když z takových dvou klauzulí chceme něco odvodit. •Atomy s predikáty zabarvenými jasně červenou barvou nejsou chybné, jen se Prologu moc nelíbí, že nebude možné využít je pro rezoluci s jinou klauzulí. PRAKTIKUM Z LOGICKÉHO PROGRAMOVÁNÍ (LÉTO 2024) 18 Příklad: ma rad •Zadání: • Petr má rád květiny, Ivanu a televizi. •Jan má rád jitrnice a televizi. •Věra má ráda všechno, co má rád Jan •Dotazy: • Má rád Petr televizi? • Má rád Jan květiny? •Co má rád Jan? • Kdo má rád jitrnice? •Co má rád Petr a zároveň Jan? • Kdo má co (koho) rád? PRAKTIKUM Z LOGICKÉHO PROGRAMOVÁNÍ (LÉTO 2024) 19 Příklad: zvířata •Zadání • Hektor a Lea jsou lvi, Zulejda je zajíc. • Lvi jsou silní a velcí, mají žlutou barvu. •Zajíci jsou rychlí a mají hnědou barvu. • Kdo je silný a velký, je králem zvířat. •Dotazy •Je Zulejda lev? •Je Lea králem zvířat? • Kdo je lev? •Kdo je rychlý? •Kdo je hnědý? Kdo má jakou barvu? PRAKTIKUM Z LOGICKÉHO PROGRAMOVÁNÍ (LÉTO 2024) 20 Nápověda •apropos/l - pro hledání vestavěných predikátů, kde přesně nevíme jak se jmenuje, ale známe nějaké klíčové slovo aproposfinto the database'). •help/l - potřebujeme nápovědu k vestavěnému predikátu •help(asserta). •+arjgument musí být instanciovaný, tedy mít už předem přirazenu nějakou hodnotu •-argument zde má být proměnná •?argument instanciovaný parametr nebo proměnná •@argument parametr nebude vázán unifikací • :argument jedná se o název predikátu PRAKTIKUM Z LOGICKÉHO PROGRAMOVÁNÍ (LÉTO 2024) 21 Příklad: sub_string •help('sub_string'). •sub_string(+String, PBefore, PLength, PAfter, PSubString) •sub_string("zadanretezecl23", 5, 7, Zbytek, Substr). •Sub - vrací podřetězec délky 7 začínající na páté pozici Zbytek - vrací počet zbývajících znaků •sub_string(Mzadanretezecl23M, 5, 7, _, Substr). •Když nás nezajímá výsledek nějakého parametru, použijeme anonymní proměnnou •sub_string(Mvstupl23 x2123yt", Pozice, _, _, "123"). Zajímají nás všechny pozice hledaného podřetězce PRAKTIKUM Z LOGICKÉHO PROGRAMOVÁNÍ (LÉTO 2024) 22 Přiřazování, porovnávání, unifikace •Jiný přístup nežli v procedurálních jazycích (např. C) •Predikáty -> true/false •Operátor is • Číslo is Výraz • Pokud je Číslo (zpravidla volná proměnná) úspěšně unifikováno s výsledkem Výrazu vrací true • Číslo je v relaci s hodnotou výrazu • Všechny proměnné, které se (případně) vyskytují ve Výrazu, musí být v okamžiku splňování cíle inicializované (vázané) na číselnou hodnotu jinak dojde k chybě! • ?- X is 1+4. • X = 5 • ?- 5 is 1+4. • true PRAKTIKUM Z LOGICKÉHO PROGRAMOVÁNÍ (LÉTO 2024) 23 Přiřazování, porovnávání, unifikace •Operátor = •Uspěje, pokud se oba argumenty povede unifikovat . ?- X = 1+4. • X = 1+4 •Pokud je jedna proměnná specifikovaná a druhá nespecifikovaná, stanou se obě proměnné specifikované stejnou hodnotou • ?- X is 5, X = Y. . x = Y, Y = 5 •Pokud jsou obě proměnné specifikované, porovnají se • ?- X is 5, Y is 6, X = Y. • falše PRAKTIKUM Z LOGICKÉHO PROGRAMOVÁNÍ (LÉTO 2024) 24 Přiřazování, porovnávání, unifikace •Operátor = •Jsou-li obě proměnné nespecifikovány, stanou se sdílenými. Stane-li se později jedna z nich specifikovanou, bude stejnou hodnotou specifikována i druhá proměnná • X = X Y = Z, Z is 1+4, write(X). • 5 • Dvě struktury jsou si rovny, pokud se jedná o dva stejné funktory, souhlasí počet parametrů a jednotlivé termy jsou si rovny • ?-1+2 = 1+2. true • ?-1+2 = 2+1. falše PRAKTIKUM Z LOGICKÉHO PROGRAMOVÁNÍ (LÉTO 2024) 25 Přiřazování, porovnávání, unifikace •Operátor =:= (rovno) •Provede výpočet, neprovede unifikaci -> nelze ho použít na volnou proměnnou • ?-1+2=:= 2+1. • true • ?-X=:= 1. • Arguments are not sufficiently instantiated •Operátor == (totožnost) • Neprovádí výpočet, pouze porovná •Slouží pro porovnání řetězců . ?_ 5 + 6 == 5 + 6. • true . ?- 6 + 5 == 5 + 6. • falše PRAKTIKUM Z LOGICKÉHO PROGRAMOVÁNÍ (LÉTO 2024) 26 Přiřazování, porovnávání, unifikace •Další operátory porovnání •Aritmetické • <, >, =<, <= ^- pozor kde se píše rovnítko! •Tabulka s porovnáním operátorů Predikát Význam Provádí unifikaci? Provádí výpočet? — shoduje se ano, obě strany ne \= neshoduje se, totéž jako not(...=...) ne ne is přiřazení ano, levá strana ano, pravá strana =: = vyhodnotí, ověří shodu ne ano, obě strany =\= vyhodnotí, ověří neshodu ne ano, obě strany == pouze porovná, ověří shodu ne ne \== pouze porovná, ověří neshodu ne ne PRAKTIKUM Z LOGICKÉHO PROGRAMOVÁNÍ (LÉTO 2024) 27 Aritmetické operátory - funktorý •Vrací hodnotu •Pro přiřazení do proměnné se použije is • ?- X is 5 ** 2 •Infixová i prefixová varianta •+# -# *# If ** (mocnina) // (celočíselné dělení), rem (zbytek po celočíselném dělení//) •div (celočíselné dělení se zaokrouhlením dolů), mod (zbytek po celočíselném dělení div) •max (maximum), min (minimum) • Pouze prefixová varianta • Arita 2 - max(term_cislo_l, term_cislo_2). PRAKTIKUM Z LOGICKÉHO PROGRAMOVÁNÍ (LÉTO 2024) 28 Bitové operátory - funktory •» (bitový posun vpravo), « (bitový posun vlevo) •\ (bitová negace) - unární funktor •?- X is \ 1. •V (bitové OR), A (bitové AND) •xor (bitový XOR) PRAKTIKUM Z LOGICKÉHO PROGRAMOVÁNÍ (LÉTO 2024) 29 Testování typů údajů Při práci s aritmetickými výrazy (ale i jindy) potřebujeme znalost o skutečném typu hodnoty uložené do proměnné či jiného termu. K tomuto účelu slouží vestavěné predikáty Predikát Význam - testuje, zda je argument ... atom(argument) atom, také řetězcová konstanta atomic(argument) atom, konstantní číslo, řetězec integer(argument) celé číslo, také v proměnné float(argument) racionální číslo, také v proměnné number(argument) číslo, také v proměnné string(argument) řetězec, také v proměnné var(argument) volná proměnná nonvar(argument) vázaná proměnná PRAKTIKUM Z LOGICKÉHO PROGRAMOVÁNÍ (LÉTO 2024) 30 Testování typů údajů •Volná vs. vázaná proměnná •Vázaná proměnná je asociovaná s konkrétní hodnotou •Volná proměnná nemá stanoveno co obsahuje • ?- X=2,var(X). • falše • ?- X=2,nonvar(X). •X = 2 PRAKTIKUM Z LOGICKÉHO PROGRAMOVÁNÍ (LÉTO 2024) 31 Jednoduchý vstup a výstup •write/l-vypíše svůj parametr, nevyhodnocuje ho •display/l - provede něco podobného, výraz chápe jako výraz, ale nevyhodnotí ho •nl/0 - přechod na nový řádek (new line) •read/1 - načte vstup od uživatele PRAKTIKUM Z LOGICKÉHO PROGRAMOVÁNÍ (LÉTO 2024) 32 Negace •Prologu lze využívat pouze Hornovy klauzule •Maximálně jeden pozitivní literál -> maximálně jeden atom v konsekventu -> maximálně jeden atom v hlavě klausule (pravidla) • Nemůžeme libovolně přesouvat atomy z antecedentu (tělo) do konsekventu (hlava) a naopak •Speciální predikát not •not(p(a,Y)). • Nejdříve se vyhodnotí predikát p -> true/false -> hodnota se převrátí • Když p je true -> fakt je odvoditelný z báze • not(p) -> negace není odvoditelná z báze PRAKTIKUM Z LOGICKÉHO PROGRAMOVÁNÍ (LÉTO 2024) 33