Logické programování Prezentace číslo 8
Stavový prostor Program k procházení bludiště je obecnější Můžeme hledat cestu nejen v „mapě”, která je dána, ale i ve stavovém prostoru, který je popsán pravidly, podle nichž lze přecházet mezi jednotlivými stavy. % hledej(Cil,[Seznam-proslych-mist/stavu]) hledej(S,[S|T]) :- write([S|T]), nl, fail. hledej(S,[X|T]) :- p(X,Y), not(clen(Y,[X|T])), hledej(S,[Y,X|T]).
Stavový prostor Přelévání vody Máme k dispozici nádoby o velikosti 5 a 3 litry (bez dalšího dělení), ale potřebujeme odměřit 4 litry vody Možné akce: naplň nádobu vyprázdni nádobu přelij jednu do druhé Reprezentace pomocí stavů: s(Velka,Mala) % s(0,0). - obě nádoby jsou prázdné % s(2,3). - ve velké jsou 2 litry, v malé 3 litry
Stavový prostor Přelévání vody p(s(V,M), s(5,M)). % napln velkou % prechod(Aktualni-stav, Novy-stav) p(s(V,M), s(5,M)). % napln velkou p(s(V,M), s(V,3)). % napln malou p(s(V,M), s(0,M)). % vyprazdni velkou p(s(V,M), s(V,0)). % vyprazdni malou p(s(V,M), s(V1,M1)):- % prelij velkou do male Pom is V+M, min(3,Pom,M1), V1 is Pom-M1. p(s(V,M), s(V1,M1)):- % prelij malou do velke Pom is V+M, min(5,Pom,V1), M1 is Pom-V1.
Stavový prostor prelevani:- write('Cilove mnostvi vody:'), nl, write('Velka:'), read(V), write('Mala:'), read(M), hledej(s(V,M),[s(0,0)]). % hledej(Cil,[Seznam-proslych-stavu]) hledej(S,[S|T]) :- write([S|T]), nl, fail. hledej(S,[X|T]) :- p(X,Y), not(clen(Y,[X|T])), hledej(S,[Y,X|T]). clen(H,[H|_]). clen(X,[_|T]) :- clen(X,T). min(A,B,A):-A<B, !. min(A,B,B).
Přelévání vody ?- prelevani. 16 řešení Cilove mnostvi vody: Velka:|: 4. Mala:|: 0. [s(4,0),s(1,3),s(1,0),s(0,1),s(5,1),s(3,3),s(3,0),s(0,3),s(5,3), s(5,0),s(0,0)] [s(4,0),s(1,3),s(1,0),s(0,1),s(5,1),s(3,3),s(3,0),s(0,3),s(5,3), s(2,3),s(5,0),s(0,0)] [s(4,0),s(1,3),s(1,0),s(0,1),s(5,1),s(3,3),s(3,0),s(0,3),s(2,3), s(5,0),s(0,0)] [s(4,0),s(1,3),s(1,0),s(0,1),s(5,1),s(3,3),s(3,0),s(0,3),s(5,3), s(5,2),s(0,2),s(2,0),s(2,3),s(5,0),s(0,0)] [s(4,0),s(1,3),s(1,0),s(0,1),s(5,1),s(3,3),s(3,0),s(0,3),s(5,3), s(4,3),s(5,2),s(0,2),s(2,0),s(2,3),s(5,0),s(0,0)] [s(4,0),s(1,3),s(1,0),s(0,1),s(5,1),s(3,3),s(3,0),s(0,3),s(4,3), s(5,2),s(0,2),s(2,0),s(2,3),s(5,0),s(0,0)] [s(4,0),s(4,3),s(5,2),s(0,2),s(2,0),s(2,3),s(5,0),s(0,0)] .... 16 řešení
Stavový prostor Přelévání vody – lepší pravidla % prechod(Aktualni-stav, Novy-stav) p(s(V,M), s(5,M)):-V<5, M<3. % nepln plnou a obe naraz p(s(V,M), s(V,3)):-M<3, V<5. % nepln plnou a obe naraz p(s(V,M), s(0,M)):-V>0. % je co vylevat? p(s(V,M), s(V,0)):-M>0. % je co vylevat? p(s(V,M), s(V1,M1)):- V>0,M<3, % je co a kam prelevat? Pom is V+M, min(3,Pom,M1), V1 is Pom-M1. p(s(V,M), s(V1,M1)):- M>0,V<5, % je co a kam prelevat? Pom is V+M, min(5,Pom,V1), M1 is Pom-V1.
Přelévání vody ?- prelevani. % lepsi pravidla 8 řešení Cilove mnostvi vody: Velka:|: 4. Mala:|: 0. [s(4,0),s(1,3),s(1,0),s(0,1),s(5,1),s(3,3),s(3,0),s(0,3),s(5,3), s(5,0),s(0,0)] [s(4,0),s(1,3),s(1,0),s(0,1),s(5,1),s(3,3),s(3,0),s(0,3),s(4,3), s(5,2),s(0,2),s(2,0),s(2,3),s(5,0),s(0,0)] [s(4,0),s(4,3),s(5,2),s(0,2),s(2,0),s(2,3),s(5,0),s(0,0)] [s(4,0),s(1,3),s(1,0),s(0,1),s(5,1),s(3,3),s(3,0),s(0,3),s(0,2), s(2,0),s(2,3),s(5,0),s(0,0)] [s(4,0),s(4,3),s(5,2),s(0,2),s(2,0),s(2,3),s(5,0),s(3,0),s(0,3), s(0,0)] [s(4,0),s(4,3),s(5,2),s(0,2),s(2,0),s(2,3),s(5,0),s(1,0),s(0,1), s(5,1),s(3,3),s(3,0),s(0,3),s(0,0)] [s(4,0),s(1,3),s(1,0),s(0,1),s(5,1),s(3,3),s(3,0),s(0,3),s(0,0)] [s(4,0),s(4,3),s(5,2),s(0,2),s(2,0),s(2,3),s(5,0),s(5,1),s(3,3), s(3,0),s(0,3),s(0,0)] no 8 řešení
Stavový prostor Převozník, koza, vlk a zelí % reprezentace stavu % stav(Prevoznik&lodka,Koza,Vlk,Zeli) % lodka musi byt tam, kde je prevoznik % s(l,l,l,l). - pocatecni stav - vsichni vlevo % s(p,p,p,p). - koncovy stav - vsichni vpravo % bezpecne stavy % stav je bezpecny, pokud prevoznik hlida kozu bezpecny(s(X,X,_,_)) :- !. % stav je bezpecny, pokud prevoznik hlida vlka a zeli bezpecny(s(X,_,X,X)).
Převozník, koza, vlk a zelí % prechod(Aktualni-stav, Novy-stav) % prevoznik jede sam p(s(P,K,V,Z),s(P1,K,V,Z)):-opacny_breh(P,P1). % prevoznik a koza p(s(P,P,V,Z),s(P1,P1,V,Z)):-opacny_breh(P,P1). % prevoznik a vlk p(s(P,K,P,Z),s(P1,K,P1,Z)):-opacny_breh(P,P1). % prevoznik a zeli p(s(P,K,V,P),s(P1,K,V,P1)):-opacny_breh(P,P1). opacny_breh(l,p). opacny_breh(p,l).
Převozník, koza, vlk a zelí % hledej(Poc_stav, [Plan]) hledej(X,[X|T]):-vypis([X|T]),nl,fail. % mam reseni hledej(X,[S|T]):-p(S,S1), bezpecny(S1), not(clen(S1,[S|T])), hledej(X,[S1,S|T]). clen(X,[X|_]). clen(X,[_|T]) :- clen(X,T). vypis([]). vypis([H|T]) :- write(H), nl, vypis(T).
Převozník, koza, vlk a zelí ?- hledej(s(l,l,l,l), [s(p,p,p,p)]). s(l,l,l,l) s(p,p,l,l) s(l,p,l,l) s(p,p,l,p) s(l,l,l,p) s(p,l,p,p) s(l,l,p,p) s(p,p,p,p) s(p,p,p,l) s(l,l,p,l) no P K V Z V Z P K P V Z K V P K Z P K V Z K P V Z P K V Z P K V Z
Stavový prostor N misionářů a N kanibalů Napište program, který bude řešit analogickou úlohu pro N misionářů a N kanibalů (N>=3) Do loďky se vejdou maximálně 2 osoby Vždy musí jet alespoň jedna osoba Počet kanibalů nesmí nikdy převýšit počet misionářů Pozor na vhodnou volbu reprezentace
Rozděl a panuj Hanojské věže hanoi:-write('Zadej pocet disku:'), read(N), N >= 1, presun(N,leva,prava,prostredka). % presun(Odkud,Kam,S-pomoci) presun(0,_,_,_):-!. presun(N,A,C,B):-N1 is N-1, presun(N1,A,B,C), write('presun disk z '), write(A), write(' do '), write(C), nl, presun(N1,B,C,A).
Rozděl a panuj Hanojské věže ?- hanoi. Zadej pocet disku:|: 3. presun disk z leva do prava presun disk z leva do prostredka presun disk z prava do prostredka presun disk z prostredka do leva presun disk z prostredka do prava yes