首页 > 解决方案 > 序言,在查询中重复

问题描述

我正在尝试在 prolog 中构建一个家族树,但是当siblings(X,Y).作为查询输入时,我得到重复打印,有人知道为什么吗?

例如:

parent_of(abraham, herb).
parent_of(mona, herb).
parent_of(abraham, homer).
parent_of(mona, homer).

我的规则是:

sibilings(P1,P2):-
parent_of(Parent,P1), parent_of(Parent,P2), P1 \= P2.

我知道它打印了两次,因为它为每个父母打印一次,但我是 Prolog 的新手,我不知道如何解决它。

标签: prologfamily-tree

解决方案


好吧,从逻辑上讲,Prolog 正在做正确的事情。如果 P1 和 P2 不同但共享父级,则您说 P1 和 P2 是兄弟姐妹。当你要求它生成时,它会定位 P1 = herb,P2 = homer,Parent = abraham,然后它会定位 P1 = herb,P2 = homer,Parent = mona。您没有Parent出现在规则的开头,但是 Prolog 找到的证明是不同的,所以它是一个不同的解决方案。

稍后,Prolog 还将注意到 P1 = homer,P2 = Herb,Parent = abraham,并为您提供第三个相同的解决方案。然后它会注意到 Parent = mona 并第四次将它们给你。

您可以通过对兄弟姐妹引入排序约束来消除一半的额外解决方案。你会说 P1 按字母顺序比 P2 早,基本上:

siblings(S1, S2) :- parent_of(Parent, S1), parent_of(Parent, S2), S1 @> S2.

不过,您仍然会得到有关其他父母的重复信息。无论如何,这有点作弊,因为您追求的是整个结果集的属性,但是您处于生成一个结果的规则之内。我承认我不知道一个很好的技巧来处理你从具有相同父亲和母亲的兄弟姐妹那里得到的重复。也许另一个回答者会带着我没有想到的显而易见的事情来。

另一种方法是收集独特的解决方案,如下所示:

?- setof(S1-S2, siblings(S1, S2), Solutions).
Solutions = [homer-herb].

现在,Prolog 正在通过将结果放入一个集合中来为您提供独一无二的结果。


推荐阅读