Question

Using ! and fail, I'm trying negation by failure.

The method below however gives me the warning: Singleton variables: [X].

However, it seems to work so I'm wondering if there's anything wrong with my method of doing it:

likes(vincent, big_kahuna_burger).
neg(X) :- X, !, fail.
neg(X).

So calling neg(likes(vincent, big_kahuna_burger)) will return false.

Was it helpful?

Solution

Your implementation of neg is correct. It's just giving you a warning because in the second rule, X is never used. If you write

neg(X) :- X, !, fail.
neg(_).

you will get no warning.

OTHER TIPS

To expand on the matter: you can name your variables, in swi at least, with a starting _ to indicate that they won't be used more than once. This way you can still add a meaningful name to a variable and preserve a valuable information. Here is an example with member/2 :

member(Element, [Element|Tail]).
member(Element, [Head|Tail]) :-
    member(Element, Tail).

would produce warnings, but

member(Element, [Element|_Tail]).
member(Element, [_Head|Tail]) :-
    member(Element, Tail).

would not, yet you have preserved all the information contained in your variables names.

Though, you have to note that a variable starting with a _ isn't the same thing that the anonymous variable, for example, in this code (which is kinda useless):

member(_, _).

the two _ are different variables, while in this code:

member(_A, _A).

the two _A are the same variable.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top