2011-10-03 2 views
0

C'est un problème de pichet d'eau. Le plus grand seau détient 5, le plus petit seau détient 3. Je veux obtenir 4 dans le plus grand seau.cruche d'eau en prolog

Le problème est que lorsque je cours, je ne peux obtenir aucune réponse, cela produit une erreur. Cela ne semble pas une erreur évidente, l'algorithme est simple et direct.

Quelqu'un pourrait-il m'aider à trouver un problème avec cette appli?

check_safe(X,Y):- X>=0,X=<3,Y>=0,Y=<5. 

%empty the 3 bucket 

move(state(X,Y),state(0,Y)):- X>0,check_safe(0,Y). 

%empty the 5 bucket 

move(state(X,Y),state(X,0)):- Y>0,check_safe(X,0). 

%fill the 3 bucket 

move(state(X,Y), state(3,Y)):- X<3, X>=0,check_safe(3,Y). 

%fill the 5 bucket 

move(state(X,Y),state(X,5)):- Y>=0, Y<5,check_safe(X,5). 

%transfer from 3 to 5 until the larger bucket is full 

move(state(X,Y),state(NewX,5)):- X+Y>= 5, X>0,Y>=0, NewX=X+Y-5,check_safe(NewX,5). 

%transfer from 3 to 5 until the smaller bucket is empty 

move(state(X,Y),state(0,NewY)):- X+Y<5, X>0,Y>=0, NewY=X+Y,check_safe(0,NewY). 

%transfer from 5 to 3 until the smaller is full 

move(state(X,Y),state(3,NewY)):- Y>0,X>=0,X+Y>=5, NewY=Y+X-3,check_safe(3,NewY). 

%transfer from 5 to 3 until the larger is empty 

move(state(X,Y),state(NewX,0)):-Y>0,X>=0, X+Y<5, NewX=Y+X,check_safe(NewX,0). 


path(X,X,_,[X]). 
path(X,Y,BeenStates,Path):- 
    move(X,Somewhere),not(member(Somewhere,BeenStates)), 
    path(Somewhere,Y,[Somewhere|BeenStates],Path2), Path = [X|Path2]. 


puzzle:- path(state(0,0),state(0,5),[state(0,0)],PathList),X>=0,X=<5, 
    writeOut(PathList). 

% Here's an easy little predicate for printing a list. 
writeOut([]). 
writeOut([H|T]):-write(H),nl, writeOut(T). 
+5

J'ai envie d'un jour où quelqu'un va poser une question Prolog qui n'est pas un devoir. –

+0

Probablement ne va pas se produire. Prolog requiert un style de programmation peu adapté à la grande majorité des tâches du monde réel. Cela pourrait être utile dans l'IA, mais la plupart des gens qui font de l'IA semblent utiliser Lisp pour ça. – cHao

+2

Il y a beaucoup de gens qui l'utilisent dans la réalité, ils sont juste débordés ici par les devoirs-demandeurs. –

Répondre

5

Vous n'utilisez pas "est" pour les affectations.

Votre puzzle\0 prédicat a deux variables non liées: X & Y.

Et vos prédicats path\4 sont défectueux.

Essayez:

path([state(X, 4)|Xs],[state(X, 4)|Xs]):- !. 
path([X|Xs],Rs):- 
    move(X,Y),not(member(Y,[X|Xs])), 
    path([Y,X|Xs],Rs). 

puzzle:- path([state(0,0)],PathList), 
    write(PathList), nl, fail. 

Voici ma solution à ce problème:

move(s(X,Y),s(Z,5)) :- Z is X - (5 - Y), Z >= 0. 
move(s(X,Y),s(Z,0)) :- Z is X + Y, Z =< 3. 
move(s(X,Y),s(3,Z)) :- Z is Y - (3 - X), Z >=0. 
move(s(X,Y),s(0,Z)) :- Z is X + Y, Z =< 5. 

move(s(0,Y),s(3,Y)). 
move(s(X,0),s(X,5)). 
move(s(X,Y),s(X,0)) :- Y > 0. 
move(s(X,Y),s(0,Y)) :- X > 0. 

moves(Xs) :- moves([s(0,0)],Xs). 
moves([s(X0,Y0)|T], [s(X1,4),s(X0,Y0)|T]) 
    :- move(s(X0,Y0),s(X1,4)), !. 
moves([s(X0,Y0)|T],Xs) :- 
    move(s(X0,Y0),s(X1,Y1)), 
    not(member(s(X1,Y1),[s(X0,Y0)|T])), 
    moves([s(X1,Y1),s(X0,Y0)|T],Xs). 

?- moves(Xs), write(Xs), nl, fail. 

Je reçois ces solutions:

[s(0,4),s(3,1),s(0,1),s(1,0),s(1,5),s(3,3),s(0,3),s(3,0),s(0,0)] 
[s(3,4),s(2,5),s(2,0),s(0,2),s(3,2),s(0,5),s(1,5),s(3,3),s(0,3),s(3,0),s(0,0)] 
[s(3,4),s(2,5),s(2,0),s(0,2),s(3,2),s(0,5),s(3,5),s(3,0),s(0,0)] 
[s(0,4),s(3,1),s(0,1),s(1,0),s(1,5),s(3,3),s(0,3),s(3,0),s(3,2),s(0,5),s(0,0)] 
[s(3,4),s(2,5),s(2,0),s(0,2),s(3,2),s(0,5),s(0,0)] 
[s(0,4),s(3,1),s(0,1),s(1,0),s(1,5),s(3,3),s(0,3),s(3,0),s(3,5),s(0,5),s(0,0)] 

Il est évident que l'avant-dernier, étant le plus court , est le meilleur.