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 | ||||
|
| ||||
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 | ||||
|
| ||||
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).
Example 6.13.3
|
Example 6.13.4
|
Example 6.13.5
|
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
|
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
|
| |||
p(1,2). | |||
p(1,3):- tnot(p(2,3)). | |||
p(2,3):- tnot(p(1,3)). |
| ||
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)) | ||
| ?- 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.
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. |