1

尝试编写一个程序来解决这个问题:

“给你两个水壶,一个 5 加仑的,一个 3 加仑的。它们上面都没有任何测量标记。有一个水龙头可以用来给水壶装水。目标是准确地获得4加仑水。” 这是我目前拥有的代码:

%(WaterInThree, WaterInFive)
s(A,B).

initial(s(0,0)).

goal(s(A,B)):- A + B =:= 4.

valid(A,B) :- A =< 3, A >=0, B =< 5, B >= 0.

changeState(s(0,B),s(3,B)).
changeState(s(A,0),s(A,5)).
changeState(s(A,B),s(A,0)) :- B > 0, valid(A,B).
changeState(s(A,B),s(0,B)) :- A > 0, valid(A,B).
changeState(s(A,B),s(C,D)) :- B =< 2, D is A + B, C is B - A, valid(C,D).
changeState(s(A,B),s(C,D)) :- B > 2, D is B + ( (5 - A) mod 5), valid(C,D).
changeState(s(A,B),s(3,D)) :- B =< 3, D is B - (3 - A), valid(A,D).
changeState(s(A,B),s(C,D)) :- B =:= 5, C is A + B, D is A - B, valid(C,D).


traverse(StartNode,Sol,_) :- goal(StartNode), Sol = [StartNode].
traverse(StartNode,Sol,Visit) :- changeState(StartNode, NextNode),
   not(member(NextNode, Visit)),
   traverse(NextNode, PartialSol, [NextNode|Visit]),
   Sol = [StartNode | PartialSol].

当我执行此代码时,我收到以下错误:

ERROR: Arguments are not sufficiently instantiated
ERROR: In:
ERROR:   [13] _11226=<3
ERROR:   [12] valid(_11252,5+(5-3)) 
ERROR:   [11] changeState(s(3,5),s(_11302,5+ ...)) 
ERROR:   [10] traverse(s(3,5),_11336,[s(3,5),...|...]) 
ERROR:    [9] traverse(s(3,0),_11388,[s(3,0),...]) 
ERROR:    [8] traverse(s(0,0),_11440,[s(0,0)]) 
ERROR:    [7] <user>

不太确定问题是什么,我一直在尝试解决这个问题几个小时,但无法弄清楚出了什么问题。甚至无法正确测试我创建的 changeState 谓词是否因此而工作,因此非常令人沮丧。将不胜感激任何帮助!

编辑我已将其缩小到导致错误的这一行:

changeState(s(A,B),s(C,D)) :- B > 2, D is B + ( (5 - A) mod 5), valid(C,D).

虽然无法真正看到这将如何导致该错误。

4

1 回答 1

1

真的看不出来这是怎么回事

changeState(s(A,B),s(C,D)) :- B > 2, D is B + ( (5 - A) mod 5), valid(C,D).

虽然会导致该错误。

_10148=<3
ERROR: Arguments are not sufficiently instantiated

为了

changeState(s(A,B),s(C,D)) :- 
  B > 2, 
  D is B + ( (5 - A) mod 5), 
  valid(C,D).

当它被执行(调用)时,查询是

changeState(s(0, 5), X)

A is bound to 0
B is bound to 5
X is bound to s(C,D)

那么对于

B > 2

查询是

5 > 2

这是真的

那么对于

D is B + ( (5 - A) mod 5)

查询是

D is 5 + ( (5 - 0) mod 5)

D is bound to 5

那么对于

valid(C,D)

C is unbound
D is bound to 5

查询是

valid (<unbound>,5)

唯一匹配的谓词是

valid(A,B) :- A =< 3, A >=0, B =< 5, B >= 0.

A is unbound
B is bound to 5

那么对于

A =< 3

由于 A 未绑定,因此比较=<会给出错误,因为它需要绑定两个变量。

所以回到这个声明

changeState(s(A,B),s(C,D)) :- B > 2, D is B + ( (5 - A) mod 5), valid(C,D).

您需要绑定C到一个值。


如果您使用设置跟踪

?- visible(+all),leash(-all).

然后启用跟踪

?- trace.

并运行你得到的查询

