Search code examples
prologprolog-dif

How to properly express inequality in prolog?


TL;DR: sibling(a,X) succeeds with the answer X = a, but sibling(a,a) fails.


I have the following Prolog file:

children(a, c).
children(a, d).
children(b, c).
children(b, d).

sibling(X, Y) :-
   X \== Y, A \== B,
   children(X, A), children(X, B),
   children(Y, A), children(Y, B).

It seems clear enough to me, two person are siblings if their parents are the same. Also, a person is not their own sibling.

But when I tried to run some queries on GNU Prolog, I get some strange results:

| ?- sibling(a, b).

true ? a

true

true

yes

This is the intended behavior. a and b are siblings. There are three results, which is a bit weird, but I assume Prolog is binding A = c, B = d and A = d, B = c.

| ?- sibling(a, a).

no

I think this means a and a are not siblings.

| ?- sibling(a, X).

X = a ? a

X = b

X = a

X = b

X = a

X = b

X = a

X = b

(15 ms) yes

This is where I got stuck: It says X = a, which means sibling(a,a) is true, but sibling(a,a) failed in the previous query!

I feel that I'm not understanding what \== actually does in Prolog.

What is happening, and how do I fix this?


Solution

  • Try moving the inequality to the end of the predicate. Maybe it gives you true because it's not instantiated already.

    sibling(X,Y):- children(X, A), children(X, B),
                   children(Y, A), children(Y, B),
                   X \== Y, A \== B.