[m-dev.] trace goals and reordering
Zoltan Somogyi
zoltan.somogyi at runbox.com
Thu May 1 14:38:14 AEST 2025
On Thu, 1 May 2025 14:21:07 +1000, Julien Fischer <jfischer at opturion.com> wrote:
> On Thu, 1 May 2025 at 12:49, Zoltan Somogyi <zoltan.somogyi at runbox.com> wrote:
> >
> > On Thu, 1 May 2025 12:18:22 +1000, Julien Fischer <jfischer at opturion.com> wrote:
> >
> > > The reference manual says the following about trace goals:
> > >
> > > The compiler will not delete trace goals from the bodies of the procedures
> > > containing them, even though they are 'det' and have no outputs. In their
> > > effect on program optimizations, trace goals function as a kind of
> > > impure code,
> > > but one with an implicit promise_pure around the clause in which they occur
> > >
> > > This seems a bit vague. What is meant by "kind of impure code"?
> >
> > The vagueness is hard to avoid, since listing precisely how a long list of optimizations
> > handle trace goals would be far less readable than what is there now :-(
> >
> > The intention behind that sentence, which I think I wrote, is simply to say that
> > the compiler will not delete a det trace goal with no outputs. The compiler normally
> > does eliminate such goals *unless* they are impure; this sentence modifies that
> > to "unless they are either impure or are trace goals". That's it. Feel free to make
> > that clearer.
>
> We could add something like the following:
>
> Trace goals are subject to the same ``minimal''' reordering
> required by the modes
> as other goals
So go ahead and add it, though any quotes should be balanced :-)
> (I don't think it would have helped much in this case, since the
> original author of the code in question
> assumed it was an issue with the MLDS->Java code generator,
That, I would not have guessed :-)
> > > At least as
> > > far as reordering due to modes is concerned, the implementation does not seem
> > > to treat them as impure. Is that intentional?
> >
> > Yes, though the intention was mostly to simplify the implementation, not to benefit
> > users. But allowing a trace goal to work even if it is textually before the code
> > that generates a value that the trace goal prints out *can* be considered
> > a benefit; it's in the eye of the beholder.
>
> Perhaps. I cannot think of any instances, either in Mercury itself or in
> any Opturion code, where such positioning of trace goals has been deliberate.
I can believe that. But just because the trace goal is where it is by intention,
does not necessarily imply that the goals that generate all its inputs are
deliberately placed with respect to the trace goal. The trace goal tends to be
added to a procedure body well after the procedure is first written, because
most of the time you don't know in advance exactly which procedures
you will need to instrument to find a bug.
> Silently reordering trace goals is potentially quite insidious: if a
> trace goal is logging
> details about an upcoming semidet goal and the trace goal gets moved to after
> the semidet goal, then the log messages won't be printed at all.
But many trace goals are NOT about an upcoming semidet goal, or about any
semidet goal at all. When you are testing whether *det* code gets the right answers,
getting a printout of the actual answers, so you can check them, is faster than
getting an error message (or warning treated as an error) about the trace goal
being before a goal that computes e.g. some incidental parameter of the trace goal,
such as the width to be used in the printing of the result, then fixing it, and
*then* getting the output you wanted.
> I suspect most users expect trace goals (especially those with an
> io(!IO) parameter),
> to stay where they are textually.
See above.
> > > (If so, I think the reference
> > > manual should mention the possibility that they can be reordered for
> > > mode correctness.)
> >
> > That approach would require listing all the ways in which trace goals
> > are like all other pure goals, which would be a long list. It seems simpler
> > to list the small number of ways in which they are different.
>
> As I said above, I don't think it will hurt to mention the possibility
> of reordering.
And I am not objecting to such a mention. But you know better than me
what the misunderstanding was, so you are in a better position to write the text
to help people avoid that misunderstanding.
> > To address the violation of the law of least astonishment that lead
> > to this email, we could add code to after-front-end invocation of
> > the simplification pass that, when it finds a procedure body contains
> > a trace goal (a goal feature should signal this), does an extra traversal
> > of the procedure body. This traversal would update the largest context
> > seen so far, which, in the absence of source file and line number pragmas,
> > would be the largest line number in the procedure's one-and-only file name.
> > It would then generate a warning if, when it arrived at a trace goal, the
> > context of the trace goal was *not* bigger than the largest context so far.
> > This would light up trace goals that mode analysis has moved to the right.
>
> I debugged the problem by looking at the HLDS dumps -- I don't think that's
> something we should be expecting most users to do.
Agreed. Hence the proposal above. That one I *can* implement, if you like.
Zoltan.
More information about the developers
mailing list