繁体   English   中英

了解Prolog中的递归规则

[英]Understanding recursive rules in Prolog

我正在开始Prolog,由Seven LangsSeven Langauges提供,并且在理解prolog如何处理递归方面有点挣扎。

给出以下代码:

sum(0, []).
sum(Total, [Head|Tail]) :- sum(Sum,Tail), Total is Head + Sum.

% executed in the Prolog interpreter:
sum(X, [1,2,3])
X = 6

我理解这段代码在做什么,但我对Prolog如何解析sum的递归调用有点不知所措。 主要是,对我来说很奇怪, sum没有明确的“回报”。

我的理解是这样的事情发生了:

A.解释者试图通过调用sum来统一规则总和(X,[1,2,3]):

0 Sum(X, [1, 2, 3])
1 Sum(Y, [2,3] 
2 Sum(Z, [3])
3 Sum(0, []) % our recursive base

B.一旦我们达到基本事实,它就会爬上递归的“堆栈”:

3 Sum(0, []), Total = 0 % we start at our base fact
2 Sum(1, [3]), Total = 3
1 Sum(2, [2, 3]), Total = 5 
0 Sum(X, [1, 2, 3]) Total = 6 % sweet, sweet unification

我对这种运作方式的理解是否正确? 或者,我的命令性思维是否有更好的方式来思考/表达上面发生的事情?

是的,你的想法是正确的。 我会略微改写你所说的内容,以便它可能更清晰一些。

理解Prolog执行的第一件事就是要意识到Prolog就像一个弱定理证明者。 它会尝试使您的查询成立。 那么,当你输入查询?- sum(X, [1,2,3]). ,Prolog将尽力使其成为现实。 在这种情况下,正如我们所看到的,它需要将X绑定到6 ,让我们看看如何。

你给Prolog证明sum(X, [1, 2, 3])为真的唯一元素是

sum(0, []).

sum(Total, [Head|Tail]) :- sum(Sum,Tail), Total is Head + Sum.

显然,Prolog不能对第一个条款做任何事情,因为它不能统一[][1, 2, 3] 因此它尝试使用第二个子句来证明您的查询。

然后会发生的是它试图证明sum(Sum,Tail)Total is Head + Sum顺序。 证明这两个选项中的第一个将导致递归调用,最终将使用Tail = []调用它。 此时,Prolog将使用您给出的第一个子句,并推断Sum因此为0 它现在将具有在递归的最后一步证明第二部分( Total is Head + Sum )的元素。 然后,当您猜到时,递归会回溯到初始谓词。

这是对的。 显式“返回”的作用是通过满足定义sum/2的谓词中的空列表的总和的独特方式来实现的。

您可以通过在翻译处执行目标sum(X,[ ])来说服自己。

暂无
暂无

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

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