节点没有后代

时间:2016-03-25 14:38:44

标签: prolog

我有一条规则

% 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.

3 个答案:

答案 0 :(得分:2)

你编写nondescendant / 1的方式你没有描述任何东西只匹配不匹配的东西。如果您想要具体的答案,请指明您要查找的内容。例如:如果你有一个描述所有已知人的谓词人/ 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

答案 1 :(得分:2)

你是说grandparent由于下降而应该有一个机器人后裔: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 :(得分:0)

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

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