Re: more version 7 woes re phrase/3
Jan Wielemaker <[email protected]>
| Newsgroups | gmane.comp.ai.prolog.swi |
|---|---|
| Message-ID | <[email protected]> |
On 01/13/2014 03:33 AM, Richard A. O'Keefe wrote:
>
> On 21/12/2013, at 11:01 PM, Jan Wielemaker wrote:
>> This was added (as you may have guessed) to trap strings that are passed
>> to phrase/3.
>
> We've already seen that this could be better handled by a static
> tool; breaking working code seems a high price to pay.
I still don't know. Traditional DCGs used 'C'/3 as you well know.
This theoretically had some possibility to process something else
than a list, except that 'C'/3 was (in most systems) a statically
defined built-in. As I recall, attempts to standardize DCGs
(ISO) work on the assumption that 'C'/3 is not needed and e.g.,
literals may do direct list matching (that is also what SWI-Prolog
does).
A just as sensible alternative is to define that phrase/3 works
on lists and then there are two options:
- Use DCGs for threading state as Markus showed us.
- Have an alternative to phrase/3 that works on anything and
-preferably- does not allow for list terminals.
>> Nothing changed to the compilation though. My first impression is that
>> phrase/3 is designed to deal with lists.
>
> phrase/3 is designed to work with whatever it is that the
> DCG rules it calls happen to work with. Fair to say, however,
> that the Quintus documentation explicitly called the second
> argument "List".
>
>> What about inventing another name for phrase/3,
>
> Would it not have been much more useful to define
>
> phrase(NT, S0, S) :-
> ( string(S0) ->
> string_codes(S0, C0),
> old_phrase(NT, C0, C),
> string_codes(S, C)
> ; old_phrase(NT, S0, S)
> ).
This looks like a bad idea. Not only is it seriously
inefficient, but it also breaks the clean bi-directional
semantics of phrase/3, as phrase in `generative' mode
would return a list (of codes).
I think adding a phrase_string/2,3 is a more promising
route. That can either use the technique below or use
the same technique as library(pure_input): a lazy
code-list.
> What would be even better would be if the DCG translation
> did something like
>
> [X],S0,S =>
> ( S0 = String+I0,
> S = String+I ->
> succ(I0, I),
> string_char(I, String, X)
> ; S0 = [X|S]
> )
>
> so that DCGs just worked with strings.
>
>> or even, simply go back to the basics and rely
>> on call/3:
>>
>> call(ruleset, StateIn, StateOut).
>
> which does not transform the rule body correctly.
Right :-( Provided the ruleset is sufficiently
instantiated, one could use:
:- meta_predicate
my_phrase(//, ?, ?).
user:goal_expansion(my_phrase(Rule, In, Out), Goal) :-
expand_phrase(phrase(Rule, In, Out), Goal).
At this moment, I think that Markus' technique is the most
sensible proposal that I have seen. It allows using DCGs
for threading state and does not break the assumed typing
of phrase/3. Note that my long-term aim is to provide more
(soft) typing.
Cheers --- Jan