[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