简体   繁体   English

Prolog中的递归succ加法

[英]Recursive succ addition in Prolog

add(0,Y,Y).
add(succ(X),Y,succ(Z)) :-
        add(X,Y,Z).    

I don't understand how this one works.我不明白这个是如何工作的。 If I run the query:如果我运行查询:

add(succ(succ(succ(0))), succ(succ(0)), R)

How does it remove succ from the first argument?它如何从第一个参数中删除 succ ?

If I run it:如果我运行它:

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

This satisfied the body.这让身体很满意。 We input them into the head:我们将它们输入到头部:

add(succ(X),Y,succ(Z)) %% becomes
add(succ(succ(succ(0))),succ(succ(0)),succ(R))

Ie it looks to me as if it just adds succ, not removes them from the first argument?即它在我看来好像只是添加了 succ,而不是从第一个参数中删除它们? I saw that there's another post about this exact question but it does not make sense to me.我看到有关于这个确切问题的另一篇文章,但对我来说没有意义。

When you call the goal add(succ(succ(succ(0))), succ(succ(0)), R) and Prolog tries to execute the clause with the head add(succ(X),Y,succ(Z)) , unification happens.当您调用目标add(succ(succ(succ(0))), succ(succ(0)), R)和 Prolog 尝试执行带有 head add(succ(X),Y,succ(Z))统一发生。 Unification is one of the central concepts of Prolog, and it's important to understand it well.统一是 Prolog 的核心概念之一,理解它很重要。 Unification is also the operation that is performed by the = operator.统一也是由=运算符执行的操作。 What happens when the head of the clause is executed is exactly the same as happens when you execute the following equivalent query:执行子句头部时发生的情况与执行以下等效查询时发生的情况完全相同:

?- add(succ(succ(succ(0))), succ(succ(0)), R) = add(succ(X),Y,succ(Z)).

It is important to understand that unification is not just "unpacking" or "building up" terms, but both at the same time .重要的是要了解统一不仅仅是“拆包”或“建立”术语,而是同时进行

It can "extract" information from terms:它可以从术语中“提取”信息:

?- X = f(a), Y = f(Z), X = Y.
X = Y, Y = f(a),
Z = a.

Here we found that a is the argument of the f functor in X .这里我们发现aX f函子的参数。

It can "construct" terms:它可以“构造”术语:

?- X = f(Y), Y = g(h).
X = f(g(h)),
Y = g(h).

Here we "inserted" the term g(h) into the "hole" Y in X .在这里,我们将项g(h) “插入”到X的“洞” Y中。

It can also do both at the same time to more than one term:它还可以对多个术语同时进行:

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

Here unification "unpacked" both f terms, then "filled in" a hole in each of them.这里统一“解包”了两个f项,然后在每个项中“填充”了一个洞。

Now, armed with this knowledge, what does the unification in your example do?现在,有了这些知识,您示例中的统一有什么作用?

?- add(succ(succ(succ(0))), succ(succ(0)), R) = add(succ(X),Y,succ(Z)).
R = succ(Z),
X = Y, Y = succ(succ(0)).

In particular, when succ(succ(succ(0))) is unified with succ(X) , this will bind X to succ(succ(0)) .特别是,当succ(succ(succ(0)))succ(X)统一时,这会将X绑定到succ(succ(0)) X is not bound to the entire term succ(succ(succ(0))) but only to an "inner" part. X绑定到整个术语succ(succ(succ(0)))而只绑定到“内部”部分。 This is what removes one level of succ from the argument.这是去掉了一个级别succ从参数。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM