prolog中的水壶

prolog中的水壶,prolog,water-jug-problem,Prolog,Water Jug Problem,这是一个水壶问题。较大的铲斗容纳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

这是一个水壶问题。较大的铲斗容纳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).
检查安全(X,Y):-X>=0,X==0,Y=0,检查安全(0,Y)。
%清空5桶
移动(状态(X,Y),状态(X,0)):-Y>0,检查安全(X,0)。
%把这3个桶装满
移动(状态(X,Y),状态(3,Y)):-X=0,检查安全(3,Y)。
%装满5桶
移动(状态(X,Y),状态(X,5)):-Y>=0,Y=5,X>0,Y>=0,NewX=X+Y-5,检查安全(NewX,5)。
%从3号输送至5号,直到较小的铲斗为空
移动(状态(X,Y),状态(0,NewY)):-X+Y0,Y>=0,NewY=X+Y,检查安全(0,NewY)。
%从5转移到3,直到较小的已满
移动(状态(X,Y),状态(3,NewY)):-Y>0,X>=0,X+Y>=5,NewY=Y+X-3,检查安全(3,NewY)。
%从5转移到3,直到较大者为空
移动(状态(X,Y),状态(NewX,0)):-Y>0,X>=0,X+Y=0,X=您没有使用“is”进行分配

您的
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.
很明显,倒数第二的,即最短的,是最好的。

你没有用“是”来做作业

您的
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.
很明显,倒数第二的,最短的,是最好的。

**

水壶问题:

**

%数据库
已访问\u状态(整数,整数)。
%谓词
状态(整数,整数)。
%条款
国家(2,0)。
状态(X,Y):-X<4,
不是(访问了_州(4,Y)),
断言(U状态(X,Y)),
写下(“装满4加仑的罐子:(“,X,”,“,Y,”)-->(“,4,”,“,Y,”)\n”),
州(4,Y)。
状态(X,Y):-Y<3,
不是(被访问的州(X,3)),
断言(U状态(X,Y)),
写下(“装满3加仑的罐子:(“,X,”,“,Y,”)-->(“,X,”,“,3,”)\n”),
状态(X,3)。
状态(X,Y):-X>0,
不(访问了_状态(0,Y)),
断言(U状态(X,Y)),
写下(“清空地上的4加仑水罐:(“,X,”,“,Y,”)-->(“,0,”,“,Y,”)\n”),
状态(0,Y)。
状态(X,Y):-Y>0,
非(访问了_状态(X,0)),
断言(U状态(X,0)),
写下(“清空地上的3加仑水罐:(“,X,”,“,Y,”)-->(“,X,”,“,0,”)\n”),
状态(X,0)。
状态(X,Y):-X+Y>=4,
Y>0,
新的Y=Y-(4-X),
未访问(访问州(4,纽约州)),
断言(U状态(X,Y)),
写下(“将水从3加仑的水罐倒入4加仑的水罐,直到水罐装满:(“,X,”,“,Y,”)-->(“,4,”,“,NEW_Y,”)\n”),
州(4,纽约州)。
状态(X,Y):-X+Y>=3,
X>0,
新_X=X-(3-Y),
不是(被访问的州(X,3)),
断言(U状态(X,Y)),
写下(“将4加仑水罐中的水倒入3加仑水罐中,直到水罐装满:(“,X,”,“,Y,”)-->(“,NEW_X,”,“,3,”)\n”),
州(新州,3)。
状态(X,Y):-X+Y>=4,
Y>0,
新的X=X+Y,
不(访问了_状态(新_X,0)),
断言(U状态(X,Y)),
写下(“将3加仑水罐中的所有水倒入4加仑:(“,X,”,“,Y,”)-->(“,NEW_X,”,“,0,”)\n”),
状态(新的X,0)。
状态(X,Y):-X+Y>=3,
X>0,
新的Y=X+Y,
未访问(访问状态(0,新建)),
断言(U状态(X,Y)),
写下(“将4加仑水罐中的所有水倒入3加仑:(“,X,”,“,Y,”)-->(“,0,”,“,NEW_Y,”)\n”),
状态(0,新的)。
状态(0,2):-未访问状态(2,0)),
断言(U状态(0,2)),
写下(“将2加仑从3加仑水罐倒入4加仑:(“,0,”,“,2,”)-->(“,2,”,“,0,”)\n”),
国家(2,0)。
状态(2,Y):-未访问状态(0,Y)),
断言(状态(2,Y)),
写下(“从地上的4加仑水罐中清空2加仑:(“,2,”,“,Y,”)-->(“,0,”,“,Y,”)\n”),
状态(0,Y)。
目标:-
makewindow(1,2,3,“4-3水罐问题”,0,0,25,80),
状态(0,0)。
**
>输出:
国家(2,5)。
**
**

水壶问题:

**

%数据库
已访问\u状态(整数,整数)。
%谓词
状态(整数,整数)。
%条款
国家(2,0)。
状态(X,Y):-X<4,
不是(访问了_州(4,Y)),
断言(U状态(X,Y)),
写下(“装满4加仑的罐子:(“,X,”,“,Y,”)-->(“,4,”,“,Y,”)\n”),
州(4,Y)。
状态(X,Y):-Y<3,
不是(被访问的州(X,3)),
断言(U状态(X,Y)),
写下(“装满3加仑的罐子:(“,X,”,“,Y,”)-->(“,X,”,“,3,”)\n”),
状态(X,3)。
状态(X,Y):-X>0,
不(访问了_状态(0,Y)),
断言(U状态(X,Y)),
写下(“清空地上的4加仑水罐:(“,X,”,“,Y,”)-->(“,0,”,“,Y,”)\n”),
状态(0,Y)。
状态(X,Y):-Y>0,
非(访问了_状态(X,0)),
断言(U状态(X,0)),
写下(“清空地上的3加仑水罐:(“,X,”,“,Y,”)-->(“,X,”,“,0,”)\n”),
状态(X,0)。
状态(X,Y):-X+Y>=4,
Y>0,
新的Y=Y-(4-X),
未访问(访问州(4,纽约州)),
断言(U状态(X,Y)),
写下(“将水从3加仑的水罐倒入4加仑的水罐,直到水罐装满:(“,X,”,“,Y,”)-->(“,4,”,“,NEW_Y,”)\n”),
州(4,纽约州)。
状态(X,Y):-X+Y>=3,
X>0,
新_X=X-(3-Y),
不是(被访问的州(X,3)),
断言(U状态(X,Y)),
写下(“将4加仑水罐中的水倒入3加仑水罐中,直到水罐装满:(“,X,”,“,Y,”)-->(“,NEW_X,”,“,3,”)\n”),
州(新州,3)。
状态(X,Y):-X+Y>=4,
Y>0,
新的X=X+Y,
不(访问了_状态(新_X,0)),
断言(U状态(X,Y)),
写下(“将3加仑水罐中的所有水倒入4加仑:(“,X,”,“,Y,”)-->(“,NEW_X,”,“,0,”)\n”),
状态(新的X,0)。
状态(X,Y):-X+Y>=3,
X>0,
新的Y=X+Y,
未访问(访问状态(0,新建)),
断言(U状态(X,Y)),
写下(“将4加仑水罐中的所有水倒入3加仑:(“,X,”,“,Y,”)-->(“,0,”,“,NEW_Y,”)\n”),
状态(0,新的)。
状态(0,2):-未访问状态(2,0)),
断言(U状态(0,2)),
写(“倒2 ga