kamahen / edcg

Extended DCG syntax for Prolog by Peter Van Roy
MIT License
8 stars 4 forks source link

-->> can produce non-steadfast code in the presence of cuts #5

Open kamahen opened 3 years ago

kamahen commented 3 years ago

This comment by Richard O'Keefe discusses why the original implementation of DCGs used C/3 instead of pushing the unification into the head: https://swi-prolog.iai.uni-bonn.narkive.com/cOnL0aGn/push-back-lists-on-dcg-rule-heads

It is possible that a cut in an EDCG body would violate this; whether it's important is not clear.

The implementation of ==>> uses '=/2instead of pushing the unification into the head; because==>>uses=>`, cuts are not likely in the body, so this is less of a problem.

kamahen commented 3 years ago

Here is some test code:

p2(a) --> !, [X,a], q(X).

:- use_module(library(edcg)).
edcg:pred_info(p3, 1, [dcg]).
edcg:pred_info(q3, 1, [dcg]).

p3(a) -->> !, [X,a], q3(X).

SWI-Prolog produces this:

p2(a, A, B) :-
    !,
    C=A,
    C=[X, a|D],
    q(X, D, B).

And EDCG produces this:

p3(a, A, B) :-
    !,
    A=[X|C],
    C=[a|D],
    q3(X, D, B).

Both of these simplify to:

p2(a, A, B) :-
    !,
    A=[X, a|D],
    q(X, D, B).

When the -->> is changed to ==>>, EDCG produces this:

p3(a, A, B) =>
    C=B,
    !,
    A=[D|E],
    E=[a|F],
    q3(D, F, C).

which simplifies to the following (which doesn't look quite right):

p3(a, A, B) =>
    C=B,
    !,
    A=[X,A|D],
    q3(X, D, C).