🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Article View: comp.lang.prolog
Article #864

Compiling away bagof

#864
From: Sanjai Narain
Date: Thu, 31 May 1990 20:09
88 lines
3439 bytes
This is in response to Richard O'Keefe's request to outline my approach
for compiling away bagof.  It has been developed in the context of DMOD
(Declarative MODeling) a technique for modeling dynamic systems.  The
optimization essentially consists of compiling away OR-parallelism when
the rules are deterministic.  A DMOD model of a dynamic system consists of
rules, roughly, of the form:

	causes(E,F) if Body.

where E and F are event templates, each of the form f(A1,..,Am,T), where T
denotes a real-valued, non-negative time instant.  Informally, the rule
means that event E causes event F provided Body. An example is:

	causes(falls(Domino,T),falls(NextDomino,T+delay)) if
		successor(Domino,NextDomino).

Event occurrences are (roughly) computed by repeatedly using the rule:

	occurs(F) if initial(F) or causes(E,F) and occurs(E).

Given, that e has occurred, an important problem is to compute the bag of
all events g such that causes(e,g). Suppose we have the following rules:

	causes(f(A1,..,Am,T),F1) if B1
	..
	..
	causes(f(A1,..,Am,T),Fk) if Bk

***where each Ai,T is a variable***.  Suppose f(a1,..,am,t) has occurred
where each ai, and t is ground.  Then, one can compute all the effects of
it using:

	bagof(F,causes(f(a1,..,am,t),F),Bag).

Given the overhead of calling bagof, and that this call must be made after
each event occurrence, and that the number of event occurrences can be
tens of thousands, this approach would be extremely slow.  We can do quite
a lot better.

Provided each of these causality rules is deterministic, i.e. produces at
most one effect for a given cause, we can collapse all of these rules into
a single one:

	brings_about(f(A1,..,Am,T),List) if
		cond(B1,F1,L1),
		..
		..
		cond(Bk,Fk,Lk),
		append_all([L1,..,Lk],List).

Here each Li is a variable.  Now brings_about returns a list of caused
events.  The ith call to cond calls Bi and if successful, binds Li to
[Fi].  Otherwise it binds Li to []. append_all appends all of these lists.
The definition of cond is:

	cond(Body,Event,List):-Body,!,List=[Event].
	cond(Body,Event,[]).

Now, to compute the list of all events caused by f(a1,..,am,t) one can
type:

	brings_about(f(a1,..,am,t),List).

No bagof is needed. For our current model, this is about 20 times faster.

LIMITATION: It is entirely possible that a causes rule be non-deterministic,
e.g. in:

	causes(falls(Domino,T),falls(NextDomino,T+delay)) if
		successor(Domino,NextDomino).

successor(A,B) could succeed more than once for a given value of A.  Then
we have to apply such a rule in all possible ways for a given causing
event.  This could be done by redefining the first rule for cond to:

	cond_1(Body,Event,List) :- bagof(Event,Body,List).

This reintroduces bagof. I am not sure how to eliminate this without an
intricate analysis of the program. Any suggestions would be greatly
appreciated.

My current solution is to have the user declare the event templates for
which all causality rules are deterministic, and then use cond for these,
and cond_1 for the rest.

Regards.

Sanjai Narain
Technical Details
Message-ID: <2567@randvax.UUCP>
Path: arc1-ca.pugleaf.net!utzoo!attcan!uunet!snorkelwacker!usc!randvax!narain

Show Full Headers
Complete Article Headers
Path: arc1-ca.pugleaf.net!utzoo!attcan!uunet!snorkelwacker!usc!randvax!narain
From: narain@randvax.UUCP (Sanjai Narain)
Newsgroups: comp.lang.prolog
Subject: Compiling away bagof
Message-ID: <2567@randvax.UUCP>
Date: 31 May 90 20:09:10 GMT
Organization: Rand Corp., Santa Monica, Ca.
Lines: 88