【问题标题】:SWI-Prolog family tree parent_of/2SWI-Prolog 家谱 parent_of/2
【发布时间】:2017-03-30 08:00:06
【问题描述】:
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)。它确实解决了这个问题,但我需要使用相同的谓词来定义它。

非常感谢任何帮助。

已编辑

本练习的目的是编写规则,以便您可以完成此家谱,尽管只给出了最少的事实。如您所见,它仅说明 Warren 是 Jerry 的父亲,而从兄弟姐妹的事实来看,我们知道 Jerry 是 Stuart 和 Kather 的兄弟。所以我会有一个规则,parent_of(X, Y) 来推断 Warren 也是 Stuart 和 Kather 的父亲,尽管这在上面的事实中没有说明。

主要关心的是如何编写我的parent_of(X, Y) 规则以避免它陷入无限循环。

【问题讨论】:

    标签: prolog


    【解决方案1】:

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

    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
    

    【讨论】:

    • 也许我不够清楚。让我们将其简化为我的问题的更简单版本。我只知道 Warren 是 Jerry 的父亲,那么我必须写一个规则来推断 Warren 也是 Stuart 和 Kather 的父亲。您可以忽略此兄弟(X,Y)规则并用兄弟和姐妹事实代替。主要关心的是如何编写 parent_of(X, Y) 规则以避免无限循环。
    • @Da_Pz 您应该始终致力于将任何问题简化为最简单的版本,否则您只会混淆想要提供帮助但不得不猜测您的问题的随机陌生人。
    • @Da_Pz 现在我写了一个答案之后,也许是错误的问题....你不要先在问题中简化你的问题(不要在评论中回答错误的问题)然后也许我试着回答?
    • @Da_Pz 只是一个简短的评论,因为孩子来自母亲而不是父亲(即使父亲也把一半的孩子放在母亲身上)也许最好有一个事实,说明谁是母亲而不是父亲?也可能不是。
    • 嗨@User9213,是的,我们总是可以编写像 father(X, Y)mother(X, Y) 这样的规则,但只能基于根据我们得到的事实。但是,我认为它对定义我的 parent_of(X, Y) 规则没有帮助。至于谁是孩子的父亲/母亲,我们肯定要使用谓词parent_of。如果要将 parent_of(X, Y) 定义为 (father(X, A) ; mother(X,A)),sibling(A, Y),fathermother谓词的调用会再次调用parent_of,从而进入无限循环。
    【解决方案2】:

    我看不到直接解决您问题的方法。但是,如果您的 Prolog 提供 tabling,这是一个简单的方法:

    :- use_module(library(@987654322@)). ... :- 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.

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-03-17
      • 1970-01-01
      • 2017-07-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-02-08
      • 1970-01-01
      相关资源
      最近更新 更多