.\" ----------------------- seca1.t ----------------------
.sh 1 "Extension Tables"
.pp
Extension tables store the calls and answers for a predicate. If a
call has been made before, answers are retrieved from the extension
table instead of being recomputed. Extension tables provide a
caching mechanism for Prolog. In addition, extension tables affect
the termination characteristics of recursive programs. Some Prolog
programs, which are logically correct, enter an infinite loop due
to recursive predicates. An extension table saved on recursive
predicates can find all answers (provided the set of such answers is
finite) and terminate
for some logic programs for which Prolog's evaluation strategy
enters an infinite loop. Iterations over the extension table
execution strategy provides complete evaluation of queries over
function-free Horn clause programs.
.pp
To be able to use the simple extension table evaluation on a set of
predicates, the source file should either be consulted, or
compiled with the \fBt\fR option (the \fBt\fR option
keeps the assembler from optimizing subroutine linkage and allows
the extension table facility to intercept calls to predicates).
.pp
To use extension table execution, all predicates that are to be
saved in the extension table must be passed to \fIet\fR/1. For example,
.(l
| ?\- et([pred1/1, pred2/2]), et(pred3/2)
.)l
will set up ``ET-points'' for the for predicates \fIpred1\fR/1, \fIpred2\fR/2 and
\fIpred3\fR/2, which will cause extension tables for these predicates to be
maintained during execution. At the time of the call to \fIet\fR/1, these predicates
must be defined, either by having been loaded, or through \fIconsult\fR.
.pp
The predicate \fInoet\fR/1 takes a list of predicate/arity pairs for
which ET-points should be deleted. Notice that
once an ET-point has been set up for a predicate, it will be maintained
unless explicitly deleted via \fInoet\fR/1.
If the definition of a predicate which has an ET-point defined is to be updated,
the ET-point must first be deleted via \fInoet\fR/1.
The predicate can then be reloaded and a new ET-point established.
This is enforced by the failure of the goal ``et(P/N)'' if an
ET-point already exists for the argument predicate. In this case,
the following error message will be displayed:
.(l
*et* already defined for: P/N
.)l
.pp
There are, in fact, two extension table algorithms: a simple one, which
simply caches calls to predicates which have ET-points defined; and a
complete ET algorithm, which iterates the simple extension table algorithm until
no more answers can be found. The simple algorithm is more efficient than the
complete one; however, the simple algorithm is not complete for certain
especially nasty forms of mutual recursion, while the complete
algorithm is. To use the simple extension table algorithm,
predicates can simply be called as usual.
The complete extension table algorithm may be used via the query
.(l
| ?\- et_\|star(Query).
.)l
.lp
The extension table algorithm is intended for predicates that are ``essentially
pure'', and results are not guaranteed for code using impure code.
The extension table algorithm saves only those answers which are
not instances of what is already in the
table, and uses these answers if the current call is an instance of a call
already made. For example, if a call \fIp\fR(\fIX\fR, \fIY\fR\^), with
\fIX\fR and \fIY\fR uninstantiated, is encountered and inserted into the
extension table, then a subsequent call \fIp\fR(\fIX\fR, \fIb\fR) will be
computed using the answers for \fIp\fR(\fIX\fR, \fIY\fR\^) already in the
extension table. Notice that this might not work
if var/nonvar tests are used on the second argument
in the evaluation of \fIp\fR.
.pp
Another problem with using impure code is that if an ET predicate is cut
over, then the saved call implies that all answers for that predicate were
computed,
but there are only partial results in the ET because of the cut.
So on a subsequent call the incomplete extension table answers are used
when all answers are expected.
.(l
Example:
r(X,Y) :\- p(X,Y),q(Y,Z),!,fail.
| ?\- r(X,Y) ; p(X,Y).
.)l
.lp
Let p be an ET predicate whose evaluation yields many tuples.
In the evaluation of the query, r(X,Y) makes a call to p(X,Y).
Assuming that there is a tuple such that q(Y,Z) succeeds with the
first p tuple then the evaluation of p is cut over. The call to p(X,Y)
in the query uses the extension table because of the previous call
in the evaluation of r(X,Y). Only one answer is found, whereas the
relation p contains many tuples, so the computation is not complete.
Note that "cuts" used within the evaluation of an ET predicate are ok,
as long as they don't cut over the evaluation of another ET predicate.
The evaluation of the predicate that uses cuts does not cut over any et
processing (such as storing or retrieving answers) so that the tuples that
are computed are saved. In the following example, the ET is used to generate
prime numbers where an ET point is put on prime/1.
.(l
Example:
prime(I) :\- globalset(globalgenint(2)),fail. /* Generating Primes */
prime(I) :\- genint(I), not(div(I)).
div(I) :\- prime(X), 0 is I mod X.
genint(N) :\-
repeat,
globalgenint(N),
N1 is N+1,
globalset(globalgenint(N1)).
.)l
.lp
The following summarizes the library predicates supporting the extension
table facility:
.sp
.lp
\fBet\fR(\fIL\fR)
.ip
Sets up an ET-point on the predicates \fIL\fR, which causes calls and
anwers to these predicates to be saved in an ``extension table''.
.(x b
(L) et/1
.)x
\fIL\fR is either a term \fIPred\fR/\fIArity\fR, where \fIPred\fR is a predicate
symbol and \fIArity\fR its arity, or a set of such terms represented as a list.
\fIL\fR must be
instantiated, and the predicates specified in it defined, at the time of
the call to \fIet\fR/1. Gives error messages and fails if any of
the predicates in \fIL\fR is undefined, or if an ET-point
already exists on any of them; in this case, no ET-point
is set up on any of the predicates in \fIL\fR.
.lp
\fBet_\|\fBstar\fR(Goal\fR\^)
.ip
Invokes the complete extension table algorithm on the goal \fIGoal\fR.
.(x b
(L) et_\|star/1
.)x
.lp
\fBet_\^points\fR(\fIL\fR)
.ip
Unifies \fIL\fR with a list of predicates for which an ET-point is
defined. \fIL\fR is the empty list [] if there are no ET-points defined.
.(x b
(L) et_\^points/1
.)x
.lp
\fBnoet\fR(\fIL\fR)
.ip
Deletes ET-points on the predicates specified in \fIL\fR.
.(x b
(L) noet/1
.)x
\fIL\fR is either a term \fIP\fR/\fIN\fR, where \fIP\fR is the name of a
predicate and \fIN\fR its arity, or a set of such terms represented as a
list. Gives error messages and
fails if there is no ET-point on any of the predicates specified in
\fIL\fR. Deleting an ET-point for a predicate also removes the calls and
answers stored in the extension table for that predicate. The extension
tables for all predicates for which ET-points are defined may be deleted
using \fIet_\^points\fR/1 in cojnunction with \fInoet\fR/1.
\fIL\fR must be instantiated at the time of the call to \fInoet\fR/1.
.lp
\fBet_\|remove(\fIL\^)
.ip
Removes both calls and answers for the predicates specified in \fIL\fR. In
effect, this results in the extension table for these predicates to be set
to empty. \fIL\fR must be instantiated at the time of the call to
either a term \fIP\fR/\fIN\fR, where \fIP\fR is a
predicate with arity \fIN\fR, or a list of such terms. An error occurs if
any of the predicates in \fIL\fR does not have an ET-point set.
All extension tables can be emptied by using \fIet_\^points\fR/1 in
conjunction with \fIet_\^remove\fR/1.
.(x b
(L) et_\|remove/1
.)x
.lp
\fBet_\|answers\fR\^(\fIP\fR/\fIN\fR, \fITerm\fR\^)
.ip
Retrieves the answers stored in the extension table for the predicate \fIP\fR/\fIN\fR
in \fITerm\fR one at a time. \fITerm\fR is of the form
\fIP\fR(\fIt\fR\*<1\*>, ..., \fIt\*\fR). An error results and
\fIet_\^answers\fR/2 fails if \fIP\fR/\fIN\fR is not fully specified (ground),
or if \fIP\fR/\fIN\fR does not have an ET-point set.
.lp
\fBet_\|calls\fR(\fIP/N\fR, \fITerm\fR\^)
.ip
Retrieves the calls stored in the extension table for the predicate \fIP/N\fR
in \fITerm\fR one at a time. \fITerm\fR is of the form
\fIP\fR(\fIt\fR\*<1\*>, ..., \fIt\*\fR). An error results and
\fIet_\^calls\fR/2 fails if \fIP\fR/\fIN\fR is not fully specified (ground),
or if \fIP\fR/\fIN\fR does not have an ET-point set.
.(x b
(L) et_\|calls/2
.)x
.lp
.\" -------------------- end of section seca1.t ----------------------