5

次のプログラムがあるとします。

a(tom). 
v(pat).

およびクエリ (false を返す):

\+ a(X), v(X).

Xトレースすると、が にインスタンス化されtom、述語a(tom)が成功し、したがって\+ a(tom)失敗することがわかります。

私はいくつかのチュートリアルで、\+Prolog の not ( ) は単なるテストであり、インスタンス化を引き起こさないことを読みました。

  1. 誰かが私のために上記の点を明確にしてもらえますか? インスタンス化を見ることができるように。

  2. not (失敗としての否定) と論理否定には違いがあることを理解しています。どのような場合に同じように動作し、いつ異なる動作をするかを説明している良い記事を参照できますか?

4

2 に答える 2

3

素晴らしい質問です。

短い答え: あなたは「ヒラヒラ」に出くわしました。

問題は、演算子 \+ の実装が、変数を含まないリテラル、つまりグラウンド リテラルに適用された場合にのみ機能することです。変数のバインディングを生成することはできませんが、サブゴールが成功するか失敗するかをテストするだけです。したがって、否定を含むプログラムへのクエリに対する妥当な回答を保証するには、否定演算子をグラウンド リテラルにのみ適用できるようにする必要があります。それが非グラウンドリテラルに適用された場合、プログラムはフラウンダーと言われます。 リンク

クエリを逆にすると

v(X), \+ a(X).

正しい答えが得られます。一部の実装またはメタ インタープリターは、もがく目標を検出し、すべての変数が確定するまでそれらを遅らせます。

ポイント 1) については、NAF ツリー内のインスタンス化が表示されます。そこで何が起こるかは、外部にある変数 (この場合は v(X)) に影響を与えるべきではありません。Prolog は、非効率性を回避するために単純な方法で動作することがよくあります。理論的には、変数をインスタンス化する代わりにエラーを返すだけです。

2) これは、このトピックに関する私のお気に入りの記事です: Nonmonotonic Logic Programming .

于 2013-02-06T11:28:06.450 に答える
1

WRT ポイント 2、ウィキペディアの記事は良い出発点のようです。

NAF を理解するのが難しい場合があることは、すでに経験済みです。これの一部は、(論理的)否定が、微積分を述語する単純なコンテストでさえも定義することが本質的に難しいためである可能性があります (たとえば、ラッセルのパラドックスを参照)。. forall /2の実際のライブラリ定義を理解できるかどうかを確認してください (ドキュメントを読んでください。合成的で興味深いものです)。これは、障害駆動型ループを実行するための推奨される方法です。

%%  forall(+Condition, +Action)
%
%   True if Action if true for all variable bindings for which Condition
%   if true.

forall(Cond, Action) :-
    \+ (Cond, \+ Action).

初めて見たときは魔法のように見えたのを覚えています...

チュートリアルについて編集して、私のリンク コレクションを 'spelunking' しているときに、JRFisher による優れたサイトを見つけました。興味深い内容でいっぱいですが、説明が少し簡潔であることが残念で、生徒は頻繁に練習問題で自分自身に答える必要があります。失敗による否定に専念している段落 2.5を参照してください。セクション 3 もお楽しみいただけると思います。

于 2013-02-05T20:22:51.660 に答える