I have a strange question with using negation in SWI Prolog. When I use the following code without a space after negation "\+", it gives an error:
2 ?- assert((only_child(X) :- mother(M,X),\+(mother(M,_),\+ X==_))).
true.
3 ?- only_child(cathy).
ERROR: only_child/1: Undefined procedure: (\+)/2
ERROR: However, there are definitions for:
ERROR: (\+)/1
Exception: (7) \+(mother(melody, _G2102), \+cathy==_G2107) ? creep
4 ?-
However if I use space after negation, it works perfectly fine.
2 ?- assert((only_child(X) :- mother(M,X),\+ (mother(M,_),\+ X==_))).
true.
3 ?- only_child(cathy).
false.
4 ?-
But the following code works fine for both, using space after "\+" and without using space.
4 ?- \+ father(michael,cathy).
false.
5 ?- \+father(michael,cathy).
false.
6 ?-
Can anyone please explain this to me? Its really very puzzling. I will be really thankful.
The opening parenthesis is special when parsing Prolog. If there is no space between an identifier and an opening paren, the identifier is always treated as the name of a functor (even if it is not alphanumeric). Whatever is inside the parens is treated as a list of arguments for this functor.
However, if there is a space, the paren is treated in its normal, mathematical function of grouping expressions. The comma inside such an expression serves the role of a boolean and operator.
So:
"func(A,B)" - OK - invoke `func` on parameters `A`, `B`
"func (A,B)" - syntax error - interpreted as an identifier stuck together
with an AND expression
"\+ (A,B)" - OK - operator `\+` acting on `(A,B)` (A and B)
"\+(A,B)" - error - invoke `\+` with two parameters `A`, `B`
but \+ only takes one argument
"\+(A)" - OK - since `\+` takes one argument, it can
be invoked as a functor with one argument inside parens
The parser is also intelligent enough to split operators from identifiers (the first letter triggers a new token):
"\+ father(A,B)" - OK - invoke functor `father` with `A` and `B`,
negate the result
"\+father(A,B)" - still OK - the parser will stop reading the
name of the operator when it encounters the 'f',
so the result is same as above
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