tst_insert.c

00001 /* File:      tst_insert.c
00002 ** Author(s): Ernie Johnson
00003 ** Contact:   xsb-contact@cs.sunysb.edu
00004 ** 
00005 ** Copyright (C) The Research Foundation of SUNY, 1986, 1993-1998
00006 ** 
00007 ** XSB is free software; you can redistribute it and/or modify it under the
00008 ** terms of the GNU Library General Public License as published by the Free
00009 ** Software Foundation; either version 2 of the License, or (at your option)
00010 ** any later version.
00011 ** 
00012 ** XSB is distributed in the hope that it will be useful, but WITHOUT ANY
00013 ** WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
00014 ** FOR A PARTICULAR PURPOSE.  See the GNU Library General Public License for
00015 ** more details.
00016 ** 
00017 ** You should have received a copy of the GNU Library General Public License
00018 ** along with XSB; if not, write to the Free Software Foundation,
00019 ** Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
00020 **
00021 ** $Id: tst_insert.c,v 1.19 2005/12/22 23:34:02 tswift Exp $
00022 ** 
00023 */
00024 
00025 
00026 #include "xsb_config.h"
00027 #include "xsb_debug.h"
00028 
00029 #include <stdio.h>
00030 #include <stdlib.h>
00031 
00032 #include "debugs/debug_tries.h"
00033 
00034 #include "auxlry.h"
00035 #include "cell_xsb.h"
00036 #include "inst_xsb.h"
00037 #include "register.h"
00038 #include "error_xsb.h"
00039 #include "psc_xsb.h"
00040 #include "deref.h"
00041 #include "table_stats.h"
00042 #include "trie_internals.h"
00043 #include "tst_aux.h"
00044 #include "thread_xsb.h"
00045 #include "memory_xsb.h"
00046 
00047 
00048 
00049 /*===========================================================================
00050 
00051     This file defines a set of functions for inserting a set of terms
00052     into different types of tries.  Note that these routines STRICTLY
00053     insert the terms -- NO searching is performed.
00054 
00055       BTNptr bt_insert(BTNptr,BTNptr,Cell)
00056       TSTNptr tst_insert(TSTNptr,TSTNptr,Cell,xsbBool)
00057 
00058     They are intended for internal use only by the trie search routines,
00059     which use them for term insert only after ensuring that some related
00060     term set doesn't already exist in the trie.
00061 
00062     These insertion functions assume a non-NULL node pointer, a nonempty
00063     set of terms, and appropriate initialization of the trie Trail.
00064 
00065 ===========================================================================*/
00066 
00067 
00068 /*=========================================================================*/
00069 
00070 /*
00071  *             Time-Stamp Index Creation and Access Methods
00072  *             ============================================
00073  *
00074  * Recall that Time-Stamp Indices are central to identifying unifying
00075  * term sets with time stamps greater than a given value.
00076  */
00077 
00078 /*-------------------------------------------------------------------------*/
00079 
00080 /*
00081  * Allocate a TSI node, associate it with a TST node 'tstn', and place
00082  * it at the head of the Time-Stamp Index managed by the hash table 'ht'.
00083  *
00084  * This operation is used for symbols inserted into an established hash
00085  * table.  The timestamp of this new entry will be set at the end of the
00086  * TST Insert operation when we walk back up the trie adjusting all
00087  * timestamps to a new max as we go.  Hence, the head of the entry list
00088  * is where this new entry belongs.
00089  */
00090 
00091 inline static  TSINptr tsiHeadInsert(CTXTdeclc TSTHTptr ht, TSTNptr tstn) {
00092 
00093   TSINptr pTSIN;
00094 
00095   New_TSIN(pTSIN, tstn);
00096   TSIN_Prev(pTSIN) = NULL;
00097   TSIN_Next(pTSIN) = TSTHT_IndexHead(ht);
00098   TSIN_Prev(TSTHT_IndexHead(ht)) = pTSIN;
00099   TSTHT_IndexHead(ht) = pTSIN;
00100   return pTSIN;
00101 }
00102     
00103 /*-------------------------------------------------------------------------*/
00104 
00105 /*
00106  *  Used during the creation of a Time-Stamp Index, allocates a TSI node
00107  *  for a given TST node and inserts it into the TSI in (decreasing)
00108  *  timestamp order.
00109  *
00110  *  NOTE: We cannot assume that the time stamp of the incoming node is  
00111  *  greater than that of all of the nodes already present in the TSI.
00112  *  Although this is the norm once the TSI is established, when a
00113  *  sibling list is moved to a hashing format, Entries are created for
00114  *  the nodes one at a time, but this node-processing order is not
00115  *  guaranteed to coincide with time stamp order.
00116  */
00117 
00118 inline static  TSINptr tsiOrderedInsert(CTXTdeclc TSTHTptr ht, TSTNptr tstn) {
00119 
00120   TSINptr nextTSIN;     /* Steps thru each TSIN inspecting time stamp */
00121   TSINptr newTSIN;      /* To be inserted after nextTSIN */
00122 
00123 
00124   New_TSIN(newTSIN, tstn);
00125 
00126   /* Determine proper position for insertion
00127      --------------------------------------- */
00128   nextTSIN = TSTHT_IndexHead(ht);
00129   while ( IsNonNULL(nextTSIN) &&
00130          (TSIN_TimeStamp(newTSIN) < TSIN_TimeStamp(nextTSIN)) )
00131     nextTSIN = TSIN_Next(nextTSIN);
00132 
00133 
00134   /* Splice newTSIN between nextTSIN and its predecessor
00135      --------------------------------------------------- */
00136   if ( IsNonNULL(nextTSIN) ) {
00137     TSIN_Prev(newTSIN) = TSIN_Prev(nextTSIN);
00138     TSIN_Next(newTSIN) = nextTSIN;
00139     if ( IsTSindexHead(nextTSIN) )
00140       TSTHT_IndexHead(ht) = newTSIN;
00141     else
00142       TSIN_Next(TSIN_Prev(nextTSIN)) = newTSIN;
00143     TSIN_Prev(nextTSIN) = newTSIN;
00144   }
00145   else {   /* Insertion is at the end of the TSIN list */
00146     TSIN_Prev(newTSIN) = TSTHT_IndexTail(ht);
00147     TSIN_Next(newTSIN) = NULL;
00148     if ( IsNULL(TSTHT_IndexHead(ht)) )  /* First insertion into TSI */
00149       TSTHT_IndexHead(ht) = newTSIN;
00150     else
00151       TSIN_Next(TSTHT_IndexTail(ht)) = newTSIN;
00152     TSTHT_IndexTail(ht) = newTSIN;
00153   }
00154 
00155   return newTSIN;
00156 }
00157 
00158 /*-------------------------------------------------------------------------*/
00159 
00160 /*
00161  * Remove a TSI entry node from a TSI and place it on the global TSI
00162  * free list for later reuse.
00163  */
00164 
00165 void tsiRemoveEntry(CTXTdeclc TSTHTptr ht, TSINptr tsin) {
00166 
00167   /* Splice out the TSIN from the Index
00168      ---------------------------------- */
00169   if ( IsTSindexHead(tsin) )
00170     TSTHT_IndexHead(ht) = TSIN_Next(tsin);
00171   else
00172     TSIN_Next(TSIN_Prev(tsin)) = TSIN_Next(tsin);
00173   if ( IsTSindexTail(tsin) )
00174     TSTHT_IndexTail(ht) = TSIN_Prev(tsin);
00175   else
00176     TSIN_Prev(TSIN_Next(tsin)) = TSIN_Prev(tsin);
00177 
00178   /* Place the TSIN on the FreeList
00179      ------------------------------- */
00180   SM_DeallocateStruct(smTSIN,tsin);
00181 }
00182 
00183 /*-------------------------------------------------------------------------*/
00184 
00185 /*
00186  * Increase the time stamp of a hashed TSTN to that which is greater
00187  * than any other.  Hence, its TSI entry must be moved to the head of
00188  * the list to maintain our ordering property.
00189  */
00190 
00191 inline static  void tsiPromoteEntry(TSTNptr tstn, TimeStamp ts) {
00192 
00193   TSINptr tsin;
00194   TSTHTptr ht;
00195 
00196   tsin = TSTN_GetTSIN(tstn);
00197   TSIN_TimeStamp(tsin) = ts;
00198   if ( IsTSindexHead(tsin) )
00199     return;
00200 
00201   /* Splice out the TSIN from the Index
00202      ---------------------------------- */
00203   ht = TSTN_GetHashHdr(TSTN_Parent(tstn));
00204   TSIN_Next(TSIN_Prev(tsin)) = TSIN_Next(tsin);
00205   if ( IsTSindexTail(tsin) )
00206     TSTHT_IndexTail(ht) = TSIN_Prev(tsin);
00207   else
00208     TSIN_Prev(TSIN_Next(tsin)) = TSIN_Prev(tsin);
00209 
00210   /* Place the TSIN at the head of the Index
00211      --------------------------------------- */ 
00212   TSIN_Prev(tsin) = NULL;
00213   TSIN_Next(tsin) = TSTHT_IndexHead(ht);
00214   TSIN_Prev(TSTHT_IndexHead(ht)) = tsin;
00215   TSTHT_IndexHead(ht) = tsin;
00216 }
00217 
00218 /*--------------------------------------------------------------------------*/
00219 
00220 /*
00221  * This function may be called externally, and is made available to
00222  * support lazy creation of Time-Stamp Indices.
00223  *
00224  * An example of this use is for incomplete subsumptive Answer Sets.
00225  * TSIs are created only once a properly subsumed subgoal is issued.
00226  */
00227 
00228 void tstCreateTSIs(CTXTdeclc TSTNptr pTST) {
00229 
00230   TSTNptr *pBucket, tstn;
00231   TSTHTptr ht;
00232   int bucketNum;
00233 
00234   if ( IsNULL(pTST) )
00235     return;
00236 
00237   /*** For each hash table ... ***/
00238   for ( ht = TSTRoot_GetHTList(pTST);  IsNonNULL(ht);
00239         ht = TSTHT_InternalLink(ht) ) {
00240 
00241     /*** For each bucket in this hash table ... ***/
00242     for ( pBucket = TSTHT_BucketArray(ht), bucketNum = 0;
00243           (unsigned int)bucketNum < TSTHT_NumBuckets(ht);
00244           pBucket++, bucketNum++ )
00245 
00246       /*** For each TSTN in a bucket... ***/
00247       for ( tstn = *pBucket;  IsNonNULL(tstn);  tstn = TSTN_Sibling(tstn) )
00248 
00249         /*** Create a TSIN for each symbol (TSTN) ***/
00250         TSTN_SetTSIN(tstn,tsiOrderedInsert(CTXTc ht,tstn));
00251   }
00252 }
00253 
00254 /*=========================================================================*/
00255 
00256 /*
00257  *                      TST Hash Table Creation
00258  *                      =======================
00259  */
00260 
00261 
00262 /*
00263  * The number of children of 'parent' has increased beyond the threshold
00264  * and requires a hashing structure.  This function creates a hash table
00265  * and inserts the children into it.  The value of the third argument
00266  * determines whether a TSI is also created for the children.
00267  *
00268  * After its creation, the hash table is referenced through the `Child'
00269  * field of the parent.  Hash tables in a TST are also linked to one
00270  * another through the TST's root.
00271  */
00272 
00273 inline static
00274 void tstnHashifyChildren(CTXTdeclc TSTNptr parent, TSTNptr root, xsbBool createTSI) {
00275 
00276   TSTNptr children;           /* child list of the parent */
00277   TSTNptr tstn;               /* current child for processing */
00278   TSTHTptr ht;                /* HT header struct */
00279   TSTNptr *tablebase;         /* first bucket of allocated HT */
00280   unsigned long  hashseed;    /* for hashing symbols of the TSTNs */
00281 
00282 
00283   New_TSTHT(ht,TSTN_TrieType(root),root);
00284   children = TSTN_Child(parent);
00285   TSTN_SetHashHdr(parent,ht);
00286   tablebase = TSTHT_BucketArray(ht);
00287   hashseed = TSTHT_GetHashSeed(ht);
00288   for (tstn = children;  IsNonNULL(tstn);  tstn = children) {
00289     children = TSTN_Sibling(tstn);
00290     TrieHT_InsertNode(tablebase, hashseed, tstn);
00291     MakeHashedNode(tstn);
00292     if ( createTSI )
00293       TSTN_SetTSIN(tstn, tsiOrderedInsert(CTXTc ht, tstn));
00294   }
00295 }
00296 
00297 /*=========================================================================*/
00298 
00299 /*
00300  *                    Inserting a Symbol into a Trie
00301  *                    ==============================
00302  */
00303 
00304 
00305 /*-------------------------------------------------------------------------*/
00306 
00307 /*
00308  * Adds a node containing 'symbol' below 'parent', which currently has
00309  * no children.  Optimizes away certain checks performed by the
00310  * xxxInsertSymbol() routines.
00311  */
00312 
00313 inline static
00314 TSTNptr tstnAddSymbol(CTXTdeclc TSTNptr parent, Cell symbol, int trieType) {
00315 
00316   TSTNptr newTSTN;
00317 
00318   New_TSTN(newTSTN,trieType,INTERIOR_NT,symbol,parent,NULL);
00319   TSTN_Child(parent) = newTSTN;
00320   return newTSTN;
00321 }
00322 
00323 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
00324 
00325 inline static
00326 BTNptr btnAddSymbol(CTXTdeclc BTNptr parent, Cell symbol, int trieType) {
00327 
00328   BTNptr newBTN;
00329 
00330   New_BTN(newBTN,trieType,INTERIOR_NT,symbol,parent,NULL);
00331   BTN_Child(parent) = newBTN;
00332   return newBTN;
00333 }
00334 
00335 /*-------------------------------------------------------------------------*/
00336 
00337 /*
00338  * Inserts a node containing 'symbol' at the head of the sibling chain
00339  * below 'parent' and returns a pointer to this node.  If this addition
00340  * causes the chain to become "too long", then creates a hashing
00341  * environment for the children.
00342  */
00343 
00344 inline static
00345 TSTNptr tstnInsertSymbol(CTXTdeclc TSTNptr parent, Cell symbol, int trieType,
00346                          TSTNptr root, xsbBool createTSI) {
00347 
00348   TSTNptr tstn, chain;
00349   int chain_length;
00350 
00351 
00352   chain = TSTN_Child(parent);
00353   New_TSTN(tstn,trieType,INTERIOR_NT,symbol,parent,chain);
00354   TSTN_Child(parent) = tstn;
00355   chain_length = 1;
00356   while ( IsNonNULL(chain) ) {
00357     chain_length++;
00358     chain = TSTN_Sibling(chain);
00359   }
00360   if ( IsLongSiblingChain(chain_length) )
00361     tstnHashifyChildren(CTXTc parent,root,createTSI);
00362   return tstn;
00363 }
00364 
00365 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
00366 
00367 inline static
00368 BTNptr btnInsertSymbol(CTXTdeclc BTNptr parent, Cell symbol, int trieType) {
00369 
00370   BTNptr btn, chain;
00371   int chain_length;
00372 
00373 
00374   chain = BTN_Child(parent);
00375   New_BTN(btn,trieType,INTERIOR_NT,symbol,parent,chain);
00376   BTN_Child(parent) = btn;
00377   chain_length = 1;
00378   while ( IsNonNULL(chain) ) {
00379     chain_length++;
00380     chain = BTN_Sibling(chain);
00381   }
00382   if ( IsLongSiblingChain(chain_length) )
00383     hashify_children(CTXTc parent,trieType);
00384   return btn;
00385 }
00386 
00387 /*-------------------------------------------------------------------------*/
00388 
00389 /*
00390  * Inserts a node containing 'symbol' in the appropriate bucket of the
00391  * hash table maintained by 'parent' and returns a pointer to this node.
00392  * If this addition causes the chain to become "too long", then expand
00393  * the hash table.
00394  */
00395 
00396 inline static
00397 TSTNptr tsthtInsertSymbol(CTXTdeclc TSTNptr parent, Cell symbol, int trieType,
00398                           xsbBool maintainsTSI) {
00399 
00400   TSTHTptr ht;
00401   TSTNptr tstn, chain, *bucket;
00402   int chain_length;
00403 
00404 
00405   ht = TSTN_GetHashHdr(parent);
00406   bucket = CalculateBucketForSymbol(ht,symbol);
00407   chain = *bucket;
00408   New_TSTN(tstn,trieType,HASHED_INTERIOR_NT,symbol,parent,chain);
00409   *bucket = tstn;
00410   TSTHT_NumContents(ht)++;
00411   if ( maintainsTSI )
00412     TSTN_SetTSIN(tstn, tsiHeadInsert(CTXTc ht,tstn));
00413   chain_length = 1;
00414   while ( IsNonNULL(chain) ) {
00415     chain_length++;
00416     chain = TSTN_Sibling(chain);
00417   }
00418 
00419 #ifdef SHOW_HASHTABLE_ADDITIONS
00420   xsb_dbgmsg((LOG_DEBUG,"Hash Table size is %lu and now contains %lu elements.",
00421              TSTHT_NumBuckets(ht), TSTHT_NumContents(ht)));
00422   xsb_dbgmsg((LOG_DEBUG,"Addition being made to bucket %lu; now has length %d.",
00423              TrieHash(symbol, TrieHT_GetHashSeed(ht)), chain_length));
00424 #endif
00425 
00426   TrieHT_ExpansionCheck(ht,chain_length);
00427   return tstn;
00428 }
00429 
00430 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
00431 
00432 inline static  BTNptr bthtInsertSymbol(CTXTdeclc BTNptr parent, Cell symbol,
00433                                        int trieType) {
00434 
00435   BTHTptr ht;
00436   BTNptr btn, chain, *bucket;
00437   int chain_length;
00438 
00439 
00440   ht = BTN_GetHashHdr(parent);
00441   bucket = CalculateBucketForSymbol(ht,symbol);
00442   chain = *bucket;
00443   New_BTN(btn,trieType,HASHED_INTERIOR_NT,symbol,parent,chain);
00444   *bucket = btn;
00445   BTHT_NumContents(ht)++;
00446   chain_length = 1;
00447   while ( IsNonNULL(chain) ) {
00448     chain_length++;
00449     chain = BTN_Sibling(chain);
00450   }
00451 
00452 #ifdef SHOW_HASHTABLE_ADDITIONS
00453   xsb_dbgmsg((LOG_DEBUG,"Hash Table size is %lu and now contains %lu elements.",
00454              BTHT_NumBuckets(ht), BTHT_NumContents(ht)));
00455   xsb_dbgmsg((LOG_DEBUG,"Addition being made to bucket %lu; now has length %d.",
00456              TrieHash(symbol, TrieHT_GetHashSeed(ht)), chain_length));
00457 #endif
00458 
00459   TrieHT_ExpansionCheck(ht,chain_length);
00460   return btn;
00461 }
00462 
00463 /*=========================================================================*/
00464 
00465 /*
00466  *                 Updating Time Stamps Along a New Path
00467  *                 =====================================
00468  *
00469  *  Given a pointer to a leaf TSTN for a newly inserted set of terms,
00470  *  update the timestamps of all nodes lying along the path from this
00471  *  leaf to the root.  Updates effect the TSIs, if they exist.
00472  */
00473 
00474 inline static  void update_timestamps(TSTNptr tstLeaf, TSTNptr tstRoot,
00475                                       xsbBool containsTSIs) {
00476 
00477   TimeStamp tsNewAnswer;
00478 
00479 
00480   tsNewAnswer = TSTN_TimeStamp(tstRoot) + 1;
00481   if ( containsTSIs )
00482     do {
00483       if ( IsHashedNode(tstLeaf) )
00484         tsiPromoteEntry(tstLeaf, tsNewAnswer);
00485       else
00486         TSTN_TimeStamp(tstLeaf) = tsNewAnswer;
00487       tstLeaf = TSTN_Parent(tstLeaf);
00488     } while ( tstLeaf != tstRoot );
00489   else
00490     do {
00491       TSTN_TimeStamp(tstLeaf) = tsNewAnswer;
00492       tstLeaf = TSTN_Parent(tstLeaf);
00493     } while ( tstLeaf != tstRoot );
00494   TSTN_TimeStamp(tstRoot) = tsNewAnswer;
00495 }
00496 
00497 /*=========================================================================*/
00498 
00499 /*
00500  *                      Term Insertion Into a Trie
00501  *                      ==========================
00502  *
00503  * Inserts a nonempty set of terms into a trie (a non-NULL root pointer)
00504  * below the node 'lastMatch'.  Note that if the trie is empty or if no
00505  * symbols were previously matched, then 'lastMatch' will reference the
00506  * root.  The terms to insert may exist in one of two forms:
00507  *
00508  *  1) The first symbol to be inserted is passed in as an argument, and
00509  *     the remaining terms are present on the TermStack.  (This supports
00510  *     the variant-lookup operation which processes a subterm BEFORE
00511  *     searching for its occurrence in the trie; by then, the stacks
00512  *     have been altered.)  In this case, the TermStack may be empty.
00513  *
00514  *  2) All terms to be inserted are present on the TermStack, in which
00515  *     case the symbol argument 'firstSymbol' has the value
00516  *     NO_INSERT_SYMBOL.  (This supports the subsumptive-lookup operation
00517  *     which processes a subterm only AFTER determining that it can be
00518  *     subsumed by a symbol in the trie.)  In this case, the TermStack is
00519  *     expected to contain at least one term.
00520  *
00521  * In either case, any trie variables already encountered along the path
00522  * from the root of the trie to 'lastMatch' have been standardized and
00523  * their bindings noted on the Trail.  After insertion is complete, the
00524  * leaf node representing the term set is returned.
00525  */
00526 
00527 /*-------------------------------------------------------------------------*/
00528 
00529 /*
00530  * If the TST contains Time-Stamp Indices -- as noted in the argument
00531  * 'maintainTSI' -- these need to be maintained during insertion.
00532  */
00533 
00534 TSTNptr tst_insert(CTXTdeclc TSTNptr tstRoot, TSTNptr lastMatch, Cell firstSymbol,
00535                    xsbBool maintainTSI) {
00536 
00537   Cell symbol;
00538   int std_var_num,
00539       trieType;
00540 
00541 
00542   symbol = firstSymbol;
00543   std_var_num = Trail_NumBindings;
00544   trieType = TSTN_TrieType(tstRoot);
00545 
00546   /* Insert initial symbol
00547      --------------------- */
00548   if ( symbol == NO_INSERT_SYMBOL )
00549     ProcessNextSubtermFromTrieStacks(symbol,std_var_num);
00550 
00551   if ( IsNULL(TSTN_Child(lastMatch)) )
00552     lastMatch = tstnAddSymbol(CTXTc lastMatch,symbol,trieType);
00553   else if ( IsHashHeader(TSTN_Child(lastMatch)) )
00554     lastMatch = tsthtInsertSymbol(CTXTc lastMatch,symbol,trieType,maintainTSI);
00555   else
00556     lastMatch = tstnInsertSymbol(CTXTc lastMatch,symbol,trieType,tstRoot,
00557                                  maintainTSI);
00558 
00559   /* Insert remaining symbols
00560      ------------------------ */
00561   while ( ! TermStack_IsEmpty ) {
00562     ProcessNextSubtermFromTrieStacks(symbol,std_var_num);
00563     lastMatch = tstnAddSymbol(CTXTc lastMatch,symbol,trieType);
00564   }
00565   update_timestamps(lastMatch,tstRoot,maintainTSI);
00566   MakeLeafNode(lastMatch);
00567   TN_UpgradeInstrTypeToSUCCESS(lastMatch,TrieSymbolType(symbol));
00568   return lastMatch;
00569 }
00570 
00571 /*-------------------------------------------------------------------------*/
00572 
00573 
00574 BTNptr bt_insert(CTXTdeclc BTNptr btRoot, BTNptr lastMatch, Cell firstSymbol) {
00575 
00576   Cell symbol;
00577   int std_var_num;
00578   int trieType;
00579 
00580 
00581   symbol = firstSymbol;
00582   std_var_num = Trail_NumBindings;
00583   trieType = BTN_TrieType(btRoot);
00584 
00585   /* Insert initial symbol
00586      --------------------- */
00587   if ( symbol == NO_INSERT_SYMBOL )
00588     ProcessNextSubtermFromTrieStacks(symbol,std_var_num);
00589 
00590   if ( IsNULL(BTN_Child(lastMatch)) )
00591     lastMatch = btnAddSymbol(CTXTc lastMatch,symbol,trieType);
00592   else if ( IsHashHeader(BTN_Child(lastMatch)) )
00593     lastMatch = bthtInsertSymbol(CTXTc lastMatch,symbol,trieType);
00594   else
00595     lastMatch = btnInsertSymbol(CTXTc lastMatch,symbol,trieType);
00596 
00597   /* Insert remaining symbols
00598      ------------------------ */
00599   while ( ! TermStack_IsEmpty ) {
00600     ProcessNextSubtermFromTrieStacks(symbol,std_var_num);
00601     lastMatch = btnAddSymbol(CTXTc lastMatch,symbol,trieType);
00602   }
00603   MakeLeafNode(lastMatch);
00604   TN_UpgradeInstrTypeToSUCCESS(lastMatch,TrieSymbolType(symbol));
00605   return lastMatch;
00606 }
00607 
00608 /*=========================================================================*/

Generated on Wed Jul 26 13:30:43 2006 for XSB by  doxygen 1.4.5