2

数字の表現として、この非常に単純なコードがあります。問題は add2 関数を使用するときです。

例:正しくadd2(s(0)+s(s(0)), s(s(0)), Z).返されます。s(s(s(s(s(0)))))しかしadd2(0, s(0)+s(s(0)), Z).、常にreturns s(0)+s(s(0))。なぜこれが起こっているのか誰にもわかりますか?

numeral(0).
numeral(s(X)) :- numeral(X).
numeral(X+Y) :- numeral(X), numeral(Y).

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

%%  exercise 1
add2(X,Y,R) :- add(X,Y,R).
add2(X+Y,Z,R) :- add(X,Y,A),add2(A,Z,R).
add2(X,Y+Z,R) :- add(Y,Z,A),add2(X,A,R).
4

3 に答える 3

2

add2これは、最初の句と最初の句の組み合わせが原因で発生していaddます。あなたの意志は常に2番目と3番目の引数を統合するadd2(0, ..., ...)トリガーです。add(0, ..., ...)

于 2011-10-27T00:42:49.097 に答える
1

Prolog 関数では、中置記号のような記号+は評価されません。のすべての出現を評価しようとしているようです+。ただし、それらのいくつかはまだ評価されておらず、 のようにアドホックに実行しようとすると、非常に扱いにくい場合がありますadd2/3add2(0+0+0,0,R)あなたの定義でどれが失敗するかを考え てください。

あなたが呼ぶものは と呼んだnumeral/1ほうがいいかもしれませんexpression/1

eval/2式を s(X)-number に簡略化する補助述語を定義することを検討してください。ただし、そのような定義でも のようなゴールでは失敗することに注意してくださいadd2(0,0,0+0)。これは、制約または同様の手法を使用してのみ解決できる固有の問題です...

于 2011-10-26T22:25:30.753 に答える
-1

を呼び出すadd2(0, s(0)+s(s(0)), Z)と、 の最初の節と統合されます。add2/3この最初の節は先頭に 3 つの変数しかないため、 の任意の呼び出しと統合できますadd2/3。これにより、例では の最初の句が呼び出さadd/3れるため、 Z は にバインドされs(0)+s(s(0))ます。

コードの問題は、より具体的な句がadd2/3一般句の後に配置されていることです。したがって、コードを機能させるには、add2/3last の最初の句を配置し、他の 2 つの句にカットを追加します。

add2(X+Y,Z,R) :- !,add(X,Y,A),add2(A,Z,R).

その句の先頭がクエリと一致した場合は、正しい句を実行していることを確認でき、バックトラックで問題が発生することはありません。

于 2011-10-27T06:04:19.580 に答える