そう
?- canCall(mary, Person).
動作し、終了し、
?- canFind(mary, Person).
も動作し、終了します。でもなんとなく
?- canCall(mary, Person), canFind(mary, Person).
終了しません。考えられる理由は何ですか?
そう
?- canCall(mary, Person).
動作し、終了し、
?- canFind(mary, Person).
も動作し、終了します。でもなんとなく
?- canCall(mary, Person), canFind(mary, Person).
終了しません。考えられる理由は何ですか?
(実際に意味したのは、クエリは個別に終了しますが、それらの結合は終了しない場合があるということです)
ここで、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 *
また!
もちろん、あなたも動揺しています。結局、あなたはこのコードを入念にテストしました。そして終了しました。それともやった?
これは、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 .
そのようなクエリの結果はどうなるでしょうか? それは決してありえませんtrue
。false
終了する必要がある場合にのみ可能です。したがって、このクエリでは、プログラムの終了プロパティのみをテストするだけです。
これで、2 つの (普遍的に) 終了するクエリの結合は常に終了します。したがって、この種の終了ははるかに堅牢です。
ユニバーサル ターミネーションには、他にも優れた特性が多数あります。たとえば、節 (つまり、事実と規則) の順序を好きなように入れ替えることができます。どのような順序であっても、すべてのプログラムはまったく同じ終了プロパティを共有します。
もう 1 つは、プログラムの非終了の原因を failure-sliceの助けを借りて簡単に突き止めることができることです。これで読み始めてください。
コマンド指向のプログラミング言語では、この概念はすぐには存在しません。ただし、イテレータを使用すると、非常によく似た概念があります。イテレータが最初のアイテムを生成する場合、それは存在の終了に対応し、有限数のアイテムが生成される場合、つまり、有限数next
の後に終了する場合、それは普遍的な終了に対応します。すこし。
1 実際、不純なプログラムでは、あらゆる種類の無意味な動作が発生します。したがって、それらを考慮することは無意味です。
個別に実行Person
すると、2 つの異なる値に統合されます。これをチェックして。