Josh
Josh

Reputation: 657

Duplicate results in prolog

I'm terrible with prolog. I keep getting a duplicate result in this simple code"

mates(bob, john).
mates(bob, bill).
mates(andrea, sara).
mates(andrea, bill).
friends(X, Y) :- mates(X, Z), mates(Y, Z).

Calling friends(bob, X). I get bob twice. If only I could use and IF statement argh!!!

How can I elimiate duplicate results? IE If(result1 == result2) dont print;

Im looking for similar friends, ie the result should be bob and andrea (because of bill).

Upvotes: 1

Views: 2427

Answers (2)

尾崎隆大
尾崎隆大

Reputation: 158


mates(bob, john).
mates(bob, bill).
mates(andrea, sara).
mates(andrea, bill).

friends(X, Y) :-
        setof([X,Y],(friends2(X,Y),\+(X=Y)),L),
        append(L0,[[X,Y]|_],L),
        \+(append(_,[[Y,X]|_],L0)).

friends2(X, Y) :- mates(X, Z), mates(Y, Z).
friends2(X, Y) :- mates(X, Z), mates(Z, Y).
friends2(X, Y) :- mates(Z, X), mates(Z, Y).
friends2(X, Y) :- mates(Z, X), mates(Y, Z).

Upvotes: 1

Nicholas Carey
Nicholas Carey

Reputation: 74177

Shouldn't it be more along these lines?

friends( X , Y ) :- mates( X , Y ).
friends( X , Y ) :- mates( X , T ) , mates( T , Y ).

If you want similar friends (per your comment below), try:

friend( X , Y ) :-
  mates( X , T ) ,
  mates( Y , T ) ,
  X \= Y .

The \= operator means 'not unifiable with', so that should exclude cases where party A is friends with his- or herself. The exact operator for 'not unifiable with' might vary depending on implementation.

Also bear in mind that the "correct" solution is a bit more convoluted than it might seem the mates relationship is transitive: if Andrea is a mate of Bills, the presumably Bill is a mate of Andrea's. You solution should likely take that into account.

Upvotes: 3

Related Questions