次の gprolog プログラムがあります。
father(charles, harry).
daughter(elizabeth, george).
son(william, charles).
father(X, Y) :- son(Y, X).
father(X, Y) :- daughter(Y, X).
daughter(X, Y) :- \+son(X, Y), father(Y, X).
son(X, Y) :- \+daughter(X, Y), father(Y, X).
私が持っているものを考えて、私はこのクエリを試しました:
| ?- son(harry, charles).
...そして、no
(別名、私が理解していることから、「Prologはこれを証明できません。」)を得ました。トレースを実行したところ、あまり役に立たなかったようです。
{trace}
| ?- son(harry, charles).
1 1 Call: son(harry,charles) ?
1 1 Fail: son(harry,charles) ?
son(harry, charles)
私のコードの最後の行まで一致するはずなので、プログラムは最初の部分をチェックするだけで始まると思いました: \+daughter(X, Y)
(「プロローグはハリーがチャールズの娘であることを証明できません」よね?)。それはそう:
| ?- \+daughter(harry, charles).
1 1 Call: \+daughter(harry,charles) ?
2 2 Call: daughter(harry,charles) ?
2 2 Fail: daughter(harry,charles) ?
1 1 Exit: \+daughter(harry,charles) ?
(1 ms) yes
では、第二部に進むということでしょうか。father(Y, X)
つまり、father(charles, harry)
事実として与えられた をチェックします!
| ?- father(charles, harry).
1 1 Call: father(charles,harry) ?
1 1 Exit: father(charles,harry) ?
(1 ms) yes
これらの両方が真であるのに、なぜyes
forが与えられないのson(harry, charles)
でしょうか? 重要な注意として、これは不連続な述語の警告でコンパイルされました。
compiling /Users/nicolejulian/Dropbox/AI/test.pl for byte code...
/Users/nicolejulian/Dropbox/AI/test.pl:4: warning: discontiguous predicate father/2 - clause ignored
/Users/nicolejulian/Dropbox/AI/test.pl:5: warning: discontiguous predicate father/2 - clause ignored
/Users/nicolejulian/Dropbox/AI/test.pl:6: warning: discontiguous predicate daughter/2 - clause ignored
/Users/nicolejulian/Dropbox/AI/test.pl:7: warning: discontiguous predicate son/2 - clause ignored
/Users/nicolejulian/Dropbox/AI/test.pl compiled, 8 lines read - 617 bytes written, 11 ms
(1 ms) yes
以前のいくつかの実験では、基本的に警告と無限ループのどちらかを選択できるように見えたので、そのまま使用しました。(たとえば、左側のラベルをすべてグループ化すると、警告は削除されますが、クエリ| ?- father(elizabeth, george).
がクラッシュする原因になります)。
いずれにせよ、「ごまかして」son(harry, charles)
事実として付け加えることができないとすれば、Prolog の実行ステップについて何が理解できないのでしょうか?