这可以在Prolog中进行尾递归吗?

时间:2011-10-22 21:27:05

标签: recursion prolog stack-overflow tail-recursion instantiation-error

我正在学习Prolog,作为练习,我正在尝试一个简单的数据库来计算所有数字的总和,直到给定的数字(即0 = 0,1 = 1,2 = 3,3 = 6,4 = 10,...)。很容易:

counting_sum(0, 0).
counting_sum(Num, Sum) :- Num > 0, PrevNum is Num - 1,
    counting_sum(PrevNum, PrevSum), Sum is Num + PrevSum.

在堆栈溢出的情况下,counting_sum(150000, X).附近爆炸。我知道Prolog可以进行尾递归,但如果我将递归调用移到规则的末尾,我会得到

error(instantiation_error,(is)/2)
我假设

告诉我在与PrevSum统一之前我无法使用counting_sum(PrevNum, PrevSum)。这是正确的,有没有办法让这个尾递归?如果这有任何区别,我正在使用GNU Prolog 1.3.1。

P.S。我的术语仍然不稳定。如果我错误地使用了这些术语,请告诉我。

1 个答案:

答案 0 :(得分:8)

尝试这样的事情(使用累加器):

counting_sum(Count, Sum):-
  counting_sum(Count, 0, Sum).

counting_sum(0, Sum, Sum).
counting_sum(Num, PrevSum, Sum):- Num > 0, PrevNum is Num - 1,
    NextSum is PrevSum + Num,
    counting_sum(PrevNum, NextSum, Sum).