[comp.lang.prolog] assert/1, retract/1 etc. for C-Prolog, Quintus, and BIM

paul@corto.laas.fr (Paul Freedman) (12/22/89)

Some months ago, I posted a request for information about
the consequences of using assert/1, retract/1, etc. on the
runtime speed of a Prolog program.

I have just completed some tests here at LAAS
(Laboratoire d'Automatique et d'Analyse des Systemes) 
with C-Prolog (version 1.5), BIM (version 2.2 15-Jan-1988),
and Quintus (version 2.4.2 for Sun-3, SunOS 3.5),
and I thought that other people might be interested in 
a short summary of the results.

A 12 page technical report with all the details is also available.
Please send me e-mail with your old technology address :)
and I'll mail you a copy.

---------------------------------------------------------------------------

Although the built-in database predicates assert/1 and retract
fall outside the strict definition
of logic programming, they provide a means to
naturally describe the evolution of a system 
in terms of retracting the current `state', updating it in some way,
and then asserting the new `state'.
And when a data structure must be modified by multiple predicates,
it's often more convenient to maintain it in the form of
a ground predicate, rather than passing it from predicate
to predicate as an argument.

In addition, assert/1 and retract/1 can also be used in a general way
to obtain all possible assignments of arguments 
which satisfy a given predicate.
For example, findall/3 defined in (Clocksin and Mellish 1981)
first asserts each possible assignment as an atom, then
forces Prolog to backtrack to find all the other
possibilities, and finally retracts them all to obtain a list
of all the assignments.

It was in this spirit that I first wrote some 2000 lines of code
in C-Prolog (for the sequencing analysis of robotic workcells).
But I soon discovered that examples of a practical size could not be analyzed,
and this was the motivation to consider re-coding for some other
Prolog available at LAAS. 

---------------------------------------------------------------------------

Three variants on the same theme were used; in all cases,
the idea was to create a database of N atoms, collect them in 
the form of a list, and then delete them.
Two database sizes were chosen: N = 1000, and N = 10,000.
The variants for each Prolog environment were the following:

1. via the basic built-in predicates assert/1, retract/1,
and a simple user-defined predicate append/3 taken from
(Clocksin and Mellish 1981):

append([[]],L,L):- !.			/* 1st list is the empty list 	*/
append([],L,L):- !.			/* 1st list is the null list	*/
append([H|T],L1,[H|L2]):- append(T,L1,L2).

2. via the meta-level built-in predicates 
setof/3 and retractall/1

3. via via the meta-level built-in predicates 
bagof/3 and retractall/1

Since C-Prolog does not provide 
retractall/1, an equivalent predicate was user-defined
in terms of retract/1:

retractall:- retract(predicate(_)), fail.
retractall.

Before presenting the test results, a few remarks about
the three Prolog environments are in order.

* Programs can be compiled under Quintus and BIM, but not C-Prolog.

* Only Quintus performs sophisticated memory
management by re-allocating memory in a dynamic way
among the various stacks.
The C-Prolog and BIM environments are static and require
careful initialization for large programs.

