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

Nikolas Everett nik9000 at gmail.com
Sun Aug 5 10:53:19 AEST 2007


Bug or not, its unexpected.  I expected the compiler to go with the mode
that most closely matches the state of the variables.  Admittedly I think
that because I'm used to dealing with Java which picks the most precisely
defined method when doing object overloading.  So this:
class Test {
    protected static void doIt(Object o) {
        System.out.println("Object");
    }

    protected static void doIt(String string) {
        System.out.println("String:  " + string);
    }

    public static void main(String[] argv) {
        doIt(new Integer(1));
        doIt("SSS");
    }
}
Spits out this:
Object
String:  SSS

Is there a situation where you'd want to use the implied predicate instead
of the explicit one?

--Nik

On 04/08/07, Julien Fischer <juliensf at csse.unimelb.edu.au> wrote:
>
>
> On Fri, 3 Aug 2007, Barney Fisher wrote:
>
> > 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]) :-
> >   atm(Drug,Atom,T,_,_),
> >   T \= "h".
> > atoms(Drug,N1,[Atom1|[Atom2|List_a]],[T1|[T2|List_t]]) :-
> >   N1 > 1,
> >   N2 is N1 - 1,
> >   atoms(Drug,N2,[Atom2|List_a],[T2|List_t]),
> >   atm(Drug,Atom1,T1,_,_),
> >   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?
>
> No.
>
> > if not, is there a general rule for which mode
> > of a predicate will be called.
>
> Yes, they are called in declaration order
>
> >  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.
>
> See section 4.2 of the reference manual, the bit about ``implied modes''.
>
> 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
> --------------------------------------------------------------------------
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.mercurylang.org/archives/users/attachments/20070804/74e2f055/attachment.html>


More information about the users mailing list