Re: "maplist" for DCG?
"Richard A. O'Keefe" <[email protected]>
| Newsgroups | gmane.comp.ai.prolog.swi |
|---|---|
| Message-ID | <[email protected]> |
On 21/11/2013, at 3:41 AM, Alan Baljeu wrote:
> What you write seems complex. I don't see what motivates having that
> much code. I found a predicate that is apt, but much shorter.
>
> for(P,L) --> for_(L,P).
>
> for_([H|T],P) --> call(P,H),for_(T,P).
> for_([ ],_) --> { true }.
>
What I wrote was precisely the same as this except for
using the phrase//(N+1) family instead of the call//(N+1) family,
for consistency.
zic(X) --> [a], X, [b].
will use phrase//1 to interpret X.
The purpose of the two-stage process (first preprocess to produce
a rule body and then call phrase//1 on that) is to avoid the
inefficiency of repeatedly reprocessing the same non-terminals.
In fact the code you present is *precisely* the mapnt//2
that I showed you:
>
> In the absence of the phrase//(N+1) family,
>
> mapnt(NT, []) --> [].
> mapnt(NT, [A|As]) --> call(NT, A), mapnt(NT, As).
>
> will probably do.
(Why would anybody write {true} instead of the normal
indication of an empty RHS, []?)
No, for/4 is NOT the usual name for this.
So far as I know, there _isn't_ a usual name.
And for/4 has fairly often been used for other things,
e.g.,
for(Variable, Lower_Bound, Upper_Bound, Goal) :-
between(Lower_Bound, Upper_Bound, Variable),
call(Goal),
fail ; true.
call/N+1 and phrase//(N+1) are *not* the same thing in this
or any other context. Contrast
phrase(., p, [q], [p,q,r], [r])
which should succeed, with
call(., p, [q], [p,q,r], [r])
which should raise an exception because there is no ./4 predicate.
In this *instance*, where the form that is constructed does not
include any of the special syntax of DCG rule bodies, the two are
equivalent. But a general-purpose predicate should not presume
special restrictions.
As for the final paragraph, about computing
Term = (f(In1), f(In2), f(In3))
and then inserting that using phrase(Term),
that's precisely what the separate-preprocessing-step version
of mapnt//2 does.