plog_ppt6

53
PROLOG (Programmation logique) Copyright : Jean-Philippe Préaux

Upload: chfakht

Post on 09-Nov-2015

215 views

Category:

Documents


1 download

DESCRIPTION

http://www.cmi.univ-mrs.fr/~preaux/PDF/pdf_proteges/PLog/PLogTD4.pdf

TRANSCRIPT

  • 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