【问题标题】:Node has no descendant节点没有后代
【发布时间】:2016-03-25 14:38:43
【问题描述】:

我有一个规则

% X is descendant of Y
descendant(X,Y) :-

我正在尝试编写一个规则来找出哪个节点没有后代。我如何告诉 prolog 我想找到每个失败的 X descendant(X,_)

我试过了,结果不正确。

nodescendants(X) :- \+(descendant(X, _)).

编辑以更新我的问题。实际上我发现的更严格。

鉴于以下事实和规则。

cyborg(greatgrandparent).
cyborg(grandparent).

female(parent).

male(child).

cyborg(child2).

female(jr_child).

parent(greatgrandparent, grandparent).
parent(grandparent, parent).
parent(parent, child).
parent(parent, child2).
parent(child, jr_child).

% X is descendant of Y
descendant(X,Y) :-

% C is cyborg descendant of Y
cyborg_descendant(C,Y) :-

is_human_or_cyborg(X) :-
      human(X)
   ;  cyborg(X).

has_no_cyborg_descendants(X) :-
   is_human_or_cyborg(X),
   \+(cyborg_descendant(_, X)).

当我跑去寻找所有没有电子人后代的人(电子人+所有人类)时,“祖父母”被标记为真,这不应该是这种情况。作为祖父母 -> 父母 -> child2 这是一个机器人。

?- has_no_cyborg_descendants(X).
X = child ;
X = jr_child ;
X = grandparent ;
X = child2.

【问题讨论】:

  • 这个问题的解决方案实际上是在你非常相似的问题的答案中提供的,Select list out of a list?。为了生成非后代,您需要一种方法来确定X 是否是有效的后代(存在于“所有可能后代的宇宙”中)。
  • @lurker 更新了我的问题
  • cyborg_desccendant(child2, grandparent) 失败,因为在您的定义中 grandparent 必须是 child2 的父级(它不是),或者 child2 必须有一个父级是 @ 的 cyborg 后代987654332@,它没有。所以grandparent,根据你的cyborg_descendant 逻辑,没有半机械人后代(cyborg_descendant(_, grandparent) 失败)。
  • 顺便说一句,您需要将相似的事实组合在一起。所以将cyborg/1 事实和female/1 事实放在一起。如果它们不连续,并非所有 Prolog 解释器都会看到您的所有事实。您可能会看到警告,例如 warning: discontiguous predicate cyborg/1 - 从句被忽略(来自 GNU Prolog)。
  • @lurker 好吧。我将不得不仔细考虑这一点,以确保它是错误的,只要沿着链条向下的任何后代都是机器人

标签: prolog


【解决方案1】:

你是说grandparent 应该有一个 cyborg 后代由于后代:grandparent -> parent -> child2。但是,以下查询失败:

cyborg_descendant(child2, grandparent).

其实这个查询也失败了:

cyborg_descendant(_, grandparent).

很明显cyborg_descendant/2 的逻辑有问题。这导致has_no_cyborg_descendants(grandparent) 成功。

此外,您在拆分相似的事实时遇到了问题。 Prolog 期望将类似的事实(具有相同函子名称的事实)组合在一起,或者可能会忽略某些事实。所以如下:

cyborg(greatgrandparent).
cyborg(grandparent).

female(parent).

male(child).

cyborg(child2).

female(jr_child).

可能导致female(jr_child)cyborg(child2) 被忽略。 Prolog 解释器对此发出警告。您应该将其重写为:

cyborg(greatgrandparent).
cyborg(grandparent).
cyborg(child2).

female(parent).
female(jr_child).

male(child).

【讨论】:

    【解决方案2】:

    你写 nondescendant/1 的方式你没有描述任何匹配的东西,只是不匹配的东西。如果您想要具体的答案,请指定您要查找的内容。例如:如果您有一个谓词 person/1 来描述所有已知的人,并且您想知道其中谁不是后代,您可以要求一个不是后代的人:

    person(a).
    person(b).
    person(c).
    person(d).
    
    descendant(a,b).
    descendant(b,c).
    descendant(c,d).
    
    nondescendant(X) :-
        person(X),
        \+(descendant(X,_)).
    
    
    ?- nondescendant(X).
    X = d
    

    或者坚持你对 nondescendant/1 的定义并将其与另一个目标结合使用:

    ?- person(X), nondescendant(X).
    X = d
    

    【讨论】:

    • 更新了我的问题。我试过你的方法,如果只有一种人,效果很好,但现在我有 3 种不同的person
    【解决方案3】:

    实际上,当用于特定节点时,您的 nodescendants/1 谓词可以正常工作。

    如果您想找到所有 X,请使用findall/3。但是解释器必须知道要考虑哪些节点,所以你也需要考虑到这一点。你不能指望解释器自己找出所有节点。

    【讨论】:

      猜你喜欢
      • 2011-05-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-07-23
      • 2015-02-20
      • 2017-07-12
      • 2017-05-01
      • 1970-01-01
      相关资源
      最近更新 更多