* C-Prolog and Quintus both use standard `DEC-10' or `Edinburgh'
style syntax; BIM does not (despite the so-called
`compatibility' switch).
For example, the standard syntax requires that variable names
begin with an upper case letter eg. `Temp' 
(and predicates with a small letter);
under BIM, a variable must begin with an underscore and then
either a lower case or upper case letter eg. `_temp' or `_Temp'.
Such syntactical differences pose problems when porting programs
from one Prolog environment to another.

* Finally, both C-Prolog and BIM provide built-in predicates
for timing the execution of a predicate, in the form of
a `clock' which can be `read' before and after executing a predicate.
For Quintus, an external function was written based on the C function
``times''.

---------------------------------------------------------------------------

First, a summary of the test results for the two interpreted
environments: C-Prolog, and Quintus.


Prolog            Database   Program    Create DB    Collect/Delete DB
----------------------------------------------------------------------
----------------------------------------------------------------------
C-Prolog Sun-3     1000        1.          1.2          5.1
                               2.                      19.0
                               3.                       7.0
                   ---------------------------------------------------
                   10000       1.         12.3          180
                               2.                        NA
                               3.                       200
----------------------------------------------------------------------
Quintus Sun-3      1000        1.          2.2          3.6
                               2.                       2.5
                               3.                       2.0
                   ---------------------------------------------------
                   10000       1.          29           225
                               2.                        39
                               3.                        19
----------------------------------------------------------------------
C-Prolog Sun-4     1000        1.         0.37          2.1
                               2.                       6.8
                               3.                       2.5
                   ---------------------------------------------------
                   10000       1.          3.6          107
                               2.                        NA
                               3.                        95



Now a summary of the test results for the two compiled
environments: BIM and Quintus.


Prolog            Database   Program    Create DB    Collect/Delete DB
----------------------------------------------------------------------
----------------------------------------------------------------------
BIM     Sun-3      1000        1.          2.5          0.7
                               2.                       82
                               3.                       2.4
                   ---------------------------------------------------
                   10000       1.          200          7.2
                               2.                        NA
                               3.                        26
----------------------------------------------------------------------
Quintus Sun-3      1000        1.          1.4          2.3
                               2.                       2.4
                               3.                       1.7
                   ---------------------------------------------------
                   10000       1.          15.7         165
                               2.                        26
                               3.                        18




---------------------------------------------------------------------------

Comparisons among the three different Prolog environments are
difficult to make, and the following comments are strictly my own.

C-Prolog is the most research-oriented Prolog, in that
it offers just an interpreter and essentially creates a single
executable environment from any number of consulted (or re-consulted)
input files.
No special checking is performed to catch conflicting predicate
definitions, or definitions spread over several input files.
The documentation is basic but for the most part, well written.
The results in the first table indicate that
the C-Prolog programs generally execute 3 times faster on the SPARCstation
for the database of 1000 items, and about 2 times faster
for the database of 10,000 items (for which the increased performance of
the CPU is limited by the size of the swap space).

In contrast, Quintus is the most production-oriented Prolog,
in that predicates may be interpreted or compiled (and mixed
within a single executable environment), 
there are many kinds of predicate checking, 
and there is a convenient interface to the EMACS editor;
the documentation is complete and well-written.
In addition, the meta-level predicates setof, bagof, retractall
have been specially optimized for speed.
Because it follows in the C-Prolog (and DEC-10 Prolog) tradition,
Quintus also offers a standard syntax.
But the extra checking (which is important for
developing a commercial product)
makes Quintus more constraining than 
C-Prolog for research work.

Finally, BIM has an orientation somewhere between C-Prolog
and Quintus.
Unlike C-Prolog and Quintus Prolog,
BIM departs from the `standard' syntax, and this makes it difficult to port
programs written for other Prologs.
The documentation is incomplete, and sometimes difficult to follow.
Like Quintus, it offers a compiler (which runs more quickly
than the Quintus compiler), but the meta-level predicates
run more slowly.
However, the basic built-in predicates execute
more quickly under BIM than Quintus.

This advantage in raw speed was explained in a previous
posting to this newsgroup by Richard O'Keefe (18 october 1989).
The BIM compiler produces native code; the Quintus compiler does not.
This means that code compiled by BIM will execute faster,
but cannot be moved among machines with different base
architectures eg. among Sun-3, Sun-4, and VAX.
Native code also tends to be bigger, requiring more memory, which
might be important for programs which create large dynamic structures
running on memory-limited machines.

---------------------------------------------------------------------------

I finally opted to re-code those parts of my C-Prolog system
which made significant use of assert/1, retract/1, and
as a consequence, performed poorly (or not at all) on
examples, in Quintus.

In each case, the re-coding followed similar lines.
Use of assert/1, retract/1 to obtain all possible 
assignments of arguments which satisfy a given predicate 
were re-coded using the bagof/3
(and retractall/1 where required).

In addition, predicates which destructively manipulated
i.e. retracted, modified, re-asserted,
a common data structure (most often lists, or lists of
sublists), were re-coded so as to incorporate the data
structure as an additional argument which could be passed
between predicates.

In another posting to this newsgroup
(25 october 1989), Lee Naish suggested that programs which
make substantial use of assert/1, retract/1, etc. may run
more SLOWLY when compiled than when interpreted.

This was indeed the case with my code.
For example, one C-Prolog program which creates a directed graph
run under Quintus (after very minor syntactic changes) 
was taking 4 or 5 times LONGER to execute when compiled
as compared to when interpreted.

But after all of the changes noted above,
the compiled code ran about 20 times faster than before.
This meant about 3 times faster than the original code
under C-Prolog.
And the new compiled Quintus version was also able to deal with
examples too large to be treated with the original code under C-Prolog.