[mercury-users] Predicate call uses the "wrong" mode

Barney Fisher barney.fisher at googlemail.com
Sat Aug 4 03:20:56 AEST 2007


I've been investigating why some of my Mercury code is running slowly.
 I eventually found the reason: the wrong mode of a predicate was
being called.  The following is relevant code to show the problem.
Although, I can provide full sources if needed.

:- pred atm(drug,atomid,element,int,charge).
:- mode atm(in,out,out,out,out) is nondet.
:- mode atm(in,out,in,out,out) is nondet.

% atm/5 is a fact table

:- pred atoms(drug,int,atomidlist,elementlist).
:- mode atoms(in,in,out,in) is nondet.

atoms(Drug,1,[Atom],[T]) :-
   T \= "h".
atoms(Drug,N1,[Atom1|[Atom2|List_a]],[T1|[T2|List_t]]) :-
   N1 > 1,
   N2 is N1 - 1,
   Atom1 @> Atom2,
   T1 \= "h".

When compiled like this, atoms should really call atm in mode
:- mode atm(in,out,in,out,out) is nondet.
because Drug and T1 are instantiated, but it actually calls atm in mode
:- mode atm(in,out,out,out,out) is nondet.

If the code is changed to be like
:- mode atm(in,out,in,out,out) is nondet.
:- mode atm(in,out,out,out,out) is nondet.
then everything is fine (i.e. mode in,out,in,out,out is called at runtime.).

This made the difference between my program taking 5 seconds to
execute and 0.5 seconds!

I was quite surprised by this situation because I had assumed the mode
system would always call the most instantiated mode possible.  Is this
a bug in mode analysis? if not, is there a general rule for which mode
of a predicate will be called.  The code above could lead to the
assumption that the first applicable mode is chosen but I know from
other situations this isn't correct.


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