我正在用prolog创建一个家谱。我遇到麻烦的地方是当我拜访姐妹或兄弟的时候。我得到的结果是正确的,其中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).发布于 2015-12-11 17:09:00
每一对兄弟姐妹都会有相同的父亲和相同的母亲(至少在更保守的社会中是这样,在你的计划中也是如此)。这就是你得到双重答案的地方。你可能会说,兄弟姐妹总是共享双亲?
发布于 2015-12-11 18:37:45
如上所述,你会得到双重答案,因为你正在检查它们是否有相同的父代,而它们有两个。此外,你得到了更多的解决方案,因为例如,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中获得一个唯一对的列表,例如,对于sister(X,Y,L),您将获得:
X = julie
L = [[julie, amanda], [julie, mike]]
X = amanda
L = [[amanda, julie], [amanda, mike]]稍微尝试一下,以获得您所需要的东西。
https://stackoverflow.com/questions/34219368
复制相似问题