2

そう

?- canCall(mary, Person).

動作し、終了し、

?- canFind(mary, Person).

も動作し、終了します。でもなんとなく

?- canCall(mary, Person), canFind(mary, Person). 

終了しません。考えられる理由は何ですか?

4

2 に答える 2

6

(実際に意味したのは、クエリは個別に終了しますが、それらの結合は終了しない場合があるということです)

ここで、Prolog の終了プロパティの非常に基本的な側面を発見しました。次の純粋な1プログラムでこれを見てみましょう。

canFind(mary, john).

canCall(mary, bob).
canCall(A, B) :-
   canCall(B, A).

?- canCall(mary, Person).
   Person = bob
;  ... 

?- canFind(mary, Person).
   Person = john.

すべてがうまく見えます!このコードをチェックインして、誰もが使えるようにしましょう。不運な同僚が次のことを試みます。

?- canCall(mary, Person), canFind(mary, Person).
* LOOPS *

いや、これはループだ!多分私は目標を並べ替える必要があります:

?- canFind(mary, Person), canCall(mary, Person).
* LOOPS *

また!

もちろん、あなたも動揺しています。結局、あなたはこのコードを入念にテストしました。そして終了しました。それともやった?

終了の 2 つの概念

これは、Prolog で最も紛らわしいことの 1 つです。クエリの終了について、(少なくとも) 2 つの異なる概念があります。あなたがテストしたものは(時々)実存的終了と呼ばれます。ただし、これを単にfind an answerと呼ぶことをお勧めします。あなたが経験したように、それは非常にもろいです。

そして、クエリが答えを見つけるだけでなく、それらすべてを見つけてクエリを終了する場合、これは普遍的な終了または単に終了と呼ばれます。Prolog プログラマーがクエリが終了すると言う場合、それは普遍的に終了することを意味します。

では、どうすれば普遍的な終了を観察できるでしょうか? 単純にすべての回答を求めてください。GNU-Prolog では、次のように入力しaます。SPACE他のシステムでは、またはそれが終了するまでハンマーで打たなければなりません。そうしないと;Return、疲れた目や手根管がそれを止めてしまいます。

?- canCall(mary, Person).
   Person = bob
;  Person = bob
;  Person = bob
;  Person = bob
;  Person = bob
;  ...

つまり、無限に多くの答えがあることがわかります (実際、私たち有限の存在はそれを証明する必要がありますが、今のところ私を信じてください)。

これを観察する安価な方法はありませんか?答えのテキストの壁がなければ?絶対に成り立たない条件を追加することで、答えを「オフ」にすることができますfalse

代わりに次のように尋ねます。

?-canCall(mary, Person), false .

そのようなクエリの結果はどうなるでしょうか? それは決してありえませんtruefalse終了する必要がある場合にのみ可能です。したがって、このクエリでは、プログラムの終了プロパティのみをテストするだけです。

これで、2 つの (普遍的に) 終了するクエリの結合は常に終了します。したがって、この種の終了ははるかに堅牢です。

ユニバーサル ターミネーションには、他にも優れた特性が多数あります。たとえば、節 (つまり、事実と規則) の順序を好きなように入れ替えることができます。どのような順序であっても、すべてのプログラムはまったく同じ終了プロパティを共有します。

もう 1 つは、プログラムの非終了のの助けを借りて簡単に突き止めることができることです。これで読み始めてください。

コマンド指向のプログラミング言語では、この概念はすぐには存在しません。ただし、イテレータを使用すると、非常によく似た概念があります。イテレータが最初のアイテムを生成する場合、それは存在の終了に対応し、有限数のアイテムが生成される場合、つまり、有限数nextの後に終了する場合、それは普遍的な終了に対応します。すこし。


1 実際、不純なプログラムでは、あらゆる種類の無意味な動作が発生します。したがって、それらを考慮することは無意味です。

于 2016-04-05T10:20:39.253 に答える
0

個別に実行Personすると、2 つの異なる値に統合されます。これをチェックして。

于 2016-04-05T08:09:31.117 に答える