Newsgroups: comp.lang.prolog
Path: cantaloupe.srv.cs.cmu.edu!nntp.club.cc.cmu.edu!goldenapple.srv.cs.cmu.edu!rochester!cornellcs!newsstand.cit.cornell.edu!portc01.blue.aol.com!newsxfer3.itd.umich.edu!su-news-hub1.bbnplanet.com!cpk-news-hub1.bbnplanet.com!cam-news-hub1.bbnplanet.com!news.bbnplanet.com!news.maxwell.syr.edu!newsfeed.nacamar.de!news-kar1.dfn.de!news-stu1.dfn.de!news-mue1.dfn.de!news-nue1.dfn.de!news-lei1.dfn.de!news-ber1.dfn.de!news-ham1.dfn.de!news-han1.dfn.de!news.uni-bielefeld.de!news
From: Clemens Meier <clmeier@lili6.lili.uni-bielefeld.de>
Subject: Re: forall() implementation
Sender: news@hermes.hrz.uni-bielefeld.de (News Administrator)
Message-ID: <q9n2s9meff.fsf@lili6.lili.uni-bielefeld.de>
Date: Wed, 12 Mar 1997 13:24:04 GMT
References: <3323B95F.35D@enternet.com.au>
Nntp-Posting-Host: lili6.lili.uni-bielefeld.de
Organization: Universitaet Bielefeld, Linguistik und Literaturwissenschaft, Germany
X-Newsreader: Gnus v5.3/Emacs 19.34
Lines: 59


Hello!

Richard de Rozario <rdr@enternet.com.au> writes:
> 
> forall( [H|Tail], X^Y^Pred, [Y|Results]):-
>    assert( p(X^Y^Pred) ),
>    X=H,
>    call(Pred),
>    retract( p(A^B^P) ),
>    forall( Tail, A^B^P, Results).
>
> As I'm writing this I spotted a way of optimising it: assert only once. 
> Any further
> optimisations anybody?

AFAIK, use of the database is to be avoided where possible, so
if you only use assert/retract to avoid instantiating the
variables for the next recursive call, I would have used
copy_term/2 like this:

	forall([In|Ins], PredSpec, [Out|Outs]) :-
		copy_term(PredSpec, In^Out^Pred),
		call(Pred),
		forall(Ins, PredSpec, Outs).

But this seems to be only marginally more efficient, because
it essentially has to do the same thing as assert/retract:
copying (almost) all the terms concerned, but, as the SICStus
manual puts it:

     The implementation of `copy_term/2' conserves space by not
     copying ground subterms.

This doesn't impact on the time behaviour much, though.

So whether you assert the necessary goal for every input datum,
or assert it just once and read it from the database for every
datum, or if you ``copy_term'' it for every datum, the work
required remains essentially the same.

The only way (I can think of, that is) of avoiding all the lame
copying is using some kind of failure--driven--loop or bagof.
Unfortunately, this seems to take exponential time instead of
linear time for the copying.

Overall, the assert--once solution (assert/2, clause/3, erase/1)
turned out to be slightly faster than the other methods (assert,
retract and copy_term). But I'm not sure about my tests :-)

CU

Clemens

-----------------------------------------------------------------------------
When there is useful information which [your]   clmeier@lili.uni-bielefeld.de
program can send to the terminal but not get                    Clemens Meier
at itself, your customers start to say very    GO C++ 3$ UL L+>+++ E++>+++ P-
unkindly things about you.       R.A.O'Keefe   N++ R+>+++ G'''' b++ TWERPS+++
