SWI-Prolog家族树parent_of / 2

时间:2017-03-30 08:00:06

标签: prolog

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)规则以避免它进入无限循环。

2 个答案:

答案 0 :(得分:1)

我不明白为什么你需要在parent_of的定义中使用sibling。你为什么不写:

sibling(X, Y) :-
    parent_of(Parent, X),
    parent_of(Parent, Y).

我也不理解你所获得的事实的逻辑。您有malefemale,但您还有brothersister;为什么不用“兄弟是男性兄弟姐妹”和“姐妹是女性兄弟姐妹”来定义brothersister?我已经在上面展示了如何定义“兄弟姐妹有同一个父母”。

无论如何,这真是一个古老的疲惫问题,令人惊讶的是,“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.