我正在学习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。我的术语仍然不稳定。如果我错误地使用了这些术语,请告诉我。
答案 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).