eight(A,B):-
eight(A,[],B).
eight([],X,X).
eight([A|B],C,X):-
eight(B,[A|C],X).
查询
?- eight([a,b,c],X)
答案 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|[]]]]
这个谓词没有正文,所以它实际上是一个事实。统一事实时,认为已找到有效的解决方案。因此,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)。 假的。