liori
liori

Reputation: 42277

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

Upvotes: 2

Views: 236

Answers (2)

false
false

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

Paulo Moura
Paulo Moura

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

Related Questions