a space efficient engine for subsumption-based tabled evaluation of logic programs

18

Upload: sbsuny

Post on 20-Nov-2023

0 views

Category:

Documents


0 download

TRANSCRIPT

A Space E�cient Engine for Subsumption-Based Tabled Evaluation ofLogic ProgramsErnie JohnsonC.R. RamakrishnanI.V. RamakrishnanPrasad Rao�Department of Computer ScienceState University of New York at Stony BrookStony Brook, New York 11794-4400fejohnson,cram,[email protected] resolution methods increase the declarativeness and e�ciency of logic programs throughthe sharing of answer computations. In variant-based tabled logic programming systems, an-swer computations are shared only between calls that are identical modulo variable renaming.Subsumption-based tabling can yield superior performance by sharing answer computations be-tween a more general (subsuming) call and speci�c (subsumed) calls. But realizing this potential inpractice requires the capability to e�ciently index into dynamic sets of terms.In an earlier work, we proposed a data structure called Dynamic Threaded Sequential Automata(DTSA) to tackle this problem. By retrieving answers from a table one at a time, strictly in theorder of their insertion, we ensured that all relevant answers are eventually selected for resolution.Although this method showed substantial improvements in time performance for queries where thesubsumption of calls was possible, table space usage was high: potentially quadratic in the size ofcorresponding tables constructed in a variant-based tabling engine.In this paper we present an alternative to DTSA, called the Time-Stamped Trie (TST), whichnot only maintains the time e�ciency of the DTSA engine but has provably better space e�ciency.We present experimental results to validate these claims.Contact Author: Ernie JohnsonPhone: +1 - 516 - 632 - 8470Fax: +1 - 516 - 632 - 8334email: [email protected]: Department of Computer ScienceSUNY at Stony BrookStony Brook, NY 11794-4400, USA.�Currently at Telecordia Technologies, [email protected]

1 IntroductionTabled resolution methods in logic programming (LP), beginning with OLDT resolution pioneered byTamaki and Sato [11], address the well-known shortcomings of the SLD evaluation mechanism of Prolog,namely, susceptibility to in�nite looping, redundant subcomputations, and inadequate semantics fornegation. Using tabled resolution we can �nitely compute the minimal model for datalog programs.More recent methods [1, 2] compute well-founded semantics [12] for normal logic programs. Due to thisadded power, tabled evaluation enables us to fruitfully combine the areas of LP, deductive databases,and nonmonotonic reasoning. Moreover, high level implementations of complex applications involving�xed-point computations such as program analysis and model checking, which were beyond the reach oftraditional LP systems, have now been made feasible with tabled LP. In fact, using the XSB tabled LPsystem [6], we have constructed program analyzers [8] and model checkers [7, 5] that are competitive(in time and space) with existing systems consisting of much larger programs written in lower levellanguages.Surprisingly, the power and usefulness of tabled logic programming stems from one simple notion:avoid redundant computation by permitting the use of proven instances, or answers, from past compu-tation for satisfying new subgoals. Conceptually, this is achieved through the use and maintenance ofa global resource | the table | containing the called subgoals paired with the set of answers derivedfor each such subgoal. Predicates are marked a priori as either tabled or nontabled. When a call ismade, i.e., a subgoal is selected for resolution, tabled evaluation proceeds as follows. For nontabledpredicates, the subgoal is resolved against program clauses. For tabled predicates, the subgoal is �rstchecked against the entries maintained in the table. If there exists a \similar-enough subgoal", thenits associated answers can be utilized to satisfy this call through answer resolution. That is, the call isresolved against these answers rather than against program clauses; otherwise the subgoal is entered inthe table, and its answers, computed by resolving the subgoal against program clauses, are also enteredin the table. For both tabled and nontabled predicates, program clause resolution is carried out usingSLD. Thus, by keeping track of which subgoals have been called along with their computed answers,tabled logic programs bene�t from an increase in time e�ciency and the avoidance of in�nite loops.In general, there are two approaches to locate a \similar-enough" goal. One method is to lookfor an entry which is a variant of the current goal.1 This method is the one employed by the XSBsystem [9]. Although variant-based tabling has proven to be greatly bene�cial, this approach permitsonly limited sharing of answer computations.The second approach aims at expanding the sharing of answer computations. In particular, givena goal G, any entry in the call table, say G0, which subsumes G will contain in its (�nal) answer set allthe instances to satisfy G.2 Hence, the answer table of G0 can be used to resolve G. This approach,called subsumption-based tabling, permits greater reuse of computed results, avoids computationally-expensive program clause resolution, and thereby can lead to superior time performance. Space perfor-mance may also be improved since fewer calls and their associated answer sets need be stored in tables.Of course, these bene�ts come at a price: the mechanisms for e�ciently representing and accessing thecall and answer tables are more complex. In particular, answer resolution now involves indexing, sincenot all answers in a selected answer table (say, that of G0) may be applicable to the given goal (say,G). This process is especially challenging since all answers to G0 may not yet be present in the tablewhen the call to G is made.In an earlier work [10], we proposed a data structure called Dynamic Threaded Sequential Au-tomaton (DTSA) for representing and e�ciently retrieving answers from dynamic answer sets. Answerresolution is performed one tuple at a time by backtracking through a DTSA. To ensure that every1Two terms are variants if they can be made identical through variable renaming.2A term t1 subsumes a term t2 if t2 is an instance of t1. Further, t1 properly subsumes t2 if t2 is not a variant of t1.1

