[mercury-users] Disable or warn for implicit modes?

Jeff Thompson jeff at thefirst.org
Mon Feb 27 06:23:02 AEDT 2012


Thanks for the detailed reply on how the compiler selects the mode.  I 
ran across another case where the code with running slower than I 
expected.  Here is the example:

:- pred test(bool::in, list(int)::out, list(int)::out, list(int)::in) is 
nondet.
test(SetEnd, Start, End, List) :-
   (if SetEnd = yes then
     End = [1]
   else
     true),
   append(Start, End, List).

I (naively) expected End to be ground if SetEnd is yes, so that append 
would be called with the more efficient semidet mode (out, in, in).  But 
instead, the compiler re-orders the code to call append with mode(out, 
out, in) to return all search results, and only test End = [1] on each 
return.  To get the compiler to use the efficient semidet mode, I had to 
explicitly change the code to:

test(SetEnd, Start, End, List) :-
   (if SetEnd = yes then
     End = [1],
     append(Start, End, List)
   else
     append(Start, End, List)).

Is there some trick to avoid having to remember to put the same code for 
append in two places?

Thanks again for any help,
- Jeff

On 2/23/2012 9:59 AM, Julien Fischer wrote:
>
> Hi,
>
> On Tue, 14 Feb 2012, Jeff Thompson wrote:
>
>> Hello.  Sometimes the compiler will create an implicit mode which is
>> not declared.  For example, if the predicate  argument only has an
>> "out" mode but is called with "in", it will call the predicate with a
>> temporary "out" argument and check for equality on return.
>
> Yes, this is what is referred to as an implied mode.  Note that the
> compiler will only do this in the absence of a mode that exactly matches
> the mode required by the call to the predicate.
>
>> But if this is done when there are different clauses for different
>> modes, it can cause unexpected behavior.
>
> You mean, it may select the mode that you don't expect?  The easiest way
> to avoid this is to provide explicit mode declarations that exactly
> match the modes of any calls to the predicate in question.
>
> If you don't do this then the choice of mode is still predicatable,
> after all the algorithm used by the mode checker has to eventually
> settle on a single mode.  Briefly, the algorithm used by the compiler
> is as follows:
>
> Given a candidate set of modes:
>
> (1) remove modes that are strictly less informative or strictly less
> instanstiated from the set of candidate modes; if we're left with one
> mode then we're done otherwise ...
>
> (2) prioritize the reamining modes by their determinism;
> the priority is determined by the position of the determinims in
> the determinism lattice -- see section 6.1 ``Determinism categories''
> of the reference manual.  If we are left with one mode with the highest
> priority then we're done, otherwise ...
>
> (3) If step 2 still doesn't yield a single mode, then the first
> mode that occurs in declaration order is the one selected.
>
>> Is there a compiler switch to disable or warn if implicitly calling a 
>> predicate with an undeclared mode?
>
> No.
>
> Julien.

--------------------------------------------------------------------------
mercury-users mailing list
Post messages to:       mercury-users at csse.unimelb.edu.au
Administrative Queries: owner-mercury-users at csse.unimelb.edu.au
Subscriptions:          mercury-users-request at csse.unimelb.edu.au
--------------------------------------------------------------------------



More information about the users mailing list