递归函数如何在Prolog中工作?

时间:2015-05-25 12:46:00

标签: prolog

我正在prolog中读取一个递归函数,它返回列表中所有元素的Sum,如下所示:

sum([ ], 0).
sum( [Elem | Tail], S):- sum(Tail, S1),
                         S is S1 + Elem.

我无法理解两个问题:

1:在“: - ”的左侧,我们有目标。这意味着所有计算都将在“: - ”的右侧完成,然后我们可以使用目标作为正常函数。这意味着我们给出我们的参数和变量,结果将被放在它们上面,右侧负责计算。

在此代码中,目标本身正在计算头部和尾部。我的意思是在我看来代码应该是这样的(但它不起作用!):

sum(Tail, S1):-sum( [Elem | Tail], S),........

因为目标应该给出参数而右侧负责计算。

2:我无法理解这段代码是如何逐步运作的。任何人都可以给我一个非常简单的例子,比如它如何计算[1,2,3]的总和?

3 个答案:

答案 0 :(得分:1)

prolog的一个重要部分是匹配(更一般地说,统一)。当Prolog运行时遇到像sum(X,Y)这样的目标时,它会尝试将该术语与sum的规则的左侧(头部)按照它们出现的顺序进行匹配。如果第一个规则失败,则系统将移至第二个规则,依此类推。

在这种情况下,如果X是空列表,则第一个头只会匹配。如果它不为空,则匹配失败,并尝试下一个头。只要X是任何非空列表,这将成功。它不仅会成功,而且会将列表的第一个元素绑定到Elem,列表的其余部分(可能为空)到Tail。由于此规则头部的第二个参数是变量,因此它将绑定到Y是什么。

让我们通过一些例子来说明:

  

和([],X)?

第一个头匹配,将X绑定到0。

和([1],X)?

第一个头不匹配,因为[1]与[]不匹配。第二个是Elem< -1,Tail< - []。因此,我们可以继续执行规则的右侧:

sum(Tail,S1), S is S1 + Elem

由于Tail< - [],目标总和(Tail,S1)将产生绑定S1< -0(见上文)。因此,对于Elem< -1和S1< -0,S1 + Elem = 1。

等等。希望这里有足够的余下来做。

答案 1 :(得分:1)

:-的左侧,您有一个规则的头部;在右侧,你有规则的主体。当:-侧和身体缺失时,规则变为事实

说计算仅在正文中执行是不正确的,因为Prolog的决策过程适用于规则的两个方面。规则负责人扮演重要角色的概念是统一,这是一种语言决定哪些条款适用于查询的过程,并在规则头部中对变量进行检查和临时分配。查询的一部分(“统一”它们)。

例如,当您查询sum([1,2,3], X)时,Prolog会检查两个sum子句,并确定查询仅与第二个查询统一,因为[]无法与{{1}统一}}

现在,我们需要将[1,2,3][1,2,3]统一起来,只要我们在规则正文中进行临时分配:[Elem | Tail]和{{1} }。此时,它尝试再次解析Elem=1,将Tail = [2,3]作为第一个参数传递。第一条规则不匹配,因此进行了sum[2,3]的另一个临时分配。在第三级递归中,我们达到了作业Elem=2Tail=[3]。这是当我们达到第一个规则时,产生Elem=3的赋值。第三级调用为其添加Tail=[];第二级添加S1=0。第一级添加1,并返回时3设置为2

答案 2 :(得分:0)

您对执行过程中发生的事情的猜测相当奇怪。根本没有任何功能。

为了评估目标sum([1,2,3], X),选择了第二个子句,因为[1,2,3](目标的第一个参数)和[]之间没有匹配(在第一条)。

匹配实例化Elem=1Tail=[2,3]S = X。然后评估目标sum([2,3], S1),并成功(在递归之后),返回替换S1=5。然后S=5+1S绑定到6。