Search code examples
prologswi-prologdcg

Ignore rest of input


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

Solution

  • 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.