Vestavěné predikáty (pokračování) Vstup a výstup program může číst data ze vstupního proudu (input stream) program může zapisovat data do výstupního proudu (output stream) dva aktivní proudy 3 aktivní vstupní proud M aktivní výstupní proud uživatelský terminál - user datový vstup z terminálu user chápán jako jeden ze vstupních proudů datový výstup na terminál chápán jako jeden z výstupních proudů soubor 1 soubor 2 uživatelsky terminal program user soubor 3 soubor 4 vstupni proudy vystupni proudy Hana Rudová, Logické programování I, 21. března 201 2 Vstupní a výstupní proudy: vestavěné predikáty M změna (otevření) aktivního vstupního/výstupního proudu: see(S)/tell (S) ctěni( Soubor ) :- see( Soubor ), cteni_ze_souboru( Informace ), see( user ). uzavření aktivního vstupního/výstupního proudu: seen/told Hana Rudová, Logické programování 1,21. března 201 2 3 Vstupní a výstupní proudy: vestavěné predikáty M změna (otevření) aktivního vstupního/výstupního proudu: see(S)/tell (S) ctěni( Soubor ) :- see( Soubor ), cteni_ze_souboru( Informace ), see( user ). uzavření aktivního vstupního/výstupního proudu: seen/told M zjištění aktivního vstupního/výstupního proudu: seeing(S)/tel 1 ing(S) ctěni( Soubor ) :- seeing( StarySoubor ), see( Soubor ), cteni_ze_souboru( Informace ), seen, see( StarySoubor ). Hana Rudová, Logické programování 1,21. března 201 2 3 Sekvenční přístup M čtení dalšího termu: read(Term) * při čtení jsou termy odděleny tečkou | ?- read(A), read( ahoj(B) ), k textovým souborům read( [C,D] ). Hana Rudová, Logické programování 1,21. března 201 2 4 Sekvenční přístup k textovým souborům M čtení dalšího termu: read(Term) M při čtení jsou termy odděleny tečkou | ?- read(A), read( ahoj(B) ), read( [C,D] ). |: ahoj. ahoj( petre ). [ ahoj( 'Petre!' ), jdeme ]. A = ahoj, B = petre, C = ahoj('Petre!'), D = jdeme Hana Rudová, Logické programování 1,21. března 201 2 4 Sekvenční přístup k textovým souborům M čtení dalšího termu: read(Term) M při čtení jsou termy odděleny tečkou | ?- read(A), read( ahoj(B) ), read( [C,D] ). |: ahoj. ahoj( petre ). [ ahoj( 'Petre!' ), jdeme ]. A = ahoj, B = petre, C = ahoj('Petre!'), D = jdeme * po dosažení konce souboru je vrácen atom end_of_fi 1 e zápis dalšího termu: write(Term) ?- write( ahoj ). ?- write( 'Ahoj Petre!' ). nový řádek na výstup: nl N mezer na výstup: tab(N) Hana Rudová, Logické programování 1,21. března 201 2 4 Sekvenční přístup k textovým souborům M čtení dalšího termu: read(Term) 3 při čtení jsou termy odděleny tečkou | ?- read(A), read( ahoj(B) ), read( [C,D] ). |: ahoj. ahoj( petre ). [ ahoj( 'Petre!' ), jdeme ]. A = ahoj, B = petre, C = ahoj('Petre!'), D = jdeme 3 po dosažení konce souboru je vrácen atom end_of_fi 1 e zápis dalšího termu: write(Term) ?- write( ahoj ). ?- write( 'Ahoj Petre!' ). nový řádek na výstup: nl N mezer na výstup: tab(N) M čtení/zápis dalšího znaku: getO(Znak) , get(NeprazdnyZnak)/put(Zn 3 po dosažení konce souboru je vrácena -1 Hana Rudová, Logické programování 1,21. března 201 2 4 Příklad čtení ze souboru process_file( Soubor ) :- seeing( StarySoubor ), see( Soubor ), repeat, read( Term ), process_term( Term ), Term == end_of_file, i ■ » seen, see( StarySoubor ). repeat. repeat :- repeat. 6 zjištěni aktivního proudu vo otevřeni souboru Soubor vo čteni termu Term vo manipulace s termem vo je konec souboru? vo uzavřeni souboru 6 aktivace původniho proudu 6 opakováni Hana Rudová, Logické programování 1,21. března 201 2 5 Ctení programu ze souboru Interpretování kódu programu ?- consul t(program) . ?- consultCprogram.pl') . 3 ?- consult( [programl, 'program2.pl'] ). M Kompilace kódu programu ?- compile( [programl, 'program2.pl'] ). M ?- [program]. 3 ?- [user]. zadávání kódu ze vstupu ukončené CTRL+D M další varianty podobně jako u interpretování 3 typické zrychlení: 5 až 10 krát Hana Rudová, Logické programování 1,21. března 201 2 6 Všechna řešení Backtracking vrací pouze jedno řešení po druhém M Všechna řešení dostupná najednou: bagof/3, setof/3, findall/3 M bagof( X, P, S ): vrátí seznam S, všech objektů X takových, že P je splněno vek( petr, 7 ). vek( anna, 5 ). vek( tomas, 5 ). ?- bagof( Dite, vek( Dite, 5 ), Seznam ). Hana Rudová, Logické programování 1,21. března 201 2 7 Všechna řešení Backtracking vrací pouze jedno řešení po druhém M Všechna řešení dostupná najednou: bagof/3, setof/3, findall/3 M bagof( X, P, S ): vrátí seznam S, všech objektů X takových, že P je splněno vek( petr, 7 ). vek( anna, 5 ). vek( tomas, 5 ). ?- bagof( Dite, vek( Dite, 5 ), Seznam ). Seznam = [ anna, tomas ] Hana Rudová, Logické programování 1,21. března 201 2 7 Všechna řešení Backtracking vrací pouze jedno řešení po druhém M Všechna řešení dostupná najednou: bagof/3, setof/3, findall/3 M bagof( X, P, S ): vrátí seznam S, všech objektů X takových, že P je splněno vek( petr, 7 ). vek( anna, 5 ). vek( tomas, 5 ). ?- bagof( Dite, vek( Dite, 5 ), Seznam ). Seznam = [ anna, tomas ] M Volné proměnné v cíli P jsou všeobecně kvantifikovány ?- bagof( Dite, vek( Dite, Vek ), Seznam ). Hana Rudová, Logické programování 1,21. března 201 2 7 Všechna řešení Backtracking vrací pouze jedno řešení po druhém M Všechna řešení dostupná najednou: bagof/3, setof/3, findall/3 M bagof( X, P, S ): vrátí seznam S, všech objektů X takových, že P je splněno vek( petr, 7 ). vek( anna, 5 ). vek( tomas, 5 ). ?- bagof( Dite, vek( Dite, 5 ), Seznam ). Seznam = [ anna, tomas ] M Volné proměnné v cíli P jsou všeobecně kvantifikovány ?- bagof( Dite, vek( Dite, Vek ), Seznam ). Vek = 7, Seznam = [ petr ]; Vek = 5, Seznam = [ anna, tomas ] Hana Rudová, Logické programování 1,21. března 201 2 7 Všechna řešení M Pokud neexistuje řešení bagof(X, P,S) neuspěje bagof: pokud nějaké řešení existuje několikrát, pak S obsahuje duplicity M bagof, setof, findall: P je libovolný cíl vek( petr, 7 ). vek( anna, 5 ). vek( tomas, 5 ). ?- bagof( Dite, ( vek( Dite, 5 ), Dite \= anna ), Seznam ). Seznam = [ tomas ] Hana Rudová, Logické programování 1,21. března 201 2 8 Všechna řešení M Pokud neexistuje řešení bagof(X, P,S) neuspěje bagof: pokud nějaké řešení existuje několikrát, pak S obsahuje duplicity bagof, setof, findall: P je libovolný cíl vek( petr, 7 ). vek( anna, 5 ). vek( tomas, 5 ). ?- bagof( Dite, ( vek( Dite, 5 ), Dite \= anna ), Seznam ). Seznam = [ tomas ] 3 bagof, setof, findall: na objekty shromažďované v X nejsou žádná omezení: X je term ?- bagof( Dite-Vek, vek( Dite, Vek ), Seznam ). Seznam = [petr-7,anna-5,tomas-5] Hana Rudová, Logické programování 1,21. března 201 2 8 Existenční kvantifikátor „" " M Přidání existenčního kvantifikátoru „~ " ^> hodnota proměnné nemá význam ?- bagof( Dite, Vek~vek( Dite, Vek ), Seznam ). Hana Rudová, Logické programování 1,21. března 201 2 9 Existenční kvantifikátor „" " M Přidání existenčního kvantifikátoru „~ " ^> hodnota proměnné nemá význam ?- bagof( Dite, Vek~vek( Dite, Vek ), Seznam ). Seznam = [petr,anna,tomas] Hana Rudová, Logické programování 1,21. března 201 2 9 Existenční kvantifikátor „" " M Přidání existenčního kvantifikátoru „~ " ^> hodnota proměnné nemá význam ?- bagof( Dite, Vek~vek( Dite, Vek ), Seznam ). Seznam = [petr,anna,tomas] Anonymní proměnné jsou všeobecně kvantifikovány, i když jejich hodnota není (jako vždy) vracena na výstup ?- bagof( Dite, vek( Dite, _Vek ), Seznam ). Seznam = [petr] ; Seznam = [anna,tomas] Hana Rudová, Logické programování 1,21. března 201 2 9 Existenční kvantifikátor „" " M Přidání existenčního kvantifikátoru „~ " ^> hodnota proměnné nemá význam ?- bagof( Dite, Vek~vek( Dite, Vek ), Seznam ). Seznam = [petr,anna,tomas] Anonymní proměnné jsou všeobecně kvantifikovány, i když jejich hodnota není (jako vždy) vracena na výstup ?- bagof( Dite, vek( Dite, _Vek ), Seznam ). Seznam = [petr] ; Seznam = [anna,tomas] Před operátorem „" " může být i seznam ?- bagof( Vek ,[Jméno,Přijmeni]"vek( Jméno, Prijmeni, Vek ), Seznam ). Seznam = [7,5,5] Hana Rudová, Logické programování 1,21. března 201 2 9 Všechna řešení III. M setof( X, P, S ): rozdíly od bagof 3 S je uspořádaný podle @< M případné duplicity v S jsou eliminovány Hana Rudová, Logické programování 1,21. března 201 2 10 Všechna řešení M setof( X, P, S ): rozdíly od bagof 3 S je uspořádaný podle @< 3 případné duplicity v S jsou eliminovány M findallC X, P, S ): rozdíly od bagof 3 všechny proměnné jsou existenčně kvantifikovány ?- findaIK Dite, vek( Dite, Vek ), Seznam ). Hana Rudová, Logické programování 1,21. března 201 2 10 Všechna řešení M setof( X, P, S ): rozdíly od bagof 3 S je uspořádaný podle @< 3 případné duplicity v S jsou eliminovány M findall( X, P, S ): rozdíly od bagof 3 všechny proměnné jsou existenčně kvantifikovány ?- findall( Dite, vek( Dite, Vek ), Seznam ). ^> v S jsou shromažďovány všechny možnosti i pro různá řešení => findall uspěje přesně jednou Hana Rudová, Logické programování 1,21. března 201 2 10 Všechna řešení M setof( X, P, S ): rozdíly od bagof 3 S je uspořádaný podle @< 3 případné duplicity v S jsou eliminovány M findallC X, P, S ): rozdíly od bagof 3 všechny proměnné jsou existenčně kvantifikovány ?- findaIK Dite, vek( Dite, Vek ), Seznam ). ^> v S jsou shromažďovány všechny možnosti i pro různá řešení => findall uspěje přesně jednou 3 výsledný seznam může být prázdný => pokud neexistuje řešení, uspěje a vrátí S = [] Hana Rudová, Logické programování 1,21. března 201 2 10 Všechna řešení M setof( X, P, S ): rozdíly od bagof * S je uspořádaný podle @< 3 případné duplicity v S jsou eliminovány M findall( X, P, S ): rozdíly od bagof 3 všechny proměnné jsou existenčně kvantifikovány ?- findall( Dite, vek( Dite, Vek ), Seznam ). ^> v S jsou shromažďovány všechny možnosti i pro různá řešení => findall uspěje přesně jednou 3 výsledný seznam může být prázdný => pokud neexistuje řešení, uspěje a vrátí S = [] M ?- bagof( Dite, vek( Dite, Vek ), Seznam ). Vek = 7, Seznam = [ petr ]; Vek = 5, Seznam = [ anna, tomas ] ?- findall( Dite, vek( Dite, Vek ), Seznam ). Hana Rudová, Logické programování 1,21. března 201 2 1 0 Všechna řešení M setof( X, P, S ): rozdíly od bagof 3 S je uspořádaný podle @< 3 případné duplicity v S jsou eliminovány M findall( X, P, S ): rozdíly od bagof 3 všechny proměnné jsou existenčně kvantifikovány ?- findaIK Dite, vek( Dite, Vek ), Seznam ). ^> v S jsou shromažďovány všechny možnosti i pro různá řešení => findall uspěje přesně jednou 3 výsledný seznam může být prázdný => pokud neexistuje řešení, uspěje a vrátí S = [] 3 ?- bagof( Dite, vek( Dite, Vek ), Seznam ). Vek = 7, Seznam = [ petr ]; Vek = 5, Seznam = [ anna, tomas ] ?- findall( Dite, vek( Dite, Vek ), Seznam ). Seznam = [petr,anna,tomas] Hana Rudová, Logické programování 1,21. března 201 2 1 0 Testování typu termu var(X) X je volná proměnná nonvar(X) X není proměnná Hana Rudová, Logické programování 1,21. března 201 2 Vestavěné predikáty Testování typu termu var(X) nonvar(X) X je volná proměnná X není proměnná atom(X) i nteger(X) float(X) atomi c(X) X je atom (pavel , 'Pavel Novák', <- X je integer X je float X je atom nebo číslo ->) Hana Rudová, Logické programování 1,21. března 201 2 11 Vestavěné predikáty Testování typu termu var(X) nonvar(X) X je volná proměnná X není proměnná atom(X) i nteger(X) float(X) atomi c(X) X je atom (pavel , 'Pavel Novák', <- X je integer X je float X je atom nebo číslo ->) compound(X) X je struktura Hana Rudová, Logické programování 1,21. března 201 2 11 Vestavěné predikáty Určení počtu výskytů prvku v seznamu count( X, S, N ) Hana Rudová, Logické programování 1,21. března 201 2 12 Vestavěné predikáty Určení počtu výskytů prvku v seznamu count( X, S, N ) :- count( X, S, 0, N ). Hana Rudová, Logické programování 1,21. března 201 2 12 Vestavěné predikáty Určení počtu výskytů prvku v seznamu count( X, S, N ) :- count( X, S, 0, N ). count( _, [], N, N ). Hana Rudová, Logické programování 1,21. března 201 2 12 Vestavěné predikáty Určení počtu výskytů prvku v seznamu count( X, S, N ) :- count( X, S, 0, N ). count( _, [], N, N ). count( X, [X|S], NO, N) :- !, Nl is NO + 1, count( X, S, Nl, N). Hana Rudová, Logické programování 1,21. března 201 2 12 Vestavěné predikáty Určení počtu výskytů prvku v seznamu count( X, S, N ) :- count( X, S, 0, N ). count( _, [], N, N ). count( X, [X|S], NO, N) :- !, Nl is NO + 1, count( X, S, Nl, N). count( X, [_|S], NO, N) :- count( X, S, NO, N). Hana Rudová, Logické programování 1,21. března 201 2 12 Vestavěné predikáty Určení počtu výskytů prvku v seznamu count( X, S, N ) :- count( X, S, 0, N ). count( _, [], N, N ). count( X, [X|S], NO, N) :- !, Nl is NO + 1, count( X, S, Nl, N). count( X, [_|S], NO, N) :- count( X, S, NO, N). :-? count( a, [a,b,a,a], N ) N=3 Hana Rudová, Logické programování 1,21. března 201 2 12 Vestavěné predikáty Určení počtu výskytů prvku v seznamu count( X, S, N ) :- count( X, S, 0, N ). count( _, [], N, N ). count( X, [X|S], NO, N) :- !, Nl is NO + 1, count( X, S, Nl, N). count( X, [_|S], NO, N) :- count( X, S, NO, N). :-? count( a, [a,b,a,a], N ) :-? count( a, [a,b,X,Y], N). N=3 Hana Rudová, Logické programování 1,21. března 201 2 12 Vestavěné predikáty Určení počtu výskytů prvku v seznamu count( X, S, N ) :- count( X, S, 0, N ). count( _, [], N, N ). count( X, [X|S], NO, N) :- !, Nl is NO + 1, count( X, S, Nl, N). count( X, [_|S], NO, N) :- count( X, S, NO, N). :-? count( a, [a,b,a,a], N ) :-? count( a, [a,b,X,Y], N). N=3 N=3 Hana Rudová, Logické programování 1,21. března 201 2 12 Vestavěné predikáty Určení počtu výskytů prvku v seznamu count( X, S, N ) :- count( X, S, 0, N ). count( _, [], N, N ). count( X, [X|S], NO, N) :- !, NI is NO + 1, count( X, S, NI, N). count( X, [_|S], NO, N) :- count( X, S, NO, N). :-? count( a, [a,b,a,a], N ) :-? count( a, [a,b,X,Y], N). N=3 N=3 count( _, [], N, N ). count( X, [Y|S], NO, N ) :- nonvar(Y), X = Y, !, NI is NO + 1, count( X, S, NI, N ). count( X, [_|S], NO, N ) :- count( X, S, NO, N ). Hana Rudová, Logické programování 1,21. března 201 2 12 Vestavěné predikáty Konstrukce a dekompozice atomu 3 Atom (opakování) M řetězce písmen, čísel, „_" začínající malým písmenem: pavel , pavel_novak, x2 , x4_34 3 řetězce speciálních znaků:+, <->, ===> M řetězce v apostrofech: 'Pavel', 'Pavel Novák', 'prší', 'ano' ?- 'ano'=A. A = ano Hana Rudová, Logické programování 1,21. března 201 2 Vestavěné predikáty Konstrukce a dekompozice atomu M Atom (opakování) M řetězce písmen, čísel, „_" začínající malým písmenem: pavel , pavel_novak, x2 , x4_34 3 řetězce speciálních znaků: +, <->, ===> M řetězce v apostrofech: 'Pavel', 'Pavel Novák', 'prší', 'ano' ?- 'ano'=A. A = ano Řetězec znaků v uvozovkách * př. "ano", "Pavel" ?- A="Pavel". ?- A="ano". A = [80,97,118,101,108] A=[97,110,111] M př. použití: konstrukce a dekompozice atomu na znaky, vstup a výstup do souboru Hana Rudová, Logické programování 1,21. března 201 2 Vestavěné predikáty Konstrukce a dekompozice atomu 3 Atom (opakování) M řetězce písmen, čísel, „_" začínající malým písmenem: pavel , pavel_novak, x2 , x4_34 3 řetězce speciálních znaků:+, <->, ===> M řetězce v apostrofech: 'Pavel', 'Pavel Novák', 'prší', 'ano' ?- 'ano'=A. A = ano Řetězec znaků v uvozovkách * př. "ano", "Pavel" ?- A="Pavel". ?- A="ano". A = [80,97,118,101,108] A=[97,110,111] M př. použití: konstrukce a dekompozice atomu na znaky, vstup a výstup do souboru Konstrukce atomu ze znaků, rozložení atomu na znaky name( Atom, SeznamASCIIKodu ) name( ano, [97,110,111] ) name( ano, "ano" ) Hana Rudová, Logické programování 1,21. března 2012 13 Vestavěné predikáty Konstrukce a dekompozice termu M Konstrukce a dekompozice termu Term =.. [ Funktor | SeznamArgumentu ] a(9,e) =.. [a,9,e] Hana Rudová, Logické programování 1,21. března 201 2 14 Vestavěné predikáty Konstrukce a dekompozice termu M Konstrukce a dekompozice termu Term =.. [ Funktor | SeznamArgumentu ] a(9,e) =.. [a,9,e] Cil =.. [ Funktor | SeznamArgumentu ], call( Cil ) Hana Rudová, Logické programování 1,21. března 201 2 14 Vestavěné predikáty Konstrukce a dekompozice termu M Konstrukce a dekompozice termu Term =.. [ Funktor | SeznamArgumentu ] a(9,e) =.. [a,9,e] Cil =.. [ Funktor | SeznamArgumentu ], call( Cil ) atom =.. X Hana Rudová, Logické programování 1,21. března 201 2 14 Vestavěné predikáty Konstrukce a dekompozice termu M Konstrukce a dekompozice termu Term =.. [ Funktor | SeznamArgumentu ] a(9,e) =.. [a,9,e] Cil =.. [ Funktor | SeznamArgumentu ], call( Cil ) atom =. . X => X = [atom] Hana Rudová, Logické programování 1,21. března 201 2 14 Vestavěné predikáty Konstrukce a dekompozice termu M Konstrukce a dekompozice termu Term =.. [ Funktor | SeznamArgumentu ] a(9,e) =.. [a,9,e] Cil =.. [ Funktor | SeznamArgumentu ], call( Cil ) atom =. . X => X = [atom] Pokud chci znát pouze funktor nebo některé argumenty, pak je efektivnější: functor( Term, Funktor, Arita ) functor( a(9,e), a, 2 ) Hana Rudová, Logické programování 1,21. března 201 2 14 Vestavěné predikáty Konstrukce a dekompozice termu M Konstrukce a dekompozice termu Term =.. [ Funktor | SeznamArgumentu ] a(9,e) =.. [a,9,e] Cil =.. [ Funktor | SeznamArgumentu ], call( Cil ) atom =. . X => X = [atom] Pokud chci znát pouze funktor nebo některé argumenty, pak je efektivnější: functor( Term, Funktor, Arita ) functor( a(9,e), a, 2 ) functor(atom,atom,0) functor(l,1,0) Hana Rudová, Logické programování 1,21. března 201 2 14 Vestavěné predikáty Konstrukce a dekompozice termu M Konstrukce a dekompozice termu Term =.. [ Funktor | SeznamArgumentu ] a(9,e) =.. [a,9,e] Cil =.. [ Funktor | SeznamArgumentu ], call( Cil ) atom =. . X => X = [atom] Pokud chci znát pouze funktor nebo některé argumenty, pak je efektivnější: functor( Term, Funktor, Arita ) functor( a(9,e), a, 2 ) fu ncto r(atom,atom,0) i functor(l,l,0) arg( 2, a(9,e), e) arg( N, Term, Argument ) Hana Rudová, Logické programování 1,21. března 201 2 14 Vestavěné predikáty Rekurzivní rozklad termu Term je proměnná (var/1), atom nebo číslo (atomic/1) => konec rozkladu Hana Rudová, Logické programování 1,21. března 201 2 Vestavěné predikáty Rekurzivní rozklad termu M Term je proměnná (var/1), atom nebo číslo (atomic/1) => konec rozkladu M Term je složený (=. ./2 , functor/3) => procházení seznamu argumentů a rozklad každého argumentu Hana Rudová, Logické programování 1,21. března 2012 15 Vestavěné predikáty Rekurzivní rozklad termu M Term je proměnná (var/1), atom nebo číslo (atomic/1) => konec rozkladu 3 Term je seznam ([_!_])=> [] ... řešen výše jako atomi c procházení seznamu a rozklad každého prvku seznamu M Term je složený (=. ./2 , functor/3) => procházení seznamu argumentů a rozklad každého argumentu Hana Rudová, Logické programování 1,21. března 201 2 Vestavěné predikáty Rekurzivní rozklad termu M Term je proměnná (var/1), atom nebo číslo (atomic/1) => konec rozkladu 3 Term je seznam ([_!_])=> [] ... řešen výše jako atomi c procházení seznamu a rozklad každého prvku seznamu M Term je složený (=. ./2 , functor/3) => procházení seznamu argumentů a rozklad každého argumentu Příklad: ground/1 uspěje, pokud v termu nejsou proměnné; jinak neuspěje Hana Rudová, Logické programování 1,21. března 201 2 Vestavěné predikáty Rekurzivní rozklad termu M Term je proměnná (var/1), atom nebo číslo (atomic/1) => konec rozkladu 3 Term je seznam ([_!_])=> [] ... řešen výše jako atomi c procházení seznamu a rozklad každého prvku seznamu M Term je složený (=. ./2 , functor/3) => procházení seznamu argumentů a rozklad každého argumentu Příklad: ground/1 uspěje, pokud v termu nejsou proměnné; jinak neuspěje ground(Term) :- atomic(Term), !. Hana Rudová, Logické programování 1,21. března 201 2 Vestavěné predikáty Rekurzivní rozklad termu M Term je proměnná (var/1), atom nebo číslo (atomic/1) => konec rozkladu 3 Term je seznam ([_!_])=> [] ... řešen výše jako atomi c procházení seznamu a rozklad každého prvku seznamu M Term je složený (=. ./2 , functor/3) => procházení seznamu argumentů a rozklad každého argumentu Příklad: ground/1 uspěje, pokud v termu nejsou proměnné; jinak neuspěje ground(Term) :- atomic(Term), !. ground(Term) :- var(Term), !, fail. Hana Rudová, Logické programování 1,21. března 201 2 Vestavěné predikáty Rekurzivní rozklad termu M Term je proměnná (var/1), atom nebo číslo (atomic/1) => konec rozkladu 3 Term je seznam ([_!_])=> [] ... řešen výše jako atomi c procházení seznamu a rozklad každého prvku seznamu M Term je složený (=. ./2 , functor/3) => procházení seznamu argumentů a rozklad každého argumentu Příklad: ground/1 uspěje, pokud v termu nejsou proměnné; jinak neuspěje g round(Term) :- atomic(Term), !. ground(Term) :- var(Term), !, fail. ground([H|T]) :- !, ground(H), ground(T). Hana Rudová, Logické programování 1,21. března 201 2 Vestavěné predikáty Rekurzivní rozklad termu M Term je proměnná (var/1), atom nebo číslo (atomic/1) => konec rozkladu 3 Term je seznam ([_!_])=> [] ... řešen výše jako atomi c procházení seznamu a rozklad každého prvku seznamu M Term je složený (=. ./2 , functor/3) => procházení seznamu argumentů a rozklad každého argumentu Příklad: ground/1 uspěje, pokud v termu nejsou proměnné; jinak neuspěje ground(Term) :- atomic(Term), !. ground(Term) :- var(Term), !, fail. ground([H|T]) :- !, ground(H), ground(T). ground(Term) :- Term =.. [ _Funktor | Argumenty ], ground( Argumenty ). Hana Rudová, Logické programování 1,21. března 201 2 Vestavěné predikáty Rekurzivní rozklad termu M Term je proměnná (var/1), atom nebo číslo (atomic/1) => konec rozkladu procházení seznamu a rozklad každého prvku seznamu M Term je složený (=. ./2 , functor/3) => procházení seznamu argumentů a rozklad každého argumentu Příklad: ground/1 uspěje, pokud v termu nejsou proměnné; jinak neuspěje ground(Term) :- atomic(Term), !. ground(Term) :- var(Term), !, fail. ground([H|T]) :- !, ground(H), ground(T). ground(Term) :- Term =.. [ _Funktor | Argumenty ], 3 Term je seznam ([_|_]) => [] ... řešen výše jako atomic ground( Argumenty ). ?- ground(s(2,[a(l,3),b,c],X)). ?- ground(s(2,[a(l,3),b,c])). no yes Hana Rudová, Logické programování 1,21. března 201 2 1 5 Vestavěné predikáty Příklad: dekompozice termu I. M count_term( Integer, Term, N ) určí počet výskytů celého čísla v termu Hana Rudová, Logické programování 1,21. března 201 2 16 Vestavěné predikáty Příklad: dekompozice termu I. M count_term( Integer, Term, N ) určí počet výskytů celého čísla v termu * ?- count_term( 1, a(l,2,b(x,z(a,b,1)),Y), N ). N=2 Hana Rudová, Logické programování 1,21. března 201 2 16 Vestavěné predikáty Příklad: dekompozice termu I. M count_term( Integer, Term, N ) určí počet výskytů celého čísla v termu * ?- count_term( 1, a(l,2,b(x,z(a,b,1)),Y), N ). N=2 3 count_term( X, T, N ) :- count_term( X, T, 0, N). Hana Rudová, Logické programování 1,21. března 201 2 16 Vestavěné predikáty Příklad: dekompozice termu I. count_term( Integer, Term, N ) určí počet výskytů celého čísla v termu M ?- count_term( 1, a(l, 2 , b(x, z(a, b, 1)) , Y) , N ). N=2 3 count_term( X, T, N ) :- count_term( X, T, 0, N). count_term( X, T, NO, N ) :- integer(T), X = T, !, N is NO + 1. Hana Rudová, Logické programování 1,21. března 201 2 16 Vestavěné predikáty Příklad: dekompozice termu I. 3 count_term( Integer, Term, N ) určí počet výskytů celého čísla v termu ?- count_term( 1, a(l, 2 , b(x, z(a, b, 1)) , Y) , N ). N=2 count_term( X, T, N ) :- count_term( X, T, 0, N). count_term( X, T, NO, N ) :- integer(T), X = T, !, N is NO + 1. count_term( _, T, N, N ) :- atomic(T), !. Hana Rudová, Logické programování 1,21. března 201 2 16 Vestavěné predikáty Příklad: dekompozice termu I. 3 count_term( Integer, Term, N ) určí počet výskytů celého čísla v termu ?- count_term( 1, a(l, 2 , b(x, z(a, b, 1)) , Y) , N ). N=2 3 count_term( X, T, N ) :- count_term( X, T, 0, N). count_term( X, T, NO, N ) :- integer(T), X = T, !, N is NO + 1. count_term( _, T, N, N ) :- atomic(T), !. count_term( _, T, N, N ) :- var(T), !. Hana Rudová, Logické programování 1,21. března 201 2 16 Vestavěné predikáty Příklad: dekompozice termu I. M count_term( Integer, Term, N ) určí počet výskytů celého čísla v termu M ?- count_term( 1, a(l,2,b(x,z(a,b,1)),Y), N ). N=2 3 count_term( X, T, N ) :- count_term( X, T, 0, N). count_term( X, T, NO, N ) :- integer(T), X = T, !, N is NO + 1. count_term( _, T, N, N ) :- atomic(T), !. count_term( _, T, N, N ) :- var(T), !. count_term( X, T, NO, N ) :- T =.. [ _ | Argumenty ], Hana Rudová, Logické programování 1,21. března 201 2 16 Vestavěné predikáty Příklad: dekompozice termu I. M count_term( Integer, Term, N ) určí počet výskytů celého čísla v termu M ?- count_term( 1, a(l,2,b(x,z(a,b,1)),Y), N ). N=2 3 count_term( X, T, N ) :- count_term( X, T, 0, N). count_term( X, T, NO, N ) :- integer(T), X = T, !, N is NO + 1. count_term( _, T, N, N ) :- atomic(T), !. count_term( _, T, N, N ) :- var(T), !. count_term( X, T, NO, N ) :- T =.. [ _ | Argumenty ], count_arg( X, Argumenty, NO, N ). Hana Rudová, Logické programování 1,21. března 201 2 16 Vestavěné predikáty Příklad: dekompozice termu I. count_term( Integer, Term, N ) určí počet výskytů celého čísla v termu M ?- count_term( 1, a(l,2,b(x,z(a,b,1)),Y), N ). N=2 3 count_term( X, T, N ) :- count_term( X, T, 0, N). count_term( X, T, NO, N ) :- integer(T), X = T, !, N is NO + 1. count_term( _, T, N, N ) :- atomic(T), !. count_term( _, T, N, N ) :- var(T), !. count_term( X, T, NO, N ) :- T =.. [ _ | Argumenty ], count_arg( X, Argumenty, NO, N ). count_arg( _, [], N, N ). Hana Rudová, Logické programování 1,21. března 201 2 16 Vestavěné predikáty Příklad: dekompozice termu I. count_term( Integer, Term, N ) určí počet výskytů celého čísla v termu 3 ?- count_term( 1, a(l,2,b(x,z(a,b,1)),Y), N ). N=2 3 count_term( X, T, N ) :- count_term( X, T, 0, N). count_term( X, T, NO, N ) :- integer(T), X = T, !, N is NO + 1. count_term( _, T, N, N ) :- atomic(T), !. count_term( _, T, N, N ) :- var(T), !. count_term( X, T, NO, N ) :- T =.. [ _ | Argumenty ], count_arg( X, Argumenty, NO, N ). count_arg( _, [], N, N ). count_arg( X, [ H | T ], NO, N ) :- count_term( X, H, 0, NI), Hana Rudová, Logické programování 1,21. března 201 2 16 Vestavěné predikáty Příklad: dekompozice termu I. M count_term( Integer, Term, N ) určí počet výskytů celého čísla v termu M ?- count_term( 1, a(l,2,b(x,z(a,b,1)),Y), N ). N=2 3 count_term( X, T, N ) :- count_term( X, T, 0, N). count_term( X, T, NO, N ) :- integer(T), X = T, !, N is NO + 1. count_term( _, T, N, N ) :- atomic(T), !. count_term( _, T, N, N ) :- var(T), !. count_term( X, T, NO, N ) :- T =.. [ _ | Argumenty ], count_arg( X, Argumenty, NO, N ). count_arg( _, [], N, N ). count_arg( X, [ H | T ], NO, N ) :- count_term( X, H, 0, NI), N2 is NO + NI, Hana Rudová, Logické programování 1,21. března 201 2 16 Vestavěné predikáty Příklad: dekompozice termu I. M count_term( Integer, Term, N ) určí počet výskytů celého čísla v termu 3 ?- count_term( 1, a(l,2,b(x,z(a,b,1)),Y), N ). N=2 3 count_term( X, T, N ) :- count_term( X, T, 0, N). count_term( X, T, NO, N ) :- integer(T), X = T, !, N is NO + 1. count_term( _, T, N, N ) :- atomic(T), !. count_term( _, T, N, N ) :- var(T), !. count_term( X, T, NO, N ) :- T =.. [ _ | Argumenty ], count_arg( X, Argumenty, NO, N ). count_arg( _, [], N, N ). count_arg( X, [ H | T ], NO, N ) :- count_term( X, H, 0, NI), N2 is NO + NI, count_arg( X, T, N2, N ). Hana Rudová, Logické programování 1,21. března 201 2 16 Vestavěné predikáty Příklad: dekompozice termu I. count_term( Integer, Term, N ) určí počet výskytů celého čísla v termu * ?- count_term( 1, a(l,2,b(x,z(a,b,1)),Y), N ). N=2 3 count_term( X, T, N ) :- count_term( X, T, 0, N). count_term( X count_term( _ count_term( _ count_term( X T, NO, N ) :- integer(T), X = T, !, N i s NO + 1 T, N, N ) :- atomic(T), !■ T, N, N ) :- var(T), !. T, NO, N ) :- T =.. [ _ | Argumenty ], count_arg( X, Argumenty, NO, N ). count_arg( _, [], N, N ). count_arg( X, [ H | T ], NO, N ) :- count_term( X, H, 0, NI), N2 is NO + NI, count_arg( X, T, N2, N ). ?- count_term( 1, [a,2,[b,c],[d,[e,f],Y]], N ). Hana Rudová, Logické programování 1,21. března 201 2 16 Vestavěné predikáty Příklad: dekompozice termu I count_term( Integer, Term, N ) určí počet výskytů celého čísla v termu * ?- count_term( 1, a(l,2,b(x,z(a,b,1)),Y), N ). N=2 3 count_term( X, T, N ) :- count_term( X, T, 0, N). count_term( X count_term( _ count_term( _ count_term( X T, NO, N ) :- integer(T), X = T, !, N is NO + 1. T, N, N ) :- atomic(T), !■ T, N, N ) :- var(T), !. T, NO, N ) :- T =.. [ _ | Argumenty ], count_arg( X, Argumenty, NO, N ). count_arg( _, [], N, N ). count_arg( X, [ H | T ], NO, N ) :- count_term( X, H, 0, NI), N2 is NO + NI, count_arg( X, T, N2, N ). M ?- count_term( 1, [a,2,[b,c],[d,[e,f],Y]], N ). count_term( X, T, NO, N ) :- T = [_|_], !, count_arg( X, T, NO, N ). klauzuli přidáme před poslední klauzuli count_term/4 Hana Rudová, Logické programování 1,21. března 2012 16 Vestavěné predikáty Cvičení: dekompozice termu M Napište predikát substitute( Podterm, Term, Podterml, Terml), který nahradí všechny výskyty Podterm v Term termem Podterml a výsledek vrátí v Terml M Předpokládejte, že Term a Podterm jsou termy bez proměnných ?- substitute( sin(x), 2*sin(x)*f(sin(x)), t, F ). F=2*t*f(t) Hana Rudová, Logické programování 1,21. března 201 2 Vestavěné predikáty