2

我正在努力在序言中创建一个家谱。当我拜访姐妹或兄弟时,我遇到了麻烦。我得到的结果是正确的,其中 julie 是 mike 的妹妹,julie 是 amanda 的妹妹,amanda 是 mike 的妹妹,amanda 是 julie 的妹妹。但是会发生什么而不是在那里结束,如果我继续按“n”键,它将再次循环返回结果。为什么会这样?

parent(pete,mike).
parent(pete,julie).
parent(pete,amanda).
parent(mary,mike).
parent(mary,julie).
parent(mary,amanda).
female(mary).
female(julie).
female(amanda).
male(mike).
male(pete).



mother(X,Y):-
    parent(X,Y),
    female(X).

father(X,Y):-
    parent(X,Y),
    male(X).

sibling(X,Y):-
    parent(Z,X),
    parent(Z,Y),
    X\=Y.

sister(X,Y):-
    sibling(X,Y),
    female(X).

brother(X,Y):-
    sibling(X,Y),
    male(X).
4

2 回答 2

1

如前所述,您会得到双重答案,因为您正在检查他们是否有相同的父母,并且他们有两个。此外,您将获得更多解决方案,因为例如 mike 是 amanda 的兄弟,而且 amanda 是 mike 的兄弟,您没有采取任何措施来阻止这两种解决方案的出现。所以而不是:

sibling(X, Y):-
    parent(Z, X),
    parent(Z, Y),
    X\=Y.

要解决两个父母的问题,你可以说他们总是共享两个父母:

sibling(X, Y):-
    mother(Z, X),
    mother(Z, Y),
    father(W, X),
    father(W, Y),
    X\=Y.

你可以通过引入@<来解决第二个问题(X=mike, Y=amanda; X=amanda, Y=mike):

sibling(X, Y):-
    mother(Z, X),
    mother(Z, Y),
    father(W, X),
    father(W, Y),
    X@<Y.

这样,只会出现一组解决方案,但您必须小心,因为它可能无法满足您的需求,具体取决于您想要实现的目标(X=julie,Y=amanda 在这个案例)。

根据需要,也许更优雅和通用的解决方案(不要求父母双方相同)将 setof (http://www.swi-prolog.org/pldoc/doc_for?object=setof/3)与您的原来的兄弟条款,但你会修改你的兄弟/姐妹条款,例如:

sibling(X, Y):-
    parent(Z, X),
    parent(Z, Y),
    X\=Y.

sister(X,Y,L):-
    female(X),
    setof([X, Y], (sibling(X, Y)), L).

brother(X,Y,L):-
    male(X),
    setof([X, Y], (sibling(X, Y)), L).

这将为您提供列表 L 中唯一对的列表,例如,对于您得到的姐妹(X,Y,L):

X = julie
L = [[julie, amanda], [julie, mike]]

X = amanda
L = [[amanda, julie], [amanda, mike]]

稍微玩一下以获得您需要的东西。

于 2015-12-11T10:37:45.490 回答
1

每对兄弟姐妹都会有同一个父亲同一个母亲(至少在更保守的社会中,在你目前的计划中)。这是你得到双重答案的地方。你也许可以说兄弟姐妹总是共享双亲

于 2015-12-11T09:08:59.833 回答