用递归调用替换prolog基本情况

Kar*_*ala 4 recursion prolog

我是Prolog的新手,最近开始学习它,使用了很棒的书,现在学习Prolog!.有一些我不完全理解的东西,这真的让我烦恼.其中一个练习题是

我们有以下知识库和谓词:

child(anne,bridget).
child(bridget,caroline).
child(caroline,donna).
child(donna,emily).

descend(X,Y)  :-  child(X,Y).
descend(X,Y)  :-  child(X,Z),
                  descend(Z,Y).
Run Code Online (Sandbox Code Playgroud)

如果我们将谓词更改为以下内容会发生什么:

descend(X,Y)  :-  child(X,Y).
descend(X,Y)  :-  descend(X,Z),
                  descend(Z,Y).
Run Code Online (Sandbox Code Playgroud)

我知道这会导致对错误情况的无限递归,但我无法完全理解为什么.

如果我理解正确,在上面的第一种情况下,如果给出错误的查询child(X,Z)会耗尽其所有选项,试图将多个元素统一到Z然后失败,回溯到之前的X然后尝试再次选择Z以满足子项(X,Z) ).(如果我错了,请纠正我).

我不确定为什么下降谓词的第二个定义不会发生同样的情况.

mat*_*mat 5

让我们花点时间将您显示的片段减少到一个明确显示不确定原因片段.

最初的片段是您发布的整个程序:

descend(X,Y)  :-  child(X,Y).
descend(X,Y)  :-  descend(X,Z),
                  descend(Z,Y).

现在,我们false/0在一些地方插入.例如:

descend(X,Y)  :-  false, child(X,Y).
descend(X,Y)  :-  descend(X,Z),
                  false,
                  descend(Z,Y).

我使用删除线文本来表示程序中对终止没有影响的部分.也就是说,我们实际上最终得到:

descend(X,Y)  :-  descend(X,Z).

仅这个片段已经导致不确定.没有你添加的纯子句,没有任何单个目标可以阻止它!因此,要使此终止,您必须更改此片段.

有关更多信息,请参阅.