Path: utzoo!utgpu!news-server.csri.toronto.edu!cs.utexas.edu!sdd.hp.com!usc!snorkelwacker.mit.edu!bloom-beacon!eru!hagbard!sunic!kuling!kuling.docs.uu.se!mattias From: mattias@arnold.csd.uu.se (Mattias Waldau) Newsgroups: comp.lang.prolog Subject: Re: Compiler smartness? Message-ID: Date: 25 Nov 90 18:11:49 GMT References: Sender: news@kuling.UUCP Distribution: comp Organization: csd Lines: 78 In-reply-to: zhou@hiromi.csce.kyushu-u.junet's message of 20 Nov 90 05:59:19 GMT In article zhou@hiromi.csce.kyushu-u.junet (Neng Fa Zhou) writes: In article dowding@ai.sri.com (John Dowding) writes: > I was poking around in some old code, and came across the following > clauses (names changed to protect the inocent): > > foo(Term, Term):- > (var(Term) ; atomic(Term)), > !. > foo([Head|Tail], Result):- > ... > > > I was wondering if the following is more efficient: > > foo(Term, Term):- > var(Term), > !. > foo(Term, Term):- > atomic(Term), > !. > foo([Head|Tail], Result):- > ... Yes, it is more efficient than the original one. > > Are Prolog compilers (particularly, Quintus version 2.4) smart enough > index correctly on the 1st argument in either or both of these cases? > The compiler for the TOAM is smart enough to compile this program to efficient code. The compiler first infers modes for a program, then transforms the program to a canonical form based on the inferred modes. Suppose [d,f] is the mode of foo/2, the canonical form of the predicate is foo(Term, NewTerm):- var(Term), !, NewTerm = Term. foo(Term, NewTerm):- atomic(Term), !, NewTerm = Term. foo([Head|Tail], Result):- ... This canonical form was probably what the original program should have looked like anyway. The intension was probably that the first clause should have been the only that should have be applicable if the first argument is a variable. However, the call :-foo(X,frobozz) matches the last clause, which is probably wrong. It is a very common error to write the clause bar(X,X) :- foo(X), !. instead of the clause bar(X,Y) :- foo(X), !, X=Y. The last program is more efficient, since the unification X=Y is only done if the predicate foo(X) before the cut succeeds. If foo is a predicate like atomic, var... the indexing of SICStus will make the program above very efficient. (I also believe that SICStus will expand the disjunction into two clauses.) -- Mattias Waldau Computing Science Department mattias@emil.csd.uu.se P.O. Box 520, S-751 20 Uppsala, Sweden Phone: +46-18-181055