我正试图编写一个程序来解决Prolog中的河内问题塔。这里的帖子都没有帮助我,所以我决定自问。我写了以下代码。它适用于2个磁盘,但进入无限循环3。
hanoi(1,A,B,_,[(A,B)]).
hanoi(X,A,B,C,Y):-
hanoi(X2,A,C,B,Y1),
hanoi(1,A,B,_,[Y2]),
hanoi(X2,C,B,A,Y3),
append(Y1,[Y2|Y3],Y),
X2 is X-1.
以下列方式调用:
?- hanoi(3, a, b, c, Y).
a,b,c是钉子。 3是磁盘数,X是我们想要的结果。
我需要在Y中得到结果。我试图递归地找到X-1光盘从第1到第3的移动,使用2个1个光盘从第1个到第2个,X-1个光盘来自peg 3到2并附加它们。我无法理解我做错了什么。任何帮助或指导将不胜感激!谢谢!
答案 0 :(得分:2)
明显的问题 -
当你有一个连词时,比如:
a, b, c
你有两个这样的,逻辑和程序的读物。逻辑阅读将是:
"如果a
为真,且b
为真,且c
为真,则结合为真。"
程序性阅读是:
"如果a
被评估并成功,则连接将成功,然后评估b
并且它也成功,然后评估c
并且它也成功。 #34; (或者,换句话说,对解决方案空间进行深度优先搜索)
如果你足够小心,那么就没有必要在程序上阅读你的代码。但是,只有当连接中的所有子目标都完全重叠逻辑和程序读数时才会出现这种情况。
这里的罪犯是is/2
。它没有纯粹的逻辑意义。它评估右手操作数(算术表达式)并将结果与左手(通常是未绑定的变量)统一。
在这里,你有一个连词(在第二个子句的正文中),实际上,"评估a(X)
,然后,如果成功,找到X
的值&#34 ;.显而易见的问题是a(X)
要求X
的值以终止的方式进行评估。
因此,在使用其结果的所有子目标之前移动is
,或者查看使用约束。