next up previous contents index
Next: Deleting Tables and Table Up: Tabled Predicate Manipulations Previous: Operators for Declaring and   Contents   Index


Predicates for Table Inspection

The user should be aware that skeletons that are dynamically created (e.g., by functor/3) are located in usermod (refer to Section 3.3). In such a case, the tabling predicates below may not behave in the desired manner if the tabled predicates themselves have not been imported into usermod.

We maintain two running examples in this section for explanatory purposes. One uses variant-based tabling:

Variant Example
Program Table
:- table p/2.
:- use_variant_tabling p/2.
p(1,2).
p(1,3).
p(1,_).
p(2,3).
Subgoal
p(1,Y) p(1,2)
p(1,3)
p(1,Y)
p(X,3) p(1,3)
p(2,3)

and the other uses subsumption-based tabling:

Subsumptive Example
Program Table
:- table q/2.
:- use_subsumptive_tabling q/2.
q(a,b).
q(b,c).
q(a,c).
Subgoal
q(X,Y) q(a,b)
q(b,c)
q(a,c)
q(a,Y) q(a,b)
q(a,c)
q(X,c) q(b,c)
q(a,c)

Note that in the subsumptive example, the subgoals q(a,Y) and q(X,c) are subsumed by, and hence obtain their answers from, the subgoal q(X,Y).




get_call(+CallTerm,-TableEntryHandle,-ReturnTemplate)
Tabling
Searches the table for an entry whose subgoal is a variant of CallTerm. Should the subgoal exist, then the handle to this entry is assigned to the second argument, while in the third, its return template is constructed. These latter two arguments should be given as variables.

Example 6.13.3  

Variant Predicate

| ?- get_call(p(X,Y),Ent,Ret).

no
| ?- get_call(p(1,Y),Ent,Ret).

Y = _h92
Ent = 136039108
Ret = ret(_h92);

no
| ?- get_call(p(X,3),Ent,Ret).

X = _h84
Ent = 136039156
Ret = ret(_h84);

no
| ?- get_call(p(1,3),Ent,Ret).

no

Subsumptive Predicate

| ?- get_call(q(X,Y),Ent,Ret).

X = _h80
Y = _h94
Ent = 136043988
Ret = ret(_h80,_h94);

no
| ?- get_call(q(a,Y),Ent,Ret).

Y = _h88
Ent = 136069412
Ret = ret(a,_h88);

no
| ?- get_call(q(X,c),Ent,Ret).

X = _h80
Ent = 136069444
Ret = ret(_h80,c);

no


