您好我正在拼命尝试从我的理解中理解这个片段设置变量X:1
,Z:[2,3]
。现在我再也找不到......
prefix([],X).
prefix([X|Y],[X|Z]):-prefix(Y,Z).
?-prefix(W,[1,2,3]).
答案 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 = 1
和Z = [2,3]
。现在这意味着W = [1|Y]
(Y
仍未绑定)。由于这是谓词子句的头部,Prolog将执行该主体......
现在,对于W = [1|Y]
,X = 1
和Z = [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 = 1
和Z = [2,3]
。因此,Y = []
在这种情况下会成功prefix([X|Y], [X|Z])
,X = 1
和Y = []
。因此,原始调用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
的前缀
递归流程遵循此描述。