我正在做一个基本的族谱计划,而且只打印一次列表就遇到了麻烦。
firstcousin(C,X) :-
grandparent(G,X),
grandparent(G,C),
C\=X,
\+sibiling(C,X).
它打印出正确的人,只是它列表两次。我知道这与祖父母有关,因为每个人都有两个祖父母。所以基本上它会看一个X
和C
的祖父母,然后看另一个祖父母。所以,总而言之,我只是不想重复表兄弟列表。
答案 0 :(得分:0)
问题在于,有四种方法可以检查是否有人是我的堂兄:我们要么分享我母亲的母亲,父亲的母亲,母亲的父亲或父亲的父亲。如果其中任何一个是真的(那个人不是我或我的兄弟姐妹),那么“某人”就是我的堂兄。 Prolog会尝试每一个选项,所以你可能会让你的堂兄四次列出!你可以看看我让两姐妹嫁给两个兄弟。
另一种看待它的方式:我可以通过两种方式走进树中找到谁是我的堂兄弟,而Prolog会尝试两种方式。在角落的情况下,有四种方式在树上行走。
无论如何,在这个具体的问题中,处理这个问题的一个好方法是在族谱树中没有两个级别来检查表兄弟。你可以说,如果我的一个父母和他的一个父母同胞,那么有人就是我的堂兄。请注意,这还没有解决角落的情况(现在有两种方式而不是四种方式),我会让你尝试解决。
firstcousin(C, X) :- parent(C, O), parent(X, T), C \= X, sibling(O, T).
另一个选择当然是编写firstcousins(C, X)
,其中X将是C的所有一级堂兄的列表,然后您可以检查新元素是否还不是列表的元素。变体包括计算整个列表然后删除重复项。我发现这种方法不如纯逻辑解决方案那么优雅。