Re: [m-users.] Is this a compiler bug?

Volker Wysk <[email protected]>
Newsgroups gmane.comp.lang.mercury.general
Message-ID <[email protected]>
Am Mittwoch, dem 16.11.2022 um 12:46 +1100 schrieb Mark Brown:
> On Wed, Nov 16, 2022 at 6:07 AM Volker Wysk <[email protected]> wrote:
> > 
> > Hi there.
> > 
> > Am Dienstag, dem 15.11.2022 um 16:05 +1100 schrieb Julien Fischer:
> > > On Sat, 12 Nov 2022, Volker Wysk wrote:
> > > 
> > > > The following program fails to compile:
> > > > 
> > > > :- module pairbug.
> > > > :- interface.
> > > > :- import_module io.
> > > > 
> > > > :- pred main(io::di, io::uo) is det.
> > > > 
> > > > :- implementation.
> > > > :- import_module pair, string.
> > > > 
> > > > :- pred p(pair(string, string)::out, io::di, io::uo) is det.
> > > > p("foo" - "bar", !IO).
> > > > 
> > > > main(!IO) :-
> > > >    p(A - B, !IO).    % <- line 19
> > > > 
> > > > 
> > > > The message is:
> > > > 
> > > > pairbug.m:006: In `main'(di, uo):
> > > > pairbug.m:006:   error: determinism declaration not satisfied.
> > > > pairbug.m:006:   Declared `det', inferred `semidet'.
> > > > pairbug.m:006:   The reason for the difference is the following.
> > > > pairbug.m:019:   In argument 1 of call to predicate `pairbug.p'/3:
> > > > pairbug.m:019:   unification with `V_9' can fail.
> > > > 
> > > > 
> > > > But the following works:
> > > > 
> > > > main(!IO) :-
> > > >    p(P, !IO),
> > > >    P = A - B.
> > > > 
> > > > 
> > > > This must either be something stupid or a compiler bug...
> > > 
> > > It is a consequence of the following:
> > > 
> > > - how the clauses are translated into superhomogenous form;
> > > - the fact that A and B are unused;
> > > - the fact that the current Mercury implementation does not support
> > >    partial instantiation properly.
> > > 
> > > (Superhomogenous form is the form by which clauses are represented
> > > inside the compiler.)
> > > 
> > > Here's what the compiler sees for the first version immediately
> > > before mode analysis:
> > > 
> > >     main(STATE_VARIABLE_IO_0, STATE_VARIABLE_IO) :-
> > >        V_8 = A - B,
> > >        p(V_9, STATE_VARIABLE_IO_0, STATE_VARIABLE_IO),
> > >        V_8 = V_9.
> > > 
> > > (The variables prefixed with 'V_' or 'STATE_VARIABLE_' are introduced
> > > by the compiler.)
> > > 
> > > Here's what the compiler sees for the second version immediately
> > > before mode analysis:
> > > 
> > >     main(STATE_VARIABLE_IO_0, STATE_VARIABLE_IO) :-
> > >         p(P, STATE_VARIABLE_IO_0, STATE_VARIABLE_IO),
> > >         P = A - B.
> > > 
> > > The first version constructs a partially-instantiated term, e.g.
> > > pair(<<free>>, <<free>>), puts the output of p/3 into V_9 and then
> > > attempts to unify them (which I suspect is where it falls over).
> > > Is that what you were intending?
> > 
> > Yes, it is. And you're right about the point where it falls over. See below.
> > 
> > > You might ask: why doesn't mode analysis reorder the first version to
> > > be like the second. The answer is: it doesn't have any reason to do
> > > such reordering.
> > > 
> > > One of the other pieces of compiler you get from that program is:
> > > 
> > >     pairbug.m:014: In clause for predicate `main'/2:
> > >     pairbug.m:014:   warning: variables `A, B' occur only once in this scope.
> > > 
> > > If I have a version of the program, that uses A or B, e.g.
> > > 
> > >      main(!IO) :-
> > >        p(A - B, !IO),
> > >        io.print(A, !IO).
> > > 
> > > then mode analysis will reorder things appropriately.
> > 
> > You talk about "reordering" of the clauses, which make up the two
> > superhomogenous forms. The second form, you say, could or could not be a
> > reordered version of the first. But the two superhomogenous forms can't be
> > reordered versions of each other, because the first one consists of three
> > clauses, whereas the second one consists of two clauses. I don't fully get
> > what you're saying.
> 
> Mode analysis can also introduce unifications like the V_8 = V_9 above.
> 
> > 
> > I'm wondering if there's some documentation about superhomogenous forms and
> > mode analysis. The word "superhomogenous" doesn't occur in the language
> > reference manual. But "mode analysis" is mentioned a couple of times. I'm
> > going to study it.
> > 
> > 
> > The following version of main fails to compile (like expected) with
> > "Unification of `P1' and `P2' can fail". (Here we have the point of
> > failure). Even though that isn't the case:
> > 
> > main(!IO) :-
> >     P1 = A - B,
> >     p(P2, !IO),
> >     P1 = P2.
> > 
> > I suppose this due to what you described as "the fact that the current
> > Mercury implementation does not support partial instantiation properly".
> > 
> > If I remember correctly, this has already been addressed at some point in
> > this mailing list. And that the full support of partial instantiation had
> > been implemented, but then was dropped again, because it made the compiler
> > too slow.
> > 
> > I find the state of affairs a bit disappointing. The programmer shouldn't
> > have to cope with superhomogenous forms and mode analysis.
> 
> Strong modes and determinism have both advantages and disadvantages:
> Mercury takes the view that the former greatly outweigh the latter.

