走过Prolog中的递归因子程序?

时间:2014-12-06 18:44:35

标签: recursion prolog factorial

我真的很难理解递归在Prolog中是如何工作的。

factorial(0,1).   
factorial(N,F) :-  
   N>0, 
   N1 is N-1, 
   factorial(N1,F1), 
   F is N * F1.

我理解第一部分是基本情况,这将结束程序的延续。但是,让我困惑的部分是第二个因子调用(N1,F1)的参数。有人可以解释一切如何执行和计算的步骤吗?

1 个答案:

答案 0 :(得分:0)

第二条规则基本上表示FN 的阶乘,如果 N大于零N1 N-1生成的数字F1N1 {{1}的阶乘}}是FN的产物。

示例

让我们说你想找到3的阶乘。

F1

Prolog将-? factorial(3,F). 置于目标堆栈上,然后查找头部与第一个目标匹配的规则。 factorial(3,F)有两个规则(事实factorial/2可以看作是没有正文的规则),但是对于第一个0不与5统一,因此无法使用。第二个统一,factorial(0,1)被实例化为5,Prolog将条件添加到堆栈中:

N

满足第一个目标,因为3大于零。第二个是通过将3 > 0, N1 is 3-1, factorial(N1,F1), F is 3*F1 绑定到N1的算术评估结果来满足的,所以现在有一堆目标:

3-1

再次,Prolog查找可能用于满足factorial(2,F1), F is 3*F1 的规则并使用第二个(factorial(2,F1)与2统一,NF统一,不同的名称是用于变量):

F1

接下来,2 > 0, N2 is 2-1, factorial(N2,F2), F1 is 2*F2, F is 3*F1 为真,2 > 0N2的算术结果统一,因此目标堆栈变为:

2-1

再次使用factorial(1,F2), F1 is 2*F2, F is 3*F1 的第二条规则:

factorial/2

1 > 0, N3 is 1-1, factorial(N3,F3), F2 is 1*F3, F1 is 2*F2, F is 3*F1 变为零(满足N3时):

N3 is 1-1

此时,factorial(0,F3), F2 is 1 * F3, F1 is 2*F2, F is 3*F1 的第一条规则可用于满足factorial/2,但会创建选择点,因为可以使用更多规则。因此,factorial(0, F3)成功将factorial(0,F3)实例化为1。

F3

通过满足堆叠中剩余的所有目标,F2 is 1 * 1, F1 is 2 * F2, F is 3 * F3 变为6并且您获得了第一个解决方案。但是,F有一个选择点。此时可以使用第二条规则:

factorial(0, F3)

但是0>0, N4 is 0-1, factorial(N4,F4), F3 is 0*F4, F2 is 1*F3, F1 is 2*F2, F is 3*F3 失败并且执行停止,因为没有其他选择指向回溯到。

您可以通过使用[绿色]剪切操作符来避免为0>0留下无用的选择点。

factorial(0,_)