5

私はPrologを学んでおり、練習問題として、与えられた数(すなわち、0 = 0,1 = 1,2,2 = 3,3 = 6)までのすべての数の合計を計算する単純なデータベースを試しています。 、4 = 10、...)。十分に簡単:これはPrologでテール再帰的に行うことができますか?

スタックオーバーフローでどこか counting_sum(150000, X).周りに吹く
counting_sum(0, 0). 
counting_sum(Num, Sum) :- Num > 0, PrevNum is Num - 1, 
    counting_sum(PrevNum, PrevSum), Sum is Num + PrevSum. 

。私は、プロローグに末尾再帰を行うことができますことを理解し、私は、ルールの最後に再帰呼び出しを移動する場合、私はそれがcounting_sum(PrevNum, PrevSum)で統一されています前に、私はPrevSumを使用することはできません私に言っていると仮定し

error(instantiation_error,(is)/2) 

を取得します。それは正しいのですか?これを尾を再帰的にする方法はありますか?私はGNU Prolog 1.3.1を使用しています。

P.S.私はまだ専門用語では不安定です。私が間違って言葉を使用した場合は教えてください。

+1

あなたがインスタンス化エラーの原因について正しいです。 –

答えて

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). 
+1

ありがとうございます。私はアキュムレータに遭遇していなかった。それは[有用なイディオムのように見える](http://www.lix.polytechnique.fr/~liberti/public/computing/prog/prolog/prolog-tutorial.html#iteration)。アキュムレータが何であるかを読んで理解したら、私は新しいアキュムレータを使ってコードを書いてコードをチェックすることができました。私は同じことを思いついた。問題:私はまだ 'counting_sum(350000、X) 'でスタックオーバーフローが発生します。 –

+1

それは変です。 SWIで提供したコードを「3500000」(数字の10倍)で試してみました。 – gusbro

+2

私は推測していますが、GNU Prologは解釈モードでテール最適化を実行しないかもしれません(しかし、SWI Prologはそうします)。 @RyanStewart:コンパイルされたgprolog実行可能ファイルを使用したかどうかを確認する方法、またはインタプリタだけを確認する方法はありますか? – hardmath

関連する問題