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

时间:2018-01-20 11:55:07

标签: prolog prefix

您好我正在拼命尝试从我的理解中理解这个片段设置变量X:1Z:[2,3]。现在我再也找不到......

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

1 个答案:

答案 0 :(得分:3)

Prolog并没有真正"设置"变量到值。当您进行查询或使用统一运算符=/2时,它会尝试统一参数。

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

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

当您进行此查询时,Prolog将开始搜索您声明的事实和谓词(包括您在Prolog环境中预定义的事件)以查找匹配prefix(W, [1,2,3]).的内容。遇到的第一个候选人是:

prefix([], X).

Prolog尝试将W[]统一,并以W = []成功。然后,它会尝试将[1,2,3]X统一起来。这也成功X = [1,2,3]。因此,complete子句会成功,您将获得此查询的第一个解决方案:

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,Prolog再次从数据库顶部开始搜索断言的事实和规则,并尝试将prefix(Y, [2,3])prefix([], X).匹配。这与Y = []和{{1}成功}}。请记住:这是来自X = [2,3]的递归通话,因此,当prefix([X|Y], [X|Z])通话返回时,请记下所有通知。我们有prefix(Y, [2,3])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])的所有解决方案。

我不打算通过所有这些。那太长了,这是你的任务,不是我的。 :)尝试理解我上面提到的Prolog如何搜索你的事实和规则并尝试自己的原则。

在理解如何跟踪谓词时,它也有助于理解如何语义读取

W

这表示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]Y 的前缀

递归流程遵循此描述。