[英]Understanding recursive rules in Prolog
我正在开始Prolog,由Seven Langs的Seven 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.