我有事实:male
,female
和child
例如
/* tg and yem are mother and father. rika,kiku and susu are children*/
female(rika).
female(tg).
male(kiku).
male(susu).
male(yem).
child(rika,tg).
child(kiku,tg).
child(susu,tg).
child(rika,yem).
child(kiku,yem).
child(susu,yem).
现在我需要一个查询来提取姐妹关系,如
sister(Sister1,Sister2):-
female(Sister1),
child(Sister1,X),child(Sister2,X),
Sister1 \= Sister2.
但它会导致重复的回复。如何改进以获得单一答案?
答案 0 :(得分:2)
由于谓词始终终止,您可以使用谓词setof/3删除重复的解决方案:
?- setof(X-Y, sister(X,Y), Xs).
Xs = [rika-kiku, rika-susu].
第一个参数定义表示一个解决方案的术语模板,第二个参数定义要收集答案替换的目标,第三个参数是实例化模板术语列表。
如果父母有两个女儿成为姐妹,你仍然会有裁员。例如。如果你添加事实
female(ala).
child(ala,tg).
child(ala,yem).
到您的知识库,然后查询包含所有姐妹两次。
?- setof(X-Y, sister(X,Y), Xs).
Xs = [ala-kiku, ala-rika, ala-susu, rika-ala, rika-kiku, rika-susu].
一个原因是你用两个论点定义了你的谓词姐妹:姐妹是Sister1和她的兄弟姐妹之间的关系。 (你写它的方式,变量名Sister2给出了错误的直觉,兄弟姐妹也是女性,但这只是一个旁注)。如果我们只想知道谁是姐妹,这是一个集合(或一个地方的谓词) - 让我们称之为is_sister/1
:
is_sister(Xs) :-
setof(X, Y^sister(X,Y), Xs).
如果查看答案替换,查询setof(X, sister(X,Y), Xs).
和setof(X, Y^sister(X,Y), Xs).
会有很大差异。原因是Y
在第一个模板中是免费的,您将根据Y
的可能替换获得一组。在第二个例子中,Y^
绑定变量 - 我们在一个集合中获得X的所有实例化,与Y的绑定无关。