我正在尝试在我的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.
答案 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.
(这个;
对两个条款有点主观,所以我不会过多地争论它......只要知道两种方式都是可能的,并且会产生相同的结果)