male(jerry).
male(stuart).
male(warren).
male(peter).
female(kather).
female(maryalice).
female(ann).
brother(jerry,stuart).
brother(jerry,kather).
brother(peter, warren).
sister(ann, maryalice).
sister(kather,jerry).
parent_of(warren,jerry).
parent_of(maryalice,jerry).
我得到了上述事实,我需要使用谓词 parent_of 来定义规则。是的,它与parent_of定义的上述事实是相同的谓词。
假设我有sibling(X, Y)
规则将返回所有正确的兄弟对。
我将parent_of(X, Y)
规则写为parent_of(X, Y) :- parent_of(X, A), sibling(A, Y).
然而,这个实现将引导我进入无限循环。
有没有办法定义规则parent_of(X, Y)
,使其返回
(warren, jerry),
(warren, stuart),
(warren, kather),
(maryalice, jerry),
(maryalice, stuart),
(maryalice, kather)
我也试过
parent_of(X, Y) :-
parent_of(X, jerry),
brother(jerry, Y).
我可以通过这种方式获得正确的答案,但最终出现在“Out of local stack”错误中。除此之外,我认为规则没有问题,因为我对它进行了硬编码。
我看到过将规则名称更改为其他内容的建议,例如another_parent_of(X, Y)
。它确实解决了这个问题,但是我需要使用相同的谓词来定义它。
非常感谢任何帮助。
EDITED
本练习的目的是编写规则,以便您可以完成此族谱,尽管只给出了最小的事实。正如你所看到的,它只说Warren是Jerry的父亲,从兄弟姐妹的事实来看,我们知道Jerry是Stuart和Kather的兄弟。因此,我将有一个规则,parent_of(X, Y)
推断出沃伦也是斯图亚特和凯瑟的父亲,尽管上面的事实没有说明。
主要关注的是我如何编写parent_of(X, Y)
规则以避免它进入无限循环。
答案 0 :(得分:1)
我不明白为什么你需要在parent_of
的定义中使用sibling
。你为什么不写:
sibling(X, Y) :-
parent_of(Parent, X),
parent_of(Parent, Y).
我也不理解你所获得的事实的逻辑。您有male
和female
,但您还有brother
和sister
;为什么不用“兄弟是男性兄弟姐妹”和“姐妹是女性兄弟姐妹”来定义brother
和sister
?我已经在上面展示了如何定义“兄弟姐妹有同一个父母”。
无论如何,这真是一个古老的疲惫问题,令人惊讶的是,“Prolog家族之树”多次被反刍。
the cow the old cow she is dead
it sleeps well the horned head
we poor lads tis our turn now
to hear such tunes as killed the cow
答案 1 :(得分:0)
我看不到直接解决问题的方法。但如果你的Prolog提供tabling,这是一个简单的方法:
:- use_module(library(tabling)).
...
:- table parent_of/2.
parent_of(warren,jerry).
parent_of(maryalice,jerry).
parent_of(X, Y) :- parent_of(X, A), sibling(A, Y).
...
?- parent_of(X,Y).
X = warren,
Y = stuart ;
X = warren,
Y = jerry ;
X = warren,
Y = kather ;
X = maryalice,
Y = stuart ;
X = maryalice,
Y = jerry ;
X = maryalice,
Y = kather.