Vestavěné predikáty (pokračování) Testování typu termu var(X) X je volná proměnná nonvar(X) X není proměnná Hana Rudová, Logické programování I, 1 8. března 201 3 2 Vestavěné predikáty Testování typu termu var(X) X je volná proměnná nonvar(X) 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í I, 1 8. března 201 3 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 ->) compound(X) X je struktura Hana Rudová, Logické programování I, 1 8. března 201 3 2 Vestavěné predikáty Určení počtu výskytů prvku v seznamu count( X, S, N ) Hana Rudová, Logické programování I, 1 8. března 201 3 3 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í I, 1 8. března 201 3 3 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í I, 1 8. března 201 3 3 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í I, 1 8. března 201 3 3 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í I, 1 8. března 201 3 3 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í I, 1 8. března 201 3 3 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í I, 1 8. března 201 3 3 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í I, 1 8. března 201 3 3 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í I, 1 8. března 201 3 3 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í I, 1 8. března 201 3 4 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í I, 1 8. března 201 3 4 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í I, 18. března 2013 4 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í I, 1 8. března 201 3 5 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í I, 1 8. března 201 3 5 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í I, 1 8. března 201 3 5 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í I, 1 8. března 201 3 5 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í I, 1 8. března 201 3 5 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í I, 1 8. března 201 3 5 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í I, 1 8. března 201 3 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í I, 1 8. března 201 3 6 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í I, 18. března 201 3 6 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í I, 1 8. března 201 3 6 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í I, 1 8. března 201 3 6 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í I, 1 8. března 201 3 6 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í I, 1 8. března 201 3 6 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). Hana Rudová, Logické programování I, 1 8. března 201 3 6 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í I, 1 8. března 201 3 6 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í I, 1 8. března 201 3 6 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í I, 1 8. března 201 3 7 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í I, 1 8. března 201 3 7 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í I, 1 8. března 201 3 7 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í I, 1 8. března 201 3 7 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 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í I, 1 8. března 201 3 7 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í I, 1 8. března 201 3 7 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í I, 1 8. března 201 3 7 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í I, 1 8. března 201 3 7 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 ). Hana Rudová, Logické programování I, 1 8. března 201 3 7 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), Hana Rudová, Logické programování I, 1 8. března 201 3 7 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í I, 1 8. března 201 3 7 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, count_arg( X, T, N2, N ). Hana Rudová, Logické programování I, 1 8. března 201 3 7 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í I, 1 8. března 201 3 7 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í I, 18. března 201 3 7 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í I, 1 8. března 201 3 8 Vestavěné predikáty Technika a styl programování v Prologu Technika a styl programování v Prologu M Styl programování v Prologu m některá pravidla správného stylu 3 správný vs. špatný styl 3 komentáře Ladění Efektivita Hana Rudová, Logické programování I, 1 8. března 201 3 10 Technika a styl programování v Prologu Styl programování v Prologu I. Cílem stylistických konvencí je m redukce nebezpečí programovacích chyb psaní čitelných a srozumitelných programů, které se dobře ladí a modifikují Hana Rudová, Logické programování I, 1 8. března 201 3 Technika a styl programování v Prologu Styl programování v Prologu I. Cílem stylistických konvencí je m redukce nebezpečí programovacích chyb m psaní čitelných a srozumitelných programů, které se dobře ladí a modifikují M Některá pravidla správného stylu m krátké klauzule 3 krátké procedury; dlouhé procedury pouze s uniformní strukturou (tabulka) Hana Rudová, Logické programování I, 1 8. března 201 3 Technika a styl programování v Prologu Styl programování v Prologu I. Cílem stylistických konvencí je m redukce nebezpečí programovacích chyb m psaní čitelných a srozumitelných programů, které se dobře ladí a modifikují M Některá pravidla správného stylu m krátké klauzule 3 krátké procedury; dlouhé procedury pouze s uniformní strukturou (tabulka) m klauzule se základními (hraničními) případy psát před rekurzivními klauzulemi 3 vhodná jména procedur a proměnných St nepoužívat seznamy ([. . .]) nebo závorky ({...}, (...)) pro termy pevné arity m vstupní argumenty psát před výstupními Hana Rudová, Logické programování I, 1 8. března 201 3 Technika a styl programování v Prologu Styl programování v Prologu I. Cílem stylistických konvencí je m redukce nebezpečí programovacích chyb m psaní čitelných a srozumitelných programů, které se dobře ladí a modifikují M Některá pravidla správného stylu m krátké klauzule 3 krátké procedury; dlouhé procedury pouze s uniformní strukturou (tabulka) m klauzule se základními (hraničními) případy psát před rekurzivními klauzulemi 3 vhodná jména procedur a proměnných St nepoužívat seznamy ([. . .]) nebo závorky ({...}, (...)) pro termy pevné arity m vstupní argumenty psát před výstupními m struktura programu - jednotné konvence v rámci celého programu, např. mezery, prázdné řádky, odsazení s klauzule stejné procedury na jednom místě; prázdné řádky mezi klauzulemi; každý cíl na zvláštním řádku Hana Rudová, Logické programování 1,18. března 2013 11 Technika a styl programování v Prologu Správný styl programování konstrukce setříděného seznamu Seznam3 ze setříděných seznamů Seznámí, Seznam2: merge( Seznámí, Seznam2, Seznam3 ) mergeC [2,4,7], [1,3,4,8], [1,2,3,4,4,7,8] ) Hana Rudová, Logické programování I, 1 8. března 201 3 12 Technika a styl programování v Prologu Správný styl programování konstrukce setříděného seznamu Seznam3 ze setříděných seznamů Seznámí, Seznam2: merge( Seznámí, Seznam2, Seznam3 ) 3 mergeC [2,4,7], [1,3,4,8], [1,2,3,4,4,7,8] ) merge( [], Seznam, Seznam ) :- Hana Rudová, Logické programování I, 1 8. března 201 3 12 Technika a styl programování v Prologu Správný styl programování M konstrukce setříděného seznamu Seznam3 ze setříděných seznamů Seznámí, Seznam2: merge( Seznámí, Seznam2, Seznam3 ) 3 mergeC [2,4,7], [1,3,4,8], [1,2,3,4,4,7,8] ) M merge( [], Seznam, Seznam ) :- ! . % prevence redundantních řešení Hana Rudová, Logické programování I, 1 8. března 201 3 12 Technika a styl programování v Prologu Správný styl programování M konstrukce setříděného seznamu Seznam3 ze setříděných seznamů Seznámí, Seznam2: merge( Seznámí, Seznam2, Seznam3 ) 3 mergeC [2,4,7], [1,3,4,8], [1,2,3,4,4,7,8] ) M merge( [], Seznam, Seznam ) :- ! . % prevence redundantních řešení merge( Seznam, [], Seznam ). Hana Rudová, Logické programování I, 1 8. března 201 3 12 Technika a styl programování v Prologu Správný styl programování konstrukce setříděného seznamu Seznam3 ze setříděných seznamů Seznámí, Seznam2: merge( Seznámí, Seznam2, Seznam3 ) 3 mergeC [2,4,7], [1,3,4,8], [1,2,3,4,4,7,8] ) merge( [], Seznam, Seznam ) :- ! . % prevence redundantních řešení merge( Seznam, [], Seznam ). merge( [X|Telol], [Y|Telo2], [X|Telo3] ) :- Hana Rudová, Logické programování I, 1 8. března 201 3 12 Technika a styl programování v Prologu Správný styl programování konstrukce setříděného seznamu Seznam3 ze setříděných seznamů Seznámí, Seznam2: merge( Seznámí, Seznam2, Seznam3 ) 3 mergeC [2,4,7], [1,3,4,8], [1,2,3,4,4,7,8] ) 3 merge( [], Seznam, Seznam ) :- ! . % prevence redundantních řešení merge( Seznam, [], Seznam ). merge( [X|Telol], [Y|Telo2], [X|Telo3] ) :-X < Y, !, Hana Rudová, Logické programování I, 1 8. března 201 3 12 Technika a styl programování v Prologu Správný styl programování konstrukce setříděného seznamu Seznam3 ze setříděných seznamů Seznámí, Seznam2: merge( Seznámí, Seznam2, Seznam3 ) 3 mergeC [2,4,7], [1,3,4,8], [1,2,3,4,4,7,8] ) M merge( [], Seznam, Seznam ) :- ! . % prevence redundantních řešení merge( Seznam, [], Seznam ). merge( [X|Telol], [Y|Telo2], [X|Telo3] ) :-X < Y, !, merge( Telol, [Y|Telo2], Telo3 ). Hana Rudová, Logické programování I, 1 8. března 201 3 12 Technika a styl programování v Prologu Správný styl programování konstrukce setříděného seznamu Seznam3 ze setříděných seznamů Seznámí, Seznam2: merge( Seznámí, Seznam2, Seznam3 ) 3 mergeC [2,4,7], [1,3,4,8], [1,2,3,4,4,7,8] ) merge( [], Seznam, Seznam ) :- ! . % prevence redundantních řešení merge( Seznam, [], Seznam ). merge( [X|Telol], [Y|Telo2], [X|Telo3] ) :-X < Y, !, merge( Telol, [Y|Telo2], Telo3 ). merge( Seznámí, [Y|Telo2], [Y|Telo3] ) :- Hana Rudová, Logické programování I, 1 8. března 201 3 12 Technika a styl programování v Prologu Správný styl programování konstrukce setříděného seznamu Seznam3 ze setříděných seznamů Seznámí, Seznam2: merge( Seznámí, Seznam2, Seznam3 ) merge( [2,4,7], [1,3,4,8], [1,2,3,4,4,7,8] ) merge( □ , Seznam, Seznam ) :- ! . % prevence redundantních řešení merge( Seznam, [], Seznam ). merge( [X|Telol], [Y|Telo2], [X|Telo3] ) :-X < Y, !, merge( Telol, [Y|Telo2], Telo3 ). merge( Seznámí, [Y|Telo2], [Y|Telo3] ) :-merge( Seznámí, Telo2, Telo3 ). Hana Rudová, Logické programování I, 1 8. března 201 3 12 Technika a styl programování v Prologu Špatný styl programování merge( SI, S2, S3 ) :- 51 =[],!, S3 = S2; % první seznam je prázdný 52 = [] , ! , S3 = SI; % druhý seznam je prázdný 51 = [X|TI], 52 = [Y|T2], C X < Y, !, Z = X, % Z je hlava seznamu S3 merge( TI, S2, T3 ) ; Z = Y, merge( SI, T2, T3) ), 53 = [ Z | T3 ]. Hana Rudová, Logické programování I, 1 8. března 201 3 1 3 Technika a styl programování v Prologu Styl programování v Prologu II. M Středník „;" může způsobit nesrozumitelnost klauzule m nedávat středník na konec řádku, používat závorky 3 v některých případech: rozdělení klauzle se středníkem do více klauzulí Hana Rudová, Logické programování I, 1 8. března 201 3 14 Technika a styl programování v Prologu Styl programování v Prologu II M Středník „;" může způsobit nesrozumitelnost klauzule m nedávat středník na konec řádku, používat závorky 3 v některých případech: rozdělení klauzle se středníkem do více klauzulí M Opatrné používání operátoru řezu 3 preferovat použití zeleného řezu (nemění deklarativní sémantiku) m červený řez používat v jasně definovaných konstruktech negace: P, !, fail; true alternativy: Podminka, !, Cill ; Ci 12 Podminka -> Cill Cil 2 \+ P Hana Rudová, Logické programování I, 1 8. března 201 3 14 Technika a styl programování v Prologu Styl programování v Prologu II M Středník „;" může způsobit nesrozumitelnost klauzule m nedávat středník na konec řádku, používat závorky 3 v některých případech: rozdělení klauzle se středníkem do více klauzulí M Opatrné používání operátoru řezu 3 preferovat použití zeleného řezu (nemění deklarativní sémantiku) m červený řez používat v jasně definovaných konstruktech M Opatrné používání negace „\+" m negace jako neúspěch: negace není ekvivalentní negaci v matematické logice negace: P, !, fail; true alternativy: Podminka, !, Cill ; Cil2 Podminka -> Cill Cil 2 \+ P Hana Rudová, Logické programování I, 1 8. března 201 3 14 Technika a styl programování v Prologu Styl programování v Prologu II M Středník „;" může způsobit nesrozumitelnost klauzule 3 nedávat středník na konec řádku, používat závorky 3 v některých případech: rozdělení klauzle se středníkem do více klauzulí M Opatrné používání operátoru řezu 3 preferovat použití zeleného řezu (nemění deklarativní sémantiku) 3 červený řez používat v jasně definovaných konstruktech M Opatrné používání negace „\+" 3 negace jako neúspěch: negace není ekvivalentní negaci v matematické logice Pozor na assert a retract: snižuji transparentnost chování programu negace: P, !, fail; true alternativy: Podminka, !, Cill ; Ci 12 Podminka -> Cill Cil 2 \+ P Hana Rudová, Logické programování I, 1 8. března 201 3 14 Technika a styl programování v Prologu Dokumentace a komentáře M co program dělá, jak ho používat (jaký cíl spustit a jaké jsou očekávané výsledky), příklad použití Hana Rudová, Logické programování I, 1 8. března 201 3 Technika a styl programování v Prologu Dokumentace a komentáře co program dělá, jak ho používat (jaký cíl spustit a jaké jsou očekávané výsledky), příklad použití které predikáty jsou hlavní (top-level) Hana Rudová, Logické programování I, 1 8. března 201 3 Technika a styl programování v Prologu Dokumentace a komentáře M co program dělá, jak ho používat (jaký cíl spustit a jaké jsou očekávané výsledky), příklad použití M které predikáty jsou hlavní (top-level) 3 jak jsou hlavní koncepty (objekty) reprezentovány Hana Rudová, Logické programování I, 1 8. března 201 3 Technika a styl programování v Prologu Dokumentace a komentáře co program dělá, jak ho používat (jaký cíl spustit a jaké jsou očekávané výsledky), příklad použití 3 které predikáty jsou hlavní (top-level) 3 jak jsou hlavní koncepty (objekty) reprezentovány doba výpočtu a paměťové nároky Hana Rudová, Logické programování I, 1 8. března 201 3 Technika a styl programování v Prologu Dokumentace a komentáře M co program dělá, jak ho používat (jaký cíl spustit a jaké jsou očekávané výsledky), příklad použití M které predikáty jsou hlavní (top-level) M jak jsou hlavní koncepty (objekty) reprezentovány M doba výpočtu a paměťové nároky jaké jsou limitace programu Hana Rudová, Logické programování I, 1 8. března 201 3 Technika a styl programování v Prologu Dokumentace a komentáře M co program dělá, jak ho používat (jaký cíl spustit a jaké jsou očekávané výsledky), příklad použití M které predikáty jsou hlavní (top-level) M jak jsou hlavní koncepty (objekty) reprezentovány M doba výpočtu a paměťové nároky jaké jsou limitace programu M zda jsou použity nějaké speciální rysy závislé na systému Hana Rudová, Logické programování I, 1 8. března 201 3 Technika a styl programování v Prologu Dokumentace a komentáře M co program dělá, jak ho používat (jaký cíl spustit a jaké jsou očekávané výsledky), příklad použití M které predikáty jsou hlavní (top-level) M jak jsou hlavní koncepty (objekty) reprezentovány M doba výpočtu a paměťové nároky jaké jsou limitace programu M zda jsou použity nějaké speciální rysy závislé na systému jaký je význam predikátů v programu, jaké jsou jejich argumenty, které jsou vstupní a které výstupní (pokud víme) m vstupní argumenty „+", výstupní „-" merge( +Seznaml, +Seznam2 , -Seznam3 ) 3 JmenoPredikatu/Arita merge/3 Hana Rudová, Logické programování I, 1 8. března 201 3 Technika a styl programování v Prologu Dokumentace a komentáře co program dělá, jak ho používat (jaký cíl spustit a jaké jsou očekávané výsledky), příklad použití M které predikáty jsou hlavní (top-level) M jak jsou hlavní koncepty (objekty) reprezentovány doba výpočtu a paměťové nároky jaké jsou limitace programu M zda jsou použity nějaké speciální rysy závislé na systému jaký je význam predikátů v programu, jaké jsou jejich argumenty, které jsou vstupní a které výstupní (pokud víme) m vstupní argumenty „+", výstupní „-" merge( +Seznaml, +Seznam2 , -Seznam3 ) m JmenoPredi katu/Arita merge/3 3 algoritmické a implementační podrobnosti Hana Rudová, Logické programování 1,18. března 2013 15 Technika a styl programování v Prologu Ladění Přepínače na trasování: trace/0, notrace/0 Trasování specifického predikátu: spy/1, nospy/1 m spy( merge/3 ) M debug/0, nodebug/0: pro trasování pouze predikátů zadaných spy/1 Hana Rudová, Logické programování I, 1 8. března 201 3 16 Technika a styl programování v Prologu Ladění M Přepínače na trasování: trace/0, notrace/0 Trasování specifického predikátu: spy/1, nospy/1 3 spy( merge/3 ) debug/0, nodebug/0: pro trasování pouze predikátů zadaných spy/1 M Libovolná část programu může být spuštěna zadáním vhodného dotazu: trasování cíle m vstupní informace: jméno predikátu, hodnoty argumentů při volání 3 výstupní informace St při úspěchu hodnoty argumentů splňující cíl & při neúspěchu indikace chyby m nové vyvolání přes stejný cíl je volán při backtrackingu Hana Rudová, Logické programování I, 1 8. března 201 3 16 Technika a styl programování v Prologu Krabičkový (4-branový) model M Vizualizace řídícího toku (backtrackingu) na úrovni predikátu 3 Cal 1: volání cíle 3 Exit: úspěšné ukončení volání cíle 3 Fai 1: volání cíle neuspělo 3 Redo: jeden z následujících cílů neuspěl a systém backtrackuje, aby nalezl alternativy k předchozímu řešení Call Exit > + predek( X, Z ) :- rodic( X, Z ). + > < I predekC X, Z ) :- rodic( X, Y ), + predek( Y, Z ). + < Fail Redo Hana Rudová, Logické programování I, 1 8. března 201 3 1 7 Technika a styl programování v Prologu Příklad: trasování a(X) :- nonvar(X). a(X) :- c(X). a(X) :- d(X). cd). d(2). Call I ------> + a(X) I a(X) <------+ a(X) Fail I Exi t nonvar(X).| ------> c(X). I d(X). + <------ Redo Hana Rudová, Logické programování I, 1 8. března 201 3 18 Technika a styl programování v Prologu Příklad: trasování a(X) :- nonvar(X). 1 ?- a(X). a(X) :- c(X). 1 1 Call : a(_463) ? a(X) :- d(X). 2 2 Call : nonvar(_463) cd). 2 2 Fai 1 : nonvar(_463) d(2). Call I ------> + a(X) I a(X) <------+ a(X) Fail I Exi t nonvar(X).| ------> c(X). I d(X). + <------ Redo Hana Rudová, Logické programování I, 1 8. března 201 3 18 Technika a styl programování v Prologu Příklad: trasování a(X) a(X) a(X) c(l). d(2). - nonvar(X) - c(X). - d(X). Call I ------> + a(X) I a(X) <------+ a(X) Fai 1 I I Exi t nonvar(X).| ------> c(X). I d(X). + <------ I Redo a(X) ? X 1 1 Call a(_463) ? 2 2 Call nonvar (_ _463) ? 2 2 Fail nonvarC _463) ? 3 2 Call c(_463) ? 3 2 Exit c(l) ? 1 1 Exit a(l) ? = 1 ? Hana Rudová, Logické programování I, 1 8. března 201 3 18 Technika a styl programování v Prologu Příklad: trasování a(X) a(X) a(X) c(l). d(2). - nonvar(X) - c(X). - d(X). Call I ------> + a(X) I a(X) <------+ a(X) Fai 1 I I Exi t nonvar(X).| ------> c(X). I d(X). + <------ I Redo a(X) ? X = 1 ? 1 1 Call a(_463) 7 2 2 Call nonvar (_ _463) ? 2 2 Fail nonvar (_ _463) ? 3 2 Call c(_463) ? 3 2 Exit : c(l) ? 1 1 Exit : a(l) ? 1 1 Redo : a(l) ? 4 2 Call : d(_463) 7 Hana Rudová, Logické programování I, 1 8. března 201 3 18 Technika a styl programování v Prologu Příklad: trasování a(X) :- nonvar(X). a(X) :- c(X). a(X) :- d(X). c(l). d(2). Cal1 I I ------> + a(x) :- nonvar(X).| I a(X) :- c(X). I <------+ a(X) :- d(X). + Fail I I 1 ?- a(X). 1 1 Call : 2 2 Call : 2 2 Fail : 3 2 Call : 3 2 Exi t: ? 1 1 Exi t: Exit X = 1 ? ; ------> 1 1 Redo: 4 2 Call : <------ 4 2 Exi t: Redo 1 1 Exi t: X = 2 ? ; no % trace a(_463) ? nonvar(_463) ? nonvar(_463) ? c(_463) ? c(D ? a(l) ? a(l) ? d(_463) ? d(2) ? a(2) ? Hana Rudová, Logické programování I, 1 8. března 201 3 18 Technika a styl programování v Prologu Efektivita Čas výpočtu, paměťové nároky, a také časové nároky na vývoj programu m u Prologu můžeme častěji narazit na problémy s časem výpočtu a pamětí m Prologovské aplikace redukují čas na vývoj 3 vhodnost pro symbolické, nenumerické výpočty se strukturovanými objekty a relacemi mezi nimi Hana Rudová, Logické programování I, 1 8. března 201 3 19 Technika a styl programování v Prologu Efektivita Čas výpočtu, paměťové nároky, a také časové nároky na vývoj programu m u Prologu můžeme častěji narazit na problémy s časem výpočtu a pamětí m Prologovské aplikace redukují čas na vývoj 3 vhodnost pro symbolické, nenumerické výpočty se strukturovanými objekty a relacemi mezi nimi Pro zvýšení efektivity je nutno se zabývat procedurálními aspekty m zlepšení efektivity při prohledávání odstranění zbytečného backtrackingu i- zrušení provádění zbytečných alternativ co nejdříve návrh vhodnějších datových struktur, které umožní efektivnější operace s objekty Hana Rudová, Logické programování I, 1 8. března 201 3 19 Technika a styl programování v Prologu Zlepšení efektivity: základní techniky -0 Optimalizace posledního volání (LCO) a akumulátory Rozdílové seznamy při spojování seznamů M Caching: uložení vypočítaných výsledků do programové databáze Hana Rudová, Logické programování I, 1 8. března 201 3 20 Technika a styl programování v Prologu Zlepšení efektivity: základní techniky M Optimalizace posledního volání (LCO) a akumulátory Rozdílové seznamy při spojování seznamů M Caching: uložení vypočítaných výsledků do programové databáze M Indexace podle prvního argumentu 3 např. v SICStus Prologu m při volání predikátu s prvním nainstaniovaným argumentem se používá hašovací tabulka zpřístupňující pouze odpovídající klauzule 3 zamestnanec( Prijmem', KrestniJméno, Odděleni, ...) 3 seznamy( [], ...) :- ... . seznamy( [H|T], ...) :- ... . Hana Rudová, Logické programování I, 1 8. března 201 3 20 Technika a styl programování v Prologu Zlepšení efektivity: základní techniky M Optimalizace posledního volání (LCO) a akumulátory Rozdílové seznamy při spojování seznamů M Caching: uložení vypočítaných výsledků do programové databáze M Indexace podle prvního argumentu 3 např. v SICStus Prologu m při volání predikátu s prvním nainstaniovaným argumentem se používá hašovací tabulka zpřístupňující pouze odpovídající klauzule 3 zamestnanec( Prijmem', KrestniJméno, Odděleni, ...) 3 seznamy( [], ...) :- ... . seznamy( [H|T], ...) :- ... . -0 Determinismus: 3 rozhodnout, které klauzule mají uspět vícekrát, ověřit požadovaný determinismus Hana Rudová, Logické programování 1,18. března 201 3 20 Technika a styl programování v Prologu