有人可以解释序言如何逐步解释这一点吗?

Can someone explain how prolog interprets this step by step?

您好,我拼命地试图从我的理解中理解这个片段,它设置了变量 X:1Z:[2,3]。现在我不能再进一步了...

prefix([],X).
prefix([X|Y],[X|Z]):-prefix(Y,Z).
?-prefix(W,[1,2,3]).

Prolog 并不真正"set" 变量值。当您进行查询或使用统一运算符 =/2.

时,它会尝试统一参数

让我们看看当您进行查询时 Prolog 中会发生什么。

?- prefix(W, [1,2,3]).

当您进行此查询时,Prolog 将开始搜索您断言的事实和谓词(包括那些在您的 Prolog 环境中预定义的)匹配的东西 prefix(W, [1,2,3]). 它遇到的第一个候选者是:

prefix([], X).

Prolog 尝试统一 W[],并成功统一 W = []。然后它试图统一 [1,2,3]XX = [1,2,3] 也成功了。所以完整的子句成功了,你得到了这个查询的第一个解决方案:

W = [] ?

如果此时您按下 ;,Prolog 将 回溯 如果有选择点,因为您有额外的 prefix/2 子句。所以 Prolog 回到那个点并尝试将 prefix(W, [1,2,3])prefix([X|Y],[X|Z]) 匹配。它试图统一W[X|Y]并成功统一W = [X|Y](是的,在这一点上,这些都是可变的),并成功统一[1,2,3][X|Z] X = 1Z = [2,3]。这现在意味着 W = [1|Y]Y 仍未绑定)。由于这是谓词子句的头部,Prolog 将执行主体...

所以现在使用 W = [1|Y]X = 1Z = [2,3],Prolog 将调用:

prefix(Y, Z).

换句话说,它将调用 prefix(Y, [2,3])。由于现在这是对 prefix/2 的 "fresh" 查询,Prolog 再次从断言的事实和规则数据库的顶部开始搜索,并尝试将 prefix(Y, [2,3])prefix([], X). 匹配。这成功了Y = []X = [2,3]。请记住:这是来自 prefix([X|Y], [X|Z]) 的递归调用,所以让我们记下 prefix(Y, [2,3]) 调用 returns 时的所有统一。我们有 X = 1Z = [2,3],现在 Y = []。因此,在这种情况下,prefix([X|Y], [X|Z]) 会以 X = 1Y = []Z = [2,3] 成功。因此,原始调用 prefix(W, [1,2,3]) 成功:

W = [X|Y] = [1|[]] = [1].

最后一次调用prefix(Y, [2,3])留下了一个选择点,就像prefix(W, [1,2,3])原来做的一样!因此,您可以使用与上述相同的逻辑追回那个人,直到您用尽所有成功的可能性。您最终将获得 W.

的所有解决方案

我不会一一列举。那太长了,这是你的任务,不是我的。 :) 尝试理解我上面给出的关于Prolog如何搜索你的事实和规则的原则并自己尝试。


了解如何追踪谓词,了解如何从语义上阅读它也很有帮助。

prefix([], X).

这表示 [] 是任何列表的前缀。从技术上讲,由于这是特定于列表的,因此可能更准确地写成:

prefix([], L) :- is_list(L).

或者...

prefix([], []).
prefix([], [_|_]).

否则,简单地使用 prefix([], _).prefix([], X).,像 prefix(P, 3) 这样的愚蠢的东西会成功 P = []

那么递归谓词:

prefix([X|Y], [X|Z]) :- prefix(Y, Z).

这表示,[X|Y][X|Z]的前缀ifY是[=的前缀70=].

递归流程遵循此描述。