1
votes

I have facts: male, female and child.
eg.

/* 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).

Now I need a query to extract sister relation like

sister(Sister1,Sister2):-
     female(Sister1),
     child(Sister1,X),child(Sister2,X), 
     Sister1 \= Sister2.

But it results duplicate responses. How can I improved to get single answers?

1
Do you mean to write a relationship between two sisters, or is only one of the two arguments supposed to be a sister? (The variable names claim both, the implementation claims only one) - user1812457

1 Answers

2
votes

Since your predicate always terminates, you can use the predicate setof/3 to remove duplicate solutions:

?- setof(X-Y, sister(X,Y), Xs).
Xs = [rika-kiku, rika-susu].

The first argument defines a term template representing one solution, the second defines the goal of which you want to collect the answer substitutions and the third argument is the list of instantiated template terms.

You will still have redundancy if a parent has two daughters, which become sisters. E.g. if you add the facts

female(ala).
child(ala,tg).
child(ala,yem).

to your knowledgebase, then the query contains all sisters twice.

?- setof(X-Y, sister(X,Y), Xs).
Xs = [ala-kiku, ala-rika, ala-susu, rika-ala, rika-kiku, rika-susu].

One reason is that you defined your predicate sister with two arguments : sister is a relation between Sister1 and her sibling. (The way you wrote it, the variable name Sister2 gives the wrong intuition that the sibling is also female, but that's just a side note). If we only want to know who is a sister, this is a set (or one-place predicate) - let's call it is_sister/1:

is_sister(Xs) :-
  setof(X, Y^sister(X,Y), Xs).

If you look at the answer substitutions, the queries setof(X, sister(X,Y), Xs). and setof(X, Y^sister(X,Y), Xs). differ a lot. The reason is that Y is free in the first template and you will receive a set depending on the possible substitutions of Y. In the second example, the Y^ binds the variable - we obtain all instantiations of X in one set, independent of the binding of Y.