Prolog无限递归没有填满堆栈?

时间:2016-10-18 23:57:58

标签: recursion prolog stack-overflow

使用以下示例,由于无限递归,堆栈会快速填充...

is_pos_integer(X):- is_pos_integer(Y),X is Y+1.
is_pos_integer(0).

但是,以下示例在运行并请求回溯(使用;)时,会在不填充堆栈的情况下命中相同的无限递归...

is_pos_integer(0).
is_pos_integer(X):- is_pos_integer(Y),X is Y+1.

我不相信这两个函数都是尾递归的,那么为什么第二个会导致........... StackOverflow? (yaaaaoww .... 太阳镜

1 个答案:

答案 0 :(得分:2)

假设您的查询类似于?- is_pos_integer(1),那么解释如下:

第一个例子进入无限循环,不受尾递归的影响。所以堆栈填满了。

第二个例子也将最终填满,但速度很慢。

让我们标记第一个子句A和第二个子句B.当您调用is_pos_integer(0)的第一个版本时,调用模式是AAAAA ...(不在堆栈中)。当您调用第二个版本时,您获得A(返回到true到顶级),然后在回溯BA失败,因为0不等于0 + 1,然后BBA再次失败,因为0不等于1 + 1,等等你接到BB ... B(n次)的呼叫,然后是失败的A.最终你会用完堆栈,但这需要很长时间。