prolog查询中的单例变量

时间:2013-12-16 01:06:23

标签: prolog

我是Prolog的新手,遇到了问题。当我在下面的数据中询问?-grandfather(daniel,george)时,我的答案是错误的。我不明白为什么我的查询不起作用。我还收到一条警告消息,指出 [C,D]是单例变量。此警告不再发生。再说一遍,我不确定为什么。

mother(jules,mary).
mother(jules,martha).
mother(jules,andy).
mother(mary,annie).
mother(mary,george).
mother(martha,jesse).
mother(martha,june).
mother(june,camile).
father(daniel,mary).
father(daniel,martha).
father(daniel,andy).
father(adrian,annie).
father(adrian,george).
father(carlo,camile).

brothers(A,B):-father(C,A),father(C,B);mother(D,A),mother(D,B).

grandfather(E,W):-father(E,father(C,W));father(E,mother(D,W)).

2 个答案:

答案 0 :(得分:1)

您可以更简单地编写祖父查询:

grandfather(E,W):-father(E,A),father(A,W).
grandfather(E,W):-father(E,A),mother(A,W).

grandfather(E,W):-father(E,A),father(A,W);father(E,A),mother(A,W).

现在:

6 ?- grandfather(daniel,george).
true .
7 ?- grandfather(daniel,annie).
true .

在这里,我们要求Prolog找到E的孙子:E是A的父亲,A是W的父亲/母亲。

或者更具体地说,检查一下丹尼尔是否有一个名叫乔治的孙子。 Prolog检查:丹尼尔有一个女儿玛丽,玛丽有一个儿子乔治。所以它会回归真实。如果你trace,你会看到:

[trace] 3 ?- grandfather(daniel,george).
   Call: (6) grandfather(daniel, george) ? creep
   Call: (7) father(daniel, _G1931) ? creep
   Exit: (7) father(daniel, mary) ? creep
   Call: (7) father(mary, george) ? creep
   Fail: (7) father(mary, george) ? creep
   Redo: (7) father(daniel, _G1931) ? creep
   Exit: (7) father(daniel, martha) ? creep
   Call: (7) father(martha, george) ? creep
   Fail: (7) father(martha, george) ? creep
   Redo: (7) father(daniel, _G1931) ? creep
   Exit: (7) father(daniel, andy) ? creep
   Call: (7) father(andy, george) ? creep
   Fail: (7) father(andy, george) ? creep
   Redo: (6) grandfather(daniel, george) ? creep
   Call: (7) father(daniel, _G1931) ? creep
   Exit: (7) father(daniel, mary) ? creep
   Call: (7) mother(mary, george) ? creep
   Exit: (7) mother(mary, george) ? creep
   Exit: (6) grandfather(daniel, george) ? creep
true .

[C,D] are singleton variables表示子句中只有一个或多个变量出现一次。这不会影响程序,您仍然可以运行查询。

Singleton Variables on SWI Documentation

答案 1 :(得分:0)

  

感谢您的回答,最后一个问题,我试图为像这样的堂兄弟做一个规则

     

表亲(X,Y): - 母亲(A,X),母(B,Y),母亲(d,A),母亲(d,B),父亲(C,A),父亲(C, B)。

     

它说如果X的母亲和Y的母亲有相同的母亲和父亲X,Y是表兄弟。但是当我问这个问题的时候? - 堂兄弟(安妮,乔治)prolog回答是,而且不应该那样,因为安妮和乔治都是兄弟,所以我猜必定存在逻辑错误

A和B(X和Y的母亲)可以是平等的,这就是为什么它给兄弟们提供了。

您应该指定他们没有相同的母亲和父亲(A \ = B)。


关闭问题:

使用“父”可以减少您在这类问题(家谱)中的编码。

mother(A,B) :- parent(A,B).

甚至:

mother(A,B) :- parent(A,B), female(A).

通过这种方式,您不需要将表亲问题(或任何此类问题,如兄弟)应用于母亲和父亲。

在兄弟们中:

brothers(A,B):-father(C,A),father(C,B);mother(D,A),mother(D,B).

可能是:

brothers(A,B):-parent(X,A),parent(X,B).