\+ can be used to create grammars that are less ambiguous.
The advantage of using \+ over ! for example, is a certain
declarativity of \+, so that for example the resulting DCG
rules can be reordered.
Lets make an example, consider the following grammar:
s([X|Y]) --> t(X), s(Y). % 1
s([]) --> []. % 2
t(2) --> [a,a]. % 3
t(1) --> [a]. % 4
The above grammar is highly ambiguous, for example I get multiple
parses for the following input:
?- phrase(s(A),[a,a,a,a,a]).
A = [2,2,1] ;
A = [2,1,2] ;
A = [2,1,1,1] ;
etc..
Now assume I want to prefer the long parse of t over the
short parse of t. I can do this with a cut as follows:
t(2) --> [a,a], !. % 5
t(1) --> [a]. % 6
?- phrase(s(A),[a,a,a,a,a]).
A = [2,2,1] ;
No
Unfortunately I cannot reorder. Since doing the following
does not give the desired result. Although s(A) now yields
the results in a different order, we are back to square one,
since the grammar is ambiguous again:
t(1) --> [a]. % 7
t(2) --> [a,a], !. % 8
?- phrase(s(A),[a,a,a,a,a]).
A = [1,1,1,1,1] ;
A = [1,1,1,2] ;
A = [1,1,2,1] ;
etc...
Now lets try the same with \+. We can replace the cut
by the following negation:
t(2) --> [a,a]. % 9
t(1) --> [a], \+ [a]. % 10
?- phrase(s(A),[a,a,a,a,a]).
A = [2,2,1] ;
No
Now lets try whether we can reorder. We reorder the
grammar rules of t//1:
t(1) --> [a], \+ [a]. % 11
t(2) --> [a,a]. % 12
?- phrase(s(A),[a,a,a,a,a]).
A = [2,2,1] ;
No
The declarativity is very useful. It means for example
that we can use \+ in a right-to-left chart parser that
picks the grammar rules in an arbitrary order. The
declarativity assures that the bottom up forward chaining
of the chart parser yields the same result independently of
the input order of the DCG rules.
It is then possible to apply the DCG technique in large
natural language (NL) projects and it scales well. The
NL grammars can be empirically tuned into determinism.
The more deterministic a grammar the more efficient
its parsing. Complex NL grammars that are otherwise
intractable become feasible.
Bye
phrase(s([1]),[a]).
succeeds, butphrase(s([1]),L)
fails. Exactly that kind of impureness is what bothers me. – Pipeline