What is the logical 'not' in Prolog?

The problem that I face, is a bit trivial. I want to use logical not in Prolog, but it seems that not/1 is not the thing that I want:

course(ai).
course(pl).
course(os).

have(X,Y) :- course(X),course(Y),not(X = Y).

I query:

have(X,Y), write(X-Y), nl , fail.

And I do not get the result I want :(


In place of not(X = Y) you need to write \+ X = Y or X \= Y. But consider to use dif(X,Y) instead. dif/2 is present in B, SWI, YAP, SICStus. To see the difference:

?- X = b, dif(a, X).
X = b.

?- X = b, \+ a = X.
X = b.

So up to now everything seems to be fine. But what, if we simply exchange the order of the two goals?

?- \+ a = X, X = b.
false.

?- dif(a, X), X = b.
X = b.

(\+)/1 now gives us a different result, because there is an answer for a = X, the goal \+ a = X will fail.

(\+)/1 is thus not negation, but means not provable at this point in time.

A safe approximation of dif/2 is possible in ISO Prolog, too.


In both SWI-Prolog and GNU Prolog, the following should work:

have(X, Y) :- course(X), course(Y), X \= Y.

In SWI-Prolog, you can also use dif/2, which can be more convenient since you can use it earlier in the predicate:

have(X, Y) :- dif(X, Y), course(X), course(Y).

As an adjunct to the answer by user "false" above, i.e.

"In place of not(X = Y) you need to write \+ X = Y,"

This might give the impression that:

a. "not" and "\+" are different things

b. The \+ will work whereas the not will, err, not.

My understanding is that "not" and "\+" are equivalent, but that \+ is preferred in modern Prolog programs, because it conveys a sense that is more intuitive. Specifically, whereas "not" might suggest "is not true" to the unwary coder, "\+" suggests "is not provable" which is much closer to the truth of what that operation is really saying. In Prolog, the "not" is an example of "negation as failure", but it is felt that \+ will make it clearer to the programmer just what precisely is being asserted in any given rule. So you CAN use "not" (most PL implementations keep it for backwards-compatibility) but to be an idiomatic modern PL programmer, you probably should prefer to use \+.