Reputation: 7288
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
.
Upvotes: 0
Views: 214
Reputation: 7493
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.
Upvotes: 1
Reputation: 39366
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.
Upvotes: 1