relevant answer is visited, answers are retrieved strictly in the order of their insertion into the table.However, this organization has the potential to dramatically increase the size of the representationof the answer set. Additionally, incremental traversal of the DTSA for each answer resolution forcesus to maintain complex state information. Although an implementation based on this strategy showsimprovement in time performance on queries where the subsumption of calls is possible, it performspoorly in space when compared to the variant-based tabling engine.In this paper we describe a di�erent approach for organizing tables in a subsumption-based tablingengine in which relevant answers are periodically collected from the subsuming call's answer set andcached for later consumption. A new batch of answers is collected during answer resolution if all answerscurrently held in the cache have already been resolved against the goal. Each such collection phasecompletely searches the set for answers which have been entered since the previous phase, selectingonly those answers which unify with the subsumed goal. Since the search is carried out to completionduring each phase, only minimal state information need be maintained between phases. We deviseTime-Stamped Tries (TST ) as the data structure for organizing tables in this approach. Speci�cally,when TSTs are used to represent the answer sets of subsuming subgoals, only the time at which the lastanswer was added to the set is required to represent the state. Time-Stamped Tries support e�cientretrieval of recently inserted answers as they support indexing on both the time an answer is insertedas well as the symbols in the answer term. Our experiments show that the time performance of asubsumption-based tabling system using TSTs is comparable to that using DTSA, while table spaceusage is always better than that of the DTSA whenever there is some sharing due to subsumption.Furthermore, the table space using TSTs is never more than twice the size of tables in the variant-basedengine. In contrast, the space usage of the DTSA can sometimes be quadratic in terms of a variantengine's space usage.The rest of the paper is organized as follows. In Section 2, we present an operational overview oftabling operations and answer resolution in subsumption-based tabling. The design and implementationof TSTs appears in Section 3. Comparisons between DTSA, TST and variant-based tabling enginesappear in Section 4. In Section 5 we provide performance results of a subsumption-based tabling engineimplemented using TSTs. In Section 6 we discuss how one can use a subsumption-based engine tocontrol the degree of goal directedness. This provides exibility in incorporating bottom-up evaluationwithin a top-down framework without having to change the logic programming engine's core evaluationstrategy.2 Tabled Evaluation and Answer ResolutionIn this section, we give an overview of the time-stamp-based approach to e�ciently support subsumptivetabling. We begin with an abstract description of the operations of a tabling system.2.1 An Overview of Tabling OperationsWe can view top-down tabled evaluation of a program in terms of four abstract table operations: call-check-insert, answer-check-insert, retrieve-answer and pending-answers. Below, we describe each ofthese operations in the context of subsumptive tabling.Call-check-insert Given a call c, the call-check-insert operation checks if there is a call c0 in the calltable such that c0 subsumes c. If there is no such c0 this operation inserts c in the call table. Insertionof c in the table indicates that the subgoal will be resolved using program clause resolution (PCR). If asubsuming c0 is found, then the corresponding subgoal will be resolved using answer clause resolution2

(ACR). By identifying an appropriate subsuming call c0, the operation also determines the answer tablewith which answer clause resolution will be performed. Note that call-check-insert is independent ofthe data structures used to represent answer tables.A subgoal that is resolved using PCR creates answers to be inserted into the corresponding answertable, say T , and is known as the producer of T . A subgoal that is resolved using ACR with respect toan answer table T 0 is known as a consumer of T 0.Answer-check-insert Answers that are computed for a tabled subgoal c using PCR are enteredin the answer table corresponding to c using answer-check-insert operations. This operation insertsa given answer a in an answer table T i� a is not already present in T . Note that, while the datastructures used to represent answer tables may be di�erent between subsumptive and variant tabling,the requirements on answer-check-insert remain the same.Retrieve-answer Answer clause resolution of a goal G against a set of terms T = ft1; t2; : : : ; tngin an answer table produces a set R such that r 2 R i� r = ti�i for some ti, where �i = mgu(G; ti).This resolution is performed using retrieve-answer operations. In a tuple-at-a-time resolution engine,a consumer choice point is placed so that the answers can be retrieved one by one using backtracking.We avoid returning the same answer multiple times by explicitly maintaining an answer continuation inthe choice point, which represents the set of all answers remaining to be retrieved. Hence the argumentssupplied to a retrieve-answer operation depends on whether the �rst answer or a subsequent answer isdemanded. This operation is split naturally into:�rst answer: Given an answer table T and a call c, return an answer from T that uni�es with c, andan answer continuation.next answer: Given an answer table T , a call c, and an answer continuation , return the nextanswer a from T that uni�es with c as speci�ed by , and a modi�ed answer continuation 0 thatrepresents all answers represented by except a.Answer continuation ? denotes that there are no more remaining answers; note that in the presenceof incomplete answer tables, ? cannot be interpreted as the end of answer resolution.Pending-answers When a retrieve-answer operation for a call c on an incomplete table T returns?, the call c will be suspended. The suspended call is later resumed when new answers have been addedto T , or when T is determined to be complete. Suspension and resumption of calls are performed bya process called answer scheduling in the engine. The answer scheduler invokes pending-answers todetermine whether a suspended call needs to be resumed. Given an answer continuation, pending-answers succeeds i� the continuation represents a non-empty set of answers.2.2 Answer Retrieval in Subsumptive TablingThe DTSA, proposed as a data structure for answer tables in [10], directly supports the �rst-answer andnext-answer operations. In this paper, we describe a two-tier mechanism to realize these operations. Atthe fundamental level, we decouple the operation of identifying the answers relevant to a given goal in ananswer set from the operation of unifying these answers with the goal. The rationale for the decouplingfollows from the observation that identi�cation must deal with indexing into dynamically growing sets.The uni�cation operation generalizes the answer consumption operation in variant tabling [9], replacingthe substitution operation (binding variables to terms) with uni�cation. Separating these operationsinto distinct phases is key to the space- as well as time-e�cient design described in this paper.3

Note that the operation identifying relevant answers, no longer burdened with answer uni�cation,is not constrained to a tuple-at-a-time process. We hence propose an e�cient mechanism to identifyall relevant answers that have been added since the last time the table was inspected. We associatea time stamp with each answer and maintain, as part of the answer continuation, the maximum timestamp of any answer in the set. The answer terms and their time stamps are stored in a data structurecalled a Time-Stamped Trie (TST), which is described in detail in Section 3. TST provides an accessfunction, identify relevant answers which, given a table T , time stamp � and goal G, identi�es the setof all answers in T with time stamps greater than � that unify with G. It returns this set as a list (withsome internal order) as well as the maximum time stamp of any answer in T .Recall that answers are consumed from a table by a �rst answer operation followed by a sequenceof next answer operations. We can implement these tuple-at-a-time operations based on TSTs asfollows (see Figure 1). We assume that time stamps are positive (non zero) integers. To compute�rst answer, we use identify relevant answers with a time stamp of zero (thereby qualifying all availableanswers), select one answer from the returned set as the current answer, and store those remaining in aninternal data structure called an answer list. The answer list, together with the maximum time stampreturned by identify relevant answers, form the answer continuation. On (subsequent) invocations ofnext answer, we simply manipulate the answer list component of the continuation, as long as the answerlist is not empty. Should the answer list be empty, we \refresh" the continuation by another call toidentify relevant answers, using the time stamp component of the continuation to restrict identi�cationto only those answers that have been inserted since the last call to identify relevant answers. Let � bethe time stamp returned by an invocation of identify relevant answers. Since the operation identi�esall relevant answers, h[ ]; �i represents the empty continuation, ?.We can view �rst answer as a special case of next answer : one with an open answer continua-tion. Note that the continuation that represents all answers in a table is of the form h[ ]; 0i. Thus,�rst answer(T;G) can be realized simply as next answer(T;G; h[ ]; 0i).We now formally state the requirement on identify relevant answers that is needed to show thecorrectness of �rst answer and next answer :Requirement 1 Given an answer table T representing a set of answers S, a goal G and a time stamp� , identify relevant answers(T;G; �) returns a permutation of the set fa 2 S j a uni�es with G andtimestamp(a) > �g.The correctness of operation retrieve-answer is then ensured by the following proposition:Proposition 1 Given a goal G and answer table T representing a set of answers S, letha1; 1i; : : : ; han; ni be a sequence of values such that ha1; 1i = �rst answer(T;G) and hai+1; i+1i= next answer(T;G; i), 1 � i < n, and n = ? = h[ ]; �i. Further, let B be the set fb 2 S jb uni�es with G and timestamp(b) > �g. Then, provided identify relevant answers satis�es Require-ment 1, the sequence ha1; : : : ; ani is a permutation of the set fb� j b 2 B, where � = mgu(b; G)g.3 Time-Stamped TriesIn this section we describe the Time-Stamped Trie, a data structure for supporting iden-tify relevant answers, which requires indexing on term symbols as well as time stamps.Before introducing the Time-Stamped Trie, we review the trie data structure as used for repre-senting answer tables [9]. We begin by de�ning notational conventions and terminology. A position ina term is either the empty string � that reaches the root of the term, or �:i, where � is a position andi is an integer, that reaches the ith child of the term reached by �. By tj� we denote the symbol at4

