2013-11-01 26 views
0

我正試圖解決swi-prolog中的2個水罐問題:給定2個罐的容量分別爲4加侖和3加侖,我想要找到在水罐中獲得2加侖的步驟容量4和0在另一個。序列中的2個水罐

我在C++中使用bfs和dfs編寫了這個問題的程序:http://kartikkukreja.wordpress.com/2013/10/11/water-jug-problem/。現在,我試圖在序言中解決這個問題。我對語言完全陌生,我的代碼不會終止。

這裏是我到目前爲止的代碼:

% state(0, 0) is the initial state 
% state(2, 0) is the goal state 
% Jugs 1 and 2 have capacities 4 and 3 respectively 
% P is a path to the goal state 
% C is the list of visited states 

solution(P) :- 
    path(0, 0, [state(0, 0)], P). 

path(2, 0, [state(2, 0)|_], _). 

path(0, 2, C, P) :- 
not(member(state(2, 0), C)), 
path(2, 0, [state(2, 0)|C], R), 
P = ['Pour 2 gallons from 3-Gallon jug to 4-gallon.'|R]. 

path(X, Y, C, P) :- 
X < 4, 
not(member(state(4, Y), C)), 
path(4, Y, [state(4, Y)|C], R), 
P = ['Fill the 4-Gallon Jug.'|R]. 

path(X, Y, C, P) :- 
Y < 3, 
not(member(state(X, 3), C)), 
path(X, 3, [state(X, 3)|C], R), 
P = ['Fill the 3-Gallon Jug.'|R]. 

path(X, Y, C, P) :- 
X > 0, 
not(member(state(0, Y), C)), 
path(0, Y, [state(0, Y)|C], R), 
P = ['Empty the 4-Gallon jug on ground.'|R]. 

path(X, Y, C, P) :- 
Y > 0, 
not(member(state(X, 0), C)), 
path(X, 0, [state(X, 0)|C], R), 
P = ['Empty the 3-Gallon jug on ground.'|R]. 

path(X, Y, C, P) :- 
X + Y >= 4, 
X < 4, 
Y > 0, 
NEW_Y = Y - (4 - X), 
not(member(state(4, NEW_Y), C)), 
path(4, NEW_Y, [state(4, NEW_Y)|C], R), 
P = ['Pour water from 3-Gallon jug to 4-gallon until it is full.'|R]. 

path(X, Y, C, P) :- 
X + Y >=3, 
X > 0, 
Y < 3, 
NEW_X = X - (3 - Y), 
not(member(state(NEW_X, 3), C)), 
path(NEW_X, 3, [state(NEW_X, 3)|C], R), 
P = ['Pour water from 4-Gallon jug to 3-gallon until it is full.'|R]. 

path(X, Y, C, P) :- 
X + Y =< 4, 
Y > 0, 
NEW_X = X + Y, 
not(member(state(NEW_X, 0), C)), 
path(NEW_X, 0, [state(NEW_X, 0)|C], R), 
P = ['Pour all the water from 3-Gallon jug to 4-gallon.'|R]. 

path(X, Y, C, P) :- 
X + Y =< 3, 
X > 0, 
NEW_Y = X + Y, 
not(member(state(0, NEW_Y), C)), 
path(0, NEW_Y, [state(0, NEW_Y)|C], R), 
P = ['Pour all the water from 4-Gallon jug to 3-gallon.'|R]. 

任何幫助表示讚賞。

回答

0

Prolog 中的'equal'運算符不是執行算術運算,但是統一了它的兩個參數。 嘗試(例如)替換此

NEW_Y = Y - (4 - X) 

NEW_Y is Y - (4 - X) 

OT:也Prolog的,就像任何其他的語言,從代碼保的好處:路/ 4規則公開相同的模式,因此代碼可能是有幫助的謂詞更乾淨:再次,例如

path(0, 2, C, P) :- 
    not(member(state(2, 0), C)), 
    path(2, 0, [state(2, 0)|C], R), 
    P = ['Pour 2 gallons from 3-Gallon jug to 4-gallon.'|R]. 

可能是

path(0, 2, C, ['Pour 2 gallons from 3-Gallon jug to 4-gallon.'|R]) :- 
    upd_path(2, 0, C, R). 

給出

upd_path(X, Y, C, R). 
     not(member(state(X, Y), C)), 
     path(X, Y, [state(X, Y)|C], R). 

編輯:另一個OT暗示:使用memberchk/2代替構件/ 2。它更高效,並且可以更容易地追蹤執行,而且是確定性的。

編輯另外,遞歸不關閉描述名單的基本情況:儘量

path(2, 0, [state(2, 0)|_], []).