河内prolog塔

时间:2016-10-11 01:02:46

标签: prolog towers-of-hanoi

您好我的河内塔实施有问题。 我需要打印带有必要移动的列表列表,但是我的算法在盘数为N = 1时才起作用。 这是我的代码

['106', '36', '90', '60', '105', '75', '59']

这是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).

我需要这样的东西

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

L = [left,right]

(16 ms) yes

当N = 4时,

如果有人能帮助我,我会感激不尽。

2 个答案:

答案 0 :(得分:2)

在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).

请注意......

  • 使用更少的参数
  • 避免使用append/3

我也冒昧地使用......

  • 名称 moves//4 ,以明确我们正在描述移动,而不是单一移动。
  • CLP(FD)声明性算术的约束(更易于理解)
  • (-)/2表示,这是Prolog中的惯例。

示例查询,使用DCG的 phrase/2 接口谓词:

?- phrase(moves(4,left,right,center), Ls).
Ls = [left-center, left-right, center-right, left-center, right-left, ... ].

答案 1 :(得分:0)

您可以写一些小改动:

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.