?- traverse(s(0,0), Sol, [s(0,0)]).
   Call: (8) traverse(s(0, 0), _9866, [s(0, 0)])
   Unify: (8) traverse(s(0, 0), _9866, [s(0, 0)])
   Call: (9) goal(s(0, 0))
   Unify: (9) goal(s(0, 0))
   Call: (10) 0+0=:=4
   Fail: (10) 0+0=:=4
   Fail: (9) goal(s(0, 0))   
   Redo: (8) traverse(s(0, 0), _9866, [s(0, 0)])
   Unify: (8) traverse(s(0, 0), _9866, [s(0, 0)])
   Call: (9) changeState(s(0, 0), _10092)
   Unify: (9) changeState(s(0, 0), s(3, 0))
   Exit: (9) changeState(s(0, 0), s(3, 0))
^  Call: (9) not(member(s(3, 0), [s(0, 0)]))
^  Unify: (9) not(user:member(s(3, 0), [s(0, 0)]))
^  Exit: (9) not(user:member(s(3, 0), [s(0, 0)]))
   Call: (9) traverse(s(3, 0), _10116, [s(3, 0), s(0, 0)])
   Unify: (9) traverse(s(3, 0), _10116, [s(3, 0), s(0, 0)])
   Call: (10) goal(s(3, 0))
   Unify: (10) goal(s(3, 0))
   Call: (11) 3+0=:=4
   Fail: (11) 3+0=:=4
   Fail: (10) goal(s(3, 0))   
   Redo: (9) traverse(s(3, 0), _10116, [s(3, 0), s(0, 0)])
   Unify: (9) traverse(s(3, 0), _10116, [s(3, 0), s(0, 0)])
   Call: (10) changeState(s(3, 0), _10116)
   Unify: (10) changeState(s(3, 0), s(3, 5))
   Exit: (10) changeState(s(3, 0), s(3, 5))   
^  Call: (10) not(member(s(3, 5), [s(3, 0), s(0, 0)]))
^  Unify: (10) not(user:member(s(3, 5), [s(3, 0), s(0, 0)]))
^  Exit: (10) not(user:member(s(3, 5), [s(3, 0), s(0, 0)]))
   Call: (10) traverse(s(3, 5), _10140, [s(3, 5), s(3, 0), s(0, 0)])
   Unify: (10) traverse(s(3, 5), _10140, [s(3, 5), s(3, 0), s(0, 0)])
   Call: (11) goal(s(3, 5))
   Unify: (11) goal(s(3, 5))
   Call: (12) 3+5=:=4
   Fail: (12) 3+5=:=4
   Fail: (11) goal(s(3, 5))   
   Redo: (10) traverse(s(3, 5), _10140, [s(3, 5), s(3, 0), s(0, 0)])
   Unify: (10) traverse(s(3, 5), _10140, [s(3, 5), s(3, 0), s(0, 0)])
   Call: (11) changeState(s(3, 5), _10140)
   Unify: (11) changeState(s(3, 5), s(3, 0))
   Call: (12) 5>0
   Exit: (12) 5>0
   Call: (12) valid(3, 5)
   Unify: (12) valid(3, 5)
   Call: (13) 3=<3
   Exit: (13) 3=<3
   Call: (13) 3>=0
   Exit: (13) 3>=0
   Call: (13) 5=<5
   Exit: (13) 5=<5
   Call: (13) 5>=0
   Exit: (13) 5>=0
   Exit: (12) valid(3, 5)   
   Exit: (11) changeState(s(3, 5), s(3, 0))
^  Call: (11) not(member(s(3, 0), [s(3, 5), s(3, 0), s(0, 0)]))
^  Unify: (11) not(user:member(s(3, 0), [s(3, 5), s(3, 0), s(0, 0)]))
^  Fail: (11) not(user:member(s(3, 0), [s(3, 5), s(3, 0), s(0, 0)]))
   Redo: (11) changeState(s(3, 5), _10140)
   Unify: (11) changeState(s(3, 5), s(0, 5))
   Call: (12) 3>0
   Exit: (12) 3>0
   Call: (12) valid(3, 5)
   Unify: (12) valid(3, 5)
   Call: (13) 3=<3
   Exit: (13) 3=<3
   Call: (13) 3>=0
   Exit: (13) 3>=0
   Call: (13) 5=<5
   Exit: (13) 5=<5
   Call: (13) 5>=0
   Exit: (13) 5>=0
   Exit: (12) valid(3, 5)
   Exit: (11) changeState(s(3, 5), s(0, 5))