get_calls(#CallTerm,-TableEntryHandle,-ReturnSkeleton)
Tabling
Identifies through backtracking each subgoal in the table which unifies with CallTerm. For those that do, the handle to the table entry is assigned to the second argument, and its return skeleton is constructed in the third. These latter two arguments should be given as variables.

Example 6.13.4  

Variant Predicate

| ?- get_calls(p(X,Y),Ent,Ret).

X = _h80
Y = 3
Ent = 136039156
Ret = ret(_h80);

X = 1
Y = _h94
Ent = 136039108
Ret = ret(_h94);

no
| ?- get_calls(p(X,3),Ent,Ret).

X = _h80
Ent = 136039156
Ret = ret(_h80);

X = 1
Ent = 136039108
Ret = ret(3);

no
| ?- get_calls(p(1,3),Ent,Ret).

Ent = 136039156
Ret = ret(1);

Ent = 136039108
Ret = ret(3);

no

Subsumptive Predicate

| ?- get_calls(q(X,Y),Ent,Ret).

X = a
Y = _h94
Ent = 136069412
Ret = ret(a,_h94);

X = _h80
Y = c
Ent = 136069444
Ret = ret(_h80,c);

X = _h80
Y = _h94
Ent = 136043988
Ret = ret(_h80,_h94);

no
| ?- get_calls(q(a,Y),Ent,Ret).

Y = _h88
Ent = 136069412
Ret = ret(a,_h88);

Y = c
Ent = 136069444
Ret = ret(a,c);

Y = _h88
Ent = 136043988
Ret = ret(a,_h88);

no


get_calls_for_table(+PredSpec,?Call)
Tabling
Identifies through backtracking all the subgoals whose predicate is that of PredSpec and which unify with Call. PredSpec is left unchanged while Call contains the unified resultant.

Example 6.13.5  

Variant Predicate

|?- get_calls_for_table(p(1,3),Call).  

Call = p(_h142,3);

Call = p(1,_h143);

no
| ?- get_calls_for_table(p/2,Call).

Call = p(_h137,3);

Call = p(1,_h138);

no

Subsumptive Predicate

| ?- get_calls_for_table(q(X,Y),Call). 

X = _h80
Y = _h94
Call = q(a,_h167);

X = _h80
Y = _h94
Call = q(_h166,c);

X = _h80
Y = _h94
Call = q(_h166,_h167);

no


get_returns(+TableEntryHandle,#ReturnSkeleton)
Tabling
Backtracks through the answers for the subgoal whose table entry is referenced through the first argument, TableEntryHandle, and instantiates ReturnSkeleton with the variable bindings corresponding to the return.

The supplied values for the entry handle and return skeleton should be obtained from some previous invocation of a table-inspection predicate.

Example 6.13.6  

Variant Predicate

| ?- get_calls(p(X,3),Ent,Ret),
     get_returns(Ent,Ret).

X = 2
Ent = 136039156    % p(X,3)
Ret = ret(2);

X = 1
Ent = 136039156    
Ret = ret(1);

X = 1
Ent = 136039108    % p(1,Y)
Ret = ret(3);

X = 1
Ent = 136039108
Ret = ret(3);

no

Subsumptive Predicate

| ?- get_calls(q(a,c),Ent,Ret),
     get_returns(Ent,Ret).

Ent = 136069412    % q(a,Y)
Ret = ret(a,c);

Ent = 136069444    % q(X,c)
Ret = ret(a,c);

Ent = 136043988    % q(X,Y)
Ret = ret(a,c);

no
| ?- get_calls(q(c,a),Ent,Ret),
     get_returns(Ent,Ret).

no


get_returns(+TableEntryHandle,#ReturnSkeleton,-ReturnHandle)
Tabling
Functions identically to get_returns/2, but also obtains a handle to the return given in the second argument.

get_returns_for_call(+CallTerm,?AnswerTerm)
Tabling
Succeeds through backtracking for each answer of the subgoal CallTerm which unifies with AnswerTerm. Fails if CallTerm is not a subgoal in the table or AnswerTerm does not unify with any of its answers or the answer set is empty.

The answer is created in its entirety, including fresh variables; the call is not further instantiated. However, an explicit unification of the call with its answer may be performed if so desired.

Example 6.13.7  

Variant Predicate

| ?- get_returns_for_call(p(1,Y),
                          AnsTerm).

Y = _h88
AnsTerm = p(1,_h161);

Y = _h88
AnsTerm = p(1,3);

Y = _h88
AnsTerm = p(1,2);

no
| ?- get_returns_for_call(p(X,Y),
                          AnsTerm).

no
| ?- get_returns_for_call(p(1,2),
                          AnsTerm).

no

Subsumptive Predicate

| ?- get_returns_for_call(q(a,Y),
                          AnsTerm).

Y = _h88
AnsTerm = q(a,c);

Y = _h88
AnsTerm = q(a,b);

no
| ?- get_returns_for_call(q(X,c),
                          AnsTerm).

X = _h80
AnsTerm = q(b,c);

X = _h80
AnsTerm = q(a,c);

no


get_residual(#CallTerm,?DelayList)
Tabling
Backtracks through the answer set of each completed subgoal in the table which unifies with CallTerm. With each successful unification, this argument is further instantiated as well as that of the DelayList.

Example 6.13.8   For the following program and table
:- table p/2.
p(1,2).
p(1,3):- tnot(p(2,3)).
p(2,3):- tnot(p(1,3)).
Call
p(1,X) p(1,2)
p(1,3):- tnot(p(2,3))
p(1,3) p(1,3):- tnot(p(2,3))
p(2,3) p(2,3):- tnot(p(1,3))
the completed subgoals are p(1,X), p(1,3), and p(2,3). Calls to get_residual/2 will act as follows
 
| ?- get_residual(p(X,Y),List).

X = 1       % from subgoal p(1,X)
Y = 2
List = [];

X = 1       % from subgoal p(1,X)
Y = 3
List = [tnot(p(2,3))];

X = 1       % from subgoal p(1,3)
Y = 3
List = [tnot(p(2,3))];

X = 2       % from subgoal p(2,3)
Y = 3
List = [tnot(p(1,3))];

no

Since the delay list of an answer consists of those literals whose truth value is unknown in the well-founded model of the program (see Chapter 5) get_residual/2 can be useful when extensions of the well-founded model are desired.

table_state(+CallTerm,?PredType,?CallType,?AnsSetStatus)


table_state(+TableEntryHandle,?PredType,?CallType,?AnsSetStatus)
Tabling
Succeeds whenever CallTerm is a subgoal in the table, or TableEntryHandle is a valid reference to a table entry, and its predicate type, the type of the call, and the status of its answer set, unify with arguments 2 through 4, respectively.

XSB defines three sets of atomic constants, one for each parameter. Taken together, they provide a detailed description of the given call. The valid combinations and their specific meaning is given in the following table. Notice that not only can these combinations describe the characteristics of a subgoal in the table, but they are also equipped to predict how a new goal would have been treated had it been called at that moment.

PredType CallType AnsSetStatus Description
complete Self explanatory.
variant producer incomplete Self explanatory.
no_entry undefined The call does not appear in the table.
complete Self explanatory.
producer incomplete Self explanatory.
The call is in the table and is properly
complete subsumed by a completed producer.
subsumed The call is in the table and is properly
incomplete subsumed by an incomplete producer.
The call is not in the table, but if it were
subsumptive complete to be called, it would consume from a
completed producer.
The call is not in the table, but if it had
no_entry incomplete been called at this moment, it would
consume from an incomplete producer.
The call is not in the table, but if it had
undefined been called at this moment, it would be
a producer.
undefined undefined undefined The given predicate is not tabled.


next up previous contents index
Next: Deleting Tables and Table Up: Tabled Predicate Manipulations Previous: Operators for Declaring and   Contents   Index
Luis Fernando P. de Castro 2003-06-27