使用List Prolog的河内塔

时间:2018-12-17 11:37:49

标签: list prolog towers-of-hanoi

我知道已经有一些示例程序可以解决这个问题,但是我需要用6张碟片来制作河内塔,这是分配作业的特定方式,我遇到了麻烦。我目前拥有的代码如下:

s([],[],[]).

initial(s([1,2,3,4,5,6], [], [])).

goal(s([],[],[1,2,3,4,5,6])).

我也有26行代码来验证有效状态,但是我自己测试了该代码,它可以工作,我遇到的问题是创建代码以将光盘从一个堆栈移动到另一个堆栈。下面是我尝试与示例查询一起执行的操作的示例:

changeState((s([A | B],[],[])), s([C], [D], [])) :- C is B, D is A.
?- changeState((s([1,2,3,4,5,6],[],[])), s([2,3,4,5,6], [1], [])).

所以这是一个开始,所有6块板都在第一叠上,我想将顶板移到第二叠上。本质上,我希望能够从列表中删除第一个元素,然后将其添加到另一个列表中,无论它是否为空。

编辑:

在完成上面的工作后,现在我需要帮助来解决遍历谓词。整个代码如下:

%Post A, Post B, Post C
s([],[],[]).

initial(s([1,2,3,4,5,6], [], [])).

goal(s([],[],[1,2,3,4,5,6])).

valid([], _).
valid([H|_], X) :-
    X < H.

changeState((s([A|T1], T2, T3)), s(T1, [A|T2], T3)) :-
    valid(T2, A).
changeState((s([A|T1], T2, T3)), s(T1, T2, [A|T3])) :-
    valid(T3, A).
changeState(s(T1, [A|T2], [B|T3]), s(T1, T2, [A,B|T3])) :-
    valid(A,B).
changeState(s([A|T1], T2, [B|T3]), s([B,A|T1], T2, T3)) :-
    valid(B, A).
changeState(s(T1, [A|T2], [B|T3]), s(T1, [B,A|T2], T3)) :-
    valid(B, A).
changeState(s([A|T1], [B|T2], T3), s(T1, [A,B|T2], T3)) :-
    valid(A,B).
changeState(s([A|T1], [B|T2], T3), s([B,A|T1], T2, T3)) :-
    valid(B,A).
changeState(s([A|T1], T2, [B|T3]), s(T1, T2, [A,B|T3])) :-
    valid(A,B).
changeState(s(T1, [A|T2], T3), s(T1, T2, [A|T3])) :-
    valid(T3, A).
changeState(s(T1, [A|T2], T3), s([A|T1], T2, T3)) :-
    valid(T1, A).
changeState(s(T1, T2, [A|T3]), s(T1, [A|T2], T3)) :-
    valid(T2, A).
changeState(s(T1, T2, [A|T3]), s([A|T1], T2, T3)) :-
    valid(T1, A).

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].

当我运行此查询时:

?- traverse((s([1,2,3,4,5,6], [], [])), Sol, s([1,2,3,4,5,6], [], [])).

我得到以下输出:output

在得到这些响应约10分钟后,我将其保持运行状态,但它仍然没有产生新的响应,因此它只是一遍又一遍地继续运行。如上所述,该程序的目的是使用Lists用6张光盘解决“河内塔”问题。对于那些不熟悉河内之塔的人,您实际上需要将所有光盘从第一叠移动到最后第三叠。您一次只能移动一张光盘,也不能将较大的光盘放在较小的光盘上。因此,您从(s([1,2,3,4,5,6],[],[]))开始,每个列表分别代表堆栈A,堆栈B,堆栈C,目标是以( s([],[],[1,2,3,4,5,6]))。我手动通过changeState谓词遍历了整个解决方案(63步),所有转换都被接受,因此问题在于横向谓词。横向谓词旨在显示导致求解的所有步骤以及所有可能的求解。这也意味着停止循环,这样就不只是一次又一次地交换相同的2张光盘。无法完全弄清谓词是什么导致我得到此输出,这对Prolog还是很陌生,所以我将不胜感激!

1 个答案:

答案 0 :(得分:1)

您可以在此处使用 unification 代替is/2(通常用于评估表达式)。

