Prolog 根据他们拥有的孩子数量显示相同数量的输出

问题描述

我有以下事实和规则:

/* fact */
parent(parent1,child1).
parent(parent2,child1).
parent(parent1,child2).
parent(parent2,child2).
parent(parent1,child3).
parent(parent2,child3).
parent(parent1,child4).
parent(parent2,child4).

/* rule */
spouse(X,Y):- parent(X,Z),parent(Y,X \= Y.

但是当我尝试执行时:

spouse(X,parent1).

这些是输出

X = parent2;
X = parent2;
X = parent2;
X = parent2;
false.

似乎相同输出数量是基于他们拥有的孩子数量输出应该是唯一的 parent2。我可以知道如何解决这个问题吗?

解决方法

您可以使用 setof/3 告诉 Prolog“将它们全部收集到一个集合中”并输出该集合,自然消除重复项:

parent(parent1,child1).
parent(parent2,child1).
parent(parent1,child2).
parent(parent2,child2).
parent(parent1,child3).
parent(parent2,child3).
parent(parent1,child4).
parent(parent2,child4).

spouse(X,Y):-
   parent(X,Z),parent(Y,X \= Y.
   
spouse_unique(X,Y) :-
   setof([Xso,Yso],spouse(Xso,Yso),Set),format("Collected the set ~q~n",[Set]),member([X,Y],Set).

此处,member/2 调用在重做时从 Set 中挑选元素。

?- spouse_unique(X,Y).
Collected the set [[parent1,parent2],[parent2,parent1]]
X = parent1,Y = parent2 ;
X = parent2,Y = parent1.
?- spouse_unique(X,parent1).
Collected the set [[parent1,parent1]]
X = parent2.
,

在 SWI-Prolog 中,不需要更改程序。您只需要使用元谓词 distinct/1:

?- distinct(spouse(X,parent1)).
X = parent2 ;
false.

?- distinct(spouse(X,Y)).
X = parent1,Y = parent1 ;
false.