3

Arguments are not sufficiently instantiated以下に示すように、私が書いた加算ルールによる乗算のエラーが発生し続けます。

mult(_, 0, 0).                                   %base case for multiplying by 0
mult(X, 1, X).                                   % another base case
mult(X, Y, Z) :-
   Y > 1,
   Y1 is Y - 1,
   mult(X, Y1, Z1),
   Z is X + Z1. 

私は Prolog を初めて使用し、そのような単純な問題でさえ本当に苦労しています。

書籍やオンライン チュートリアルに関する推奨事項があれば、ぜひ参考にしてください。

Ubuntu Linux の SWI-Prolog で実行しています。

4

2 に答える 2

4

mult/3最初の2つの引数の定義では、既知である必要があります。それらの1つがまだ変数である場合、インスタンス化エラーが発生します。例えば。正解ですがmult(2, X, 6)、インスタンス化エラーが発生します。X = 3実際、唯一の答えです。

あなたが持っているいくつかのオプションがあります:

、制約、またはメタ-論理述語。

後継演算の開始点は次のとおりです。

add(0,Y,Y).
add(s(X),Y,s(Z)) :- add(X,Y,Z).

別のアプローチは、整数に対して制約を使用することです。YAPとSWIにはlibrary(clpfd)、非常に柔軟な方法で使用できるがあります。通常の整数計算と、より一般的な制約の両方に使用できます。もちろん、乗算はすでに事前定義されています。

?-A * B#=C。
A * B#=C。

?-A * B#= C、C=6。
C = 6、
A in -6 .. -1 \ / 1..6、
A * B#= 6、
B in -6 .. -1 \/1..6。

?-A * B#= C、C = 6、A=2。
A = 2、
B = 3、
C=6。

メタ論理述語:さまざまなケースを区別し、それらを異なる方法で処理するためvar/1nonvar/1、を使用するこのオプションはお勧めできません。ground/1これはエラーが発生しやすいので、それらを使用する正しいプログラムを見たことはめったにありません。実際、非常によく知られている教科書でさえ、重大な誤りが含まれています。

于 2012-03-20T12:29:33.010 に答える
2

最後の2つの呼び出しが逆になっていると思います。意味しないでください:

mult(X,Y,Z):- Y>1,Y1 is Y-1, Z1 is X+Z, mult(X,Y1,Z1).

編集:気にしないでください、コードをもう一度見てください、そしてそれは意味がありません。元のコードは正しいと思います。

そのエラーが発生している理由については、述語をどのように呼び出しているかを知る必要があります。入力例を教えてください。

述語を呼び出す正しい方法は次のmult(+X, +Y, ?Z)とおりです。

?- mult(5,0,X).
X = 0

?- mult(5,1,X).
X = 5

?- mult(5,5,X).
X = 25

?- mult(4,4,16).
yes

?- mult(3,3,10).
no

最初の2つの引数で自由変数を使用して呼び出すと、そのエラーが発生します。これは、それらの1つが、の右側isまたはのいずれかの側で使用され、<これらの述語は基底項が成功することを期待しているためです。

于 2012-03-19T18:09:16.157 に答える