5

アサートとリトラクトに関する Prolog の論理ビューを詳しく説明してもらえますか?

たとえば、以下のコードでは、Prolog は最初の実行で true を返し、その後の実行で false を返します。asserta(nextBound(100))Prolog の論理ビューが満たされると、nice(X) は開始時の値でまだ凍結されているため、この変更は無視され、 nextbound(100)false でなければならない理由がわかりません 。

nextBound(10000).

nice(X) :-
   asserta(nextBound(100)),
   retract(nextBound(10000)),
   nextBound(100).
4

2 に答える 2

5

歴史的なビューから始めると、論理更新ビューは Quintus 2.0 (現在の後継は SICStus) で最初に実装され、1987 年に文献で説明されました。ISO Prolog ISO/IEC 13211-1:1995 で採用されました。主要な考え方は、動的述語のゴールは、ゴールが実行される時点で存在する句を正確に考慮に入れるというものです。追加であれ削除であれ、それ以上の変更は、まさにその目標の実行には考慮されません。

論理更新ビューの前には、多かれ少なかれ一貫性のあるさまざまな実装がありましたが、ほとんどは Prolog システムのさまざまな最適化と互換性がありませんでした。違いは、複数の回答がある可能性のある目標がある場合にのみ表示されることに注意してください。単純な目標として、またはリトラクトretract/1使用してまたはを使用している場合assertz/1。のみを使用した場合、違いは見られませんasserta/1。したがって、あなたの例では違いを明確にすることはできません。

動的述語を考えてみましょうp/1。次のインタラクションはトップレベルのみを使用してp/1いるため、ファクトをアサートし、すぐに のすべてのファクトを撤回して、システムに知らせp/1ます。retractall(p(_))また、次のクエリを開始する前に、すべてのファクトを削除します。

?- asserta(p(1)).
true.  % now p/1 is known to the system.

?- retractall(p(_)), assertz(p(1)), p(X), assertz(p(2)).
X = 1.  % only one answer!

?- retractall(p(_)), assertz(p(1)), p(X), assertz(p(2)), p(Y).
X = 1, Y = X ;
X = 1,
Y = 2.

したがって、最初の目標p(X)は のみp(1)を参照しますが、2 番目の目標p(Y)は両方を参照します。これは、アクティブな目標に適用されます。

?- retractall(p(_)), assertz(p(1)), assertz(p(2)), p(X), assertz(p(3)), p(Y).
X = 1, Y = X ;
X = 1,
Y = 2 ;
X = 1,
Y = 3 ;
X = 2,
Y = 1 ;
X = 2, Y = X ;
X = 2,
Y = 3 ;
X = 2,
Y = 3 ;
false.

X繰り返しますが、は 1 または 2 のみであり、3 ではないことに注意してください。

p(X)あるいは、各目標が次のように置き換えられると想像できます。

... findall(Xi, p(Xi), Xis), member(X, Xis) ...

これは、背後にあるアイデアを少し示しています。概念的には、すべての回答は一時的に保存され、その後でのみ各回答が表示されます。

ええと、上記はまったく当てはまりません。なぜなら、のp/1だけがこのように処理されるからです。つまり、事実のみを保存する限り、上記の説明は完璧ですが、ルールも保存する場合は、より複雑な説明が必要になります。

 ... findall(Xi-Bi, clause(p(Xi),Bi), XiBis), member(X-B,XiBis), B ...

繰り返しになりますが、これは明らかな真実ではありません。カットなどのよりエキゾチックな問題が介入する可能性があるからです。とりあえずそのままにしておきます1 .

同様に、retract/1それを実行した時点で見た句も見たり削除したりします。ほとんどの場合、これは非常に直感的であり、私たちの期待に一致します。それにもかかわらず、次のような非常にばかげた状況があります。

?- retractall(p(_)),
   assertz(p(1)), assertz(p(2)),
   retract(p(X)), ( X = 1, retract(p(Y)) ; X = 2, Y = none ).
X = 1,
Y = 2 ;
X = 2,
Y = none.

ここではp(2)、データベースには単一のファクトしか含まれていませんでしたが、ファクトは 2 回削除されました。p(2).


脚注

1 実際に交換する

... p(X) ...

... findall(Xi-Bi, clause(p(Xi),Bi), XiBis), answs_goal_x(XiBis,X, G), G ...

answs_goal_x([], _, true).
answs_goal_x([Xi-Bi|XiBis], X, ( X = Xi, Bi ; G) ) :-
   answs_goal_x(XiBis, X, G).
于 2015-01-23T19:41:30.347 に答える