我正在尝试编写一个gprolog程序,该程序可以确认,基于这首歌(在这里听 :-))的一些“合理”的背景知识,当我查询grandpa(me, me)
时(即,我真的是我自己的祖父吗?),它会回答是。这是我人工智能课程的一个作业,我们被要求自己决定要包含哪些事实和谓词。尽管它充满了冗余和一些我没有使用的条款(有些只是为了这首歌),但这是我拼凑起来的,必要的假设是继子女被视为完全/一般的子女:
3 male(me). 4 male(mydad). 5 male(mybaby). 6 female(widow). 7 female(redhead). 8 grandma(Z, X) :- female(Z), child(Z, Y), child(Y, X). 9 grandpa(Z, X) :- male(Z), child(Z, Y), child(Y, X). 10 child(me, mydad). 11 child(redhead, widow). 12 child(mybaby, me). 13 child(A, B) :- married(B, C), married(A, D), child(D, C). 14 child(C, A) :- married(A, B), child(C, B). %step children as children 15 married(me, widow). 16 married(widow, me). 17 married(mydad, redhead).
这有点草率,但我认为最重要的是第13和14条款。特别是,第14条款试图确保,例如,我的父亲是我的孩子,因为他嫁给了我的继子女,因此是我的女婿。
无论如何,追踪显示运行查询似乎有效——某种程度上:
{trace}| ?- grandpa(me, me). 1 1 Call: grandpa(me,me) ? 2 2 Call: male(me) ? 2 2 Exit: male(me) ? 3 2 Call: child(me,_366) ? 3 2 Exit: child(me,mydad) ? 4 2 Call: child(mydad,me) ? 5 3 Call: married(me,_415) ? 5 3 Exit: married(me,widow) ? 6 3 Call: married(mydad,_440) ? 6 3 Exit: married(mydad,redhead) ? 7 3 Call: child(redhead,widow) ? 7 3 Exit: child(redhead,widow) ? 4 2 Exit: child(mydad,me) ? 1 1 Exit: grandpa(me,me) ? true ? (2 ms) yes
我担心的是true?
语句。如果我只是按回车键,yes
就会出现,但输入像a
这样的东西会导致无限循环,每轮调用堆栈都会变得越来越大,然后再次出现“true”。这是怎么回事?我以为查询的成功“确认”意味着事情的结束。我看不到还有其他变量需要检查!
回答:
true
和yes
的使用是为了区分是否可能有更多的解。Prolog可以检查证明堆栈,寻找选择点,即等待被否定的替代计算的地方。
按a
,你会强调导致悖论的主循环:
... Redo: (31) child(redhead, me) Call: (32) married(me, _G2289) Exit: (32) married(me, widow) Call: (32) child(redhead, widow) Exit: (32) child(redhead, widow) Exit: (31) child(redhead, me) Exit: (30) child(redhead, widow) Exit: (29) child(redhead, me) Exit: (28) child(redhead, widow)...
(注意:使用SWI-Prolog获得的追踪,请忽略小的差异)