我正在学习Prolog .
我有这个递归谓词:
添加(0,Y,Y) . add(succ(X),Y,succ(Z)): - add(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)
.
任何帮助都是 greatly appreciated . 提前致谢!
1 回答
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)))))
.