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?
TL;DR: Use prolog-dif—or iso_dif/2
(on iso-prolog conforming systems like gnu-prolog)!
Good question, +1!
In fact, it's a question I have asked myself, and the answer has to do with logical-purity: logical purity is a central aspect of what makes Prolog as a language so special, as it enables you to:
Unlike many other programming languages, Prolog programs have both procedural semantics (defining the execution steps and their order) and declarative semantics (allowing you to state relations that should hold and let the Prolog processor find a proper way of execution by itself).
But, beware: Prolog has some features that, when used, ruin declarative semantics. To prevent this, try to structure your application into two parts: an impure shell for dealing with side-effects (input/output) and a logically pure base which comprises pure monotonic Prolog code.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With