Recursion Prolog中的递归成功加法

Recursion Prolog中的递归成功加法,recursion,prolog,addition,successor-arithmetics,Recursion,Prolog,Addition,Successor Arithmetics,我不明白这是怎么回事。 如果我运行查询: add(0,Y,Y). add(succ(X),Y,succ(Z)) :- add(X,Y,Z). 它如何从第一个参数中删除succ 如果我运行它: add(succ(succ(succ(0))), succ(succ(0)), R) 这使身体感到满意。我们将它们输入头部: X=succ(succ(succ(0))) Y=succ(succ(0)) R=? 也就是说,在我看来,它只是增加了成功,而不是从第一个参数中删除了成功

我不明白这是怎么回事。 如果我运行查询:

add(0,Y,Y).
add(succ(X),Y,succ(Z)) :-
        add(X,Y,Z).    
它如何从第一个参数中删除succ

如果我运行它:

add(succ(succ(succ(0))), succ(succ(0)), R)
这使身体感到满意。我们将它们输入头部:

X=succ(succ(succ(0)))
Y=succ(succ(0))
R=?

也就是说,在我看来,它只是增加了成功,而不是从第一个参数中删除了成功?我看到有另一篇关于这个问题的帖子,但对我来说没有意义。

当你调用目标
add(suc(suc(suc(0))),suc(suc(0)),R)
并且Prolog试图执行带有头的子句
add(suc(X),Y,suc(Z))
,统一就发生了。统一是Prolog的核心概念之一,理解它很重要。统一也是由
=
运算符执行的操作。执行子句头时发生的情况与执行以下等效查询时发生的情况完全相同:

add(succ(X),Y,succ(Z)) %% becomes
add(succ(succ(succ(0))),succ(succ(0)),succ(R))
重要的是要理解,统一不仅仅是“解包”或“建立”术语,而是两者同时存在

它可以从以下术语中“提取”信息:

?- add(succ(succ(succ(0))), succ(succ(0)), R) = add(succ(X),Y,succ(Z)).
这里我们发现
a
X
f
函子的参数

它可以“构造”术语:

在这里,我们将术语
g(h)
插入
X
中的“孔”
Y

它还可以同时对多个术语执行这两项操作:

?- X = f(Y), Y = g(h).
X = f(g(h)),
Y = g(h).
在这里,统一“解包”两个
f
术语,然后在每个术语中“填充”一个孔

现在,有了这些知识,你的例子中的统一做了什么

?- X = f(a, B), Y = f(A, b), X = Y.
X = Y, Y = f(a, b),
B = b,
A = a.

特别是,当
succ(succ(0))
succ(X)
统一时,这将
X
绑定到
succ(0))
X
未绑定到整个术语
succ(succ(0))
,而仅绑定到“内部”部分。这将从参数中删除一级的
succ

第二个子句上的模式匹配将设置
X=succ(succ(0))
,因此这里您将“解包”函子。
?- X = f(a, B), Y = f(A, b), X = Y.
X = Y, Y = f(a, b),
B = b,
A = a.
?- add(succ(succ(succ(0))), succ(succ(0)), R) = add(succ(X),Y,succ(Z)).
R = succ(Z),
X = Y, Y = succ(succ(0)).