Prolog程序中的存在异常

时间:2012-04-20 03:03:08

标签: prolog

我正在尝试在我的prolog程序中编写一条规则,以确定某人是否是其他人的兄弟。

例如,如果我键入brother_of(chris,X),它将返回christy,因为chris是christy的兄弟。但是,当我键入它时,我得到一个存在异常。我已经包含了涵盖所有内容的事实,但也许这是我的规则定义中的一个问题?代码如下。

/* Facts */
female(ella).
female(jodi). 
female(sonya).
female(jane). 
female(christy). 
female(mary).
male(arnold).
male(chris).
male(louis).
male(mark).  
father(arnold).
father(louis).
father(mark).
mother(ella).
mother(jodi).
mother(jane).
mother(mary).
father_of(arnold, chris). /* arnold is the father of chris */
father_of(arnold, christy).
father_of(louis, mark).
father_of(mark, arnold). 
mother_of(mary, chris).
mother_of(mary, christy).          
mother_of(jane, arnold).    
mother_of(ella, sonya).
mother_of(jodi, ella).
mother_of(jodi, mark).

/* Rules */

brother_of(X, Y) :-
    male(X),
    ((father_of(Z, X), father_of(Z, Y));
    (mother_of(W, X), mother_of(W, Y))),
    X =\= Y.

1 个答案:

答案 0 :(得分:1)

运算符=\=仅用于算术(AFAIK),以查看两个术语是否不同(不可统一)使用运算符\=

X \= Y.

更新:cut!)目标的简要介绍:当在谓词中使用剪切时,这意味着除了已找到的(即你在搜索树中“切割剩余的分支”)。例如:

first_child(X,Y) :-
    father_of(X,Y), !.

?- first_child(arnold,Y).

Y = chris ;

no

达到切割后,所有选择点切割之前都会被丢弃(但可以在之后创建新的选择点)。在你的例子中,你知道如果X和Y拥有相同的父亲,那么如果他们也拥有相同的母亲则无关紧要。因此,您可以在“共同父亲”部分成功之后立即进行裁剪:

brother_of(X, Y) :-
    male(X),
    ((father_of(Z, X), father_of(Z, Y), X \= Y, !); # If cut is reached, will not run the next line
    (mother_of(W, X), mother_of(W, Y), X \= Y)).

但请注意,使用剪切有许多陷阱(请参阅链接的维基百科文章中的“绿色剪切”与“红色剪切”),但这里描述的内容太多了。 (注意我如何重复X \= Y - 如果我不这样做,程序有时会失败)

最后,我还想指出在编写Prolog代码时经常不鼓励使用;(尽管可以在需要时使用)。相反,将它写在两个子句中:

brother_of(X, Y) :-
    male(X),
    father_of(Z, X),
    father_of(Z, Y), 
    X \= Y,
    !.
brother_of(X, Y) :-
    male(X),
    mother_of(W, X),
    mother_of(W, Y), 
    X \= Y.

(这个;对两个条款有点主观,所以我不会过多地争论它......只要知道两种方式都是可能的,并且会产生相同的结果)