plog_ppt6
DESCRIPTION
http://www.cmi.univ-mrs.fr/~preaux/PDF/pdf_proteges/PLog/PLogTD4.pdfTRANSCRIPT
-
PROLOG (Programmation logique)
Copyr
ight :
Jean-P
hilipp
e Pra
ux
-
PrologLe langage de programmation logique Prolog applique la mthode de rsolution des clauses de Horn.Un programme Prolog est un ensemble de clauses dfinies (thorie consistante)Cest un fichier texte saisi par lutilisateur. Ce dernier peut alors interroger Prolog pour savoir si un but en est consquence.Pour cela il saisit une clause ngative. Prolog lui applique le principe de rsolution : cest la clause dentre de la stratgie linaire par entre.Co
pyrigh
t : Jea
n-Phili
ppe P
raux
-
Une rgle dans prolog est une clause dfinie :qui scrit :et se lit aux conditions ou, si .
Elle est quivalente la formule :
1 ... pP N N
1: ,..., .pP N NP
P1,..., pN N
1,..., pN N
1 1... ( ... )p pP N N P N N
1( ... )pN N P Copyr
ight :
Jean-P
hilipp
e Pra
ux
-
Dans une rgleest la tte et est la queue.
Si la queue est vide on parle dun fait que lon crit :
Un programme Prolog est constitu de rgles et de faits.
1: ,..., .pP N NP 1,..., pN N
.P
Copyr
ight :
Jean-P
hilipp
e Pra
ux
-
Exemple :Programme :pere(marc,anne).pere(pierre,marc).grandpere(X,Z):- pere(X,Y), pere(Y,Z).A la question :?- grandpere(X,anne).Il rpond : X=pierre YesA la question :?- grandpere(pierre,anne).Il rpond : Yes
Essai1.pl
Copyr
ight :
Jean-P
hilipp
e Pra
ux
-
On peut rajouter loisir de nouvelles rgles, comme :
aieul(X,Y):- pere(X,Y).aieul(X,Y):- pere(X,Z), aieul(X,Z).
Attention : lordre dcriture est ici trs important !! Il faut penser la stratgie employe par le programme !!
Pour cette raison Prolog est un langage difficile ! Mais il est aussi trs puissant !Co
pyrigh
t : Jea
n-Phili
ppe P
raux
-
Prolog se prte particulirement bien aux appels rcursifs. Mais attention lordre dcriture !.Prendre comme rgle gnrale : Les rgles non inductives doivent tant que possible prcder les rgles inductives.Pour la mise au point on utilisera extensivement la commande trace.
Copyr
ight :
Jean-P
hilipp
e Pra
ux
-
On la dit prolog applique tant que possible le principe de rsolution, et retourne les unificateurs, en intraction avec lutilisateur.En gnral il retourne plusieurs rponses.
Aprs chaque rponse :; donne la suite (No signifie pas dautres)[Enter] arrte le processus (Yes signifie un succs, et No un chec.)Co
pyrigh
t : Jea
n-Phili
ppe P
raux
-
Variables anonymes
Si lon ne dsire pas que prolog retourne dunificateur, il suffit dutiliser la variable anonyme _.Ex :?- pere(_,anne).Yes.
Copyr
ight :
Jean-P
hilipp
e Pra
ux
-
Autre exemple dutilisation de _
livre(Victor Hugo,Notre dame de paris).livre(Edmond Rostand, Cyrano de
Bergerac).livre(Emile Zola,Hernani).auteur(X):- livre(X,_).
Ou plus simplement : ?- livre(X,_).
Livre.plCopyr
ight :
Jean-P
hilipp
e Pra
ux
-
Le ou, le et dans les questions et le non.
On peut entrer plusieurs questions spares par ; (correspondant ou) ou par , (correspondant et).Exemple : ?- pere(pierre,X),pere(X,Y).
Ou bien :?- pere(pierre,X);pere(X,Y).
Nont pas le mme comportement.not(predicat) russit si predicat choue.
Essai1.pl
Copyr
ight :
Jean-P
hilipp
e Pra
ux
-
Le prdicat prdfini =Cest lopration dunification. Il retourne yes en cas de succs, et fournit lunificateur.Exemple :?- f(X)=f(pierre).X=pierre.Yes.Attention, il nexiste pas daffectation en prolog. Lunification en gnralise certains aspects, mais pas tous :?- X=X+1.renvoie noCo
pyrigh
t : Jea
n-Phili
ppe P
raux
-
Prdicats, oprateurs, et termes prdfinis
Afin de ne pas se restreindre un moteur dinfrence, prolog contient un ensemble de termes, fonctions, oprateurs et prdicats prdfinis, lui permettant deffectuer des calculs, de travailler avec des entres-sorties, du texte, (etc) comme on le demande gnralement un langage de programmationCertains prdicats prdfinis ne servent qu mieux contrler la procdure de preuve (cut, fail, true, repeat,.).Co
pyrigh
t : Jea
n-Phili
ppe P
raux
-
Termes prdfinis
Prolog comprend tous les termes :Les nombres : 0, 2, -1, 0.5, etcLes chanes de caractres : Bonjour tous, etc, les caractres ascii (), etcIl connat les oprateurs arithmtiques : +, - (unaires et binaires), *, / , ().Et la plupart des fonctions mathmatiques : cos(), sin(), tan(), sqrt(), log(), exp(), etcCo
pyrigh
t : Jea
n-Phili
ppe P
raux
-
Pour les employer utiliser le prdicat prdfini : is :
?- X is 3*(2+1).X=9 Yes.is value le terme de droite, avant de tenter lunification. Il retourne Yes en cas de succs.
Le prdicat prdfini =:= value les 2 membres avant de vrifier sils sont gaux. Sa ngation est =\=.
?- 4+2 =:= 3*2.Yes.
Copyr
ight :
Jean-P
hilipp
e Pra
ux
-
Dautres prdicats prdfinisNe pas confondre = (opration dunification), avec is (qui value dabord le membre de droite), et le prdicat == qui neffectue aucune unification!?- f(a)==f(a). Yes.?- X==f(a). No.?- f(X)=f(X). X=_001 Yes.== teste si les 2 membres sont syntaxiquement identiques. Sa ngation est :\==Co
pyrigh
t : Jea
n-Phili
ppe P
raux
-
Prdicats prdfinis dentre-sortie
Les prdicats : write (et writef la C) qui crivent leurs arguments et russissent toujours,Ex :aide :- write(Aide : ce programme fait ).read(X) lit un terme sur la console, et tente de lunifier avec X. Il russit si lunification russit.Co
pyrigh
t : Jea
n-Phili
ppe P
raux
-
Exemple :iam :- write(Entrez votre nom :), read(X),nl,write(votre nom est),tab(1), write(X),nl.
nl russit toujours et passe la ligne.tab(n) russit toujours et crit n espaces.
On a aussi put() et get() pour les caractres.
Inout.plCopyr
ight :
Jean-P
hilipp
e Pra
ux
-
Exemple : Structure de testLa procdure test demande un nombre lutilisateur et teste sa nullit :
test1:-write(Entrez un nombre :), read(X), nul1(X).nul1(X):- X==0, nl, write(nul).nul1(X):- X \==0, nl, write(non nul).
Copyr
ight :
Jean-P
hilipp
e Pra
ux
-
Exemple : Structure de testLa procdure test demande un nombre lutilisateur et teste sa nullit :
test2:-write(Entrez un nombre :), read(X), nul2(X).nul1(X):- X==0, nl, write(nul).nul1(X):- X \==0, nl, write(non nul).
ou bien :nul2(X):- nl, X==0 -> write(nul) ; write(non nul).
avec loprateur :(if) condition -> (then) action 1 ; (else) action 2.
ifthenelse.pl
Copyr
ight :
Jean-P
hilipp
e Pra
ux
-
Exemple: structure de boucleSi p(n) est un prdicat toujours vrai (procdure), faire p(i) de i=0,1,,9 :
p(N):-write('iteration'),tab(1),write(N),nl.boucleP:- N=0, boucle(N).boucle(N):- N
-
La coupureOn la vu la question ?- P(X). prolog cherche toutes les solutions X.Parfois il est intressant voire ncessaire -- darrter sa recherche une seule solution, soit quand : On na besoin que dune solution. Seule la premire solution est exacte. La recherche de toutes les solutions entrane
une boucle infinie.Pour cela on a la coupure !. Cest un prdicat prdfini qui russit toujours.Co
pyrigh
t : Jea
n-Phili
ppe P
raux
-
Si T est le terme qui a t mis en correspondance avec la tte dune rgle dont la queue contient une coupure qui a russi, alors aucune autre unification ne sera dans la suite applique T.
Exemple :a(paul).a(pierre).p(X):- a(X), !.q(X):- a(X).Dans lappel de p(X), la coupure ayant russi pour X=paul, alors pour les buts a(X), p(X)aucune autre valeur de X ne sera cherche.
Cut.pl
Copyr
ight :
Jean-P
hilipp
e Pra
ux
-
Exemple : le calcul de factorielle n.
fact(0,1):- !.fact(N,R):- integer(N), N1 is N-1,
fact(N1,R1), R is N*R1.
Remarque : Ici, sans la coupure la procdure trouverait la bonne solution, mais tournerait ensuite indfiniment. (essayer fact0(3,R) qui est crit sans le cut.)
On appelle ?- fact(3,R).on obtient : R=6. Fact.plCo
pyrigh
t : Jea
n-Phili
ppe P
raux
-
Le prdicat prdfini fail retourne toujours un chec.Il est utile par exemple pour rpter une routine tant que tous les cas nont pas t traits. Exemple :pere(pierre,paul).pere(pierre,andre).pere(pierre,jules).[]enfants(X):-pere(X,Y),write(X),tab(1),
write(a pour enfant :),tab(1),write(Y),nl, fail.
?-enfants(pierre). affichera tous les enfants de pierre en une seule fois avant de finir par un chec: No.
Essai1.pl
Copyr
ight :
Jean-P
hilipp
e Pra
ux
-
Encore mieux : le prdicat prdfini functor(T,F,N) russit si T peut correspondre un terme fonctionnel ou prdicatif, F au nom de cette fonction ou prdicat, et N au nombre darguments.?- functor(pere(X,Y),F,N).F=pere, N=2. Yes.
Le prdicat arg(N,T,A) russit si T fonction ou prdicat, et A est le Nieme argument de T.?- arg(2,pere(pierre,paul),A).A=paul, Yes.Co
pyrigh
t : Jea
n-Phili
ppe P
raux
-
On considre une base de donne comme plus haut avec les prdicats pere(x,y), grandpere(x,y), fils(x,y), Considrons :tout(P):-functor(T,P,2), T, write(Le),tab(1),write(P),tab(1),write(de),tab(1),arg(2,T,X2),write(X2),
tab(1), write(est),tab(1), arg(1,T,X1), write(X1),nl, fail.
On peut ensuite appeler tout(pere), tout(fils), etc et obtenir la liste de toutes les relations paternelles, etc
Essai1.pl
Copyr
ight :
Jean-P
hilipp
e Pra
ux
-
Prolog et les listesPour utiliser pleinement prolog, on ne peut se passer des listes.Dfinition : [] est une liste appele la liste vide. Si t est un terme quelconque, et L est une liste, [t,L]
est la liste ayant pour tte t et pour queue L.En gnral on note [a,b,c] plutt que [a,[b,[c,[] ] ] ].Loprateur fondamental est [P|Q] qui unifie P avec la tte de la liste, et Q avec sa queue.[P1,P2,P3|Q] est la liste dont les 3 premiers lments sont P1, P2, P3, et le reste Q.Co
pyrigh
t : Jea
n-Phili
ppe P
raux
-
Pour dterminer si un lment figure dans une liste :membre(X,[X|_]).membre(X,[_|L]) :- membre(X,L).
Liste.pl
Copyr
ight :
Jean-P
hilipp
e Pra
ux
-
Pour dterminer si un lment figure dans une liste :membre(X,[X|_]).membre(X,[_|L]) :- membre(X,L).Pour placer un lment en tte de liste :insere(X,L,R) :- R=[X|L].
Liste.pl
Copyr
ight :
Jean-P
hilipp
e Pra
ux
-
Pour dterminer si un lment figure dans une liste :membre(X,[X|_]).membre(X,[_|L]) :- membre(X,L).Pour placer un lment en tte de liste :insere(X,L,R) :- R=[X|L].Pour placer un lment en queue de liste :
finsere(X,[],[X]).finsere(X,[Y|Z],R) :- finsere(X,Z,R1), R=[Y|R1].
Liste.pl
Copyr
ight :
Jean-P
hilipp
e Pra
ux
-
Pour dterminer si un lment figure dans une liste :membre(X,[X|_]).membre(X,[_|L]) :- membre(X,L).Pour placer un lment en tte de liste :insere(X,L,R) :- R=[X|L].Pour placer un lment en queue de liste :
finsere(X,[],[X]).finsere(X,[Y|Z],R) :- finsere(X,Z,R1), R=[Y|R1].Pour retourner la longueur dune liste :card([],0) :- !.card([T|Q],N) :- card(Q,N1) , N is N1+1.
Liste.pl
Copyr
ight :
Jean-P
hilipp
e Pra
ux
-
Pour dterminer si un lment figure dans une liste :membre(X,[X|_]).membre(X,[_|L]) :- membre(X,L).Pour placer un lment en tte de liste :insere(X,L,R) :- R=[X|L].Pour placer un lment en queue de liste :
finsere(X,[],[X]).finsere(X,[Y|Z],R) :- finsere(X,Z,R1), R=[Y|R1].Pour retourner la longueur dune liste :card([],0) :- !.card([T|Q],N) :- card(Q,N1) , N is N1+1.Compter le nombre doccurrence dun lment :occur(X,[],0) :- !.occur(X,[T|Q],N) :- X==T -> occur(X,Q,N1), N is N1+1, ; occur(X,Q,N1), N is N1.
Liste.pl
Copyr
ight :
Jean-P
hilipp
e Pra
ux
-
Exemple complet
Le jeu des 3 pices.Un jeu consiste mettre 3 pices sur la mme face par une suite dexactement 3 mouvements consistant chacun retourner simultanment 2 des 3 pices.A la question jeu(pile,face,pile) (par exemple) prolog retournera les 3 mouvements effectuer.Co
pyrigh
t : Jea
n-Phili
ppe P
raux
-
% Les 2 faces sont pile et face :opp(pile,face). opp(face,pile).
Copyr
ight :
Jean-P
hilipp
e Pra
ux
-
% Les 2 faces sont pile et face :opp(pile,face). opp(face,pile).
% Mouvement accepts X1,Y1,Z1 -> X2,Y2,Z2 :mouv(X,Y1,Z1,X,Y2,Z2) :- opp(Y1,Y2) , opp(Z1,Z2).mouv(X1,Y,Z1,X2,Y,Z2) :- opp(X1,X2) , opp(Z1,Z2).mouv(X1,Y1,Z,X2,Y2,Z) :- opp(X1,X2) , opp(Y1,Y2).
Copyr
ight :
Jean-P
hilipp
e Pra
ux
-
% Les 2 faces sont pile et face :opp(pile,face). opp(face,pile).
% Mouvement accepts X1,Y1,Z1 -> X2,Y2,Z2 :mouv(X,Y1,Z1,X,Y2,Z2) :- opp(Y1,Y2) , opp(Z1,Z2).mouv(X1,Y,Z1,X2,Y,Z2) :- opp(X1,X2) , opp(Z1,Z2).mouv(X1,Y1,Z,X2,Y2,Z) :- opp(X1,X2) , opp(Y1,Y2).
% Affichage de ltat des pices :affiche(X,Y,Z) :- write(X) , tab(1) , write(Y) , tab(1), write(Z) , nl.
Copyr
ight :
Jean-P
hilipp
e Pra
ux
-
% Les 2 faces sont pile et face :opp(pile,face). opp(face,pile).
% Mouvement accepts X1,Y1,Z1 -> X2,Y2,Z2 :mouv(X,Y1,Z1,X,Y2,Z2) :- opp(Y1,Y2) , opp(Z1,Z2).mouv(X1,Y,Z1,X2,Y,Z2) :- opp(X1,X2) , opp(Z1,Z2).mouv(X1,Y1,Z,X2,Y2,Z) :- opp(X1,X2) , opp(Y1,Y2).
% Affichage de ltat des pices :affiche(X,Y,Z) :- write(X) , tab(1) , write(Y) , tab(1), write(Z) , nl.
% prdicat jeu(.,.,.) appeler pour jouer.jeu(X0,Y0,Z0) :- mouv(X0,Y0,Z0,X1,Y1,Z1) , mouv(X1,Y1,Z1,X2,Y2,Z2) , mouv(X2,Y2,Z2,R,R,R), affiche(X0,Y0,Z0) , affiche(X1,Y1,Z1) , affiche(X2,Y2,Z2), affiche(R,R,R).
troispieces.pl
Copyr
ight :
Jean-P
hilipp
e Pra
ux
-
Rsultat :A lappel de :
?- jeu(pile,face,pile).
Prolog retourne :
pile face pilepile pile facepile face pilepile pile face
Yes.Co
pyrigh
t : Jea
n-Phili
ppe P
raux
-
Exemple completOn dispose dun programme donnant des trajets sens unique entre diverses villes :arc(paris,madrid). arc(moscou,pekin).arc(paris,reykjavic). arc(paris,moscou).arc(madrid,moscou). arc(paris,ouagadougou). arc(boston,paris). arc(boston,ouagadougou).arc(boston,reyjkjavic). arc(ouagadougou,pekin).
Ecrire un prdicat chemin(ville1,ville2,liste) qui retourne dans liste une trajet possible de la ville1 la ville2 (si cest possible).
Copyr
ight :
Jean-P
hilipp
e Pra
ux
-
Rponse :
chemin(X,Y,[X,Y]) :- arc(X,Y).chemin(X,Y,[X|L]) :- arc(X,Z) , chemin(Z,Y,L).
1 ?- chemin(paris,pekin,X).X = [paris, madrid, moscou, pekin] ;X = [paris, moscou, pekin] ;X = [paris, ouagadougou, pekin];No
Trajet.plCopyr
ight :
Jean-P
hilipp
e Pra
ux
-
On se donne de plus les distances reliant les villes :
arc(paris,madrid,10). arc(moscou,pekin,25).arc(paris,reykjavic,15). arc(boston,ouagadougou,35).arc(madrid,moscou,25). arc(boston,paris,30).arc(paris,ouagadougou,15). arc(paris,moscou,30).arc(boston,reyjkjavic,20). arc(ouagadougou,pekin,20).
Ecrire un predicat chemin(ville1,ville2,liste,dist) qui retourne en plus la longueur du trajet.
Comment chercher tous les trajets possibles issus de Boston de longueur
-
Rponse :
chemin(X,Y,[X,Y],N) :- arc(X,Y,N).chemin(X,Y,[X|L],N) :- arc(X,Z,M) , chemin(Z,Y,L,P), N is M+P.
2 ?- chemin(boston,Y,L,N),N
-
Comment modifier le programme pour que les trajets ne soient plus sens unique ?
Rponse :darc(X,Y) :- arc(X,Y). darc(X,Y) :- arc(Y,X).darc(X,Y,N) :- arc(X,Y,N). darc(X,Y,N) :- arc(Y,X,N).%trajet(X,Y,[X,Y],_) :- darc(X,Y).trajet(X,Y,[X|Q],L) :- darc(X,Z) , not(membre(Z,L)), trajet(Z,Y,Q,[Z|L]).%trajet(X,Y,[X,Y],_,N) :- darc(X,Y,N).trajet(X,Y,[X|Q],L,N) :- darc(X,Z,M) , not(membre(Z,L)), trajet(Z,Y,Q,[Z|L],P), N is M+P.
Attention : il faut prendre garde appeler trajet par :
3 ?- trajet(paris,pekin,L,[paris]) outrajet(paris,pekin,L,[paris],N)Copyr
ight :
Jean-P
hilipp
e Pra
ux
-
On peut aussi ajouter les rgles :
path(X,Y,L) :- trajet(X,Y,L,[X]). et path(X,Y,L,N) :- trajet(X,Y,L,[X],N).
4 ?- trajet(paris,moscou,X,[paris],N),N
-
Exemple complet
Le loup, la chvre et le chou.Un passeur doit faire traverser la rivire laide dune barque un loup, une chvre et un chou,. A chaque traverse il ne peut transporter avec lui que le loup, la chvre ou le chou. Il doit prendre garde ne pas laisser sur une berge le loup et la chvre, ou le la chvre et le chou car le loup mange la chvre et la chvre mange le chou.Comment procder ? Co
pyrigh
t : Jea
n-Phili
ppe P
raux
-
%Ltat du systme est ltat de la berge gauche donn par une liste de 4 boolens : [P,L,V,C]
Copyr
ight :
Jean-P
hilipp
e Pra
ux
-
%Ltat du systme est ltat de la berge gauche donn par une liste de 4 boolens : [P,L,V,C]
%Ltat de lautre berge sobtient par :negatif([X,Y,Z,W],[A,B,C,D]):-A is 1-X,B is 1-Y,C is 1-Z,D is 1-W.
Copyr
ight :
Jean-P
hilipp
e Pra
ux
-
%Ltat du systme est ltat de la berge gauche donn par une liste de 4 boolens : [P,L,V,C]
%Ltat de lautre berge sobtient par :negatif([X,Y,Z,W],[A,B,C,D]):-A is 1-X,B is 1-Y,C is 1-Z,D is 1-W.
% Etat accept dune berge :acceptable([1|_]).acceptable([0,B,C,_]):-B==1,C==0.acceptable([0,B,C,D]):-C==1,B==0,D==0.acceptable([0,0,0,_]).
% Etat accept des 2 berges :accepte([A,B,C,D]):-acceptable([A,B,C,D]),negatif([A,B,C,D],[X,Y,Z,W]),acceptable([X,Y,Z,W]).
Copyr
ight :
Jean-P
hilipp
e Pra
ux
-
%Ltat du systme est ltat de la berge gauche donn par une liste de 4 boolens : [P,L,V,C]
%Ltat de lautre berge sobtient par :negatif([X,Y,Z,W],[A,B,C,D]):-A is 1-X,B is 1-Y,C is 1-Z,D is 1-W.
% Etat accept dune berge :acceptable([1|_]).acceptable([0,B,C,_]):-B==1,C==0.acceptable([0,B,C,D]):-C==1,B==0,D==0.acceptable([0,0,0,_]).
% Etat accept des 2 berges :accepte([A,B,C,D]):-acceptable([A,B,C,D]),negatif([A,B,C,D],[X,Y,Z,W]),acceptable([X,Y,Z,W]).
% passages autoriss :passage([1,B,C,D],[0,B,C,D]):-accepte([0,B,C,D]).passage([1,B,C,1],[0,B,C,0]):-accepte([0,B,C,0]).passage([1,B,1,D],[0,B,0,D]):-accepte([0,B,0,D]).passage([1,1,C,D],[0,0,C,D]):-accepte([0,0,C,D]).passage(X,Y):-negatif(X,A),passage(A,Y).
Copyr
ight :
Jean-P
hilipp
e Pra
ux
-
%Ltat du systme est ltat de la berge gauche donn par une liste de 4 boolens : [P,L,V,C]
%Ltat de lautre berge sobtient par :negatif([X,Y,Z,W],[A,B,C,D]):-A is 1-X,B is 1-Y,C is 1-Z,D is 1-W.
% Etat accept dune berge :acceptable([1|_]).acceptable([0,B,C,_]):-B==1,C==0.acceptable([0,B,C,D]):-C==1,B==0,D==0.acceptable([0,0,0,_]).
% Etat accept des 2 berges :accepte([A,B,C,D]):-acceptable([A,B,C,D]),negatif([A,B,C,D],[X,Y,Z,W]),acceptable([X,Y,Z,W]).
% passages autoriss :passage([1,B,C,D],[0,B,C,D]):-accepte([0,B,C,D]).passage([1,B,C,1],[0,B,C,0]):-accepte([0,B,C,0]).passage([1,B,1,D],[0,B,0,D]):-accepte([0,B,0,D]).passage([1,1,C,D],[0,0,C,D]):-accepte([0,0,C,D]).passage(X,Y):-negatif(X,A),passage(A,Y).
% chemin dun tat lautre :chemin(L,L,Vu):-montre(Vu).chemin(L1,L2,Vu):-L1=[0,_,_,_],passage(L1,L),negatif(L,N),not(membre(N,Vu)),chemin(N,L2,[N|Vu]).chemin(L1,L2,Vu):-passage(L1,L),not(membre(L,Vu)),chemin(L,L2,[L|Vu]).
Copyr
ight :
Jean-P
hilipp
e Pra
ux
-
%Ltat du systme est ltat de la berge gauche donn par une liste de 4 boolens : [P,L,V,C]
%Ltat de lautre berge sobtient par :negatif([X,Y,Z,W],[A,B,C,D]):-A is 1-X,B is 1-Y,C is 1-Z,D is 1-W.
% Etat accept dune berge :acceptable([1|_]).acceptable([0,B,C,_]):-B==1,C==0.acceptable([0,B,C,D]):-C==1,B==0,D==0.acceptable([0,0,0,_]).
% Etat accept des 2 berges :accepte([A,B,C,D]):-acceptable([A,B,C,D]),negatif([A,B,C,D],[X,Y,Z,W]),acceptable([X,Y,Z,W]).
% passages autoriss :passage([1,B,C,D],[0,B,C,D]):-accepte([0,B,C,D]).passage([1,B,C,1],[0,B,C,0]):-accepte([0,B,C,0]).passage([1,B,1,D],[0,B,0,D]):-accepte([0,B,0,D]).passage([1,1,C,D],[0,0,C,D]):-accepte([0,0,C,D]).passage(X,Y):-negatif(X,A),passage(A,Y).
% chemin dun tat lautre :chemin(L,L,Vu):-montre(Vu).chemin(L1,L2,Vu):-L1=[0,_,_,_],passage(L1,L),negatif(L,N),not(membre(N,Vu)),chemin(N,L2,[N|Vu]).chemin(L1,L2,Vu):-passage(L1,L),not(membre(L,Vu)),chemin(L,L2,[L|Vu]).
% solution obtenus en crant un chemin de ltat initial [1,1,1,1] ltat final [0,0,0,0] :solution:-chemin([1,1,1,1],[0,0,0,0],[[1,1,1,1]]).
% montre(Vu) : gre l'affichage du rsultat. A crire.
Chevre.pl
Copyr
ight :
Jean-P
hilipp
e Pra
ux
-
A lappel de :
?- solution.
Prolog retourne (dpend de lcriture de montre/1):
rive gauche rive droite
[1, 1, 1, 1] |~~~~~~~~~| [0, 0, 0, 0][0, 1, 0, 1] |~~~~~~~~~| [1, 0, 1, 0][1, 1, 0, 1] |~~~~~~~~~| [0, 0, 1, 0][0, 1, 0, 0] |~~~~~~~~~| [1, 0, 1, 1][1, 1, 1, 0] |~~~~~~~~~| [0, 0, 0, 1][0, 0, 1, 0] |~~~~~~~~~| [1, 1, 0, 1][1, 0, 1, 0] |~~~~~~~~~| [0, 1, 0, 1][0, 0, 0, 0] |~~~~~~~~~| [1, 1, 1, 1]
Le passeur va droite avec la chvreLe passeur va gauche tout seulLe passeur va droite avec le chouLe passeur va gauche avec la chvreLe passeur va droite avec le loupLe passeur va gauche tout seulLe passeur va droite avec la chvre
YesCo
pyrigh
t : Jea
n-Phili
ppe P
raux