理解特定 Prolog 递归谓词时遇到问题

发布于 2024-10-12 08:30:42 字数 852 浏览 3 评论 0原文

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

添加(0,Y,Y)。
添加(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)

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

I'm in the process of learning Prolog.
I have this recursive predicate:

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

Alright, so experienced Prolog programmers will probably understand what this predicate does. At first sight it doesn't look too hard to understand; when given two numerals as the first and second argument, it will return the result of adding them up as its third argument. Sounds simple? Indeed.

But I have a major problem comprehending how this actually works. I've re-read the description of this predicate many times but yet I am not able to understand how it actually works. And that's why I'm asking for help.

By querying this:
add(succ(succ(succ(0))), succ(succ(0)), R).
Prolog will instantiate and thus return R as succ(succ(succ(succ(succ(0))))). Fine. This must be correct. However I have no clue why it is so.

What I have problems understanding is how and why Prolog strips off the outermost succ functor from the original query. Again, as it is recursive, it passes on the results as arguments onto itself, and thus stripping off the outermost succ functor until the goal can be unified. I do understand how the succ(Z) and the argument R works, but I am seemingly unable to comprehend how it actually strips off the outermost succ functor, as mentioned. For me, it seems like it's adding a succ instead of stripping it, because of succ(X) in the predicate definition.

Any help is greatly appreciated. Thanks in advance!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

遗弃M 2024-10-19 08:30:42

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) 可以在任何时间 A 与 succ(B) 匹配可以匹配到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)))))

Prolog sees the line add(succ(X),Y,succ(Z)) ... and thinks "oh, it can be matched to the query add(succ(succ(succ(0))), succ(succ(0)), R)., because I can set (unify) X=succ(succ(0)), Y=succ(succ(0)), succ(Z)=R !" The important condition for Prolog, the one that determines it can do it is that succ(succ(succ(0))) can be matched to succ(X), the rest is just simple, because Y and R can be in this first step set arbitrarily (they are not unified yet). And succ(succ(succ(0))) can be matched to succ(X) just because succ(A) can be matched to succ(B) any time A can be matched to B - you see it is not very hard for computer to decide it.

The next step is that Prolog looks at the rest of the line (:- add(X,Y,Z)) and generate query add(succ(succ(0)), succ(succ(0)), Z). Remember that succ(Z)=R and it won't change until (if) the computation path is rejected. The next query will be add(succ(0), succ(succ(0)), Z'), where succ(Z')=Z. Then add(0, succ(succ(0)), Z''), where succ(Z'')=Z'.

Then can Prolog use the first rule, determine that Z''=Y=succ(succ(0)). Then there is nothing left to do, so it just write to the output that R=succ(Z)=succ(succ(Z'))=succ(succ(succ(Y)))=succ(succ(succ(succ(succ(0))))).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文