^  Call: (11) not(member(s(0, 5), [s(3, 5), s(3, 0), s(0, 0)]))
^  Unify: (11) not(user:member(s(0, 5), [s(3, 5), s(3, 0), s(0, 0)]))
^  Exit: (11) not(user:member(s(0, 5), [s(3, 5), s(3, 0), s(0, 0)]))
   Call: (11) traverse(s(0, 5), _10164, [s(0, 5), s(3, 5), s(3, 0), s(0, 0)])
   Unify: (11) traverse(s(0, 5), _10164, [s(0, 5), s(3, 5), s(3, 0), s(0, 0)])
   Call: (12) goal(s(0, 5))
   Unify: (12) goal(s(0, 5))
   Call: (13) 0+5=:=4
   Fail: (13) 0+5=:=4
   Fail: (12) goal(s(0, 5))   
   Redo: (11) traverse(s(0, 5), _10164, [s(0, 5), s(3, 5), s(3, 0), s(0, 0)])
   Unify: (11) traverse(s(0, 5), _10164, [s(0, 5), s(3, 5), s(3, 0), s(0, 0)])
   Call: (12) changeState(s(0, 5), _10164)
   Unify: (12) changeState(s(0, 5), s(3, 5))
   Exit: (12) changeState(s(0, 5), s(3, 5))
^  Call: (12) not(member(s(3, 5), [s(0, 5), s(3, 5), s(3, 0), s(0, 0)]))
^  Unify: (12) not(user:member(s(3, 5), [s(0, 5), s(3, 5), s(3, 0), s(0, 0)]))
^  Fail: (12) not(user:member(s(3, 5), [s(0, 5), s(3, 5), s(3, 0), s(0, 0)]))
   Redo: (12) changeState(s(0, 5), _10164)
   Unify: (12) changeState(s(0, 5), s(0, 0))
   Call: (13) 5>0
   Exit: (13) 5>0
   Call: (13) valid(0, 5)
   Unify: (13) valid(0, 5)
   Call: (14) 0=<3
   Exit: (14) 0=<3
   Call: (14) 0>=0
   Exit: (14) 0>=0
   Call: (14) 5=<5
   Exit: (14) 5=<5
   Call: (14) 5>=0
   Exit: (14) 5>=0
   Exit: (13) valid(0, 5)
   Exit: (12) changeState(s(0, 5), s(0, 0))
^  Call: (12) not(member(s(0, 0), [s(0, 5), s(3, 5), s(3, 0), s(0, 0)]))
^  Unify: (12) not(user:member(s(0, 0), [s(0, 5), s(3, 5), s(3, 0), s(0, 0)]))
^  Fail: (12) not(user:member(s(0, 0), [s(0, 5), s(3, 5), s(3, 0), s(0, 0)]))
   Redo: (12) changeState(s(0, 5), _10164)
   Unify: (12) changeState(s(0, 5), s(0, 5))
   Call: (13) 0>0
   Fail: (13) 0>0
   Redo: (12) changeState(s(0, 5), _10164)
   Unify: (12) changeState(s(0, 5), s(_10148, _10150))
   Call: (13) 5=<2
   Fail: (13) 5=<2
   Redo: (12) changeState(s(0, 5), _10164)
   Unify: (12) changeState(s(0, 5), s(_10148, _10150))
   Call: (13) 5>2
   Exit: (13) 5>2
   Call: (13) _10150 is 5+(5-0)mod 5
   Exit: (13) 5 is 5+(5-0)mod 5
   Call: (13) valid(_10148, 5)
   Unify: (13) valid(_10148, 5)
   Call: (14) _10148=<3
ERROR: Arguments are not sufficiently instantiated
ERROR: In:
ERROR:   [14] _11032=<3
ERROR:   [13] valid(_11058,5) at *.pl:10
ERROR:   [12] changeState(s(0,5),s(_11096,5)) at *.pl:17
ERROR:   [11] traverse(s(0,5),_11124,[s(0,5),...|...]) at *.pl:26
ERROR:   [10] traverse(s(3,5),_11176,[s(3,5),...|...]) at *.pl:28
ERROR:    [9] traverse(s(3,0),_11228,[s(3,0),...]) at *.pl:28
ERROR:    [8] traverse(s(0,0),_11280,[s(0,0)]) at *.pl:28
ERROR:    [7] <user>
   Exception: (14) _10148=<3 ? Unknown option (h for help)
于 2018-12-16T11:26:48.620 回答