2

範囲内の製品の製品を計算するプログラムを作成する必要があります。ここに画像の説明を入力

次のコードを書きました。

mult(N,N,R,R).
mult(N,Nt,R,Rt):-N1=Nt+1,R1=Rt*(1/(log(Nt))),mult(N,N1,R,R1).

Ntこれにより、 ~Nの基本的な製品が実装され1/ln(j)ます。私が理解している限り、Nt と N が等しいときに停止する必要があります。ただし、次の理由で機能させることができません。

?- mult(10,2,R,1), write(R).
ERROR: Out of global stack

次のエラー。SWI-Prolog のデフォルト ライブラリを使用せずにループを実装する他の方法はありますか?

4

2 に答える 2

2

Your program never terminates! To see this consider the following failure-slice of your program:

mult(N,N,R,R) :- false.
mult(N,Nt,R,Rt):-
   N1=Nt+1,
   R1=Rt*(1/(log(Nt))),
   mult(N,N1,R,R1), false.

この新しいプログラムは決して終了しないため、元のプログラムも終了しません。これが決して終わらないことを確認するために、2 つの(=)/2目標を考えてみましょう。最初に、新しい変数N1は何かと統合されます。これは常に成功します。同様に、2 番目の目標は常に成功します。再帰ゴールの前に失敗する可能性はありません。したがって、このプログラムは決して終了しません。

何らかの目標を追加するか、既存の目標を置き換える必要があります。見える部分で。多分追加し N > Ntます。

(=)/2さらに、2 つの目標を で置き換えることをお勧めし(is)/2ます。ただし、厳密に言えば、これは終了には必要ありません。

于 2014-11-23T18:08:13.773 に答える
0

グローバル スタックから出たということは、再帰のチェーンが長すぎて、おそらく無限のチェーンに入ったということです。

問題は、割り当て=の代わりに使用することに起因します。is

mult(N,N,R,R).
mult(N,Nt,R,Rt):-N1 is Nt+1, R1 is Rt*(1/(log(Nt))), mult(N,N1,R,R1). 

答えを得た後に先に進むのを避けるために、最初の文節にカットを挿入することをお勧めします。

グラフィカル デバッガ (SWI のものなど) を使用している場合は、'trace' と 'debug' をオンにして実行してみてください。N1 = Nt+1与えNtて 2を実行すると項 が得られることがすぐにわかります2+12+1+1+1+(...)with 10 と統一​​することはないので、そこが問題です。

于 2014-11-23T18:02:30.003 に答える