So do I, with my limited level of understanding.

> One of the consequences of this is that not all program
> transformations that are logically correct are mode/determinism
> correct, so programmers will necessarily have to "cope" with it to
> some extent. 

A better word would be "to concern oneself with". (Sorry, English isn't my
native language.)

> But you're right that the compiler could do more in cases
> like this one.
> 
> > Maybe the proper
> > support of partial instantiation can be implemented after all, with the
> > computers becoming more powerful all the time...?
> 
> A rule of thumb that I find helps deal with this is, "If your code is
> easier for a programmer to analyse, then it is easier for the compiler
> to analyse." So I think the first thing I would have done in this
> situation would be to just try putting the unification with A - B
> after the call, since it's an output of the call, and see if the
> compiler gets it.

Actually, I have. But I couldn't understand why it didn't work the way it
did it first. So now, I'm trying to come to an understanding of what's going
on.

But I don't think the code is easier to comprehend when you put the
unification after the call. 

> Given that the workaround for this problem usually makes your code
> easier to read, I don't consider it a priority to attempt to improve
> the compiler in this regard. 

But you get an unintelligible error message, the way it is now. When you
know what's wrong, you can make a workaround. But in my case, I didn't
understand what's going on.

> I do agree that we could document the
> rules better, however, e.g., by characterizing exactly which modes a
> unification can have.

Yes, this sounds like what I'm after.


Best regards,
Volker

_______________________________________________
users mailing list
[email protected]
https://lists.mercurylang.org/listinfo/users
signature.asc (application/pgp-signature, 833 B)
-----BEGIN PGP SIGNATURE-----

iQIzBAABCgAdFiEE6QXGh82Ov3+2nrxp+K4ydFOsHoUFAmN2POQACgkQ+K4ydFOs
HoVbzw/9FbR1W/N2yatPecx9mvflr8pe0jVHhlgo+fNNJ5fjyvzmW6Ov8YO/SKm+
Jvw5Fxjf03bC3judQszPhza66XsS85voOXVvRUE37OmAFi7C9FlCWnAZbSj+kRfE
40N81jQQ9Cb6C7ooCX8z5frlXNeqt+wBWkoV1O1FfGvSP/Kj9Csm6GpI1le8N2fe
PzV7IdoaqH0md7YEJGxb7frosyRWYOR02QAKJzogMWcy4uUJx8qJ8xal+akO4XyB
6mjUJ16AwQakv9naHsk7d5JEbpx0Buls9rjFyFFlAkaXGh9GWvQ9QC0+fJS8BYKi
IWaGWx3b1kgYbmJIPKddQhrmLK07xTd8DYyWvqECwpuTd9aUJBWomyWCBIG7E7Zu
sOXKt+9IMchSLXvqPqYMsZ/OmE1Meh9d3RUV+JoMMhvE2xyl0ElCxAut2Sao0r6j
sfyyDwlbEroTxeEMeBY/aOB1DoMU7+eEaJ7TAIMsmhtr5BDClDaq3QHGHBDE8EQa
2DMx+iWuMyPTf3jOwHuywRnIvRo1rOpTa+HzZrOjXFcNfK1cHUF9ofLeYkwfmNUo
0WZZoEyr/BxiZ2xGXRtf4vCncozpd5yZVJH94s8+VduFmKSHV9RmqGlT960S1fJJ
ydlh0Kfbw31TmTdGpILL4Oy9+u2GfwGMiMNMjKovOhMpmVg3MVo=
=U5je
-----END PGP SIGNATURE-----
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.