理解特定Prolog递归谓词的问题

时间:2011-01-15 21:10:44

标签: recursion prolog

我正在学习Prolog。
我有这个递归谓词:

  

加(0,Y,Y)。
  add(succ(X),Y,succ(Z)): -
  添加(X,Y,Z)。

好的,经验丰富的Prolog程序员可能会理解这个谓词的作用。乍一看,它看起来并不难理解;当给出两个数字作为第一个和第二个参数时,它将返回将它们作为第三个参数加起来的结果。听起来很简单?确实

但是我有一个主要的问题,理解这实际上是如何工作的。我已经多次重读这个谓词的描述但是我无法理解它是如何工作的。这就是我寻求帮助的原因。

通过查询:
add(succ(succ(succ(0))), succ(succ(0)), R).
Prolog将实例化,从而将R作为succ(succ(succ(succ(succ(0)))))返回。精细。这必须是正确的。但是我不知道为什么会这样。

我遇到的问题是 为什么 Prolog剥离原始查询中最外层的succ仿函数。同样,因为它是递归的,它将结果作为参数传递给自身,从而剥离最外面的succ仿函数,直到目标可以统一。我确实理解succ(Z)和参数R是如何工作的,但我似乎无法理解它如何实际剥离最外面的succ仿函数,如上所述。对我来说,似乎添加一个succ而不是剥离它,因为谓词定义中有succ(X)

任何帮助非常感谢。提前谢谢!

1 个答案:

答案 0 :(得分:3)

Prolog看到行add(succ(X),Y,succ(Z)) ...并认为“哦,它可以与查询add(succ(succ(succ(0))), succ(succ(0)), R).匹配,因为我可以设置(统一)X = succ(succ(0)),Y = succ (succ(0)),succ(Z)= R!“ Prolog的重要条件是决定它可以做到的一个重要条件是succ(succ(succ(0)))可以与succ(X)匹配,其余的只是简单,因为Y和R可以是在第一步任意设定(它们尚未统一)。并且succ(succ(succ(0)))可以匹配到succ(X)只是因为succ(A)可以匹配succ(B)任何时候A可以与B匹配 - 你看到计算机决定它并不是很难

下一步是Prolog查看该行的其余部分(: - add(X,Y,Z))并生成查询add(succ(succ(0)), succ(succ(0)), Z)。请记住,succ(Z)= R并且它将不会改变,直到(如果)计算路径被拒绝。下一个查询将是add(succ(0), succ(succ(0)), Z'),其中succ(Z')= Z.然后是add(0, succ(succ(0)), Z''),其中succ(Z'')= Z'。

然后Prolog可以使用第一条规则,确定Z''=Y=succ(succ(0))。然后没有什么可做的,所以它只是写入输出R=succ(Z)=succ(succ(Z'))=succ(succ(succ(Y)))=succ(succ(succ(succ(succ(0)))))