1

さて、私はプロローグの初心者なので、質問をはっきりと理解できない場合は申し訳ありませんが、これは私が苦労しているところです:

divide_by(X, D, I, R) :- (D > X), I is 0, R is X.

divide_by(X, D, I, R) :-
X >= D,
X_1 is X - D,
I_1 is I + 1,
divide_by(X_1, D, I_1, R),
R is X_1.

ユーザーが入力したときに X / D の結果を表示できるように、2 つの引数 (X と D) を受け入れ、反復 (I) と剰余 (R) を返すプログラムを作成しようとしています。 3、I、R)。例えば。

コードをトレースすると、最初のインクリメントで 0 になり、そのカウントが間違っているため、間違っていることがわかります。しかし、ループを再帰するたびにリセットせずに I が 0 であることを宣言する方法がわかりません。(クエリで I を 0 として宣言したくありません)

また、再帰が終了すると (X < D の場合)、基本ケースのために 0 に設定されることにも気付きました。

これを修正する方法を教えてくれる人は親切ですか?

4

1 に答える 1

1

アキュムレータを導入し、次のようなヘルパー述語を使用する必要があります。

divide(_,0,_,_) :- !, fail . % X/0 is undefined and so can't be solved.
divide(0,_,0,0) :- !.        % 0/X is always 0.
divide(X,Y,Q,R) :-           % the ordinary case, simply invoke the
  divrem(X,Y,0,Q,R)          % helper with the accumulator seeded with 0
  .

divrem(X,Y,Q,Q,X) :-   % if X < Y, we're done.
  X < Y .              %
divrem(X,Y,T,Q,R) :-   % otherwise...
  X >= Y ,             % as long as X >= Y,
  X1 is X - Y ,        % compute the next X
  T1 is T + 1 ,        % increment the accumulator
  divrem(X1,Y,T1,Q,R)  % recurse down
  .                    % Easy!
于 2013-02-21T17:59:17.973 に答える