Reputation: 42277
What's the preferred way to ignore rest of input? I found one somewhat verbose way:
ignore_rest --> [].
ignore_rest --> [_|_].
And it works:
?- phrase(ignore_rest, "foo schmoo").
true ;
But when I try to collapse these two rules into:
ignore_rest2 --> _.
Then it doesn't:
?- phrase(ignore_rest2, "foo schmoo").
ERROR: phrase/3: Arguments are not sufficiently instantiated
Upvotes: 2
Views: 236
Reputation: 10120
What you want is to state that there is a sequence of arbitrarily many characters. The easiest way to describe this is:
... -->
[].
... -->
[_],
... .
Using [_|_]
as a non-terminal as you did, is an SWI-Prolog specific extension which is highly problematic. In fact, in the past, there were several different extensions to/interpretations of [_|_]
. Most notably Quintus Prolog did permit to define a user-defined '.'/4
to be called when [_|_]
was used as a non-terminal. Note that [_|[]]
was still considered a terminal! Actually, this was rather an implementation error. But nevertheless, it was exploited. See for such an example:
David B. Searls, Investigating the Linguistics of DNA with Definite Clause Grammars. NACLP 1989.
Upvotes: 4
Reputation: 18663
Why not simply use phrase/3
instead of phrase/2
? For example, assuming that you have a prefix//0
non-terminal that consumes only part of the input:
?- phrase(prefix, Input, _).
The third argument of phrase/3
returns the non-consumed terminals, which you can simply ignore.
Upvotes: 4