Vstup/výstup, databázové operace, rozklad termu Ctení 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 vestavěný predikát Hana Rudová, Logické programování 1,10. dubna 201 2 2 Vstup/výstup, databázové operace, rozklad termu Predikáty pro vstup a výstup I ?- read(A), read( ahoj(B) ), read( [C,D] ). |: ahoj. ahoj( petre ). [ ahoj( 'Petre!' ), jdeme ]. A = ahoj, B = petre, C = ahoj('Petre!'), D = jdeme I ?- write(a(l)), write('.'), nl, write(a(2)), write('.'), nl. a(l). a(2). yes M seeing, see, seen, read telling, tell, told, write see/tel1(Soubor) M pokud Soubor není otevřený: otevření a aktivace 3 pokud Soubor otevřený: pouze aktivace (tj. udělá z něj aktivní vstupní/výstupní stream) standardní vstupní a výstupní stream: user Hana Rudová, Logické programování 1,10. dubna 201 2 3 Vstup/výstup, databázové operace, rozklad termu Příklad: vstup/výstup Napište predikát uloz_do_souboru( Soubor ), který načte několik fakt ze vstupu a uloží je do souboru Soubor. | ?- uloz_do_souboru( 'soubor.pl' ). |: fakt(mi rek, 18). |: fakt(pavel,4). |: end_of_fi 1 e. | ?- 1 i sti ng(fakt/2) . % pozor:li sti ng/1 lze použít pouze při consult/1 (ne u compi 1 e/1) fakt(mi rek, 18). fakt(pavel, 4). yes | ?- consult(soubor). yes yes Hana Rudová, Logické programování 1,10. dubna 201 2 4 Vstup/výstup, databázové operace, rozklad termu Implementace: vstup/výstup uloz_do_souboru( Soubor ) :-seeing( StaryVstup ), telling( StaryVystup ), see( user ), tel 1( Soubor ), repeat, read( Term ), process_term( Term ), Term == end_of_fi 1e, i seen, told, tell( StaryVystup ), see( StaryVstup ). process_term(end_of_fi 1e) :- !. process_term( Term ) :- write( Term ), write('.'), nl. Hana Rudová, Logické programování 1,10. dubna 2012 5 Vstup/výstup, databázové operace, rozklad termu Databázové operace Databáze: specifikace množiny relací Prologovský program: programová databáze, kde jsou relace specifikovány explicitně (fakty) i implicitně (pravidly) Vestavěné predikáty pro změnu databáze během provádění programu: assert( Klauzule ) přidání Klauzule do programu asserta( Klauzule ) přidání na začátek assertz( Klauzule ) přidání na konec retract( Klauzule ) smazání klauzule unifikovatelné s Klauzule Pozor: retract/1 lze použít pouze pro dynamické klauzule (přidané pomocí assert) a ne pro statické klauzule z programu Pozor: nadměrné použití těchto operací snižuje srozumitelnost programu Hana Rudová, Logické programování 1,10. dubna 201 2 6 Vstup/výstup, databázové operace, rozklad termu Databázové operace: příklad Napište predikát vytvor_program/0, který načte několik klauzulí ze vstupu a uloží je do programové databáze. | ?- vytvor_program. |: fakt(pavel, 4). |: praviďlo(X,Y) :- fakt(X,Y). |: end_of_fi 1 e. yes | ?- list-ingCfakt/2). fakt(pavel, 4). yes | ?- listing(pravidlo/2). pravidlo(A, B) :- fakt(A, B). yes | ?- clause( pravidlo (A, B) , C) . % cl ause/2 použitelný pouze pro dynamické klauzule C = fakt(A,B) ? yes Hana Rudová, Logické programování 1,10. dubna 201 2 7 Vstup/výstup, databázové operace, rozklad termu Databázové operace: implementace vytvo r_p rog ram :- seeing( StaryVstup ), see( user ), repeat, read( Term ), uloz_term( Term ), Term == end_of_fi1e, i ■ > seen, see( StaryVstup ). uloz_term( end_of_fi1 e ) :- !. uloz_term( Term ) :- assert( Term ). Hana Rudová, Logické programování 1,10. dubna 201 2 8 Vstup/výstup, databázové operace, rozklad termu 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,10. dubna 201 2 9 Vstup/výstup, databázové operace, rozklad termu Rekurzivní rozklad termu Term je proměnná (var/1), atom nebo číslo (atomic/1) => konec rozkladu M Term je seznam ([_|_]) => procházení seznamu a rozklad každého prvku seznamu 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), !. % Term je atom nebo číslo NEBO ground(Term) :- var(Term), !, fail. % Term není proměnná NEBO ground([H|T]) :- !, ground(H), ground(T). % Term je seznam a ani hlava ani tělo ?- 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,10. dubna 201 2 10 Vstup/výstup, databázové operace, rozklad termu subterm(S,T) Napište predikát subterm(S ,T) pro termy S a T bez proměnných, které uspějí, pokud je S podtermem termu T. Tj. musí platit alespoň jedno z podterm S je právě term T NEBO podterm S se nachází v hlavě seznamu T NEBO M podterm S se nachází v těle seznamu T NEBO T je složený term (compound/1) a S je podtermem některého argumentu T M otestujte :- subterm(l,2) . pokud nepoužijeme (compound/1), pak tento dotaz cyklí M otestujte :- subterm(a, [1,2]) . ověřte, zda necyklí (nutný červený řez níže) | ?- subterm(sin(3),b(c,2,[1,b],sin(3),a)). yes Hana Rudová, Logické programování 1,10. dubna 201 2 Vstup/výstup, databázové operace, rozklad termu subterm(S,T) Napište predikát subterm(S ,T) pro termy S a T bez proměnných, které uspějí, pokud je S podtermem termu T. Tj. musí platit alespoň jedno z podterm S je právě term T NEBO podterm S se nachází v hlavě seznamu T NEBO M podterm S se nachází v těle seznamu T NEBO T je složený term (compound/1) a S je podtermem některého argumentu T M otestujte :- subterm(l,2) . pokud nepoužijeme (compound/1), pak tento dotaz cyklí M otestujte :- subterm(a, [1,2]) . ověřte, zda necyklí (nutný červený řez níže) | ?- subterm(sin(3),b(c,2,[1,b],sin(3),a)). yes subterm(T,T) :- !. subterm(S,[H|_]) :- subterm(S,H), !. subterm(S, [_|T]) :- !, subterm(S,T) . subterm(S,T) :- compound(T), T=..[_|Argumenty], subterm(S,Argumenty). Hana Rudová, Logické programování I, 10. dubna 201 2 11 Vstup/výstup, databázové operace, rozklad termu same(A,B) Napište predikát same(A, B), který uspěje, pokud mají termy A a B stejnou strukturu. Tj. musí platit právě jedno z M A i B jsou proměnné NEBO M pokud je jeden z argumentů proměnná (druhý ne), pak predikát neuspěje, NEBO M A i B jsou atomic a unifikovatelné NEBO M A i B jsou seznamy, pak jak jejich hlava tak jejich tělo mají stejnou strukturu NEBO M A i B jsou složené termy se stejným funktorem a jejich argumenty mají stejnou strukturu | ?- same([1,3,sin(X),s(a,3)],[l,3,sin(X),s(a,3)]). yes Hana Rudová, Logické programování 1,10. dubna 201 2 12 Vstup/výstup, databázové operace, rozklad termu same(A,B) Napište predikát same(A, B), který uspěje, pokud mají termy A a B stejnou strukturu. Tj. musí platit právě jedno z M A i B jsou proměnné NEBO M pokud je jeden z argumentů proměnná (druhý ne), pak predikát neuspěje, NEBO M A i B jsou atomic a unifikovatelné NEBO M A i B jsou seznamy, pak jak jejich hlava tak jejich tělo mají stejnou strukturu NEBO