J'étudie des stratégies de recherche dans l'espace d'état dans Prolog, je regarde le programme suivant, est le fameux problème de cruches d'eau, pour le garder simple, vous avez 2 cruches (4 et 3 litres), vous pouvez remplir, vider et transférer l'eau dans l'autre pichet jusqu'à ce que le premier soit vide ou le second est plein. Le but est d'avoir 2 litres (les cruches n'ont pas de mesure). Cette mise en œuvre devrait être une première en largeur.Prolog - première recherche de pichet d'eau
go:-solution(S).
solution(ActionList):-init(I),nl,write(init),tab(4),write(I),
nl,solution(I,[],ActionList),!.
solution(State,VisitedStates,[]) :- final(State).
solution(State,VisitedStates, [Action|Rest]) :- applicable(Action,State) ,
apply(Action,State,NewState),
\+visited(NewState,VisitedStates), write(Action), tab(4) , write(NewState), nl,
solution(NewState,[State|VisitedStates],Rest).
visited(State,[VisitedState|OtherVisitedStates]) :- sameState(State,VisitedState).
visited(State,[VisitedState|OtherVisitedStates]) :- visited(State,OtherVisitedStates).
sameState(S,S).
init(state(0,0)).
final(state(2,X)).
applicable(emptyA,state(Qa,Qb)) :- Qa > 0.
applicable(emptyB,state(Qa,Qb)) :- Qb > 0.
applicable(fillA,state(Qa,Qb)) :- Qa < 4.
applicable(fillB,state(Qa,Qb)) :- Qb < 3.
applicable(emptyAinB,state(Qa,Qb)) :- Qa > 0 , Qtot is Qa + Qb , Qtot =< 3.
applicable(emptyBinA,state(Qa,Qb)) :- Qb > 0, Qtot is Qa + Qb , Qtot =< 4.
applicable(fillAwithB,state(Qa,Qb)) :- Qa < 4, Qtrasf is 4 - Qa , Qtrasf =< Qb.
applicable(fillBwithA,state(Qa,Qb)) :- Qb < 3, Qtrasf is 3 - Qb , Qtrasf=<Qa.
apply(emptyA,state(Qa,Qb),state(0,Qb)).
apply(emptyB,state(Qa,Qb),state(Qa,0)).
apply(fillA,state(Qa,Qb),state(4,Qb)).
apply(fillB,state(Qa,Qb),state(Qa,3)).
apply(emptyAinB,state(Qa,Qb),state(0,Qtot)) :- Qtot is Qa+Qb.
apply(emptyBinA,state(Qa,Qb),state(Qtot,0)) :- Qtot is Qa+Qb.
apply(fillAwithB,state(Qa,Qb),state(4,NewQb)) :- NewQb is Qb-(4-Qa).
apply(fillAwithB,state(Qa,Qb),state(NewQa,3)) :- NewQa is Qa-(3-Qb).
Ce qui est moins clair pour moi est de savoir comment comprendre c'est beadthfirst et non en profondeur d'abord par exemple, en regardant le code. Je regarde la mise en œuvre de BF dans le livre "Programmation Prolog pour l'Intelligence Artificielle" (I.Bratko) et il me semble différent car il garde toutes les alternatives candidates (nœud ou états dans mon cas) avec leur chemin (comme devrait être en théorie). Une autre question: BF devrait trouver le chemin le plus court d'abord, mais la réponse de mon programme:
init state(0,0)
fillA state(4,0)
fillB state(4,3)
emptyA state(0,3)
emptyBinA state(3,0)
fillB state(3,3)
fillAwithB state(4,2)
emptyA state(0,2)
emptyBinA state(2,0)
clairement ce n'est pas le plus court chemin, les opérations 2 et 4 sont inutilement.
Détails supplémentaires: J'ai essayé d'exécuter avec trace, et ne semble pas être un BF définitif, car à partir de "state (0,0)" les seuls états directement accessibles sont "state (4,0)" et " state (0,3) ", puis dans un BFS ces 3 nœuds à visiter, mais en regardant la trace, ils ne sont pas, après l'état (4,0), ils visitent l'état (4,3). Maintenant pouvez-vous confirmer que je suis sur la bonne voie et ce n'est pas un BFS? mais en essayant de suivre la mise en œuvre de Bratko, j'ai un problème: je devrais énumérer chaque nœud avec son successeur, je pense que ce n'est pas faisable avec le problème du pichet d'eau. Des indices?