[英]Recursive succ addition in Prolog
add(0,Y,Y).
add(succ(X),Y,succ(Z)) :-
add(X,Y,Z).
我不明白这个是如何工作的。 如果我运行查询:
add(succ(succ(succ(0))), succ(succ(0)), R)
它如何从第一个参数中删除 succ ?
如果我运行它:
X=succ(succ(succ(0)))
Y=succ(succ(0))
R=?
这让身体很满意。 我们将它们输入到头部:
add(succ(X),Y,succ(Z)) %% becomes
add(succ(succ(succ(0))),succ(succ(0)),succ(R))
即它在我看来好像只是添加了 succ,而不是从第一个参数中删除它们? 我看到有关于这个确切问题的另一篇文章,但对我来说没有意义。
当您调用目标add(succ(succ(succ(0))), succ(succ(0)), R)
和 Prolog 尝试执行带有 head add(succ(X),Y,succ(Z))
,统一发生。 统一是 Prolog 的核心概念之一,理解它很重要。 统一也是由=
运算符执行的操作。 执行子句头部时发生的情况与执行以下等效查询时发生的情况完全相同:
?- add(succ(succ(succ(0))), succ(succ(0)), R) = add(succ(X),Y,succ(Z)).
重要的是要了解统一不仅仅是“拆包”或“建立”术语,而是同时进行。
它可以从术语中“提取”信息:
?- X = f(a), Y = f(Z), X = Y.
X = Y, Y = f(a),
Z = a.
这里我们发现a
是X
f
函子的参数。
它可以“构造”术语:
?- X = f(Y), Y = g(h).
X = f(g(h)),
Y = g(h).
在这里,我们将项g(h)
“插入”到X
的“洞” Y
中。
它还可以对多个术语同时进行:
?- X = f(a, B), Y = f(A, b), X = Y.
X = Y, Y = f(a, b),
B = b,
A = a.
这里统一“解包”了两个f
项,然后在每个项中“填充”了一个洞。
现在,有了这些知识,您示例中的统一有什么作用?
?- add(succ(succ(succ(0))), succ(succ(0)), R) = add(succ(X),Y,succ(Z)).
R = succ(Z),
X = Y, Y = succ(succ(0)).
特别是,当succ(succ(succ(0)))
与succ(X)
统一时,这会将X
绑定到succ(succ(0))
。 X
不绑定到整个术语succ(succ(succ(0)))
而只绑定到“内部”部分。 这是去掉了一个级别succ
从参数。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.