Programovací jazyk Prolog Logické programování Šárka Vavrečková Ústav informatiky, Filozoficko-přírodovědecká fakulta Slezské univerzity v Opavě sarka.vavreckova@fpf.slu.cz 1. prosince 2008
Prolog Co je to Prolog Prolog je jazyk pro logické programování, vznikl ve Francii v roce 1973 (prof. A. Colmerauer). Je to zkratka z francouzského PROgramation à LOGic ( programování v logice ). Je to interpretační deklarativní jazyk.
Prolog Varianty Prologu SWI Prolog šířený pod GNU licencí a používaný v Unixech, Linuxu a Windows, LPA Win Prolog je komerční program pro Windows považovaný za jeden z nejlepších pro tuto platformu, GNU Prolog pro Unixy a Linux, OpenProlog pro MacOS, Amzi! Prolog, Visual Prolog, Strawbery Prolog, atd., rozšíření: Fuzzy Prolog, Templog, Chronolog, Temporal Prolog, Mercury, atd. Viz www.fpf.slu.cz/ ~ vav10ui/vyukaprol.html.
Prolog Rozdíly mezi variantami licence (některé jsou komerční, jiné volně šiřitelné, také pod GPL (SWI Prolog, GNU Prolog), grafické rozhraní vždy je přítomna konzola na zadávání příkazů, ale může vypadat jinak, dále v rozhraní může/nemusí být editor samotných programů(znalostních bází), rozdíl v ovládání, klávesových zkratkách, atd., predikáty pro vstupy a výstupy, včetně práce se soubory někdy bývají jinak nazvány, případně jinak fungují, to je často způsobeno tím, že bývají psány pro různé SW platformy, další přidané predikáty, které nejsou v základní normě pro Prolog, přípony zdrojového souboru programu, atd.
Používání Prologu Postup 1. Vytvoříme znalostní bázi = program popisující svět, ve kterém se budeme pohybovat. 2. Zadáváme dotazy (cílové klauzule), Prolog odpovídá nebo no podle toho, zda je formule dotazu splnitelná v zadaném programu (světě), nebo vypíše hodnoty parametrů, pro které je splnitelná (ohodnocení). 3. Prolog rozhoduje podle našeho programu, vnitřních pravidel obdoby logických axiomů v klauzulární logice.
Používání Prologu Postup 1. Vytvoříme znalostní bázi = program popisující svět, ve kterém se budeme pohybovat. 2. Zadáváme dotazy (cílové klauzule), Prolog odpovídá nebo no podle toho, zda je formule dotazu splnitelná v zadaném programu (světě), nebo vypíše hodnoty parametrů, pro které je splnitelná (ohodnocení). 3. Prolog rozhoduje podle našeho programu, vnitřních pravidel obdoby logických axiomů v klauzulární logice.
Používání Prologu Postup 1. Vytvoříme znalostní bázi = program popisující svět, ve kterém se budeme pohybovat. 2. Zadáváme dotazy (cílové klauzule), Prolog odpovídá nebo no podle toho, zda je formule dotazu splnitelná v zadaném programu (světě), nebo vypíše hodnoty parametrů, pro které je splnitelná (ohodnocení). 3. Prolog rozhoduje podle našeho programu, vnitřních pravidel obdoby logických axiomů v klauzulární logice.
Používání Prologu Postup 1. Vytvoříme znalostní bázi = program popisující svět, ve kterém se budeme pohybovat. 2. Zadáváme dotazy (cílové klauzule), Prolog odpovídá nebo no podle toho, zda je formule dotazu splnitelná v zadaném programu (světě), nebo vypíše hodnoty parametrů, pro které je splnitelná (ohodnocení). 3. Prolog rozhoduje podle našeho programu, vnitřních pravidel obdoby logických axiomů v klauzulární logice.
Používání Prologu Postup 1. Vytvoříme znalostní bázi = program popisující svět, ve kterém se budeme pohybovat. 2. Zadáváme dotazy (cílové klauzule), Prolog odpovídá nebo no podle toho, zda je formule dotazu splnitelná v zadaném programu (světě), nebo vypíše hodnoty parametrů, pro které je splnitelná (ohodnocení). 3. Prolog rozhoduje podle našeho programu, vnitřních pravidel obdoby logických axiomů v klauzulární logice.
Program v Prologu Definice Program v Prologu je konečná neprázdná množina Hornových klauzulí. Je to ekvivalent znalostní báze klauzulární logiky a množiny speciálních axiomů Klauzulárního axiomatického systému. V programu lze použít dva druhy klauzulí: pravidla obecná tvrzení ve tvaru Závěr platí, pokud platí všechny jeho předpoklady zároveň. fakty konstantní tvrzení Používání programu spočívá v zadávání dotazů (cílových klauzulí) Hornových klauzulí bez pozitivních literálů.
Zápis klauzulí v Prologu Převod z klauzulární logiky Klauzulární logika Množinový zápis Zápis v Prologu Pravidlo B, C, D A A, B, C, D A :- B, C, D. Fakt A A A. Dotaz B, C, D B, C, D?- B, C, D. Tvar pravidla:
Zápis klauzulí v Prologu Převod z klauzulární logiky Klauzulární logika Množinový zápis Zápis v Prologu Pravidlo B, C, D A A, B, C, D A :- B, C, D. Fakt A A A. Dotaz B, C, D B, C, D?- B, C, D. Tvar pravidla: Predikat1(param) :- Predikat2(param), Predikat3(param),...
Zápis klauzulí v Prologu Převod z klauzulární logiky Klauzulární logika Množinový zápis Zápis v Prologu Pravidlo B, C, D A A, B, C, D A :- B, C, D. Fakt A A A. Dotaz B, C, D B, C, D?- B, C, D. Tvar pravidla: Predikat1(param) :- Predikat2(param), Predikat3(param),... hlava tělo
Zápis klauzulí v Prologu Převod z klauzulární logiky Klauzulární logika Množinový zápis Zápis v Prologu Pravidlo B, C, D A A, B, C, D A :- B, C, D. Fakt A A A. Dotaz B, C, D B, C, D?- B, C, D. Tvar pravidla: Predikat1(param) :- Predikat2(param), Predikat3(param),... hlava tělo klauzule
Programujeme v Prologu Postup 1. Vytvoříme textový soubor s příponou.pl, do kterého uložíme program (fakty a pravidla). Každý příkaz musí být na samostatném řádku (nebo na více řádcích), končí tečkou, komentáře jsou řádky začínající znakem %. 2. Načteme tento soubor (po uložení) do editoru Prologu (příkazem consult, případně položkou v menu (consult nebo compile) s tím, že před volbou v menu je vhodné soubor s programem v editoru Prologu otevřít). 3. Na výzvu Prologu (prompt, je to dvojznak?-, znamená zadej dotaz ) zadáváme dotazy, Prolog vypisuje odpovědi.
Programujeme v Prologu Postup 1. Vytvoříme textový soubor s příponou.pl, do kterého uložíme program (fakty a pravidla). Každý příkaz musí být na samostatném řádku (nebo na více řádcích), končí tečkou, komentáře jsou řádky začínající znakem %. 2. Načteme tento soubor (po uložení) do editoru Prologu (příkazem consult, případně položkou v menu (consult nebo compile) s tím, že před volbou v menu je vhodné soubor s programem v editoru Prologu otevřít). 3. Na výzvu Prologu (prompt, je to dvojznak?-, znamená zadej dotaz ) zadáváme dotazy, Prolog vypisuje odpovědi.
Programujeme v Prologu Postup 1. Vytvoříme textový soubor s příponou.pl, do kterého uložíme program (fakty a pravidla). Každý příkaz musí být na samostatném řádku (nebo na více řádcích), končí tečkou, komentáře jsou řádky začínající znakem %. 2. Načteme tento soubor (po uložení) do editoru Prologu (příkazem consult, případně položkou v menu (consult nebo compile) s tím, že před volbou v menu je vhodné soubor s programem v editoru Prologu otevřít). 3. Na výzvu Prologu (prompt, je to dvojznak?-, znamená zadej dotaz ) zadáváme dotazy, Prolog vypisuje odpovědi.
Programujeme v Prologu Konzultování programu Načtení (přeložení, konzultování) programu je nutné, protože Prolog si program udržuje v interním kódu, se kterým se mu pracuje jednodušeji a především rychleji. Při každé změně v souboru programu musíme (samozřejmě po uložení těchto změn) program znovu načíst, aby si Prolog mohl tento interní kód obnovit.
Programujeme v Prologu Konzultování programu Načtení (přeložení, konzultování) programu je nutné, protože Prolog si program udržuje v interním kódu, se kterým se mu pracuje jednodušeji a především rychleji. Při každé změně v souboru programu musíme (samozřejmě po uložení těchto změn) program znovu načíst, aby si Prolog mohl tento interní kód obnovit.
Příklad Zadání V programu budou tyto klauzule: 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. V klauzulární logice ma rad(petr, kvetiny) ma rad(petr, ivana) ma rad(petr, televize) ma rad(jan, jitrnice) ma rad(jan, televize) ma rad(jan, X) ma rad(vera, X)
Příklad Zadání V programu budou tyto klauzule: 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. V klauzulární logice ma rad(petr, kvetiny) ma rad(petr, ivana) ma rad(petr, televize) ma rad(jan, jitrnice) ma rad(jan, televize) ma rad(jan, X) ma rad(vera, X)
Příklad V klauzulární logice ma rad(petr, kvetiny) ma rad(petr, ivana) ma rad(petr, televize) ma rad(jan, jitrnice) ma rad(jan, televize) ma rad(jan, X) ma rad(vera, X) V Prologu ma_rad(petr,kvetiny). ma_rad(petr,ivana). ma_rad(petr,televize). ma_rad(jan,jitrnice). ma_rad(jan,televize). ma_rad(vera,x):-ma_rad(jan,x).
Příklad V klauzulární logice ma rad(petr, kvetiny) ma rad(petr, ivana) ma rad(petr, televize) ma rad(jan, jitrnice) ma rad(jan, televize) ma rad(jan, X) ma rad(vera, X) V Prologu ma_rad(petr,kvetiny). ma_rad(petr,ivana). ma_rad(petr,televize). ma_rad(jan,jitrnice). ma_rad(jan,televize). ma_rad(vera,x):-ma_rad(jan,x).
Anonymní proměnná Anonymní proměnná Použití Anonymní proměnná nahrazuje existenční termy: zapisuje se znakem podtržítka nebo tímto podtržítkem začíná: _, _Prom pro argument, ve kterém je použita, existuje hodnota, kterou tam lze dosadit, ale tato hodnota nás nezajímá, také použijeme místo běžné proměnné, pokud se tato proměnná vyskytuje v těle pravidla pouze jednou.
Anonymní proměnná Program lovi(liska,zajic). lovi(orel,mys). lovi(orel,vrabec). lovi(honza,ryba). dravec(x) :- lovi(x,_). Dotazy?- dravec(_).?- lovi(liska,_). Liška loví zajíce. Orel loví myš. Orel loví vrabce. Honza loví rybu. Kdo někoho loví, je dravec.?- lovi(x,_). X = liska ; X = orel ; X = honza ; no
Anonymní proměnná Program lovi(liska,zajic). lovi(orel,mys). lovi(orel,vrabec). lovi(honza,ryba). dravec(x) :- lovi(x,_). Dotazy?- dravec(_).?- lovi(liska,_). Liška loví zajíce. Orel loví myš. Orel loví vrabce. Honza loví rybu. Kdo někoho loví, je dravec.?- lovi(x,_). X = liska ; X = orel ; X = honza ; no
Anonymní proměnná Program lovi(liska,zajic). lovi(orel,mys). lovi(orel,vrabec). lovi(honza,ryba). dravec(x) :- lovi(x,_). Dotazy?- dravec(_).?- lovi(liska,_). Liška loví zajíce. Orel loví myš. Orel loví vrabce. Honza loví rybu. Kdo někoho loví, je dravec.?- lovi(x,_). X = liska ; X = orel ; X = honza ; no
Anonymní proměnná Program lovi(liska,zajic). lovi(orel,mys). lovi(orel,vrabec). lovi(honza,ryba). dravec(x) :- lovi(x,_). Dotazy?- dravec(_).?- lovi(liska,_). Liška loví zajíce. Orel loví myš. Orel loví vrabce. Honza loví rybu. Kdo někoho loví, je dravec.?- lovi(x,_). X = liska ; X = orel ; X = honza ; no
Anonymní proměnná Program lovi(liska,zajic). lovi(orel,mys). lovi(orel,vrabec). lovi(honza,ryba). dravec(x) :- lovi(x,_). Dotazy?- dravec(_).?- lovi(liska,_). Liška loví zajíce. Orel loví myš. Orel loví vrabce. Honza loví rybu. Kdo někoho loví, je dravec.?- lovi(x,_). X = liska ; X = orel ; X = honza ; no
Anonymní proměnná Program lovi(liska,zajic). lovi(orel,mys). lovi(orel,vrabec). lovi(honza,ryba). dravec(x) :- lovi(x,_). Dotazy?- dravec(_).?- lovi(liska,_). Liška loví zajíce. Orel loví myš. Orel loví vrabce. Honza loví rybu. Kdo někoho loví, je dravec.?- lovi(x,_). X = liska ; X = orel ; X = honza ; no
Anonymní proměnná Program lovi(liska,zajic). lovi(orel,mys). lovi(orel,vrabec). lovi(honza,ryba). dravec(x) :- lovi(x,_). Dotazy?- dravec(_).?- lovi(liska,_). Liška loví zajíce. Orel loví myš. Orel loví vrabce. Honza loví rybu. Kdo někoho loví, je dravec.?- lovi(x,_). X = liska ; X = orel ; X = honza ; no
Aritmetické a relační operátory, predikát rovnosti Predikát rovnosti Použití aritmetické operátory jsou vlastně termy (vrací hodnotu obvykle odlišnou od pravdivostní), mohou být použity jen jako argument predikátu, relační operátory jsou predikáty, predikát rovnosti existuje, ale pro jeho použití existují přísná pravidla, jeho argumenty po interpretaci musí být identické, v logických programovacích jazycích je obvykle možné operátory používat v infixovém zápisu: Prefixový zápis: +(p,q) =(X,a) =(X,+(a,Y)) Infixový zápis: p + q X = a X = a + Y
Aritmetické a relační operátory, predikát rovnosti Program predikát rovnosti matka(pepa)=jana. otec(pepa)=honza. matka(honza)=emilka. otec(honza)=karel. matka(jana)=jitka. otec(jana)=albert. matka(albert)=katerina. babicka(vnouce,babicka) :- X=matka(Vnouce),Babicka=matka(X). babicka(vnouce,babicka) :- X=otec(Vnouce),Babicka=matka(X). dedecek(vnouce,dedecek) :- X=matka(Vnouce),Dedecek=otec(X). dedecek(vnouce,dedecek) :- X=otec(Vnouce),Dedecek=otec(X). prababicka(vnouce,prababicka) :- X=matka(Vnouce),babicka(X,Prababicka). prababicka(vnouce,prababicka) :- X=otec(Vnouce),babicka(X,Prababicka).
Aritmetické a relační operátory, predikát rovnosti Část programu interpretace funkcí matka(pepa)=jana. otec(pepa)=honza. matka(honza)=emilka. otec(honza)=karel. Dotazy?- dedecek(pepa,x). X = albert ; X = karel ; no?- prababicka(pepa,x). X = katerina ; no matka(jana)=jitka. otec(jana)=albert. matka(albert)=katerina.
Aritmetické a relační operátory, predikát rovnosti Část programu interpretace funkcí matka(pepa)=jana. otec(pepa)=honza. matka(honza)=emilka. otec(honza)=karel. Dotazy?- dedecek(pepa,x). X = albert ; X = karel ; no?- prababicka(pepa,x). X = katerina ; no matka(jana)=jitka. otec(jana)=albert. matka(albert)=katerina.
Aritmetické a relační operátory, predikát rovnosti Jak moc je predikát = použitelný? Zápisy typu matka(pepa)=jana. ve většině Prologů nefungují, protože to je považováno za pokus o předefinování vestavěného predikátu. Možnost použití: v těle klauzule pro unifikaci proměnné: hlava_klauzule :-..., X=jana,... funktory raději nepoužíváme.
Aritmetické a relační operátory, predikát rovnosti Jak moc je predikát = použitelný? Zápisy typu matka(pepa)=jana. ve většině Prologů nefungují, protože to je považováno za pokus o předefinování vestavěného predikátu. Možnost použití: v těle klauzule pro unifikaci proměnné: hlava_klauzule :-..., X=jana,... funktory raději nepoužíváme.
Aritmetické a relační operátory, predikát rovnosti Jak moc je predikát = použitelný? Zápisy typu matka(pepa)=jana. ve většině Prologů nefungují, protože to je považováno za pokus o předefinování vestavěného predikátu. Možnost použití: v těle klauzule pro unifikaci proměnné: hlava_klauzule :-..., X=jana,... funktory raději nepoužíváme.
Aritmetické a relační operátory, predikát rovnosti Operátory souhrn Relační operátory, konjunkce ; disjunkce = porovnání s unifikací, identita \= opak předchozího, nerovná se is vyčíslení (provede se vyhodnocení argumentů) <, >, =<, >= porovnání ==, \== porovnání bez přiřazení =:=, =\= porovnání bez přiřazení s vyhodnocením not negace Aritmetické operátory +, -, *, /, mod, div
Aritmetické a relační operátory, predikát rovnosti Přiřazování, porovnávání?- X = 1+1. X = 1+1?- X is 1+1. X = 2?- X == 1. no?- 1 == 1.?- 2 == 1+1. no?- 2 =:= 1+1.
Testování atomů Vestavěné predikáty na testování typu údajů atom(argument) vrátí true, jestliže je argument řetězcová konstanta atomic(argument) vrátí true, jestliže je argument konstanta (řetězcová, číselná) integer(argument) vrátí true, jestliže je argument celé číslo float(argument) vrátí true, jestliže je argument reálné číslo number(argument) vrátí true, jestliže je argument číslo
Testování atomů Vestavěné predikáty na testování typu údajů?- atom(neco).?- atom(2). no?- atomic(2).?- atomic(neco).?- atom(x). no?- integer(2).?- float(2.1).?- float(2). no
Testování atomů Vestavěné predikáty na testování typu údajů?- atom(neco).?- atom(2). no?- atomic(2).?- atomic(neco).?- atom(x). no?- integer(2).?- float(2.1).?- float(2). no
Testování atomů Vestavěné predikáty na testování typu údajů?- atom(neco).?- atom(2). no?- atomic(2).?- atomic(neco).?- atom(x). no?- integer(2).?- float(2.1).?- float(2). no
Testování atomů Vestavěné predikáty na testování typu údajů?- atom(neco).?- atom(2). no?- atomic(2).?- atomic(neco).?- atom(x). no?- integer(2).?- float(2.1).?- float(2). no
Testování atomů Vestavěné predikáty na testování typu údajů?- atom(neco).?- atom(2). no?- atomic(2).?- atomic(neco).?- atom(x). no?- integer(2).?- float(2.1).?- float(2). no
Testování atomů Vestavěné predikáty na testování typu údajů?- atom(neco).?- atom(2). no?- atomic(2).?- atomic(neco).?- atom(x). no?- integer(2).?- float(2.1).?- float(2). no
Testování atomů Vestavěné predikáty na testování typu údajů?- atom(neco).?- atom(2). no?- atomic(2).?- atomic(neco).?- atom(x). no?- integer(2).?- float(2.1).?- float(2). no
Testování atomů Vestavěné predikáty na testování typu údajů?- atom(neco).?- atom(2). no?- atomic(2).?- atomic(neco).?- atom(x). no?- integer(2).?- float(2.1).?- float(2). no
Negace Negace atomu Jak znegovat atom Nejdřív můžeme vyzkoušet postup známý z klauzulární logiky transfer atomu na druhou stranu implikace (včetně řešení kvantifikátorů): pokud vyjde Hornova klauzule (za implikací jen jediný atom), je to dostačující, v opačném případě transfer nelze použít, využijeme speciální predikát not. Predikát not je jeden z mála predikátů, které mají jako argument jiný predikát: not(p(arg 1,arg 2,...,arg n ))
Negace Negace atomu Jak znegovat atom Nejdřív můžeme vyzkoušet postup známý z klauzulární logiky transfer atomu na druhou stranu implikace (včetně řešení kvantifikátorů): pokud vyjde Hornova klauzule (za implikací jen jediný atom), je to dostačující, v opačném případě transfer nelze použít, využijeme speciální predikát not. Predikát not je jeden z mála predikátů, které mají jako argument jiný predikát: not(p(arg 1,arg 2,...,arg n ))
Negace Negace atomu Jak znegovat atom Nejdřív můžeme vyzkoušet postup známý z klauzulární logiky transfer atomu na druhou stranu implikace (včetně řešení kvantifikátorů): pokud vyjde Hornova klauzule (za implikací jen jediný atom), je to dostačující, v opačném případě transfer nelze použít, využijeme speciální predikát not. Predikát not je jeden z mála predikátů, které mají jako argument jiný predikát: not(p(arg 1,arg 2,...,arg n ))
Negace Negace atomu Jak funguje not(p(arg 1,arg 2,...,arg n )) nejdřív je vyhodnocen atom p(arg 1,arg 2,...,arg n ), pak je jeho pravdivostní hodnota převrácena, vrací informaci typu Jestliže p(...) je odvoditelný z báze (programu), pak not(p(...)) není odvoditelný z báze..
Negace Negace atomu Jak funguje not(p(arg 1,arg 2,...,arg n )) nejdřív je vyhodnocen atom p(arg 1,arg 2,...,arg n ), pak je jeho pravdivostní hodnota převrácena, vrací informaci typu Jestliže p(...) je odvoditelný z báze (programu), pak not(p(...)) není odvoditelný z báze..
Negace Negace atomu Jak funguje not(p(arg 1,arg 2,...,arg n )) Problém: proměnné vázané univerzálně ( ) se stávají volnými, neumí řešit existenční vazbu (nahrazení _), při vyhodnocení p(...) ještě funguje vazba na tytéž proměnné v předchozích atomech klauzule, ale za ním se ztrácí. Řešení: atom s predikátem not dáváme v klauzuli až za všechny atomy, které obsahují tytéž proměnné (třeba až na konec klauzule, např. r(a,b) :- p(x),not(q(x)),p(y).), klauzule obsahující negaci dáváme spíše za všechny klauzule obsahující proměnnou, která je zde negována a se kterými je zároveň unifikována během výpočtu.
Negace Negace atomu Jak funguje not(p(arg 1,arg 2,...,arg n )) Problém: proměnné vázané univerzálně ( ) se stávají volnými, neumí řešit existenční vazbu (nahrazení _), při vyhodnocení p(...) ještě funguje vazba na tytéž proměnné v předchozích atomech klauzule, ale za ním se ztrácí. Řešení: atom s predikátem not dáváme v klauzuli až za všechny atomy, které obsahují tytéž proměnné (třeba až na konec klauzule, např. r(a,b) :- p(x),not(q(x)),p(y).), klauzule obsahující negaci dáváme spíše za všechny klauzule obsahující proměnnou, která je zde negována a se kterými je zároveň unifikována během výpočtu.
Negace Negace atomu Jak funguje not(p(arg 1,arg 2,...,arg n )) Problém: proměnné vázané univerzálně ( ) se stávají volnými, neumí řešit existenční vazbu (nahrazení _), při vyhodnocení p(...) ještě funguje vazba na tytéž proměnné v předchozích atomech klauzule, ale za ním se ztrácí. Řešení: atom s predikátem not dáváme v klauzuli až za všechny atomy, které obsahují tytéž proměnné (třeba až na konec klauzule, např. r(a,b) :- p(x),not(q(x)),p(y).), klauzule obsahující negaci dáváme spíše za všechny klauzule obsahující proměnnou, která je zde negována a se kterými je zároveň unifikována během výpočtu.
Negace Program osobni(autopepy). osobni(autojany). nakladni(autostandy). ma_vozik(autojany). auto(x) :- osobni(x). auto(x) :- nakladni(x). velky_naklad(x) :- nakladni(x). velky_naklad(x) :- osobni(x),ma_vozik(x). maly_naklad(x) :- auto(x),not(velky_naklad(x)). Dotazy
Negace Program osobni(autopepy). osobni(autojany). nakladni(autostandy). ma_vozik(autojany). auto(x) :- osobni(x). auto(x) :- nakladni(x). velky_naklad(x) :- nakladni(x). velky_naklad(x) :- osobni(x),ma_vozik(x). maly_naklad(x) :- auto(x),not(velky_naklad(x)). Dotazy?- nakladni(x).
Negace Program osobni(autopepy). osobni(autojany). nakladni(autostandy). ma_vozik(autojany). auto(x) :- osobni(x). auto(x) :- nakladni(x). velky_naklad(x) :- nakladni(x). velky_naklad(x) :- osobni(x),ma_vozik(x). maly_naklad(x) :- auto(x),not(velky_naklad(x)). Dotazy?- nakladni(x). X = autostandy ; no
Negace Program osobni(autopepy). osobni(autojany). nakladni(autostandy). ma_vozik(autojany). auto(x) :- osobni(x). auto(x) :- nakladni(x). velky_naklad(x) :- nakladni(x). velky_naklad(x) :- osobni(x),ma_vozik(x). maly_naklad(x) :- auto(x),not(velky_naklad(x)). Dotazy?- osobni(x),not(x=autojany).
Negace Program osobni(autopepy). osobni(autojany). nakladni(autostandy). ma_vozik(autojany). auto(x) :- osobni(x). auto(x) :- nakladni(x). velky_naklad(x) :- nakladni(x). velky_naklad(x) :- osobni(x),ma_vozik(x). maly_naklad(x) :- auto(x),not(velky_naklad(x)). Dotazy?- osobni(x),not(x=autojany). X = autopepy ; no
Interní databáze Konzultování programu Na začátku práce s programem tento program načteme do interní databáze Prologu, konzultujeme. Kdykoliv provedeme změny, musíme znovu načíst program do databáze rekonzultovat. Konzultování se provádí buď položkou v menu programového prostředí Prologu (volba Consult, Reconsult, příp. Compile), a nebo příkazy (včetně tečky): consult( Název souboru s programem ). reconsult( Název souboru s programem ).
Interní databáze Konzultování programu Na začátku práce s programem tento program načteme do interní databáze Prologu, konzultujeme. Kdykoliv provedeme změny, musíme znovu načíst program do databáze rekonzultovat. Konzultování se provádí buď položkou v menu programového prostředí Prologu (volba Consult, Reconsult, příp. Compile), a nebo příkazy (včetně tečky): consult( Název souboru s programem ). reconsult( Název souboru s programem ).
Interní databáze Obsah databáze Když chceme vypsat momentální obsah databáze, použijeme příkaz listing. Když chceme vypsat pouze ty klauzule, které obsahují určitý predikát (třeba p), použijeme příkaz listing(p).
Interní databáze Obsah databáze Když chceme vypsat momentální obsah databáze, použijeme příkaz listing. Když chceme vypsat pouze ty klauzule, které obsahují určitý predikát (třeba p), použijeme příkaz listing(p).
Predikáty se stejným jménem V různých klauzulích Více klauzulí může mít stejný cíl, představují různá řešení téhož problému, z nichž některá končí popřením, jiná splněním cíle. V téže klauzuli Rekurze je základní výpočetní prvek Prologu, nastává tehdy, když v těle klauzule je stejný predikát jako v těle klauzule, v těle klauzule tento predikát umísťujeme spíše na konec, pokud není důvod pro jiné umístění.
Predikáty se stejným jménem V různých klauzulích Více klauzulí může mít stejný cíl, představují různá řešení téhož problému, z nichž některá končí popřením, jiná splněním cíle. V téže klauzuli Rekurze je základní výpočetní prvek Prologu, nastává tehdy, když v těle klauzule je stejný predikát jako v těle klauzule, v těle klauzule tento predikát umísťujeme spíše na konec, pokud není důvod pro jiné umístění.
Predikáty se stejným jménem V různých klauzulích Více klauzulí může mít stejný cíl, představují různá řešení téhož problému, z nichž některá končí popřením, jiná splněním cíle. V téže klauzuli Rekurze je základní výpočetní prvek Prologu, nastává tehdy, když v těle klauzule je stejný predikát jako v těle klauzule, v těle klauzule tento predikát umísťujeme spíše na konec, pokud není důvod pro jiné umístění.
Příklad výpočet faktoriálu Predikáty faktorial(cislo,vysl) tento predikát bude volán uživatelem v dotazu, faktorialpom(citac,vysl,vysl) bude použit pro samotný rekurzivní výpočet.
Příklad výpočet faktoriálu Predikáty faktorial(cislo,vysl) tento predikát bude volán uživatelem v dotazu, faktorialpom(citac,vysl,vysl) bude použit pro samotný rekurzivní výpočet. faktorialpom( Citac, Vysl, Vysl )
Příklad výpočet faktoriálu Predikáty faktorial(cislo,vysl) tento predikát bude volán uživatelem v dotazu, faktorialpom(citac,vysl,vysl) bude použit pro samotný rekurzivní výpočet. faktorialpom( Citac, Vysl, Vysl ) Čítač, snižuje seo1
Příklad výpočet faktoriálu Predikáty faktorial(cislo,vysl) tento predikát bude volán uživatelem v dotazu, faktorialpom(citac,vysl,vysl) bude použit pro samotný rekurzivní výpočet. faktorialpom( Citac, Vysl, Vysl ) Čítač, snižuje seo1 Počítá výsledek, nazačátku1
Příklad výpočet faktoriálu Predikáty faktorial(cislo,vysl) tento predikát bude volán uživatelem v dotazu, faktorialpom(citac,vysl,vysl) bude použit pro samotný rekurzivní výpočet. faktorialpom( Citac, Vysl, Vysl ) Čítač, snižuje seo1 Počítá výsledek, nazačátku1 Zde bude výsledek přístupný, na začátku proměnná
Příklad výpočet faktoriálu Program v Pascalu procedure faktorial(citac,vysl: integer); var C: integer; begin if (Citac=0) then Vysl := 1 else begin C := Citac-1; Vysl := Citac * faktorial(c,vysl); end; end;
Příklad výpočet faktoriálu Program v Prologu faktorialpom(0, Vysl, Vysl). faktorialpom(citac,pomocna,vysl) :- C is Citac - 1, V is Pomocna * Citac, faktorialpom(c,v,vysl). faktorial(citac,vysl) :- faktorialpom(citac,1,vysl). Dotaz?- faktorial(4,f). F = 24.
Příklad výpočet faktoriálu Program v Prologu faktorialpom(0, Vysl, Vysl). faktorialpom(citac,pomocna,vysl) :- C is Citac - 1, V is Pomocna * Citac, faktorialpom(c,v,vysl). faktorial(citac,vysl) :- faktorialpom(citac,1,vysl). Dotaz faktorial(3,f). faktorialpom(3,1,vysl). C = 3-1 = 2, V = 1*3 = 3 faktorialpom(2,3,vysl). C = 2-1 = 1, V = 2*3 = 6 faktorialpom(1,6,vysl). C = 1-1 = 0, V = 6*1 = 6 faktorialpom(0,6,vysl). F = Vysl.
Zajímavé odkazy Test Zone on-line editor Prologu http://kti.mff.cuni.cz/~bartak/prolog/testing.html Expertní systémy v Prologu http://www.amzi.com/expertsystemsinprolog/