Recursion 这是我用Prolog编写的阶乘代码的一个问题

Recursion 这是我用Prolog编写的阶乘代码的一个问题,recursion,prolog,factorial,Recursion,Prolog,Factorial,我用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.

我用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
1
的术语。即使
N
与某个数字绑定,比如
5
,术语仍然是
5-1
,而不是
4
。仅当您特别询问
谓词或算术比较谓词之一(
=0
)时,它才会映射到
4
  • 调用
    阶乘(5-1,中间)
    执行:
    • 目标
      阶乘(5-1,中间)
      阶乘(0,1)
      不统一,跳过此子句
    • 目标
      factorial(5-1,中间)
      factorial(N,Result)
      相统一
      N=5-1
      middial=Result
      ,本条款正文以该绑定执行
      • 目标
        5-1>0
        成功
      • 调用
        阶乘((5-1)-1,中间)
        执行:
  • 这最终调用了
    factorial
    ,使用了越来越大的术语
    5
    5-1
    (5-1)-1
    ((5-1)-1)-1
    ,依此类推。由于这些术语中没有一个与
    0
    相一致,因此计算永远不会成功。由于这些术语中的每一个都与
    N
    的新副本相一致,因此第二个子句始终匹配,但最终您会得到一个包含足够
    -1
    步骤的术语,因此目标
    N>0
    将失败,并且t查询
    factorial(5,Result)
    将失败