algorithm next answer(T,G, )hL; �i = (* L is the current answer list *)(* � is the maximum time stamp of answers seen in last identi�cation phase *)(* Refresh L using an identi�cation phase if there are no remaining answers *)if ( L = [ ] ) thenhL; �i = identify relevant answers(T;G; �)endif(* Serve answers out from L one at a time *)if ( L 6= [ ] ) thena = head(L)G0 = G� where � = mgu(G;a) 0 = htail(L); � ireturn ( hG0; 0i )else 0 = h[ ]; �ireturn ( h�; 0i )endifalgorithm �rst answer(T,G)return next answer(T,G, h[ ]; 0i )Figure 1: Answer Retrieval in Subsumptive Tablingposition � in t. For example, p(a; f(X))j2:1 = X . Terms are built from a �nite set of function symbolsF and a countable set of variables V [ V̂, where V is a set of normal variables and V̂ is a set of positionvariables. The variables in the set V̂ are of the form X�, where � is a position, and are used as anotational convenience to mark certain positions of interest in a term. The set of all variables in aterm t is denoted by vars(t). We denote by �; �0; : : : the elements of F [ V . The arity of a symbol �is denoted by arity(�); note that the arity of variable symbols is 0.A trie is a tree-structured automaton, with the root as the start state and leaves as acceptingstates, used for indexing into a set of terms. Let T = ft1; t2; : : : ; tng be a set of terms. A trie for Thas a unique leaf state si for every ti, 1 � i � n, such that the sequence of symbols on the transitionsfrom the root to si correspond to the sequence of symbols encountered in a preorder traversal of ti.Moreover, for every state in a trie, all outgoing transitions have unique labels.A trie supports two operations on the set of terms, T , that it represents: (1) to determine if a goalterm t is present in T , and (2) given a goal term t, determine the set of all terms t0 2 T that unifywith t. We can formally treat these operations using the notions of skeleton and fringe from [3], whichwe recall below.De�nition 1 (Skeleton and Fringe [3]) The fringe of a term t, denoted fringe(t), is the set of allpositions � such that tj� = X� and X� 2 V̂. A skeleton is a term S over F [ V [ V̂ such thatX� 2 vars(S) i� � 2 fringe(S).With each state s in a trie, representing a set of terms T , we associate a skeleton, denoted by Skels,that represents the set of uni�cation operations that must be performed to reach that state. The fringeof Skels represents positions where further uni�cation operations need to be performed before unifyinga goal term with a term in T . The position in the goal term inspected at s is represented by the �rst5

p(a,a,a)p(b,a,W)p(a,a,c)p(a,b,b)p(a,a,d)p(a,a,a) p(a,a,c) p(a,a,d) p(a,b,b)

a,5

a,5

a,1c,3

b,2

b,4

b,4

d,5

1 3 5 4

a,2

2p(b,a,W)

W,2

p(a,a,a) p(a,a,c) p(a,a,d) p(a,b,b)

a,6

a,5

a,1c,3

a,2

b,2

b,6

W,2

21 3 5 4p(a,b,c)

6

c,6d,5 b,4

p(b,a,W)(a) (b) (c)Figure 2: Set of terms (a), its corresponding TST representation (b), and e�ect of inserting p(a,b,c)to the TST (c).position variable encountered in a preorder traversal of the skeleton. We denote this position by �(s).Each outgoing transition from s represents a uni�cation operation involving position �(s) in the goaland the symbol labeling this transition. We label transitions by �, where � is a variable or a functionsymbol. Let the skeleton of the current state be S and the position examined be �. The skeleton S 0 ofthe destination state reached by a transition labeled by � is S[t=X�], where t = f(X�:1; : : : ; X�:n) if �is a n-ary function symbol f and t = � otherwise. Note that for a leaf state s in the trie, fringe(Skels)is empty and that Skels 2 T is the term represented by the leaf s.A Time-Stamped Trie (TST) is a trie augmented with information about the relative time itsterms were inserted. The time of insertion of each term is called its time stamp, and is representedby a positive (non zero) integer. Each transition in a TST is additionally labeled with the maximumtime stamp of any leaf reachable using that transition. Hence, all transitions in a TST will be ofthe form s h�;�i�! d, where s and d are states in the TST, � is the symbol, and � is the time stamp.We refer to these attributes of a transition � as symbol(�) and timestamp(�), respectively. Sinceidentify relevant answers looks only for answers with time stamps greater than a given value � , notethat the maximum time stamp information is necessary to focus the search on portions of the TSTthat correspond to answers with such time stamp values.The TST for the set of terms in Figure 2(a) (with terms inserted in top-to-bottom order) is givenin Figure 2(b).3.1 Term Insertion in a TSTTerms are inserted into a TST in a manner analogous to the single-pass check-insert for a trie repre-sentation described in [9]. The TST is traversed recursively starting at the root. A transition fromstates s to d, s h�;�i�! d, is taken if the symbol � matches the symbol in the goal term at the positionspeci�ed by s. If a leaf node is reached, then the term already exists in the TST, and hence the TSTis left unchanged. On the other hand, if a match operation fails at a state s, then a new path is addedto the TST corresponding to the goal term. All time stamps on the root-to-leaf path corresponding tothe new term are updated with a value greater than any other time stamp in the TST. This recursiveprocedure is speci�ed in Figure 3. The TST obtained from the one in Figure 2(b) by adding the termp(a,b,c) is given in Figure 2(c). The new transitions and states, as well as the transitions whose timestamps were modi�ed by the addition, appear in bold face in the �gure.6

algorithm insert(s;t; �)(* returns true i� t was successfully inserted *)beginif ( fringe(Skels) = fg ) thenreturn ( false ) (* term already exists, hence insert fails *)endiflet Gj�(s) = f=n = �if ( 9� : s h�;� 0i�! d ) thenif ( insert(d;t; �) ) thentimestamp(�) = � (* insert successful, so update time stamp *)return ( true )elsereturn ( false ) (* insert failed; propagate failure up *)endifelse (* match fails at s, so add a new path *)create new state d and add transition � : s h�;�i�! dSkeld = Skels [f(X�(s):1; : : : ;X�(s):n)=X�(s)]insert(d;t; �)return ( true )endifendFigure 3: Term Insertion into a Time-Stamped Trie3.2 Identifying Relevant Answers using a TSTWe now describe how TST supports identify relevant answers. Given a goal G and a time stamp � ,answers in a TST T are identi�ed by recursively traversing T from the root, at each state exploring alltransitions that meet the term indexing as well as the time stamp constraints. The set of transitionsto be explored can be formally speci�ed as follows.De�nition 2 (Set of Applicable Destinations) Given a TST, T , the set of all destination statesthat are applicable upon reaching a state s in T with an initial goal G and time stamp � , denoteddest(s; G; �), is such that d 2 dest(s; G; �) i� (i) Skeld is uni�able with G, and (ii) s h�;� 0i�! d is atransition in T with � 0 > � .Among the two conditions speci�ed above for selecting applicable transitions, the �rst corresponds toindexing on terms while the second corresponds to indexing on time stamps.Given a state s in a TST, a goal G, and time stamp � , the set of all terms represented by theleaves reachable from s with time stamps greater than � and uni�able with G are given by:relevant(s; G; �) = 8<: fSkelsg if s is a leafSd 2 dest(s;G;�) relevant(d;G; �) otherwiseLet T be a TST. Then,identify relevant answers(T;G; �) = relevant(root(T ); G; �)We can establish that the above de�nition of identify relevant answers meets Requirement 1.Proposition 2 (Correctness) Given a Time-Stamped Trie T representing a set of terms S, a goalG and a time stamp � , identify relevant answers(T;G; �) computes the set fa 2 S j a uni�es with Gand timestamp(a) > �g. 7

Although one can readily derive a computation based on the above de�nition of iden-tify relevant answers, its e�ectiveness depends on the e�cient implementation of dest. It should benoted that the condition in dest for indexing on terms is identical to the one with which transitionsto be traversed are selected in a (non time-stamped) trie [9]. The indexing on time stamps, however,is unique to TSTs. We can show that identify relevant answers can be e�ciently computed given ane�cient technique to index on time stamps at each state in a TST, as formally stated below.Requirement 2 Given a TST, T , � = dest(s; G; �) is computed in time proportional to j�j.Proposition 3 (E�ciency) Let G be an open goal|i.e., a term whose immediate subterms are alldistinct variables|T be a TST, and identify relevant answers(T;G; �) be a nonempty set of terms Sfor some given value of � . Then, if dest satis�es Requirement 2, identify relevant answers(T;G; �) canbe computed in time proportional to the sum of the sizes of the terms in S.Below, we describe an implementation of dest that meets Requirement 2.3.3 Implementation NotesThe implementation of TSTs closely resembles the implementation of answer tries in XSB [9]. Brie y,each state s of the TST is represented by a node, node(s), with the tree structure maintained throughthe standard mechanism of child and sibling �elds for supporting arbitrary fanning in the tree. Thesymbol and time stamp on the transition from state s0 to s in the TST is stored in node(s). As in tries,term indexing is supported by hashing sibling nodes according to the symbol they contain. Note thatterm indexing is required for insertion as well as answer identi�cation.In the absence of indexing information on symbols, it is crucial to be able to index on timestamps, so that the applicable transitions can be selected in time proportional to the number of selectedtransitions, instead of the total number of transitions. To this end, we maintain a separate time-stampindex which stores all transitions (i.e., the sibling nodes) in reverse time-stamp order. This order letsus e�ciently select transitions based on time stamps alone, at constant time per selected transition,thereby meeting Requirement 2. Recall that when a new term is inserted into the TST, the timestamps along the path representing this term must be updated with the time assigned to this newterm (refer to Figure 2(c) and Figure 3). Since the time-stamp index structure may be reordered, itis implemented as a doubly linked list. As in the case of term indexing where hash tables are createdonly when the number of transitions is more than a small constant (8 in the current implementation),the time-stamp index structures are also built only when this threshold is exceeded.Since TSTs are needed to support answer retrieval from incomplete answer sets, and TSTs are aconservative extension of the trie data structure, the time stamp on transitions as well as the associatedtime-stamp index structure can be discarded once the answer table is completed. By maintaining thisinformation in a separate structure which can be reclaimed after completion, the �nal space usage ofthese answer sets can be reduced. Moreover, the size of an answer node is only one word larger thanthat in the variant engine. However, the total space associated with the node, including the time indexstructure, is twice that used by a node of the variant engine's answer table. We show the e�ects oftable completion on space utilization in Section 5.Finally, note that creation of these auxiliary structures in a particular TST is not necessary until itis determined that some properly subsumed call will consume from it. We create the time-stamp-relatedstructures lazily, upon encountering the �rst properly subsumed consumer.8

p(a,b,b)p(a,a,a) p(a,a,c)

a

a a

a

a

a

c d

b

p(a,a,d)

b

W

p(b,a,W)

b

a

1s

s

s

s s s

ss

s s

s s

s s

2

3

4

5

6

7

8

9

10

11

12

13

14

2s

2s

82

1s

1

4s s

7s

6 10s

s93

Answer

List

dca b

11

a b a

a b

s

33s s3 5

W(a) (b)Figure 4: DTSA (a) and Trie (b) representation of terms in Figure 2(a).4 Comparing the ImplementationsIn this section, we directly compare the approaches embodied by the implementations underlying thevariant-, TST-, and DTSA-based tabling engines. In the next section, we show how the engines performin practice. To provide the context for comparisons, we now brie y review the data structure calledDynamic Threaded Sequential Automaton (DTSA) that was used in our earlier implementation of asubsumption based tabling engine. See [10] for details.The DTSA Structure DTSA is a trie-like automaton for representing a set of terms ft1; t2; : : : ; tngwith a total ordering � on them such that for 1 � i < n, ti � ti+1. A DTSA is constructed such thatthe leaf representing term ti is visited before the leaf representing term ti+1 in a preorder traversalof the DTSA. This ensures that the given total order among the terms is preserved. The DTSAcorresponding to the answer set in Figure 2 is shown in Figure 4(a). Observe that although DTSAand tries are similar in structure, there are notable di�erences. In particular, since transitions froma state s preserve the order of terms represented by the �nal states reachable from s, there may bemultiple transitions with the same label. The loss of indexing due to this duplication is o�set by usingthreads which link states that share pre�xes. For instance, using the DTSA in Figure 4(a) to �ndterms uni�able with a given goal term p(a,a,V), after �nding the �rst term (at state s4), the nextterm, p(a,a,c), can be retrieved by backtracking to s3, following the thread to s9, and making thetransition to s10. Observe that s3; s9; s10 all have paa as their pre�x.Both the TST and DTSA engines extend the variant-based tabling engine of XSB to support theoperations of subsumptive tabling. As such, the resulting engines share many similar features witheach other and the variant engine. Below, we highlight some of the more important ones.4.1 Shared FeaturesAll engines distinguish between complete and incomplete table entries. A complete table entry issimply a call entry for which the entire set of answers has been computed. Entries for which this isnot the case are termed incomplete. Call and answer sets are represented by tries. Completed tablesin all engines take advantage of what is called compiled trie code. This is a feature of the answertries which embed WAM-like instructions at each node, enabling uni�cation with a goal with e�ciencycomparable to compiled facts (see [9] for details). Answer resolution with a completed table uses theanswer trie via these instructions. No additional machinery is needed to support subsumption since triecode instructions perform uni�cation. Incomplete tables, however, cannot take advantage of this feature9

due to the nature of trie insertions. Since new answers may be added anywhere in the trie, answers maybe missed if insertions are interleaved with answer retrievals. Answer sets for such entries, therefore,are additionally represented by a series of pointers to leaf nodes of the answer trie (see Figure 4(b)).Uni�cation of answers with the goal via these pointers is less e�cient since uni�cation factoring, i.e.,sharing of common bindings, is lost. However, all three versions of XSB ameliorate this de�ciencythrough the use of substitution factoring whereby only the substitutions for the variables of the callare stored in the answer tries [9]. Substitution factoring is performed as a part of call-check-insert.Answer tables eliminate duplicate answers modulo variance, even in the subsumptive engines. Inboth subsumption engines, sequences of leaf node pointers are also maintained for properly subsumedcalls which are resolved using incomplete answer tables. This caching of relevant answers preventssubsequent variant calls from repeating answer identi�cation. Reuse of these structures is supportedby favoring variant entries during call-check-insert, and by creating table entries for calls which haveno variant in the table and whose properly subsuming entry is incomplete. Once a table entry hascompleted, all structures created to support answer resolution from the incomplete table are reclaimed.These include the leaf node pointers, the auxiliary structures for indexing on time in the TST-basedsubsumption engine, and the entire DTSA itself in the DTSA-based subsumption engine.We now discuss how the di�erences between these structures are re ected in the implementationsof the tabling engines.4.2 Variant vs. TST-Based EngineA main component of the time overhead of subsumption as compared to variant arises from morecomplex call-check-insert and retrieve-answer operations. However, this overhead adds but a constantfactor to the evaluation time. As more and more program resolution steps are replaced by answerresolution steps, arbitrary leaps in e�ciency are possible. The interesting result, however, is that thetable space used by a TST-based engine to support this computational gain is always within a factorof that used by a variant engine. In fact,Proposition 4 (Space Complexity of TST-Based Engine) The maximum table space used dur-ing computation in a TST-based engine is at most twice that of the variant engine.This bound follows from the observation that a TST is structured like a trie with respect to therepresentation of the answers as sequences of symbols|a trie and a TST representing the same set ofanswers have the same number of nodes, and that the size of a TST node is twice that of a trie node(as explained in Section 3.3).4.3 DTSA- vs. TST-Based EngineThe biggest advantage of the TST design, as we mentioned above, is that its space complexity is ofthe same order as the variant engine. In practice, the size of incomplete producer table entries in theDTSA-based engine is at least double that of the representation in the variant engine, since an answertrie (for duplicate elimination) as well as a DTSA is created. Moreover, due to the presence of multipletransitions with the same label from a state, the number of nodes in a DTSA may be quadratic in thenumber of nodes in a corresponding TST, as the following example shows.Figure 5(a) shows a program where answers for a(X,Y) are inserted in such an order that nosharing of nodes is possible in the DTSA (Figure 5(b)). However, since answers are simply markedwith the insertion time in a TST, rather than stored in derivation order, the resulting sharing makes thecorresponding TST more compact (Figure 5(b)). It can be shown that the number of nodes requiredto represent the set of answers to the query a(X,Y) in the TST is n(n � 1)=2 + 2k, whereas in the10

:- table a/2.a(X,Y) :- p(X,Y).a(X,Y) :-p(X,Z),q(X,Z,W),a(W,Y).q(f( ),Z,g(hk(Z))).q(g( ),Z,f(hk(Z))).p(f(hk(1)),2).p(g(hk(2)),3).p(f(hk(3)),4)....p(g(hk(n-2)),n-1).p(f(hk(n-1)),n). n-2

h/1

g/1

1

2

f/1

h/1

2

h/1

3

h/1

n

h/1

4

h/1

3

h/1 h/1

f/1 g/1

h/1

2 n n

n-1

h/1

h/1

n-1n n

n-2

3

21

h/1

f/1 g/1

(a) (b) (c)Figure 5: Program (a) and two organizations of the answer set for the query a(X,Y): that which wouldbe produced in a DTSA (b) and a (Time-Stamped) Trie (c).DTSA, the number of nodes required is n(n � 1)(2 + k). As can be seen from both the diagram andthese expressions, the size of k adds but a constant factor to the size of the TST, whereas in the DTSA,its e�ect is multiplicative.Another issue stems from the treatment of calls that are variants of previously encountered sub-sumed calls. Using the set-at-a-time retrieval strategy of the TST allows any consuming call to triggera relevant answer identi�cation operation if all currently identi�ed answers have been consumed, i.e.,the answer list component of the continuation is empty. Under the backtracking strategy of the DTSAengine, only each �rst distinct consumer utilizes the DTSA for answer resolution while all subsequent(variant) calls utilize the answer list. As backtracking provides the only means to identify relevantanswers, the subsequent calls cannot retrieve more answers when needed. As a result, these evaluationpaths must be suspended until the initial consumer performs the next answer resolution. This bestowingof special functionality upon these �rst consumers, and hence some degree of importance or priorityover subsequent ones, can place additional overheads on scheduling through increased environmentswitching.There is also a signi�cant di�erence in the amount of resources needed to support answer resolutionfrom the two data structures. Note that using a DTSA, answer resolution is performed incrementallyby a nondeterministic traversal of the automaton. This incrementality allows the DTSA to shareuni�cation operations between answer resolution steps, as discussed next. However, the structure ofanswer continuations is complex and needs additional choice points (CP): one per level in the DTSA perdistinct consumer. Because stacks are frozen in XSB to maintain several paths of the evaluation tree atonce, the e�ects of these sets of choice points on the engine are cumulative and persist throughout thecomputation until the table is deemed complete. A re�nement was added to the system in which theseDTSA choice point frames were maintained outside of the choice point stack in an attempt to curtailmemory usage. As we will see in section 5, their e�ects are still signi�cant. On the other hand, sincetraversals of the TST are performed to completion during each identi�cation phase, the informationmaintained is minimal. The maximum timestamp of all answers contained in the TST is all that isrequired for starting the next identi�cation phase. Thus the representation of answer continuations ina TST-based engine is much tidier than the corresponding representation in a DTSA-based engine.Finally we note that both structures provide similar strategies for indexing. However, because theDTSA supports identi�cation and uni�cation in one step, consecutively retrieved answers may share11

(elementary) uni�cations. But because uni�cations in the TST engine always occur through answer leafpointers, each answer must be constructed in its entirety. In the worst case, the number of elementaryuni�cation operations needed to construct all relevant answers can be quadratic. Consider the casewhere n answers of the form fm(k), 1 � k � n, have been identi�ed as relevant. If the DTSA canshare uni�cations, then the number of such elementary operations needed to construct all n answerswould be �(m+ n), whereas in the TST engine, construction takes �(mn). Therefore, this ability toavoid repeating certain uni�cations gives the DTSA a computational advantage. However, it is limitedin application to the �rst distinct properly subsumed calls, as discussed above. Moreover, it is unclearhow frequently this worst-case situation arises in practice, given that only the variable substitutionsare constructed during answer resolution.5 Experimental ResultsWe now present experimental results to compare the performance of the TST engine with that of thevariant and DTSA engines.3 Here we repeat the benches presented in [9], derived from the programs:left-, right-, and double-recursive versions of transitive closure (lrtc/2, rrtc/2, drtc/2), and the samegeneration program (sg/2). In Section 6, we present the performance of the TST engine on a largeknowledge base application program developed by S. Decker [4] for the Web. We note that both theTST and DTSA engines were constructed from di�erent base versions of XSB: the TST engine fromversion 1.7.2, and the DTSA engine from version 1.4.3. The measurements were made so as to minimizethe impact of this di�erence during each experiment, as discussed below. Because the changes betweento two versions did not grossly a�ect the method of evaluation|in particular, XSB's scheduler|wefeel that the following results accurately re ect the relative performance of the systems.Time E�ciency Table 1 shows the performance of the TST engine for queries whose evaluations donot lead to subsumed calls. Overheads, therefore, only result from the more costly call-check-insert op-eration. Because the time-stamp indexes are lazily created (as explained in Section 3.3), no penalty is in-curred due to their maintenance. In general, we may also avoid updating the time stamps along the pathof insertion by assigning a time stamp of 1 to all answers entered before the �rst subsumed call is made.Query Graph Size Variant TSTlrtc(1,Y) Chain 1024 1.00 0.982048 1.00 1.034096 1.00 1.038192 1.00 0.98rrtc(1,Y) Chain 128 1.00 1.00256 1.00 0.97512 1.00 0.981024 1.00 1.01Table 1: Normalized times for evaluations with nosubsumed calls.With these optimizations, the TST engine incursvery little overhead when call subsumption is notpossible.Table 2 shows the execution times of the TSTand DTSA engines relative to their base variantengines on benches exhibiting subsumptive behav-ior. We compare the performance of each enginethrough the speedups achieved over their base vari-ant engines, seeking to reduce noise in the resultscaused by di�erences in their base implementa-tions. As each subsumptive engine merely extendsthe tabling subsystem to support subsumption, weare in e�ect measuring and comparing the perfor-mance gain achievable by each method. Noticethat in all cases, the TST engine performs at leastas well as the DTSA engine.3All benches performed on a SparcStation 20 with 64MB running Solaris 5.6.12

Query Graph Size XSB 1.4.3 XSB 1.7.2Variant DTSA Speedup Variant TST Speeduprrtc(X,Y) Chain 256 0.80 0.87 0.92 0.68 0.53 1.28512 3.36 3.44 0.97 3.05 2.16 1.411024 16.8 13.8 1.21 14.6 8.74 1.68Tree 1024 0.21 0.32 0.66 0.20 0.16 1.262048 0.48 0.77 0.62 0.45 0.37 1.214096 1.06 2.08 0.51 1.00 0.83 1.20drtc(X,Y) Chain 64 0.82 0.57 1.44 0.75 0.40 1.87128 6.54 4.60 1.43 5.88 3.09 1.90256 52.0 38.7 1.35 51.5 24.1 2.14Tree 1024 0.75 0.73 1.03 0.71 0.51 1.402048 1.87 1.91 0.98 1.72 1.25 1.384096 4.57 4.86 0.94 4.24 3.00 1.41sg(X,Y) Chain 256 0.18 0.03 5.84 0.16 0.02 7.93512 0.68 0.06 11.3 0.64 0.04 15.81024 2.73 0.12 22.5 2.58 0.09 27.5Tree 64 0.03 0.04 0.86 0.03 0.03 1.05128 0.12 0.14 0.89 0.11 0.10 1.10256 0.49 0.50 0.97 0.43 0.43 1.01lrtc(1,X), Chain 1024 7.28 0.07 108 6.91 0.05 144lrtc(2,X) 2048 29.4 0.13 219 27.5 0.10 2774096 118 0.30 392 110 0.20 574Tree 1024 4.43 0.06 86.8 4.32 0.05 87.62048 17.6 0.10 176 17.3 0.09 1904096 71.1 0.20 351 69.7 0.18 388Table 2: Speedups of DTSA and TST engines in evaluations involving subsumption.In summary, a subsumption engine based on TSTs adds little overhead to the execution of queriesthat do not allow for subsumptive table usage while providing speedups at least as good as the DTSAengine on queries that do.Table Space Usage In Table 3 we report on the memory utilized in representing the tables for someof the benches described earlier. This table space consists of the call and answer tables, where the latterconsists of answer tries, TSTs, DTSA, and answer lists as present in a particular engine. We report themaximum space consumed during evaluation, as well as the space consumed by the completed tables.Table 3 is divided into three sections: the upper portion shows results for benches that do not makeuse of subsumption; the middle section shows results for benches for which properly subsumed callsconsume answers only from incomplete tables; and the bottom portion shows results for a bench whosesubsumed calls consume answers from completed tables only. The space used by the DTSA engine forcompleted tables is identical to that of TST, and is not shown in the table.As mentioned earlier, the subsumptive engines exhibit a 20% overhead in the representation ofanswer tries as compared to the variant engine. For the benches which do not exhibit subsumption,observe that the actual increase appears lower due to the presence of the call table and answer lists inthis measure, which are present in all engines. Since answer lists are reclaimed upon completion, thespace overhead approaches 20%.The query lrtc(1,X),lrtc(2,X) exhibits behavior similar to non-subsumptive evaluations duringconstruction of the tables as subsumed calls do not occur until the tables complete. This allows both13

Query Graph Size Maximum Table Space Completed Table SpaceVariant DTSA TST Variant TSTlrtc(1,Y) Chain 4096 128 KB 144 KB 144 KB 96.1 KB 112 KB8192 256 KB 288 KB 288 KB 192 KB 224 KBrrtc(1,Y) Chain 512 4.23 MB 4.75 MB 4.75 MB 3.23 MB 3.75 MB1024 16.8 MB 18.8 MB 18.8 MB 12.8 MB 14.8 MBrrtc(X,Y) Chain 512 7.41 MB 9.89 MB 7.73 MB 6.41 MB 3.73 MB1024 29.5 MB 39.1 MB 30.8 MB 25.5 MB 14.8 MBTree 2048 1.23 MB 1.64 MB 1.23 MB 1.09 MB 702 KB4096 2.68 MB 3.58 MB 2.69 MB 2.36 MB 1.48 MBdrtc(X,Y) Chain 128 492 KB 826 KB 508 KB 429 KB 252 KB256 1.87 MB 3.19 MB 1.95 MB 1.62 MB 971 KBTree 2048 1.23 MB 1.71 MB 1.23 MB 1.09 MB 702 KB4096 2.68 MB 3.73 MB 2.69 MB 2.36 MB 1.48 MBsg(X,Y) Chain 512 88.1 KB 110 KB 84.1 KB 84.1 KB 60.1 KB1024 176 KB 220 KB 168 KB 168 KB 120 KBTree 128 231 KB 430 KB 309 KB 188 KB 168 KB256 855 KB 1602 KB 1190 KB 685 KB 629 KBlrtc(1,X), Chain 2048 320 KB 128 KB 128 KB 304 KB 112 KBlrtc(2,X) 4096 640 KB 256 KB 256 KB 608 KB 224 KBTree 2048 276 KB 100 KB 100 KB 260 KB 84.4 KB4096 522 KB 200 KB 200 KB 520 KB 168 KBTable 3: Space usage for tables in variant and subsumptive engines.subsumptive engines to avoid constructing their respective subsumption-supporting data structures.The sharing of answer tables due to subsumption leads to the subsumption engines consuming lessmaximum and �nal spaces than the variant engine.For those queries which utilize subsumption from incomplete tables, only a single table is con-structed under subsumptive evaluation|that of the original query. This table expands throughout thecomputation until it completes, terminating the evaluation. Under variant evaluation, however, severaltables are constructed in addition to the one for the query itself, but are completed incrementally duringthe computation. Therefore, memory usage is somewhat amortized as space is periodically freed by thetables as they complete. The relative performance in maximum space usage between the two tablingparadigms, then, depends not only on the amount of answer sharing that is possible|and so the extentto which duplicity can be avoided|but also on the pattern of table completion. For these queries, onlysg(X,Y) on chains exhibits conditions during the evaluation which are conducive to savings undersubsumption, and that by using TSTs only. However, as Table 3 also shows, in all subsumptive cases(middle and lower portions of the table) the TST engine yields a more compact representation of thecompleted tables, even though each TST consumes more space than the corresponding answer trie inthe variant engine.Finally, for all queries where subsumed calls are resolved only with incomplete tables, the TSTengine outperforms the DTSA engine in maximum space required as expected. The results show thatthe amount of savings can be signi�cant, in absolute (see rrtc(X,Y)) or relative terms (see drtc(X,Y)).Choice Point Creation In Table 4 we present maximum choice point stack usage which, togetherwith table space usage, accounts for most of the total memory used during query evaluation withsubsumption. As the sizes of producer and consumer choice point frames di�er between the versions of14

XSB, we have added padding to these structures to normalize the values and enable a direct comparison.For this reason, only results from one version of a variant engine is shown in this table.Query Graph Size Variant DTSA TSTlrtc(1,Y) Chain 4096 0.61 KB 0.61 KB 0.61 KB8192 0.66 KB 0.66 KB 0.66 KBrrtc(1,Y) Chain 512 36.5 KB 36.5 KB 36.5 KB1024 72.5 KB 72.5 KB 72.5 KBrrtc(X,Y) Chain 512 36.5 KB 100 KB 30.5 KB1024 72.6 KB 208 KB 60.5 KBTree 2048 1.64 KB 288 KB 120 KB4096 1.81 KB 592 KB 240 KBdrtc(X,Y) Chain 128 16.4 KB 494 KB 477 KB256 32.5 KB 1950 KB 1913 KBTree 2048 1.76 KB 1.22 MB 1.06 MB4096 1.94 KB 2.69 MB 2.34 MBsg(X,Y) Chain 512 0.71 KB 100 KB 30.5 KB1024 0.77 KB 208 KB 60.6 KBTree 128 0.76 KB 16.5 KB 7.93 KB256 0.82 KB 33.7 KB 15.5 KBlrtc(1,X), Chain 2048 0.74 KB 0.74 KB 0.74 KBlrtc(2,X) 4096 0.80 KB 0.80 KB 0.80 KBTree 2048 0.78 KB 0.78 KB 0.78 KB4096 0.84 KB 0.84 KB 0.84 KBTable 4: Maximum choice point space usage for various tablingengines.

As compared to a variant basedevaluation, choice point space islikely to increase as subsumed callsare dependent upon the more gen-eral goal, and therefore cannot com-plete before the general goal it-self is completed. Hence, the cor-responding consumer choice pointsmust remain active on the choicepoint stack. In contrast, under vari-ant evaluation, the more speci�cgoals are resolved by program reso-lution, independent of the more gen-eral call, and hence have the oppor-tunity to complete earlier and freestack space for reuse. Note thatthe former condition is a charac-teristic of subsumption-based queryevaluation rather than any particu-lar implementation of the tables. Inparticular, for the query drtc(X,Y)executed on trees of depth k, wecan show that the maximum num-ber of concurrently active choicepoints is equal to the number ofcalls to drtc/2, which is propor-tional to k2k, whereas under variant evaluation, the maximum number of active choice points is only 2k.However, there are cases, such as occurs in the evaluation of rrtc(X,Y), where the initial call pat-tern is identical under either evaluation strategy. Here, the use of subsumption actually saves spaceas the representation of a consuming call on the choice point stack is more compact than that of aproducer. Note that, even in the worst case, the choice point stack expansion is tied to the number ofinterdependent calls, and hence proportional to the table space.As discussed in Section 4.3, the DTSA engine uses more stack space than the TST due to theaddition of specialized choice points for performing answer resolution from the DTSA. As the data inTable 4 shows, the TST engine outperforms the DTSA engine in terms of choice point space usage inall examples. Moreover, the overhead is signi�cant, sometimes resulting in usage that is more thantriple that of the TST engine. Finally, note that the table space of the TST engine is proportionalto that of the variant engine, and that its choice point space usage is proportional to its table spaceusage. Therefore, the TST engine's total usage is proportional to that of the variant engine.6 DiscussionWe presented a new organization of tables based on time-stamped tries for subsumption based tabling.We showed from a theoretical as well as practical perspective that it is superior to a tabling enginebased on DTSA. Further we have shown that the space performance of such an implementation is no15

worse than a constant factor away from a variant implementation.Programs exist for which top-down, goal-directed query evaluations impose a high factor of over-head during the computation. Consequently, a pure semi-naive bottom-up evaluation can be moree�cient in such cases. Preliminary evidence suggests that the performance of our TST-based tablingengine augmented with call abstraction is competitive with semi-naive bottom-up evaluation methodsfor such queries. In general, abstraction of a call c is performed by �rst making a more general call, c0,and allowing c to consume answers from c0. Observe that doing call abstraction within a subsumptiveengine on a call c amounts to losing goal directedness as far as the evaluation of c is concerned. Thusby selectively abstracting calls we can vary the degree of goal directness employed during an evaluationwithout changing the core evaluation strategy.Execution Method Time SpeedupVariant 599.5 1.00TST-based Subsumption 107.4 5.58Bottom-Up MetaInterpreterSemiNaive 24.73 24.24Optimized SemiNaive 7.87 76.18TST-based Subsumption withCall Abstraction 4.68 128.0Table 5: Performance of distinct evaluation strategieson a query to the knowledge base, as compared to thetop-down variant-tabling strategy.We experimented with this idea on a fairlylarge tabled logic program that was sent to usby a user of the XSB system [4]. Queries onthis program|a knowledge base of Web-relateddata|were found to be more suited for bottom-up evaluation. Indeed, as we decreased thenumber of calls made during an evaluation ofthe query through the use of subsumption andthen the addition of call abstraction, the per-formance of the top-down evaluator increased.The results of our experiment is summarized inTable 5. There, the performance of several eval-uation methods on the query to the knowledgebase are shown. All are based on XSB version1.7.2. The top-down evaluators executed thequery and program directly. In the second trial using subsumption, call abstraction was applied to asingle predicate in the program. The determination of which predicate(s) would bene�t from abstrac-tion was made based on the call pattern exhibited during execution of the query in the �rst subsumptivetrial. The original program was then modi�ed to carry out the abstraction. The bottom-up metain-terpreters, executed on the variant-based XSB, utilize tries for representing the model and delta setsduring the evaluation of the program. The \optimized" version of the metainterpreter always appliesfacts from the delta set as the �rst component of the join to minimize failed join operations.The above result seems to indicate that our TST-based engine is very competitive to bottom-upevaluation methods. Thus call abstraction appears to be a powerful technique for exibly incorpo-rating bottom-up evaluation within a top-down engine. From an implementation viewpoint, analysistechniques for doing call abstraction is hence an important and worthwhile research endeavor.Finally, we noted earlier how subsumptive evaluation increases the amount of dependence betweencalls, and showed through experimentation that this leads to increased choice point stack usage. Asan increasing number of environments need be maintained at once, increased usage on other systemresources (stacks) is probable. The design of methods to eagerly detect when properly subsumedcalls have completely consumed all relevant answers may alleviate this problem but remains to beinvestigated.References[1] R. Bol and L. Degerstadt. Tabulated resolution for well-founded semantics. In Proc. of the Symp.on Logic Programming, 1993. 16

[2] W. Chen and D. S. Warren. Tabled evaluation with delaying for general logic programs. JACM,43(1), 1996.[3] S. Dawson, C.R. Ramakrishnan, I.V. Ramakrishnan, and T. Swift. Optimizing clause resolution:Beyond uni�cation factoring. In International Conference on Logic Programming. ALP, 1995.[4] S. Decker, August 1998. Personal Communication.[5] Y. Dong, X. Du, Y.S. Ramakrishna, C.R. Ramakrishnan, I.V. Ramakrishnan, S.A. Smolka,O. Sokolsky, E.W. Stark, and D.S. Warren. Fighting livelock in the i-protocol: A comparativestudy of veri�cation tools. In Tools and Algorithms for the Construction and Analysis of Systems,(TACAS '99). Springer Verlag, 1999.[6] The XSB Group. The XSB programmer's manual, Version 1.8, 1998. Available fromhttp://www.cs.sunysb.edu/�sbprolog.[7] Y. S. Ramakrishna, C. R. Ramakrishnan, I. V. Ramakrishnan, S. A. Smolka, T. W. Swift, and D. S.Warren. E�cient model checking using tabled resolution. In Proceedings of the 9th InternationalConference on Computer-Aided Veri�cation (CAV '97), Haifa, Israel, July 1997. Springer-Verlag.[8] C. R. Ramakrishnan, S. Dawson, and D. S. Warren. Practical program analysis using generalpurpose logic programming systems - a case study. In ACM Symposium on Programming LanguageDesign and Implementation, 1996.[9] I.V. Ramakrishnan, P. Rao, K. Sagonas, T. Swift, and D. S. Warren. E�cient access mechanismsfor tabled logic programs. Journal of Logic Programming, January 1999.[10] P. Rao, C.R. Ramakrishnan, and I.V. Ramakrishnan. A thread in time saves tabling time. InJoint International Conference/Symposium on Logic Programming. MIT Press, 1996.[11] H. Tamaki and T. Sato. OLDT resolution with tabulation. In International Conference on LogicProgramming, pages 84{98. MIT Press, 1986.[12] A. van Gelder, K.A. Ross, and J.S. Schlipf. The well-founded semantics for general logic programs.JACM, 38(3), July 1991.17