什么将输出以下prolog简单代码,为什么?

时间:2013-05-11 21:36:18

标签: prolog

eight(A,B):-
    eight(A,[],B).

eight([],X,X).
eight([A|B],C,X):-
    eight(B,[A|C],X).

查询

?- eight([a,b,c],X)

2 个答案:

答案 0 :(得分:1)

你在那里写的谓词eight反转了一个列表。你可以通过尝试使用不同的列表并查看结果来找到它。

沿着兔子洞

据我了解,当您运行eight([a,b,c],X).时,它会找到匹配eight/2的第一个/唯一谓词,并将[a,b,c]A统一起来,它会保留变量{ {1}}作为随机变量,可能与X类似。接下来,它将谓词的主体称为:

_G1234

这会检查谓词是否可以统一其参数。由于无法将空列表与eight([a,b,c], [], _G1234)统一,因此会找到您的第二个[a,b,c]谓词(eight/3)并将eight([A|B],C,X)[A|B] [a|[b,c]]统一起来使用C,并将未知变量传递给骑行。然后它使用新统一的变量调用谓词的主体:

[]

再次检查谓词是否可以统一其参数。同样,空列表无法与eight([b,c], [a|[]], _G1234)统一,因此它会再次找到您的第二个[b,c]谓词,并将eight/3[A|B][b|[c]]统一为{{{ 1}},并再次传递该未知变量。所以它将这个谓词的主体称为:

C

再一次,它检查谓词是否可以统一其参数。再一次,它可以统一其论点的第一个谓词是你的第二个[a|[]]谓词。因此,eight([c], [b|[a|[]]], _G1234)eight/3[A|B][c|[]]统一,并再次传递未知。它现在称身体为:

C

现在,当它检查谓词时,它可以统一,它会找到你的第一个[b|[a|[]]]谓词。它将空列表与空列表eight([], [c|[b|[a|[]]]], _G1234)eight/3统一起来,因为只有一个X,就prolog而言,它位于两个位置。因此,最终将[c|[b|[a|[]]]]X取消联系,在这种情况下为_G1234。我们最终得到了这样的东西:

X

为了简单起见,我将简化这些列表:

[c|[b|[a|[]]]]

Up谓词

这个谓词没有正文,所以它实际上是一个事实。统一事实时,认为已找到有效的解决方案。因此,prolog开始备份链,直到它到达决策点并显示有效目标。它转到上一个谓词eight([], [c|[b|[a|[]]]], [c|[b|[a|[]]]]),然后再转为eight([], [c,b,a], [c,b,a]),再转为eight([c], [b,a], [c,b,a]),最后转到eight([b,c], [a], [c,b,a])谓词的子句中的起始位置eight([a,b,c], [], [c,b,a])。因此,在您提出查询时,它已成功统一了您的原始eight/2。并将此显示为:

eight([a,b,c], [c,b,a])

由于您的程序中没有其他决策点,因此这是唯一可能的目标,并且会向您返回控件以进行更多查询。

将来,如果您想知道谓词是如何工作的,请打开tracing,使用swi-pl它只是repl中的X谓词。

答案 1 :(得分:0)

8(A,B): - 八(A,[],B)

8([],X,X)。

八([A | B],C,X): - 八(B,[A | C],X)。

小心Prolog它可能非常迂腐。

获取运行和运行查询的规则后。我得到了

8([A,B,C],X)。 假的。