2013-08-04 30 views
2

我是AI和Prolog的新手。我試圖在SWI Prolog中實施2個水罐問題。但是,我的解決方案返回global stack overflowSWI-Prolog中的水壺拼圖

我知道這個問題已被問過去,並有過無數的答案/解決方案,作爲一個完整的新手我的方法有點天真,因此我想知道我做錯了什麼。

問題:

有兩種水罐,一個具有4加侖容量,而另一可容納多達3加侖。我需要2加侖4加侖的水罐,另一個應該是空的。

下面的代碼:

member(X, [X|R]). 
member(X, [Y|R]) :- member(X,R). 

append([X|Y], Z, [X|W]) :- append(Y,Z,W). 
append([], X, X). 

/*                                    
production rules for the water jug problem                          
*/ 
maneuver(X, Y, Z):-X=:=2, Y=:=0, write('done'). 
maneuver(X, Y, Z):-X<4, \+ member(Z, (4,Y)), append(Z, [(4,Y)], A), write('Fill 4 gallon jug\n'), maneuver(4,Y,A). 
maneuver(X, Y, Z):-Y<3, \+ member(Z, (X,3)), append(Z, [(X,3)], A), write('Fill 3 gallon jug\b'), maneuver(X,3,A). 
maneuver(X, Y, Z):-X>0, \+ member(Z, (0,Y)), append(Z, [(0,Y)], A), write('Empty the 4 gallon jug\n'), maneuver(0,Y,A). 
maneuver(X, Y, Z):-Y>0, \+ member(Z, (X,0)), append(Z, [(X,0)], A), write('Empty the 3 gallon jug\n'), maneuver(X,0,A). 
maneuver(X, Y, Z):-X+Y>=4, Y>0, \+ member(Z, (4,Y-(4-X))), append(Z, [(4,Y-(4-X))], A), write('Pour from 3 gallon jug to 4 gallon jug\n'), ma$ 
maneuver(X, Y, Z):-X+Y>=3, X>0, \+ member(Z, (X-(3-Y),3)), append(Z, [(X-(3-Y),3)], A), write('Pour from 4 gallon jug to 3 gallon jug\n'), ma$ 
maneuver(X, Y, Z):-X+Y=<4, Y>0, \+ member(Z, (X+Y, 0)), append(Z, [(X+Y, 0)], A), write('Pour the water in the 3 gallon jug into the 4 gallon$ 
maneuver(X, Y, Z):-X+Y=<4, Y>0, \+ member(Z, (0, X+Y)), append(Z, [(0, X+Y)], A), write('Pour the water in the 4 gallon jug into the 3 gallon$ 

這裏的輸出。

Fill 4 gallon jug 
Fill 3 gallon juEmpty the 4 gallon jug 
Fill 4 gallon jug 
Empty the 4 gallon jug 
Fill 4 gallon jug 
Empty the 4 gallon jug 
Fill 4 gallon jug 
Empty the 4 gallon jug 
Fill 4 gallon jug 
Empty the 4 gallon jug 
Fill 4 gallon jug 
Empty the 4 gallon jug 
Fill 4 gallon jug 
Empty the 4 gallon jug 
... 
+0

你的代碼被截斷,請張貼更正一個 – CapelliC

回答

1

在Prolog的,它毫無意義的輸出動作「描述」,因爲這樣將無法行動的任何序列將被撤消,從而嘗試任何可用的替代。 然後,我會採取的第一步是「整容」:移開描述,可以從解決方案的兩個相鄰步驟(列表Z)推斷出該描述,併爲解決方案添加解決方案參數。

另一個重要的改進:所有的步驟重複相同的 - 錯 - 模式:例如

\+ member(Z, (4,Y)), append(Z, [(4,Y)], A) 

做出「子程序」(和糾正錯誤, - 我想 - 導致循環):

update(State, Step, Updated) :- 
    \+ member(Step, State), 
    append(State, [Step], Updated). 
+1

您還可以避免'附加/ 3'通過'Updated'參數作爲一個堆棧,而不是作爲一個隊列。但是,這將會以相反的順序提供解決方案。 –