1

私はプロローグが初めてです。私は再帰的なプログラムを実行していますが、問題は答えを出力しても..答えを出力した後に停止せず、最終的に「ローカルスタックから」が表示されることです。左再帰の問題である可能性があることを読みましたが、すでに言ったように、私はプロローグが初めてで、何が起こるのかよくわかりません...だから..ここにコードがあります。

f(X, Y):-
    Y is sqrt(1-((X-1)*(X-1))).

sum(SEGMENTS, 1, TOTAL):-
    f(2/SEGMENTS*1,H1),
    TOTAL is (2/SEGMENTS)*H1.

sum(SEGMENTS, NR, TOTAL):-
    N1 is (NR-1),
    sum(SEGMENTS, N1, S1),
    f(2/SEGMENTS*NR,H1),
    f(2/SEGMENTS*N1,H2),
    TOTAL is S1 + (2/SEGMENTS)*((H1+H2)/2).

台形則などで半円の面積を計算することになっています。すでに言ったように..終了しますが、基本ケースの合計(セグメント、1、合計)に到達した後、2番目の選択肢で関数を呼び出します... :S

みんなありがとう!

また、実行すると次のようになります

?- sum(3000,3000,TOTAL).
TOTAL = 1.5707983753431007 ;
ERROR: Out of local stack
4

1 に答える 1

2

問題は、最初の句が成功した後、バックトラックが2 番目の句のNR値のケースを試行することです。これにより、再帰プロセスが長くなります (再帰呼び出しごとに NR が継続的に減分され、すべての負の整数値をラップアラウンドしようとするなど)。1sum

問題を解決する簡単な方法は、2 番目のsum句にあります。の場合を想定しているため、NR > 1最初NR > 1のステートメントとして次のように入力します。

sum(SEGMENTS, NR, TOTAL) :-
    NR > 1,
    N1 is (NR-1),
    sum(SEGMENTS, N1, S1),
    f(2/SEGMENTS*NR,H1),
    f(2/SEGMENTS*N1,H2),
    TOTAL is S1 + (2/SEGMENTS)*((H1+H2)/2).

また、式は式を計算して に渡さf(2/SEGMENTS*NR, H1)ないことに注意してください。実際には、その式を象徴的に渡します。の右側に含まれているため、ここでたまたま機能するため、必要に応じて評価されます。それをたどれば、私の言いたいことがわかるでしょう。2/SEGMENTS*NRffis/2

于 2013-11-04T11:47:11.343 に答える