我编写了两个代码以使用Prolog计算阶乘。
首先是
factorial(0, 1).
factorial(N, Result) :-
N > 0, factorial(N - 1, Interim), Result is N * Interim.
,第二个是
factorial(0, 1).
factorial(N, Result) :-
N > 0, M is N - 1, factorial(M, Interim), Result is N * Interim.
当第一个代码有堆栈溢出错误时,第二个代码正常运行。
我为测试编写了以下代码。
sum_2(N, R) :- R is N + 2.
sum_f(N, R) :- sum_2(N + 2, R).
上面的代码正常执行。
我不明白为什么用于计算阶乘的第一个代码是堆栈溢出错误。
如果您能告诉我原因,我将不胜感激。
您确定第一个版本的堆栈溢出吗?你怎么称呼它?像这样的呼叫factorial(5, Result)
应该失败,即导致回答像false
或no
。
Prolog不像其他编程语言那样“评估表达式”。像这样的术语N - 1
只是数据:带有函子-
和两个自变量N
and的术语1
。即使N
势必有些数字,比如说5
,术语依然只是5 - 1
不4
。它只是映射到4
,如果你专门请教了is
谓词或算术比较谓词的一个(>
,=<
,=:=
等),对其进行评估。
因此,如果将第一个factorial
谓词称为factorial(5, Result)
,则会发生以下情况:
factorial(5, Result)
与不统一factorial(0, 1)
,将跳过此子句factorial(5, Result)
与相结合factorial(N, Result)
与统一者N = 5
,这一条款的身体与此结合执行
5 > 0
成功factorial(5 - 1, Interim)
已执行:
factorial(5 - 1, Interim)
与不统一factorial(0, 1)
,将跳过此子句factorial(5 - 1, Interim)
相结合与factorial(N, Result)
用的统一者N = 5 - 1
和Interim = Result
,这一条款的身体与此结合执行
5 - 1 > 0
成功factorial((5 - 1) - 1, Interim)
已执行:
这最终调用factorial
具有越来越大的方面5
,5 - 1
,(5 - 1) - 1
,((5 - 1) - 1) - 1
,等。由于这些术语都不曾与统一0
,因此计算将永远不会成功。由于这些术语中的每一个都与的新副本统一在一起N
,因此第二个子句始终匹配,但最终您会遇到一个包含足够- 1
步骤的术语,以致目标N > 0
将失败,并且查询factorial(5, Result)
将失败。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句