next up previous contents index
Next: 6.14.3.1 Table Deletion Predicates Up: 6.14 Tabled Predicate Manipulations Previous: 6.14.2 Predicates for Table   Contents   Index


6.14.3 Deleting Tables and Table Components

The following predicates are used to semantically invalidate tables and/or reclaim their space. The use of the word ``tables'' in this section is rather unspecific. For the purpose of deletion a table can either be information pertaining to a single subgoal of a tabled predicate (which is called here a tabled subgoal), or pertaining to all subgoals of a tabled predicate. Predicates are provided to invalidate tables not only for particular predicates and subgoals, but for all tabled predicates, all tabled predicates in a module, and in the multi-threaded engine all thread-private tabled predicates or all thread-shared tabled predicates. Overall, these predicates share similar characteristics.

First, an incomplete tabled subgoal $S$ may not be abolished by the user except under special circumstances described below. This restriction is made since if $S$ is incomplete there may be pointers to $S$ from various elements of the current execution environment, and removing all of these pointers may be difficult to do. If one of the deletion predicates is called when the current execution environment contains a choice point into a completed table that is being abolished, space for the abolished information is not immediately reclaimed. More precisely, if the current execution envonment has a choice point that points to an answer $A$ we say that $A$ is active in the current environment. If a tabled predicate $P$ or subgoal $S$ to be abolished has an answer that is active in the current environment, reclamation of space for $P$ or $S$ will be delayed until no answers for $P$ or $S$ are active. New calls to $P$ or $S$, however, will derive a new table, rather than using the abolished information.

When conditional answers are present, abolishing a specific table or call may lead to semantic or implementational complications. Consider the conditional answer r(a,b):- undef| from Figure 6.1. If the predicate r/2) (or subgoal r(a,X)) is abolished and later rederived, the rederivation of r(a,X) might have different semantics than the original derivation (e.g. if undef depended on a dynamic predicate whose definition has changed). From an implementation perspective, if space for r(a,X)) is reclaimed, then the call get_residual(p(a,X),Y) may core dump, even if there are no choice points for completed tables anywhere in the choice point stack. To address this problem, by default abolishing a subgoal $S$ (predicate $P$) will abolish all subgoals (predicates) that (transtively) depend on $S$ ($P$6.12. In this case the goal abolish_table_call(r(a,X)) would cause the deletion of p(a,X) while the goal abolish_table_pred(r/2) would cause the deletion of p/2, since there are tabled subgoals of p/2 that depend on r/2. Only dependencies from subgoals or answers to the answers that are conditional on them are taken into account for table deletion: thus the deletion r(a,X) deletes p(a,X), but not undef.

Users with programs that give rise to conditional answers in completed tables are encouraged to maintain this default behavior. However the default behavior may be changed either by setting an XSB flag:

?- set_xsb_flag(table_gc_action,abolish_tables_singly).
or by calling a 2-ary abolish command with abolish_tables_singly in the options list.

Figure 6.1: Example for Deleting Tables (Call-Variance)
Program Table
:- table p/2, r/2.
p(X,Y):- r(X,Y).

r(a,b):- undef.
r(a,c):- undef.
r(a,d):- undef.
r(a,e):- undef.

:- table  s/0, t/0.
s:- tnot(t).

t:- tnot(undef).

:- table undef/0.
undef :- tnot(undef).
Subgoal Answer Set Status
p(a,X) p(a,b):- r(a,b)$\vert$ complete
  p(a,c):- r(a,c)$\vert$  
p(b,X) p(b,d):- r(b,d)$\vert$ complete
  p(b,d):- r(b,e)$\vert$  
r(a,X) r(a,b):- undef$\vert$ complete
  r(a,c):- undef$\vert$  
r(b,X) r(b,d):- undef$\vert$ complete
  r(b,d):- undef$\vert$  
s s:- tnot(t)$\vert$ complete
t t:- tnot(undef)$\vert$ complete
undef undef:- tnot(undef)$\vert$ complete

 

In the multi-threaded engine abolishing tables private to a thread behaves exactly as in the sequential engine, regardless of whether the tables are complete or incomplete, or contain conditional answers. In addition, when a thread $T$ exits (by normal termination or via an exception), tables private to $T$ are abolished automatically and their space reclaimed, as are any incomplete shared tables owned by $T$ in local evaluation. Shared tables can be abolished by the user at any time, but their space will not be reclaimed until there is a single active thread.

As mentioned above, during normal execution, an incomplete tabled subgoal may not be abolished by the user, a restriction that is made to ensure correct evaluations. Accordingly, calling an abolish_xxx predicate when tables are incomplete raises an error. However, we note that any incomplete tables are abolished automatically by the system on exceptions (by the default system error handler) when the interpreter level is resumed.



Subsections
next up previous contents index
Next: 6.14.3.1 Table Deletion Predicates Up: 6.14 Tabled Predicate Manipulations Previous: 6.14.2 Predicates for Table   Contents   Index
Terrance Swift 2007-10-05