Prolog 河内序言塔

Prolog 河内序言塔,prolog,towers-of-hanoi,dcg,Prolog,Towers Of Hanoi,Dcg,您好,我对河内塔的实施有问题。 我需要打印带有必要移动的列表,但我的算法仅在光盘数量为N=1时有效。 这是我的密码 move(1,X,Y,_,L) :- append([X],[Y],L). move(N,X,Y,Z) :- N>1, M is N-1, move(M,X,Z,Y), move(1,X,Y,_), move(M,Z,Y,X). 这是N=1时的结果 ?- move(1,left,right,_,L). L = [

您好,我对河内塔的实施有问题。 我需要打印带有必要移动的列表,但我的算法仅在光盘数量为N=1时有效。 这是我的密码

move(1,X,Y,_,L) :-  
    append([X],[Y],L).
move(N,X,Y,Z) :- 
    N>1, 
    M is N-1, 
    move(M,X,Z,Y),
    move(1,X,Y,_), 
    move(M,Z,Y,X).
这是N=1时的结果

?- move(1,left,right,_,L).

L = [left,right]

(16 ms) yes
我需要这样的东西

    L = [[left,center],[left,right],[center,right],[left,center],[right,left],
      [right,center],[left,center],[left,right],[center,right],[center,left],
[right,left],[center,right],[left,center],[left,right],[center,right]]
当N=4时


如果有人能帮助我,我将不胜感激。

您可以写一些小改动:

move(1,X,Y,_,[[X,Y]]).

move(N,X,Y,Z,L) :- 
    N>1, 
    M is N-1, 
    move(M,X,Z,Y,L1),
    move(1,X,Y,_,L2), 
    move(M,Z,Y,X,L3),
    append(L1,L2,L4),
    append(L4,L3,L).
例如:

?- move(4,left,right,center,L).
L = [[left, center], [left, right], [center, right], [left, center], [right, left], [right, center], [left, center], [left, right], [center, right], [center, left], [right, left], [center, right], [left, center], [left, right], [center, right]] ;
false.

在Prolog中描述<强>列表<强>时,始终考虑使用<强> <强>符号> 例如,考虑:

moves(1, X, Y, _) --> [X-Y]. moves(N, X, Y, Z) --> { N #> 1, M #= N-1 }, moves(M, X, Z, Y), moves(1, X, Y, _), moves(M, Z, Y, X).
如果这是与此处所示完全相同的代码,请注意
move
的第一个子句有5个参数,而第二个子句只有4个参数。我几乎可以肯定这是一个错误。很高兴这有帮助!!真棒的回答,注意结果是列表而不是列表,但这样更清楚…谢谢你的鼓励!是的,我已经冒昧地改用成对的。要使用列表列表,只需更改第一条规则,将
X-Y
替换为
[X,Y]
,这是术语
。(X),(Y,[])
,因此与
-(X,Y)
相比有些浪费。 ?- phrase(moves(4,left,right,center), Ls). Ls = [left-center, left-right, center-right, left-center, right-left, ... ].