2011-10-03 32 views
0

這是一個水罐問題。較大的桶容​​納5個,較小的桶容納3個。我想在較大的桶中獲得4個。序言中的水罐

問題是,當我運行我無法得到任何答案時,它會產生一個錯誤。它看起來不是一個明顯的錯誤,算法簡單直接。

任何人都可以幫助我找到它有什麼問題嗎?

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

我渴望有一天有人會問一個不是家庭作業的序言問題。 –

+0

可能不會發生。 Prolog需要一種不適合絕大多數現實世界任務的編程風格。它可能對人工智能有用,但大多數人做AI似乎使用Lisp。 – cHao

+2

現實中有很多人在使用它,他們只是被功課提問者淹沒在這裏。 –

回答

5

你沒有使用「是」作業。

您的puzzle\0謂詞有兩個未綁定變量:X & Y

而您的path\4謂詞有問題。

嘗試這些:

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. 

下面是我解決這個問題:

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. 

我得到這些解決方案:

[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)] 

顯然倒數第二,在最短的時間, 是最好的。