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:
<br>class Test {<br>    protected static void doIt(Object o) {<br>        System.out.println("Object");<br>    }<br><br>    protected static void doIt(String string) {<br>        System.out.println("String:  " + string);
<br>    }<br><br>    public static void main(String[] argv) {<br>        doIt(new Integer(1));<br>        doIt("SSS");<br>    }<br>}<br>Spits out this:<br>Object<br>String:  SSS<br><br>Is there a situation where you'd want to use the implied predicate instead of the explicit one?
<br><br>--Nik<br><br><div><span class="gmail_quote">On 04/08/07, <b class="gmail_sendername">Julien Fischer</b> <<a href="mailto:juliensf@csse.unimelb.edu.au">juliensf@csse.unimelb.edu.au</a>> wrote:</span><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">
<br>On Fri, 3 Aug 2007, Barney Fisher wrote:<br><br>> I've been investigating why some of my Mercury code is running slowly.<br>> I eventually found the reason: the wrong mode of a predicate was<br>> being called.  The following is relevant code to show the problem.
<br>> Although, I can provide full sources if needed.<br>><br>> :- pred atm(drug,atomid,element,int,charge).<br>> :- mode atm(in,out,out,out,out) is nondet.<br>> :- mode atm(in,out,in,out,out) is nondet.<br>
><br>> % atm/5 is a fact table<br>><br>> :- pred atoms(drug,int,atomidlist,elementlist).<br>> :- mode atoms(in,in,out,in) is nondet.<br>><br>> atoms(Drug,1,[Atom],[T]) :-<br>>   atm(Drug,Atom,T,_,_),
<br>>   T \= "h".<br>> atoms(Drug,N1,[Atom1|[Atom2|List_a]],[T1|[T2|List_t]]) :-<br>>   N1 > 1,<br>>   N2 is N1 - 1,<br>>   atoms(Drug,N2,[Atom2|List_a],[T2|List_t]),<br>>   atm(Drug,Atom1,T1,_,_),
<br>>   Atom1 @> Atom2,<br>>   T1 \= "h".<br>><br>> When compiled like this, atoms should really call atm in mode<br>> :- mode atm(in,out,in,out,out) is nondet.<br>> because Drug and T1 are instantiated, but it actually calls atm in mode
<br>> :- mode atm(in,out,out,out,out) is nondet.<br>><br>> If the code is changed to be like<br>> :- mode atm(in,out,in,out,out) is nondet.<br>> :- mode atm(in,out,out,out,out) is nondet.<br>> then everything is fine (
i.e. mode in,out,in,out,out is called at runtime.).<br>><br>> This made the difference between my program taking 5 seconds to<br>> execute and 0.5 seconds!<br>><br>> I was quite surprised by this situation because I had assumed the mode
<br>> system would always call the most instantiated mode possible.  Is this<br>> a bug in mode analysis?<br><br>No.<br><br>> if not, is there a general rule for which mode<br>> of a predicate will be called.<br>
<br>Yes, they are called in declaration order<br><br>>  The code above could lead to the<br>> assumption that the first applicable mode is chosen but I know from<br>> other situations this isn't correct.<br><br>
See section 4.2 of the reference manual, the bit about ``implied modes''.<br><br>Julien.<br>--------------------------------------------------------------------------<br>mercury-users mailing list<br>Post messages to:       
<a href="mailto:mercury-users@csse.unimelb.edu.au">mercury-users@csse.unimelb.edu.au</a><br>Administrative Queries: <a href="mailto:owner-mercury-users@csse.unimelb.edu.au">owner-mercury-users@csse.unimelb.edu.au</a><br>Subscriptions:          
<a href="mailto:mercury-users-request@csse.unimelb.edu.au">mercury-users-request@csse.unimelb.edu.au</a><br>--------------------------------------------------------------------------<br></blockquote></div><br>