例如,假设第二个塔为空,我们可以定义从第一个塔到第二个塔的移动:

changeState((s([A|T1],[], T3)), s(T1, [A], T3)).

或者我们可以将元素移动到第二个非空的塔中,因为栈顶是一个更大的元素:

changeState(s([A|T1], [B|T2], T3), s(T1, [A,B|T2], T3)) :-
    A < B.

上面的结果总共有12条规则:3个源,乘以2个目的地,再乘以2种可能性(空目的地和非空目的地)。这不是很优雅。我们可以构造一个辅助谓词,以检查目标堆栈是否有效:

valid_stack([], _).
valid_stack([H|_], X) :-
    X < H.

因此我们可以将上面的两个规则压缩为:

changeState((s([A|T1], T2, T3)), s(T1, [A|T2], T3)) :-
    valid_stack(T2, A).

因此,这将产生六个规则:三个来源和两个目的地。

因此,我们不再需要验证移动,因为如果changeState成功,那么给出原始状态有效的提议的移动是可能的。

但是,这并不是完整的解决方案(我将其余部分留作练习)。您将需要一种机制来枚举可能的移动,并确保您不会以循环结尾(例如,在两个塔之间不断移动光盘)。

使用traverse/3谓词后,我们获得了移动到目标的列表:

?- traverse(s([1,2,3,4,5,6], [], []), S, [s([1,2,3,4,5,6], [], [])]).
S = [s([1, 2, 3, 4, 5, 6], [], []), s([2, 3, 4, 5, 6], [1], []), s([3, 4, 5, 6], [1], [2]), s([1, 3, 4, 5|...], [], [2]), s([3, 4, 5|...], [], [1, 2]), s([4, 5|...], [3], [1, 2]), s([1|...], [3], [2]), s([...|...], [...|...], [...]), s(..., ..., ...)|...] [write]
S = [s([1, 2, 3, 4, 5, 6], [], []), s([2, 3, 4, 5, 6], [1], []), s([3, 4, 5, 6], [1], [2]), s([1, 3, 4, 5, 6], [], [2]), s([3, 4, 5, 6], [], [1, 2]), s([4, 5, 6], [3], [1, 2]), s([1, 4, 5, 6], [3], [2]), s([4, 5, 6], [1, 3], [2]), s([2, 4, 5, 6], [1, 3], []), s([1, 2, 4, 5, 6], [3], []), s([2, 4, 5, 6], [3], [1]), s([4, 5, 6], [2, 3], [1]), s([1, 4, 5, 6], [2, 3], []), s([4, 5, 6], [1, 2, 3], []), s([5, 6], [1, 2, 3], [4]), s([1, 5, 6], [2, 3], [4]), s([5, 6], [2, 3], [1, 4]), s([2, 5, 6], [3], [1, 4]), s([1, 2, 5, 6], [3], [4]), s([2, 5, 6], [1, 3], [4]), s([5, 6], [1, 3], [2, 4]), s([1, 5, 6], [3], [2, 4]), s([5, 6], [3], [1, 2, 4]), s([3, 5, 6], [], [1, 2, 4]), s([1, 3, 5, 6], [], [2, 4]), s([3, 5, 6], [1], [2, 4]), s([2, 3, 5, 6], [1], [4]), s([1, 2, 3, 5, 6], [], [4]), s([2, 3, 5, 6], [], [1, 4]), s([3, 5, 6], [2], [1, 4]), s([1, 3, 5, 6], [2], [4]), s([3, 5, 6], [1, 2], [4]), s([5, 6], [1, 2], [3, 4]), s([1, 5, 6], [2], [3, 4]), s([5, 6], [2], [1, 3, 4]), s([2, 5, 6], [], [1, 3, 4]), s([1, 2, 5, 6], [], [3, 4]), s([2, 5, 6], [1], [3, 4]), s([5, 6], [1], [2, 3, 4]), s([1, 5, 6], [], [2, 3, 4]), s([5, 6], [], [1, 2, 3, 4]), s([6], [5], [1, 2, 3, 4]), s([1, 6], [5], [2, 3, 4]), s([6], [1, 5], [2, 3, 4]), s([2, 6], [1, 5], [3, 4]), s([1, 2, 6], [5], [3, 4]), s([2, 6], [5], [1, 3, 4]), s([6], [2, 5], [1, 3, 4]), s([1, 6], [2, 5], [3, 4]), s([6], [1, 2, 5], [3, 4]), s([3, 6], [1, 2, 5], [4]), s([1, 3, 6], [2, 5], [4]), s([3, 6], [2, 5], [1, 4]), s([2, 3, 6], [5], [1, 4]), s([1, 2, 3, 6], [5], [4]), s([2, 3, 6], [1, 5], [4]), s([3, 6], [1, 5], [2, 4]), s([1, 3, 6], [5], [2, 4]), s([3, 6], [5], [1, 2, 4]), s([6], [3, 5], [1, 2, 4]), s([1, 6], [3, 5], [2, 4]), s([6], [1, 3, 5], [2, 4]), s([2, 6], [1, 3, 5], [4]), s([1, 2, 6], [3, 5], [4]), s([2, 6], [3, 5], [1, 4]), s([6], [2, 3, 5], [1, 4]), s([1, 6], [2, 3, 5], [4]), s([6], [1, 2, 3, 5], [4]), s([4, 6], [1, 2, 3, 5], []), s([1, 4, 6], [2, 3, 5], []), s([4, 6], [2, 3, 5], [1]), s([2, 4, 6], [3, 5], [1]), s([1, 2, 4, 6], [3, 5], []), s([2, 4, 6], [1, 3, 5], []), s([4, 6], [1, 3, 5], [2]), s([1, 4, 6], [3, 5], [2]), s([4, 6], [3, 5], [1, 2]), s([3, 4, 6], [5], [1, 2]), s([1, 3, 4, 6], [5], [2]), s([3, 4, 6], [1, 5], [2]), s([2, 3, 4, 6], [1, 5], []), s([1, 2, 3, 4, 6], [5], []), s([2, 3, 4, 6], [5], [1]), s([3, 4, 6], [2, 5], [1]), s([1, 3, 4, 6], [2, 5], []), s([3, 4, 6], [1, 2, 5], []), s([4, 6], [1, 2, 5], [3]), s([1, 4, 6], [2, 5], [3]), s([4, 6], [2, 5], [1, 3]), s([2, 4, 6], [5], [1, 3]), s([1, 2, 4, 6], [5], [3]), s([2, 4, 6], [1, 5], [3]), s([4, 6], [1, 5], [2, 3]), s([1, 4, 6], [5], [2, 3]), s([4, 6], [5], [1, 2, 3]), s([6], [4, 5], [1, 2, 3]), s([1, 6], [4, 5], [2, 3]), s([6], [1, 4, 5], [2, 3]), s([2, 6], [1, 4, 5], [3]), s([1, 2, 6], [4, 5], [3]), s([2, 6], [4, 5], [1, 3]), s([6], [2, 4, 5], [1, 3]), s([1, 6], [2, 4, 5], [3]), s([6], [1, 2, 4, 5], [3]), s([3, 6], [1, 2, 4, 5], []), s([1, 3, 6], [2, 4, 5], []), s([3, 6], [2, 4, 5], [1]), s([2, 3, 6], [4, 5], [1]), s([1, 2, 3, 6], [4, 5], []), s([2, 3, 6], [1, 4, 5], []), s([3, 6], [1, 4, 5], [2]), s([1, 3, 6], [4, 5], [2]), s([3, 6], [4, 5], [1, 2]), s([6], [3, 4, 5], [1, 2]), s([1, 6], [3, 4, 5], [2]), s([6], [1, 3, 4, 5], [2]), s([2, 6], [1, 3, 4, 5], []), s([1, 2, 6], [3, 4, 5], []), s([2, 6], [3, 4, 5], [1]), s([6], [2, 3, 4, 5], [1]), s([1, 6], [2, 3, 4, 5], []), s([6], [1, 2, 3, 4, 5], []), s([], [1, 2, 3, 4, 5], [6]), s([1], [2, 3, 4, 5], [6]), s([], [2, 3, 4, 5], [1, 6]), s([2], [3, 4, 5], [1, 6]), s([1, 2], [3, 4, 5], [6]), s([2], [1, 3, 4, 5], [6]), s([], [1, 3, 4, 5], [2, 6]), s([1], [3, 4, 5], [2, 6]), s([], [3, 4, 5], [1, 2, 6]), s([3], [4, 5], [1, 2, 6]), s([1, 3], [4, 5], [2, 6]), s([3], [1, 4, 5], [2, 6]), s([2, 3], [1, 4, 5], [6]), s([1, 2, 3], [4, 5], [6]), s([2, 3], [4, 5], [1, 6]), s([3], [2, 4, 5], [1, 6]), s([1, 3], [2, 4, 5], [6]), s([3], [1, 2, 4, 5], [6]), s([], [1, 2, 4, 5], [3, 6]), s([1], [2, 4, 5], [3, 6]), s([], [2, 4, 5], [1, 3, 6]), s([2], [4, 5], [1, 3, 6]), s([1, 2], [4, 5], [3, 6]), s([2], [1, 4, 5], [3, 6]), s([], [1, 4, 5], [2, 3, 6]), s([1], [4, 5], [2, 3, 6]), s([], [4, 5], [1, 2, 3, 6]), s([4], [5], [1, 2, 3, 6]), s([1, 4], [5], [2, 3, 6]), s([4], [1, 5], [2, 3, 6]), s([2, 4], [1, 5], [3, 6]), s([1, 2, 4], [5], [3, 6]), s([2, 4], [5], [1, 3, 6]), s([4], [2, 5], [1, 3, 6]), s([1, 4], [2, 5], [3, 6]), s([4], [1, 2, 5], [3, 6]), s([3, 4], [1, 2, 5], [6]), s([1, 3, 4], [2, 5], [6]), s([3, 4], [2, 5], [1, 6]), s([2, 3, 4], [5], [1, 6]), s([1, 2, 3, 4], [5], [6]), s([2, 3, 4], [1, 5], [6]), s([3, 4], [1, 5], [2, 6]), s([1, 3, 4], [5], [2, 6]), s([3, 4], [5], [1, 2, 6]), s([4], [3, 5], [1, 2, 6]), s([1, 4], [3, 5], [2, 6]), s([4], [1, 3, 5], [2, 6]), s([2, 4], [1, 3, 5], [6]), s([1, 2, 4], [3, 5], [6]), s([2, 4], [3, 5], [1, 6]), s([4], [2, 3, 5], [1, 6]), s([1, 4], [2, 3, 5], [6]), s([4], [1, 2, 3, 5], [6]), s([], [1, 2, 3, 5], [4, 6]), s([1], [2, 3, 5], [4, 6]), s([], [2, 3, 5], [1, 4, 6]), s([2], [3, 5], [1, 4, 6]), s([1, 2], [3, 5], [4, 6]), s([2], [1, 3, 5], [4, 6]), s([], [1, 3, 5], [2, 4, 6]), s([1], [3, 5], [2, 4, 6]), s([], [3, 5], [1, 2, 4, 6]), s([3], [5], [1, 2, 4, 6]), s([1, 3], [5], [2, 4, 6]), s([3], [1, 5], [2, 4, 6]), s([2, 3], [1, 5], [4, 6]), s([1, 2, 3], [5], [4, 6]), s([2, 3], [5], [1, 4, 6]), s([3], [2, 5], [1, 4, 6]), s([1, 3], [2, 5], [4, 6]), s([3], [1, 2, 5], [4, 6]), s([], [1, 2, 5], [3, 4, 6]), s([1], [2, 5], [3, 4, 6]), s([], [2, 5], [1, 3, 4, 6]), s([2], [5], [1, 3, 4, 6]), s([1, 2], [5], [3, 4, 6]), s([2], [1, 5], [3, 4, 6]), s([], [1, 5], [2, 3, 4, 6]), s([1], [5], [2, 3, 4, 6]), s([], [5], [1, 2, 3, 4, 6]), s([5], [], [1, 2, 3, 4, 6]), s([1, 5], [], [2, 3, 4, 6]), s([5], [1], [2, 3, 4, 6]), s([2, 5], [1], [3, 4, 6]), s([1, 2, 5], [], [3, 4, 6]), s([2, 5], [], [1, 3, 4, 6]), s([5], [2], [1, 3, 4, 6]), s([1, 5], [2], [3, 4, 6]), s([5], [1, 2], [3, 4, 6]), s([3, 5], [1, 2], [4, 6]), s([1, 3, 5], [2], [4, 6]), s([3, 5], [2], [1, 4, 6]), s([2, 3, 5], [], [1, 4, 6]), s([1, 2, 3, 5], [], [4, 6]), s([2, 3, 5], [1], [4, 6]), s([3, 5], [1], [2, 4, 6]), s([1, 3, 5], [], [2, 4, 6]), s([3, 5], [], [1, 2, 4, 6]), s([5], [3], [1, 2, 4, 6]), s([1, 5], [3], [2, 4, 6]), s([5], [1, 3], [2, 4, 6]), s([2, 5], [1, 3], [4, 6]), s([1, 2, 5], [3], [4, 6]), s([2, 5], [3], [1, 4, 6]), s([5], [2, 3], [1, 4, 6]), s([1, 5], [2, 3], [4, 6]), s([5], [1, 2, 3], [4, 6]), s([4, 5], [1, 2, 3], [6]), s([1, 4, 5], [2, 3], [6]), s([4, 5], [2, 3], [1, 6]), s([2, 4, 5], [3], [1, 6]), s([1, 2, 4, 5], [3], [6]), s([2, 4, 5], [1, 3], [6]), s([4, 5], [1, 3], [2, 6]), s([1, 4, 5], [3], [2, 6]), s([4, 5], [3], [1, 2, 6]), s([3, 4, 5], [], [1, 2, 6]), s([1, 3, 4, 5], [], [2, 6]), s([3, 4, 5], [1], [2, 6]), s([2, 3, 4, 5], [1], [6]), s([1, 2, 3, 4, 5], [], [6]), s([2, 3, 4, 5], [], [1, 6]), s([3, 4, 5], [2], [1, 6]), s([1, 3, 4, 5], [2], [6]), s([3, 4, 5], [1, 2], [6]), s([4, 5], [1, 2], [3, 6]), s([1, 4, 5], [2], [3, 6]), s([4, 5], [2], [1, 3, 6]), s([2, 4, 5], [], [1, 3, 6]), s([1, 2, 4, 5], [], [3, 6]), s([2, 4, 5], [1], [3, 6]), s([4, 5], [1], [2, 3, 6]), s([1, 4, 5], [], [2, 3, 6]), s([4, 5], [], [1, 2, 3, 6]), s([5], [4], [1, 2, 3, 6]), s([1, 5], [4], [2, 3, 6]), s([5], [1, 4], [2, 3, 6]), s([2, 5], [1, 4], [3, 6]), s([1, 2, 5], [4], [3, 6]), s([2, 5], [4], [1, 3, 6]), s([5], [2, 4], [1, 3, 6]), s([1, 5], [2, 4], [3, 6]), s([5], [1, 2, 4], [3, 6]), s([3, 5], [1, 2, 4], [6]), s([1, 3, 5], [2, 4], [6]), s([3, 5], [2, 4], [1, 6]), s([2, 3, 5], [4], [1, 6]), s([1, 2, 3, 5], [4], [6]), s([2, 3, 5], [1, 4], [6]), s([3, 5], [1, 4], [2, 6]), s([1, 3, 5], [4], [2, 6]), s([3, 5], [4], [1, 2, 6]), s([5], [3, 4], [1, 2, 6]), s([1, 5], [3, 4], [2, 6]), s([5], [1, 3, 4], [2, 6]), s([2, 5], [1, 3, 4], [6]), s([1, 2, 5], [3, 4], [6]), s([2, 5], [3, 4], [1, 6]), s([5], [2, 3, 4], [1, 6]), s([1, 5], [2, 3, 4], [6]), s([5], [1, 2, 3, 4], [6]), s([], [1, 2, 3, 4], [5, 6]), s([1], [2, 3, 4], [5, 6]), s([], [2, 3, 4], [1, 5, 6]), s([2], [3, 4], [1, 5, 6]), s([1, 2], [3, 4], [5, 6]), s([2], [1, 3, 4], [5, 6]), s([], [1, 3, 4], [2, 5, 6]), s([1], [3, 4], [2, 5, 6]), s([], [3, 4], [1, 2, 5, 6]), s([3], [4], [1, 2, 5, 6]), s([1, 3], [4], [2, 5, 6]), s([3], [1, 4], [2, 5, 6]), s([2, 3], [1, 4], [5, 6]), s([1, 2, 3], [4], [5, 6]), s([2, 3], [4], [1, 5, 6]), s([3], [2, 4], [1, 5, 6]), s([1, 3], [2, 4], [5, 6]), s([3], [1, 2, 4], [5, 6]), s([], [1, 2, 4], [3, 5, 6]), s([1], [2, 4], [3, 5, 6]), s([], [2, 4], [1, 3, 5, 6]), s([2], [4], [1, 3, 5, 6]), s([1, 2], [4], [3, 5, 6]), s([2], [1, 4], [3, 5, 6]), s([], [1, 4], [2, 3, 5, 6]), s([1], [4], [2, 3, 5, 6]), s([], [4], [1, 2, 3, 5, 6]), s([4], [], [1, 2, 3, 5, 6]), s([1, 4], [], [2, 3, 5, 6]), s([4], [1], [2, 3, 5, 6]), s([2, 4], [1], [3, 5, 6]), s([1, 2, 4], [], [3, 5, 6]), s([2, 4], [], [1, 3, 5, 6]), s([4], [2], [1, 3, 5, 6]), s([1, 4], [2], [3, 5, 6]), s([4], [1, 2], [3, 5, 6]), s([3, 4], [1, 2], [5, 6]), s([1, 3, 4], [2], [5, 6]), s([3, 4], [2], [1, 5, 6]), s([2, 3, 4], [], [1, 5, 6]), s([1, 2, 3, 4], [], [5, 6]), s([2, 3, 4], [1], [5, 6]), s([3, 4], [1], [2, 5, 6]), s([1, 3, 4], [], [2, 5, 6]), s([3, 4], [], [1, 2, 5, 6]), s([4], [3], [1, 2, 5, 6]), s([1, 4], [3], [2, 5, 6]), s([4], [1, 3], [2, 5, 6]), s([2, 4], [1, 3], [5, 6]), s([1, 2, 4], [3], [5, 6]), s([2, 4], [3], [1, 5, 6]), s([4], [2, 3], [1, 5, 6]), s([1, 4], [2, 3], [5, 6]), s([4], [1, 2, 3], [5, 6]), s([], [1, 2, 3], [4, 5, 6]), s([1], [2, 3], [4, 5, 6]), s([], [2, 3], [1, 4, 5, 6]), s([2], [3], [1, 4, 5, 6]), s([1, 2], [3], [4, 5, 6]), s([2], [1, 3], [4, 5, 6]), s([], [1, 3], [2, 4, 5, 6]), s([1], [3], [2, 4, 5, 6]), s([], [3], [1, 2, 4, 5, 6]), s([3], [], [1, 2, 4, 5, 6]), s([1, 3], [], [2, 4, 5, 6]), s([3], [1], [2, 4, 5, 6]), s([2, 3], [1], [4, 5, 6]), s([1, 2, 3], [], [4, 5, 6]), s([2, 3], [], [1, 4, 5, 6]), s([3], [2], [1, 4, 5, 6]), s([1, 3], [2], [4, 5, 6]), s([3], [1, 2], [4, 5, 6]), s([], [1, 2], [3, 4, 5, 6]), s([1], [2], [3, 4, 5, 6]), s([], [2], [1, 3, 4, 5, 6]), s([2], [], [1, 3, 4, 5, 6]), s([1, 2], [], [3, 4, 5, 6]), s([2], [1], [3, 4, 5, 6]), s([], [1], [2, 3, 4, 5, 6]), s([1], [], [2, 3, 4, 5, 6]), s([], [], [1, 2, 3, 4, 5, 6])]

在SWI-Prolog中,您需要按 W ,您要求交互式外壳程序print the full list