【发布时间】:2013-06-28 00:11:36
【问题描述】:
我有以下 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)(“Prolog 无法证明 Harry 是 Charles 的女儿”,正确的?)。确实:
| ?- \+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 一个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 的执行步骤有什么不了解的地方?
【问题讨论】: