我真的很难理解递归在Prolog中是如何工作的。
factorial(0,1).
factorial(N,F) :-
N>0,
N1 is N-1,
factorial(N1,F1),
F is N * F1.
我理解第一部分是基本情况,这将结束程序的延续。但是,让我困惑的部分是第二个因子调用(N1,F1)的参数。有人可以解释一切如何执行和计算的步骤吗?
答案 0 :(得分:0)
第二条规则基本上表示F
是N
的阶乘,如果 N
大于零且由N1
和 N-1
生成的数字F1
是N1
和 {{1}的阶乘}}是F
和N
的产物。
示例强>
让我们说你想找到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统一,N
与F
统一,不同的名称是用于变量):
F1
接下来,2 > 0, N2 is 2-1, factorial(N2,F2), F1 is 2*F2, F is 3*F1
为真,2 > 0
与N2
的算术结果统一,因此目标堆栈变为:
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,_)