trie_internals.h

00001 /* File:      trie_internals.h
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: trie_internals.h,v 1.29 2006/01/12 21:33:53 tswift Exp $
00022 ** 
00023 */
00024 
00025 
00026 #ifndef INTERNAL_TRIE_DEFS
00027 
00028 
00029 #define INTERNAL_TRIE_DEFS
00030 
00031 
00032 /*
00033  * Internal specifications of tries that the hard-core trie routines
00034  * require.  However, these specs need not be visible to engine
00035  * components which simply use tries through normal channels.
00036  */
00037 
00038 #include "inst_xsb.h"
00039 #include "struct_manager.h"
00040 #include "tries.h"
00041 
00042 
00043 /*===========================================================================*/
00044 
00045 /*
00046  *        G E N E R I C   C O M P O N E N T - O P E R A T I O N S
00047  *        =======================================================
00048  *
00049  *  See the docs at the top of tries.h.
00050  *
00051  *  We use the following notation:
00052  *    TN_*         Trie Node operation
00053  *    TrieHT_*     Trie Hash Table operation
00054  *    TSC_*        Trie SubComponent (TN or THT) operation
00055  *    pTN          pointer to a Trie Node
00056  *    pTHT         pointer to a Trie Hash Table
00057  *    pTSC         pointer to a Trie SubComponent
00058  */
00059 
00060 #define TrieHT_Instr(pTHT)         TSC_Instr(pTHT)
00061 #define TrieHT_Status(pTHT)        TSC_Status(pTHT)
00062 #define TrieHT_TrieType(pTHT)      TSC_TrieType(pTHT)
00063 #define TrieHT_NodeType(pTHT)      TSC_NodeType(pTHT)
00064 #define TrieHT_NumBuckets(pTHT)    ( (pTHT)->numBuckets )
00065 #define TrieHT_NumContents(pTHT)   ( (pTHT)->numContents )
00066 #define TrieHT_BucketArray(pTHT)   ( (pTHT)->pBucketArray )
00067 #define TrieHT_PrevHT(pTHT)        ( (pTHT)->prev )
00068 #define TrieHT_NextHT(pTHT)        ( (pTHT)->next )
00069 #define TrieHT_GetHashSeed(pTHT)   ( TrieHT_NumBuckets(pTHT) - 1 )
00070 
00071 /*---------------------------------------------------------------------------*/
00072 
00073 /*
00074  *                   Instruction Opcode Maintenance
00075  *                   ==============================
00076  *
00077  *  Trie-embedded instructions are classified according to the type of
00078  *  choice point (CP) operation they perform and the type of symbol being
00079  *  inspected.  For each trie node, the choice point component of the
00080  *  node's instruction is directly dependent upon the node's position in a
00081  *  sibling chain: the first node is a "try" type instruction, the last is
00082  *  a "trust" type, and any ones in between get "retry" type instructions.
00083  *  If the node is the ONLY one in a chain, then no choice point need be
00084  *  established, and hence it's category is termed "no_cp".
00085  *
00086  *  The assignment of an instruction to a trie node occurs during node
00087  *  allocation when both the symbol it will contain and its initial
00088  *  position in a sibling chain are known: by default, new nodes are
00089  *  placed at the head of chains.  However, this means that the node which
00090  *  previously headed the chain must have its instruction's CP component
00091  *  altered.  Additionally, when moving a chain of nodes into a hash
00092  *  table, or expanding a hash table, requires altering the CP component.
00093  *  Fortunately, the representation of embedded-trie instructions allows
00094  *  such maintenance of their CP component.
00095  */
00096 
00097 
00098 #define TN_SetInstr(pTN,Symbol)                                 \
00099    switch( TrieSymbolType(Symbol) ) {                           \
00100    case XSB_STRUCT:                                             \
00101      TN_Instr(pTN) = (byte)trie_try_str;                        \
00102      break;                                                     \
00103    case XSB_INT:                                                \
00104    case XSB_STRING:                                             \
00105    case XSB_FLOAT:                                              \
00106      TN_Instr(pTN) = (byte)trie_try_numcon;                     \
00107      break;                                                     \
00108    case XSB_TrieVar:                                            \
00109      if (IsNewTrieVar(Symbol))                                  \
00110        TN_Instr(pTN) = (byte)trie_try_var;                      \
00111      else if (IsNewTrieAttv(Symbol)) {                          \
00112        TN_Instr(pTN) = (byte)trie_try_attv;                     \
00113      } \
00114      else {                                                     \
00115        TN_Instr(pTN) = (byte)trie_try_val;                      \
00116      } \
00117      break;                                                     \
00118    case XSB_LIST:                                               \
00119      TN_Instr(pTN) = (byte)trie_try_list;                       \
00120      break;                                                     \
00121    default:                                                     \
00122      xsb_abort("Trie Node creation: Bad tag in symbol %lx",     \
00123                Symbol);                                         \
00124    }
00125 
00126 
00127 #define TN_ResetInstrCPs(pHead,pSibling) {              \
00128    if ( IsNonNULL(pSibling) )                           \
00129      TN_RotateInstrCPtoRETRYorTRUST(pSibling);          \
00130    else                                                 \
00131      TN_Instr(pHead) -= 0x2;    /* TRY -> NO_CP */      \
00132  }
00133 
00134 
00135 /*
00136  *  Applied to the current head of a node-chain when adding a new node at
00137  *  the head of this chain.  A "try" type instruction becomes a "retry"
00138  *  and a "no_cp" type becomes a "trust".
00139  */
00140 
00141 #define TN_RotateInstrCPtoRETRYorTRUST(pTN)   TN_Instr(pTN) += 0x1
00142 
00143 
00144 /*
00145  *  An optimization which includes a "leafness" tag in the instruction
00146  *  for nodes -- containing either XSB_INT, XSB_FLOAT, or XSB_STRING
00147  *  data -- which appear as leaves of a trie.
00148  */
00149 
00150 #define TN_UpgradeInstrTypeToSUCCESS(pTN,SymbolTag)     \
00151    if ( SymbolTag == XSB_STRING || SymbolTag == XSB_INT \
00152         || SymbolTag == XSB_FLOAT )                     \
00153      TN_Instr(pTN) += 0x4
00154 
00155 
00156 /*
00157  *  When converting a long chain of nodes to a hash structure, the current
00158  *  order of the nodes within the chain is not preserved.  Hence the
00159  *  order-dependent component of the instructions must be modified: the
00160  *  choice point type.  These macros coerce a node's instruction's CP
00161  *  component to one of two types -- the two which may appear at the head
00162  *  of a chain, where nodes are inserted -- while maintaining the same
00163  *  symbol type and success status.
00164  */
00165 
00166 #define TN_ForceInstrCPtoNOCP(pTN)              \
00167    TN_Instr(pTN) = TN_Instr(pTN) & ~0x3
00168 
00169 #define TN_ForceInstrCPtoTRY(pTN)               \
00170    TN_Instr(pTN) = (TN_Instr(pTN) & ~0x3) | 0x2
00171 
00172 
00173 /*
00174  *  For testing the CP-type of an embedded trie instruction.
00175  */
00176 
00177 #define Contains_NOCP_Instr(pTN)        ( (TN_Instr(pTN) & 0x3) == 0 )
00178 #define Contains_TRUST_Instr(pTN)       ( (TN_Instr(pTN) & 0x3) == 1 )
00179 #define Contains_TRY_Instr(pTN)         ( (TN_Instr(pTN) & 0x3) == 2 )
00180 #define Contains_RETRY_Instr(pTN)       ( (TN_Instr(pTN) & 0x3) == 3 )
00181 
00182 #define TN_InstrCPType(pTN)             ( TN_Instr(pTN) & 0x3 )
00183 
00184 /*---------------------------------------------------------------------------*/
00185 
00186 /*
00187  *                          Status Definitions
00188  *                          ==================
00189  */
00190 
00191 #define VALID_NODE_STATUS       ( (byte) 0 )
00192 
00193 #define IsValidNode(pTSC)       ( TSC_Status(pTSC) == VALID_NODE_STATUS )
00194 #define IsDeletedNode(pTSC)     ( TSC_Status(pTSC) != VALID_NODE_STATUS )
00195 
00196 /* This just sets the status. To make a node valid, the instruction field must
00197    also be set. */
00198 #define MakeStatusValid(pTSC)     TSC_Status(pTSC) = VALID_NODE_STATUS
00199 
00200 /* The following definition depends upon the instruction field having
00201    already been set to a valid trie instruction code.
00202    When a node is soft-deleted, its instruction field is set to 
00203    trie_no_cp_fail and the status field keeps the original instruction (to be
00204    restored if the node is undeleted).
00205    The macro, below, only sets the status. The instruction field is set
00206    separately.
00207 */
00208 #define MakeStatusDeleted(pTSC)   TSC_Status(pTSC) = TSC_Instr(pTSC)
00209 
00210 /*---------------------------------------------------------------------------*/
00211 
00212 /*
00213  *                      Trie-Type Definitions
00214  *                      =====================
00215  *
00216  *  Should denote:
00217  *  1) The underlying structure of the trie: Basic or Time-Stamped
00218  *  2) The role the trie is playing in the system
00219  *  3) Whether the trie is thread-private or thread-shared
00220  * 
00221  *  3 is orthogonal to 1,2.  Lower 3 bits represents 1,2, upper bit
00222  *  represents 3.
00223  */
00224 
00225 enum Types_of_Tries {
00226   CALL_TRIE_TT              = 0x06,     /* binary:  0110 */
00227   BASIC_ANSWER_TRIE_TT      = 0x05,     /* binary:  0101 */
00228   TS_ANSWER_TRIE_TT         = 0x04,     /* binary:  0100 */
00229   DELAY_TRIE_TT             = 0x03,     /* binary:  0011 */
00230   ASSERT_TRIE_TT            = 0x02,     /* binary:  0010 */
00231   INTERN_TRIE_TT            = 0x01      /* binary:  0001 */
00232 };
00233 
00234 #define IsInCallTrie(pTSC)         ( TSC_TrieType(pTSC) == CALL_TRIE_TT )
00235 #define IsInAnswerTrie(pTSC)                            \
00236    ( TSC_TrieType(pTSC) == BASIC_ANSWER_TRIE_TT  ||     \
00237      TSC_TrieType(pTSC) == TS_ANSWER_TRIE_TT )
00238 #define IsInDelayTrie(pTSC)        ( TSC_TrieType(pTSC) == DELAY_TRIE_TT )
00239 #define IsInAssertTrie(pTSC)       ( TSC_TrieType(pTSC) == ASSERT_TRIE_TT )
00240 #define IsInInternTrie(pTSC)       ( TSC_TrieType(pTSC) == INTERN_TRIE_TT )
00241 
00242 #define IsInTimeStampedTrie(pTSC)  ( TSC_TrieType(pTSC) == TS_ANSWER_TRIE_TT )
00243 #define IsInBasicTrie(pTSC)        ( ! IsInTimeStampedTrie(pTSC) )
00244 
00245 #define IsPrivateTrie(pTSC) ( TSC_TrieType(pTSC) & 0x08 = 0)
00246 #define IsSharedTrie(pTSC) ( TSC_TrieType(pTSC) & 0x08 = 1)
00247 
00248 /*---------------------------------------------------------------------------*/
00249 
00250 /*
00251  *                      Node-Type Definitions
00252  *                      =====================
00253  *
00254  *  Four bits are used to describe the following attributes of a trie
00255  *  subcomponent:
00256  *    3rd bit:  TrieRoot / Non-TrieRoot
00257  *    2nd bit:  Hash Header / Trie Node
00258  *    1st bit:  Leaf / Interior
00259  *    0th bit:  Hashed / Non-Hashed
00260  *  There are 6 basic types of TSCs that we wish to discriminate.
00261  */
00262 
00263 enum Types_of_Trie_Nodes {
00264   TRIE_ROOT_NT          = 0x08,   /* binary:  1000 */
00265   HASH_HEADER_NT        = 0x04,   /* binary:  0100 */
00266   LEAF_NT               = 0x02,   /* binary:  0010 */
00267   HASHED_LEAF_NT        = 0x03,   /* binary:  0011 */
00268   INTERIOR_NT           = 0x00,   /* binary:  0000 */
00269   HASHED_INTERIOR_NT    = 0x01    /* binary:  0001 */
00270 };
00271 
00272 #define  HASHED_NODE_MASK       0x01
00273 #define  LEAF_NODE_MASK         0x02
00274 
00275 
00276 #define IsTrieRoot(pTSC)        (TSC_NodeType(pTSC) == TRIE_ROOT_NT)
00277 #define IsHashHeader(pTSC)      (TSC_NodeType(pTSC) == HASH_HEADER_NT)
00278 #define IsHashedNode(pTSC)      (TSC_NodeType(pTSC) & HASHED_NODE_MASK)
00279 #define IsLeafNode(pTSC)        (TSC_NodeType(pTSC) & LEAF_NODE_MASK)
00280 
00281 #define IsEscapeNode(pTSC)      (TSC_Instr(pTSC) == trie_proceed)
00282 
00283 /* We could also have defined these this way...
00284 #define IsTrieRoot(pTSC)        (TSC_Instr(pTSC) == trie_root)
00285 #define IsHashHeader(pTSC)      (TSC_Instr(pTSC) == hash_opcode)
00286 */
00287 
00288 /*
00289  *  From an INTERIOR-typed node, create a LEAF-typed node, keeping
00290  *  the hashing status in-tact.  All nodes are assigned a status of
00291  *  INTERIOR at allocation time.  Leaf status isn't known until
00292  *  some time afterwards.
00293  */
00294 #define MakeLeafNode(pTN)       \
00295    TN_NodeType(pTN) = TN_NodeType(pTN) | LEAF_NODE_MASK
00296 
00297 /*
00298  *  From an unHASHED-typed node, create a HASHED-typed node, keeping the
00299  *  LEAF/INTERIOR status in-tact.  Used when converting from a sibling
00300  *  chain to a hash structure.
00301  */
00302 #define MakeHashedNode(pTN)     \
00303    TN_NodeType(pTN) = TN_NodeType(pTN) | HASHED_NODE_MASK
00304 
00305 /*---------------------------------------------------------------------------*/
00306 
00307 /*
00308  *                         Symbol Manipulations
00309  *                         ====================
00310  *
00311  *  The symbols stored in tries differ slightly from their representation
00312  *  in the heap.  INTs, FLOATs, and STRINGs have the same tagged
00313  *  structure.  Lists reflect their recursive nature: [Head|Tail] begins
00314  *  with a symbol which is just the tag LIST whose Child node contains a
00315  *  symbol for Head and the Child of this node starts Tail.  E.g., [a,b]
00316  *  = LIST-a-LIST-b-[], where [] is a STRING constant, and '-' represents
00317  *  a parent-to-child connection.  Structures are STRUCT-tagged pointers to
00318  *  PSC-records.  Variables are standardized and represented by TrieVar-
00319  *  tagged integers, starting from 0.
00320  */
00321 
00322 #define TrieSymbolType(Symbol)       cell_tag(Symbol)
00323 
00324 #define IsTrieVar(Symbol)            ( TrieSymbolType(Symbol) == XSB_TrieVar )
00325 #define IsTrieFunctor(Symbol)        ( TrieSymbolType(Symbol) == XSB_STRUCT )
00326 #define IsTrieList(Symbol)           ( TrieSymbolType(Symbol) == XSB_LIST )
00327 #define IsTrieString(Symbol)         ( TrieSymbolType(Symbol) == XSB_STRING )
00328 #define IsTrieInteger(Symbol)        ( TrieSymbolType(Symbol) == XSB_INT )
00329 #define IsTrieFloat(Symbol)          ( TrieSymbolType(Symbol) == XSB_FLOAT )
00330 
00331 #define EncodeTriePSC(pPSC)             makecs(pPSC)
00332 #define EncodeTrieFunctor(Cell_STRUCT)  makecs(follow(clref_val(Cell_STRUCT)))
00333 #define EncodeTrieList(Cell_LIST)       ( (Cell)XSB_LIST )
00334 #define EncodeTrieConstant(Cell_Const)  ( (Cell)Cell_Const )
00335 
00336 #define DecodeTrieFunctor(Symbol)       (Psc)cs_val(Symbol)
00337 #define DecodeTrieList(Symbol)          ( Symbol )
00338 #define DecodeTrieString(Symbol)        string_val(Symbol)
00339 #define DecodeTrieInteger(Symbol)       int_val(Symbol)
00340 #define DecodeTrieFloat(Symbol)         float_val(Symbol)
00341 
00342 /*
00343  *  Symbols in Escape Nodes are never looked at, so we arbitrarily
00344  *  choose some value.
00345  */
00346 #define ESCAPE_NODE_SYMBOL              (Cell)0
00347 
00348 
00349 /* TrieVar Operations
00350  * ------------------
00351  *  Trie Variables are a type of symbol stored in a trie which represent
00352  *  standardized variables.  In actuality, they are 'TrieVar'-tagged,
00353  *  non-negative integers.  Along a path in the trie, the same integered
00354  *  trievar represents the same variable.  Since it is sometimes useful to
00355  *  know whether a trievar has already been encountered higher up in the
00356  *  path, first occurrences of trievars contain an additional (bit) tag.
00357  *
00358  *  When interning a term into a trie, variables in the term must be
00359  *  marked as they are encountered (to handle nonlinearity).  Marking of
00360  *  (or standardizing) these variables is performed by binding them to a
00361  *  special array of self-referential pointers, VarEnumerator[].  After
00362  *  dereferencing the variable, we can check to see whether the pointer
00363  *  lies within the array; if so, the variable has already been
00364  *  encountered.  The integer assigned to a trievar is the index into this
00365  *  array for the cell that marks the term's variable.
00366  *
00367  *  When unifying a term with a trie path, it will be necessary to track
00368  *  bindings made to variables of the trie.  Another array of
00369  *  self-referential pointers, TrieVarBindings[], is used to maintain
00370  *  these bindings.  The binding for a trievar with index I is contained
00371  *  in TrieVarBindings[I].
00372  */
00373 
00374 #ifndef MULTI_THREAD
00375 extern Cell VarEnumerator[];
00376 extern Cell TrieVarBindings[];
00377 
00378 #endif
00379 
00380 #define NEW_TRIEVAR_TAG         0x10000
00381 #define NEW_TRIEATTV_TAG        0x20000
00382 #define TRIEVAR_INDEX_MASK       0xffff
00383 
00384 #define EncodeNewTrieVar(Index)         maketrievar(Index | NEW_TRIEVAR_TAG)
00385 #define EncodeNewTrieAttv(Index)        maketrievar(Index | NEW_TRIEATTV_TAG)
00386 #define EncodeTrieVar(Index)            maketrievar(Index)
00387 
00388 #define DecodeTrieVar(Symbol)     ( trievar_val(Symbol) & TRIEVAR_INDEX_MASK )
00389 
00390 /* Use this test only after determining the Symbol to be a TrieVar */
00391 #define IsNewTrieVar(Symbol)      ( trievar_val(Symbol) & NEW_TRIEVAR_TAG )
00392 #define IsNewTrieAttv(Symbol)     ( trievar_val(Symbol) & NEW_TRIEATTV_TAG)
00393 
00394 #define StandardizeVariable(dFreeVar,Index)     \
00395    bld_ref((CPtr)dFreeVar,VarEnumerator[Index])
00396 
00397 #define IsStandardizedVariable(dFreeVar)                        \
00398    ( ((CPtr)(dFreeVar) >= VarEnumerator) &&                     \
00399      ((CPtr)(dFreeVar) <= (VarEnumerator + NUM_TRIEVARS - 1)) )
00400 
00401 #define ResetStandardizedVariable(VarAddr)      \
00402    bld_free( ((CPtr)VarAddr) )
00403 
00404 /*
00405  *  Given an address that has been determined to lie within the
00406  *  VarEnumerator array, determine its index within this array.
00407  */
00408 #define IndexOfStdVar(pVarEnumCell)     \
00409    ( (CPtr)(pVarEnumCell) - VarEnumerator )
00410 
00411 
00412 /*
00413  *  Derefs a symbol stored in a trie node by converting a TrieVar into
00414  *  an address, and then performing a normal deref operation.
00415  */
00416 #define TrieSymbol_Deref(Symbol)                        \
00417    if (IsTrieVar(Symbol)) {                             \
00418      Symbol = TrieVarBindings[DecodeTrieVar(Symbol)];   \
00419      XSB_Deref(Symbol);                                 \
00420    }
00421 
00422 #define IsUnboundTrieVar(dFreeVar)                                      \
00423    ( ((CPtr)(dFreeVar) >= TrieVarBindings) &&                           \
00424      ((CPtr)(dFreeVar) <= (TrieVarBindings + NUM_TRIEVARS - 1)) )
00425 
00426 /*---------------------------------------------------------------------------*/
00427 
00428 /*
00429  *                       Subcomponent Operations
00430  *                       =======================
00431  */
00432 
00433 
00434 #define IsEmptyTrie(Root)       IsNULL(TN_Child(Root))
00435 
00436 
00437 /*
00438  *                            Trie Nodes
00439  *                            ----------
00440  */
00441 
00442 #define TN_Init(TN,TrieType,NodeType,Symbol,Parent,Sibling) {   \
00443                                                                 \
00444    if ( NodeType != TRIE_ROOT_NT ) {                            \
00445      TN_SetInstr(TN,Symbol);                                    \
00446      TN_ResetInstrCPs(TN,Sibling);                              \
00447    }                                                            \
00448    else                                                         \
00449      TN_Instr(TN) = trie_root;                                  \
00450    TN_Status(TN) = VALID_NODE_STATUS;                           \
00451    TN_TrieType(TN) = TrieType;                                  \
00452    TN_NodeType(TN) = NodeType;                                  \
00453    TN_Symbol(TN) = Symbol;                                      \
00454    TN_Parent(TN) = Parent;                                      \
00455    TN_Child(TN) = NULL;                                         \
00456    TN_Sibling(TN) = Sibling;                                    \
00457  }
00458 
00459 
00460 #define SearchChainForSymbol(Chain,Symbol,ChainLength) {        \
00461    ChainLength = 0;                                             \
00462    while ( IsNonNULL(Chain) && (TN_Symbol(Chain) != Symbol) ) { \
00463      ChainLength++;                                             \
00464      Chain = TN_Sibling(Chain);                                 \
00465    }                                                            \
00466  }
00467 
00468 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
00469 
00470 /*
00471  *                         Trie Hash Tables
00472  *                         ----------------
00473  *
00474  *  A hash table is created below a trie node when the number of its
00475  *  children becomes greater than MAX_SIBLING_LEN.  The hash table is
00476  *  organized as a header structure containing the status of the hash
00477  *  table, as well as a few other fields.  One is a pointer which
00478  *  links all allocated (in use) hash table headers, allowing rapid
00479  *  deallocation of the bucket arrays when the tables are abolished.    
00480  *  The other is an InstrPlusType field needed to support compiled
00481  *  tries.
00482  *
00483  *  A simple and efficient hashing function is used for maintaining
00484  *  nodes in the hash table.  It uses a bit-mask, rather than division,
00485  *  to obtain a number within the range of buckets.  Because of this,
00486  *  the size of the hash table must ALWAYS BE a power of 2.
00487  */
00488 
00489 /*
00490  *  Threshold to determine when to change from a chain of children to a
00491  *  hash table for them.
00492  */
00493 #define MAX_SIBLING_LEN   8
00494 #define IsLongSiblingChain(ChainLength)    ( ChainLength > MAX_SIBLING_LEN )
00495 
00496 /*
00497  *  Hashing function for symbols
00498  */
00499 #define TRIEVAR_BUCKET  0
00500 
00501 #define TrieHash(Symbol, HashSeed)                              \
00502    ( IsTrieVar(Symbol)                                          \
00503       ? TRIEVAR_BUCKET                                          \
00504       : ( ((Symbol) >> XSB_CELL_TAG_NBITS) & (HashSeed) )       \
00505     )
00506 
00507 #define CalculateBucketForSymbol(pHT,Symbol)            \
00508    ( TrieHT_BucketArray(pHT) + TrieHash(Symbol,TrieHT_GetHashSeed(pHT)) )
00509 
00510 
00511 /*
00512  *  Hashtable sizes; must be power of 2 and > MAX_SIBLING_LEN.
00513  */
00514 #define TrieHT_INIT_SIZE     64
00515 #define TrieHT_NewSize(pHT)  ( TrieHT_NumBuckets(pHT) << 1 )
00516 
00517 extern void  hashify_children(CTXTdeclc BTNptr, int);
00518 
00519 /*
00520  *  Inserting into a bucket with few nodes reflects a good hash.  In
00521  *  this case, we do not want to waste time expanding the table.  If,
00522  *  however, the bucket contains more nodes than some threshhold AND
00523  *  the contents of the table as a whole exceeds its size, then we
00524  *  expand the hash table.
00525  *  We could also have defined this test to be solely dependent on
00526  *  the number of nodes contained in the hash table, or on the length
00527  *  of the chain in the hashed-to bucket.
00528  */
00529 
00530 #define BUCKET_CONTENT_THRESHOLD        (MAX_SIBLING_LEN / 2)
00531 
00532 #define TrieHT_ExpansionCheck(pHT,NumBucketContents) {          \
00533    if ( (NumBucketContents > BUCKET_CONTENT_THRESHOLD) &&       \
00534         (TrieHT_NumContents(pHT) > TrieHT_NumBuckets(pHT)) )    \
00535      expand_trie_ht((BTHTptr)pHT);                              \
00536  }
00537 
00538    
00539 /*
00540  *  Insert a Trie Node into a hash table whose size is HashSeed+1.
00541  */
00542 #define TrieHT_InsertNode(pBucketArray,HashSeed,pTN) {                    \
00543                                                                           \
00544    void **pBucket;                                                        \
00545                                                                           \
00546    pBucket = (void **)(pBucketArray + TrieHash(TN_Symbol(pTN),HashSeed)); \
00547    if ( IsNonNULL(*pBucket) ) {                                           \
00548      TN_ForceInstrCPtoTRY(pTN);                                           \
00549      TN_RotateInstrCPtoRETRYorTRUST((BTNptr)*pBucket);                    \
00550    }                                                                      \
00551    else                                                                   \
00552      TN_ForceInstrCPtoNOCP(pTN);                                          \
00553    TN_Sibling(pTN) = *pBucket;                                            \
00554    *pBucket = pTN;                                                        \
00555  }
00556 
00557 /*===========================================================================*/
00558 
00559 /*
00560  *        S P E C I F I C   C O M P O N E N T   O P E R A T I O N S
00561  *        =========================================================
00562  */
00563 
00564 /*-------------------------------------------------------------------------*/
00565 
00566 /*
00567  *                               Basic Tries
00568  *                               ===========
00569  */
00570 
00571 /*
00572  *                             Basic Trie Node
00573  *                             ---------------
00574  */
00575 
00576 /* For BTNs which hash children
00577    ---------------------------- */
00578 #define BTN_SetHashHdr(pBTN,pTHT)       TN_SetHashHdr(pBTN,pTHT)
00579 #define BTN_GetHashHdr(pBTN)            ( (BTHTptr)TN_GetHashHdr(pBTN) )
00580 
00581 /* For leaves of Call Tries
00582    ------------------------ */
00583 #define CallTrieLeaf_SetSF(pBTN,pSF)     BTN_Child(pBTN) = (BTNptr)(pSF)
00584 #define CallTrieLeaf_GetSF(pBTN)         ((VariantSF)BTN_Child(pBTN))
00585 
00586 /* Allocating New BTNs
00587    ------------------- */
00588 #define BTNs_PER_BLOCK   2*K
00589 extern Structure_Manager smTableBTN;
00590 extern Structure_Manager smAssertBTN;
00591 
00592 #ifndef MULTI_THREAD
00593 extern Structure_Manager *smBTN;
00594 extern Structure_Manager smTSIN;
00595 extern Structure_Manager smTSTHT;
00596 #endif
00597 
00598 extern BTNptr new_btn(CTXTdeclc int TrieType, int NodeType, Cell Symbol,
00599                       BTNptr Parent, BTNptr Sibling);
00600 
00601 #define New_BTN(BTN,TrieType,NodeType,Symbol,Parent,Sibling)    \
00602    BTN = new_btn(CTXTc TrieType,NodeType,Symbol,(BTNptr)Parent,(BTNptr)Sibling)
00603 
00604 #define CreateEscapeBTN(pBTN,TrieType,Parent) {                         \
00605    New_BTN(pBTN,TrieType,LEAF_NT,ESCAPE_NODE_SYMBOL,Parent,NULL);       \
00606    BTN_Instr(pBTN) = trie_proceed;                                      \
00607  }
00608 
00609 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
00610 
00611 /*
00612  *                        Basic Trie Hash Tables
00613  *                        ----------------------
00614  */
00615 
00616 typedef struct Basic_Trie_HashTable *BTHTptr;
00617 typedef struct Basic_Trie_HashTable {
00618   InstrPlusType info;
00619   unsigned long  numContents;
00620   unsigned long  numBuckets;
00621   BTNptr *pBucketArray;
00622   BTHTptr prev, next;              /* DLL needed for branch deletion */
00623 } BasicTrieHT;
00624 
00625 /* Field Access Macros
00626    ------------------- */
00627 #define BTHT_Instr(pTHT)                TrieHT_Instr(pTHT)
00628 #define BTHT_Status(pTHT)               TrieHT_Status(pTHT)
00629 #define BTHT_TrieType(pTHT)             TrieHT_TrieType(pTHT)
00630 #define BTHT_NodeType(pTHT)             TrieHT_NodeType(pTHT)
00631 #define BTHT_NumBuckets(pTHT)           TrieHT_NumBuckets(pTHT)
00632 #define BTHT_NumContents(pTHT)          TrieHT_NumContents(pTHT)
00633 #define BTHT_BucketArray(pTHT)          TrieHT_BucketArray(pTHT)
00634 #define BTHT_PrevBTHT(pTHT)             TrieHT_PrevHT(pTHT)
00635 #define BTHT_NextBTHT(pTHT)             TrieHT_NextHT(pTHT)
00636 
00637 #define BTHT_GetHashSeed(pTHT)          TrieHT_GetHashSeed(pTHT)
00638 
00639 /* General Header Management
00640    ------------------------- */
00641 
00642 /* TLS: Lock once (if needed), as we need to allocate, add buckets to
00643    alloc_list, etc. */
00644 
00645 #ifdef MULTI_THREAD  
00646 #define _New_TrieHT(SM,THT,TrieType) {                                  \
00647     if (threads_current_sm == PRIVATE_SM) {                             \
00648       _New_TrieHT_Sub(SM,THT,TrieType);                                 \
00649     } else {                                                            \
00650       SYS_MUTEX_LOCK( MUTEX_SM );                                       \
00651       _New_TrieHT_Sub(SM,THT,TrieType);                                 \
00652       SYS_MUTEX_UNLOCK( MUTEX_SM );                                     \
00653     }                                                                   \
00654 }
00655 #else
00656 #define _New_TrieHT(SM,THT,TrieType)  _New_TrieHT_Sub(SM,THT,TrieType) 
00657 #endif
00658 
00659 #define _New_TrieHT_Sub(SM,THT,TrieType) {                              \
00660                                                                         \
00661    void * btht;                                                         \
00662    SM_AllocateStruct(SM,btht);                                          \
00663    BTHT_Instr(((BTHTptr)btht)) = hash_opcode;                           \
00664    BTHT_Status(((BTHTptr)btht)) = VALID_NODE_STATUS;                    \
00665    BTHT_TrieType(((BTHTptr)btht)) = TrieType;                           \
00666    BTHT_NodeType(((BTHTptr)btht)) = HASH_HEADER_NT;                     \
00667    BTHT_NumContents(((BTHTptr)btht)) = MAX_SIBLING_LEN + 1;             \
00668    BTHT_NumBuckets(((BTHTptr)btht)) = TrieHT_INIT_SIZE;                 \
00669    BTHT_BucketArray(((BTHTptr)btht)) =                                  \
00670      (BTNptr *)mem_calloc(TrieHT_INIT_SIZE, sizeof(void *),TABLE_SPACE);\
00671    SM_AddToAllocList_DL(SM,((BTHTptr)btht),BTHT_PrevBTHT,BTHT_NextBTHT) \
00672    THT = btht;                                                          \
00673 }
00674 
00675    /*   Debugging: 
00676 |       printf("allocating hash for %s (%d): %x\n",
00677 |       SM_StructName(SM),xsb_thread_id,btht);                  
00678 |   for ( pBTHT = (BTHTptr)SM_AllocList(SM);  IsNonNULL(pBTHT); 
00679 |        pBTHT = (BTHTptr)BTHT_NextBTHT(pBTHT) )                        
00680 |        printf("     hash allocation chain%x\n",pBTHT);        */      
00681 
00682 extern void expand_trie_ht(BTHTptr);
00683 
00684 /* Currently SM must be a private table, or this macro must be called
00685    from within the scope of a mutex. */
00686 #define TrieHT_RemoveFromAllocList(SM,THT)      \
00687    SM_RemoveFromAllocList_DL(SM,THT,BTHT_PrevBTHT,BTHT_NextBTHT)
00688 
00689 /* Preparation for mass deallocation.  Assumes that for a shared SM it
00690    is in the scope of a mutex.  */
00691 #define TrieHT_FreeAllocatedBuckets(SM) {                       \
00692    BTHTptr pBTHT;                                               \
00693                                                                 \
00694    for ( pBTHT = (BTHTptr)SM_AllocList(SM);  IsNonNULL(pBTHT);  \
00695          pBTHT = (BTHTptr)BTHT_NextBTHT(pBTHT) ) {                      \
00696      /*     printf("freeing table for thread %d: %x\n",xsb_thread_id,pBTHT); */ \
00697      mem_dealloc(BTHT_BucketArray(pBTHT),BTHT_NumBuckets(pBTHT)*sizeof(void *),TABLE_SPACE); \
00698    }                                                                    \
00699  }
00700 
00701 /* Allocating Headers
00702    ------------------ */
00703 #define BTHTs_PER_BLOCK   16
00704 extern Structure_Manager smTableBTHT;
00705 extern Structure_Manager smAssertBTHT;
00706 #ifndef MULTI_THREAD
00707 extern Structure_Manager *smBTHT;
00708 #endif
00709 
00710 #define New_BTHT(BTHT,TrieType)      _New_TrieHT(*smBTHT,BTHT,TrieType)
00711 
00712 /*---------------------------------------------------------------------------*/
00713 
00714 /*
00715  *                          Time-Stamped Tries
00716  *                          ==================
00717  */
00718 
00719 /*
00720  *                        Time-Stamped Trie Nodes
00721  *                        -----------------------
00722  */
00723 
00724 /* For roots of TS Answer Tries
00725    ---------------------------- */
00726 #define TSTRoot_SetHTList(pTST,pTSTHT)  TSTN_Sibling(pTST) = (TSTNptr)pTSTHT
00727 #define TSTRoot_GetHTList(pTST)         ((TSTHTptr)TSTN_Sibling(pTST))
00728 
00729 /* For TSTNs which hash children
00730    ----------------------------- */
00731 #define TSTN_SetHashHdr(pTSTN,pTSTHT)   TN_SetHashHdr(pTSTN,pTSTHT)
00732 #define TSTN_GetHashHdr(pTSTN)          ( (TSTHTptr)TN_GetHashHdr(pTSTN) )
00733 
00734 /* For Hashed TSTNs
00735    ---------------- */
00736 #define TSTN_SetTSIN(pTSTN,TSIN)    TSTN_TimeStamp(pTSTN) = (TimeStamp)(TSIN)
00737 #define TSTN_GetTSIN(pTSTN)         ((TSINptr)TSTN_TimeStamp(pTSTN))
00738 #define TSTN_GetTSfromTSIN(pTSTN)   TSIN_TimeStamp(TSTN_GetTSIN(pTSTN))
00739 
00740 /* For leaves of TS Answer Tries
00741    ----------------------------- */
00742 #define TSTN_GetDelayList(pTSTN)      TSTN_Child(pTSTN)
00743 
00744 /* Allocating New TSTNs
00745    -------------------- */
00746 #define TSTNs_PER_BLOCK    K
00747 
00748 #ifndef MULTI_THREAD
00749 extern Structure_Manager smTSTN;
00750 #endif
00751 
00752 extern TSTNptr new_tstn(CTXTdeclc int TrieType, int NodeType, Cell Symbol,
00753                         TSTNptr Parent, TSTNptr Sibling);
00754 
00755 #define New_TSTN(TSTN,TrieType,NodeType,Symbol,Parent,Sibling)  \
00756    TSTN = new_tstn(CTXTc TrieType,NodeType,Symbol,Parent,Sibling)
00757 
00758 #define CreateEscapeTSTN(pTSTN,TrieType,Parent) {                       \
00759    New_TSTN(pTSTN,TrieType,LEAF_NT,ESCAPE_NODE_SYMBOL,Parent,NULL);     \
00760    TSTN_Instr(pTSTN) = trie_proceed;                                    \
00761  }
00762 
00763 #define EMPTY_TST_TIMESTAMP     0
00764 #define TSTN_DEFAULT_TIMESTAMP  1
00765 #define PRODUCER_SF_INITIAL_TS  TSTN_DEFAULT_TIMESTAMP
00766 #define CONSUMER_SF_INITIAL_TS  EMPTY_TST_TIMESTAMP
00767 
00768 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
00769 
00770 /*
00771  *                         Time Stamp Index
00772  *                         ----------------
00773  *
00774  *  Hash tables allow for indexing on symbols of the stored terms.  But
00775  *  in the absence of symbol-key info (i.e., variable processing) it is
00776  *  desirable to select symbols based on time stamp value.  Therefore,
00777  *  hashed symbols are also organized in a secondary indexing structure
00778  *  based on their time stamps.  This index allows for the selection of
00779  *  symbols with valid time stamps -- symbols having time stamp values
00780  *  greater than some given time stamp -- in time proportional to the
00781  *  number of such symbols.  The organization of a Time Stamp Index is
00782  *  maintained by a TST Hash Table and consists of a doubly-linked list
00783  *  of nodes (the 'prev' field of the first node and the 'next' field of
00784  *  the last are always NULL) which, when traversed from head to tail,
00785  *  visits the symbols in decreasing time-stamp order.  These nodes are
00786  *  assigned one to a TSTN and contain bidirectional references,
00787  *  allowing for reorganization in constant time (TSTNs are likely to
00788  *  change their time stamp value during insertions).  The nodes of this
00789  *  index are globally maintained by a "Structure Manager" structure,
00790  *  are allocated from this pool when needed, and returned when not.  To
00791  *  allow rapid deallocation in accordance with the constraints of the
00792  *  Structure_Manager, the first word in these indexing nodes contain
00793  *  one of the fields used to link them into a chain.
00794  */
00795 
00796 typedef struct TimeStamp_Index_Node *TSINptr;
00797 typedef struct TimeStamp_Index_Node {
00798   TSINptr prev;
00799   TSINptr next;
00800   TimeStamp ts;
00801   TSTNptr tstn;
00802 } TS_IndexNode;
00803 
00804 #define TSIN_Prev(TSIN)                 ((TSIN)->prev)
00805 #define TSIN_Next(TSIN)                 ((TSIN)->next)
00806 #define TSIN_TimeStamp(TSIN)            ((TSIN)->ts)
00807 #define TSIN_TSTNode(TSIN)              ((TSIN)->tstn)
00808 
00809 #define IsTSindexHead(TSIN)             IsNULL(TSIN_Prev(TSIN))
00810 #define IsTSindexTail(TSIN)             IsNULL(TSIN_Next(TSIN))
00811 
00812 /* Memory Management
00813    ----------------- */
00814 #define TSINs_PER_BLOCK  256
00815 
00816 /*
00817  *  Set `TSIN' to an unused entry in the global TS_IndexNode resource,
00818  *  and associate this entry with the TSTN pointed to by `TSTN'.
00819  * 'prev' and 'next' links are left to the caller to set.  Subsumptive
00820  *  tables use private SMs, so don't worry about allocating shared
00821  *  structures. 
00822  */
00823 #define New_TSIN(TSIN, TSTN) {                  \
00824    void *t ;                                    \
00825    SM_AllocateStruct(smTSIN,t);                 \
00826    TSIN = (TSINptr)t ;                          \
00827    TSIN_TSTNode(TSIN) = TSTN;                   \
00828    TSIN_TimeStamp(TSIN) = TSTN_TimeStamp(TSTN); \
00829  }
00830 
00831 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
00832 
00833 /*
00834  *                       Time-Stamped Trie Hash Table
00835  *                       ----------------------------
00836  *
00837  */
00838 
00839 typedef struct HashTable_for_TSTNs *TSTHTptr;
00840 typedef struct HashTable_for_TSTNs {
00841   InstrPlusType info;
00842   unsigned long  numContents;
00843   unsigned long  numBuckets;
00844   TSTNptr *pBucketArray;
00845   TSTHTptr prev, next;
00846   TSTHTptr internalLink;     /* For reclaimation of TSI Entries w/i a TST. */
00847   TSINptr index_head;        /* These fields maintain the TSI. */
00848   TSINptr index_tail;
00849 } TST_HashTable;
00850 
00851 /* Field Access Macros
00852    ------------------- */
00853 #define TSTHT_Instr(pTSTHT)             TrieHT_Instr(pTSTHT)
00854 #define TSTHT_Padding(pTSTHT)           TrieHT_Status(pTSTHT)
00855 #define TSTHT_TrieType(pTSTHT)          TrieHT_TrieType(pTSTHT)
00856 #define TSTHT_NodeType(pTSTHT)          TrieHT_NodeType(pTSTHT)
00857 #define TSTHT_NumBuckets(pTSTHT)        TrieHT_NumBuckets(pTSTHT)
00858 #define TSTHT_NumContents(pTSTHT)       TrieHT_NumContents(pTSTHT)
00859 #define TSTHT_BucketArray(pTSTHT)       TrieHT_BucketArray(pTSTHT)
00860 #define TSTHT_PrevTSTHT(pTSTHT)         TrieHT_PrevHT(pTSTHT)
00861 #define TSTHT_NextTSTHT(pTSTHT)         TrieHT_NextHT(pTSTHT)
00862 #define TSTHT_InternalLink(pTSTHT)      ((pTSTHT)->internalLink)
00863 #define TSTHT_IndexHead(pTSTHT)         ((pTSTHT)->index_head)
00864 #define TSTHT_IndexTail(pTSTHT)         ((pTSTHT)->index_tail)
00865 
00866 #define TSTHT_GetHashSeed(pTSTHT)   BTHT_GetHashSeed((BTHTptr)(pTSTHT))
00867 
00868 /* Memory Management
00869    ----------------- */
00870 #define TSTHTs_PER_BLOCK  16
00871 
00872 /* TLS: no locking for subsumptive tables, which use private SMs */
00873 #define New_TSTHT(TSTHT,TrieType,TST) {                         \
00874    _New_TrieHT_Sub(smTSTHT,TSTHT,TrieType);                             \
00875    TSTHT_InternalLink(TSTHT) = (TSTHTptr)TSTRoot_GetHTList(TST);\
00876    TSTRoot_SetHTList(TST,TSTHT);                                \
00877    TSTHT_IndexHead(TSTHT) = TSTHT_IndexTail(TSTHT) = NULL;      \
00878  }
00879 
00880 /*-------------------------------------------------------------------------*/
00881 
00882 /*
00883  *                             Answer List Node
00884  *                             ================
00885  */
00886 
00887 #define ALNs_PER_BLOCK     512
00888 extern Structure_Manager smALN;
00889 
00890 /* Allocating New ALNs
00891 
00892 New_ALN is for use in variant tables: in the MT engine it checks the
00893 subgoal frame (explicitly a parameter) to see if the private or shared
00894 structure manager is to be used.  New_Private_ALN is for use in
00895 subsumptive tables, which are private in the MT engine.
00896 
00897   ------------------- */
00898 
00899 #ifndef MULTI_THREAD
00900 #define New_ALN(subgoal,pALN, pTN, pNext) {     \
00901    void *p ;                                    \
00902                                                 \
00903    SM_AllocateStruct(smALN,p);                  \
00904    pALN = (ALNptr)p;                            \
00905    ALN_Answer(pALN) = (BTNptr)pTN;              \
00906    ALN_Next(pALN) = (ALNptr)pNext;              \
00907  }
00908 #else
00909 #define New_ALN(subgoal,pALN, pTN, pNext) {     \
00910    void *p ;                                    \
00911                                                 \
00912    if (IsSharedSF(subgoal)) {                   \
00913      SM_AllocateSharedStruct(smALN,p);          \
00914    } else {                                     \
00915      SM_AllocateStruct(*private_smALN,p);       \
00916    }                                            \
00917    pALN = (ALNptr)p;                            \
00918    ALN_Answer(pALN) = (BTNptr)pTN;              \
00919    ALN_Next(pALN) = (ALNptr)pNext;              \
00920  }
00921 #endif
00922 
00923 
00924 #ifndef MULTI_THREAD
00925 #define New_Private_ALN(pALN, pTN, pNext) {             \
00926     void *p ;                                           \
00927                                                         \
00928     SM_AllocateStruct(smALN,p);                         \
00929     pALN = (ALNptr)p;                                   \
00930     ALN_Answer(pALN) = (BTNptr)pTN;                     \
00931     ALN_Next(pALN) = (ALNptr)pNext;                     \
00932  }
00933 #else
00934 #define New_Private_ALN(pALN, pTN, pNext) {             \
00935     void *p ;                                           \
00936                                                         \
00937     SM_AllocateStruct(*private_smALN,p);                \
00938     pALN = (ALNptr)p;                                   \
00939     ALN_Answer(pALN) = (BTNptr)pTN;                     \
00940     ALN_Next(pALN) = (ALNptr)pNext;                     \
00941   }
00942 #endif
00943 
00944 /* Rui: please check this to see if its ok */
00945 #ifndef CONC_COMPL
00946 #ifndef MULTI_THREAD
00947 #define free_answer_list(SubgoalFrame) {                        \
00948     if ( subg_answers(SubgoalFrame) > COND_ANSWERS )            \
00949       SM_DeallocateStructList(smALN,                            \
00950                               subg_ans_list_ptr(SubgoalFrame),  \
00951                               subg_ans_list_tail(SubgoalFrame)) \
00952       else                                                      \
00953         SM_DeallocateStruct(smALN,subg_ans_list_ptr(SubgoalFrame));     \
00954   }
00955 #else /* MT but not CONC_COMPL */
00956 #define free_answer_list(SubgoalFrame) {                        \
00957     if (IsSharedSF(SubgoalFrame)) {                             \
00958       if ( subg_answers(SubgoalFrame) > COND_ANSWERS )          \
00959         SM_DeallocateStructList(smALN,                          \
00960                                 subg_ans_list_ptr(SubgoalFrame),        \
00961                                 subg_ans_list_tail(SubgoalFrame))       \
00962         else                                                            \
00963           SM_DeallocateSharedStruct(smALN,subg_ans_list_ptr(SubgoalFrame)); \
00964     } else {                                                            \
00965       if ( subg_answers(SubgoalFrame) > COND_ANSWERS )                  \
00966         SM_DeallocateStructList(*private_smALN,                         \
00967                                 subg_ans_list_ptr(SubgoalFrame),        \
00968                                 subg_ans_list_tail(SubgoalFrame))       \
00969         else                                                            \
00970           SM_DeallocateStruct(*private_smALN,subg_ans_list_ptr(SubgoalFrame)); \
00971     }                                                                   \
00972   }
00973 #endif
00974 #else /* CONC COMPL */
00975 #define free_answer_list(SubgoalFrame) {                        \
00976    if ( !IsNULL(subg_answers(SubgoalFrame)) )                   \
00977      SM_DeallocateStructList(smALN,                             \
00978                              subg_ans_list_ptr(SubgoalFrame),   \
00979                              subg_ans_list_tail(SubgoalFrame))  \
00980  }
00981 #endif
00982 
00983 /*===========================================================================*/
00984 
00985 /*
00986  *           L O W - L E V E L   T R I E   O P E R A T I O N S
00987  *           =================================================
00988  */
00989 
00990 
00991 /* Term Lookup
00992    ----------- */
00993 extern void *var_trie_lookup(CTXTdeclc void *, xsbBool *, Cell *);
00994 extern void *iter_sub_trie_lookup(CTXTdeclc void *trieNode, TriePathType *);
00995 
00996 #define trie_escape_lookup(Root)                \
00997    ( IsEscapeNode(TN_Child((BTNptr)Root))       \
00998      ? TN_Child((BTNptr)Root)                   \
00999      : NULL )
01000 
01001 
01002 /* Term Insertion
01003    -------------- */
01004 void *stl_restore_variant_cont(CTXTdecl);
01005 
01006 enum {NO_INSERT_SYMBOL = 0};
01007 
01008 extern BTNptr  bt_escape_search(CTXTdeclc BTNptr root, xsbBool *isNew);
01009 extern BTNptr  bt_insert(CTXTdeclc BTNptr root, BTNptr start, Cell firstSym);
01010 extern TSTNptr tst_insert(CTXTdeclc TSTNptr root, TSTNptr start, Cell firstSym,
01011                           xsbBool maintainTSI);
01012 
01013 #define TST_InsertEscapeNode(Root,NewNode) {                                \
01014    CreateEscapeTSTN(NewNode,TSTN_TrieType(Root),Root);                      \
01015    TSTN_Child(Root) = NewNode;                                              \
01016    TSTN_TimeStamp(NewNode) = TSTN_TimeStamp(Root) = TSTN_DEFAULT_TIMESTAMP; \
01017  }
01018 
01019 #define BT_InsertEscapeNode(Root,NewNode) {             \
01020    CreateEscapeBTN(NewNode,BTN_TrieType(Root),Root);    \
01021    BTN_Child(Root) = NewNode;                           \
01022  }
01023 
01024 /*===========================================================================*/
01025 
01026 /*
01027  *                      E R R O R   R E P O R T I N G
01028  *                      =============================
01029  */
01030 
01031 
01032 #define TrieError_UnknownSubtermTagMsg                          \
01033    "Trie Subterm-to-Symbol Conversion\nUnknown subterm type (%d)"
01034 
01035 #define TrieError_UnknownSubtermTag(Subterm)                    \
01036    xsb_abort(TrieError_UnknownSubtermTagMsg, cell_tag(Subterm))
01037 
01038 
01039 #define TrieError_AbsentEscapeNode(Root) {              \
01040   Cell symbol = TN_Symbol(Root);                        \
01041   if ( IsTrieString(symbol) ||                          \
01042        (IsTrieFunctor(symbol) &&                        \
01043         (get_arity(DecodeTrieFunctor(symbol)) == 0)) )  \
01044     xsb_abort("Trie Structure Anomaly\n"                \
01045               "Non-Escape-Node present in 0-ary trie"); \
01046   else                                                  \
01047     xsb_abort("Trie Structure Anomaly\n"                \
01048               "Escape Node expected but not found");    \
01049  }
01050 
01051 
01052 #define TrieError_TooManyTerms(Function)                        \
01053    xsb_abort("Trie Matching\nToo many terms for trie in "       \
01054              Function)
01055 
01056 
01057 #define TrieError_TooFewTerms(Function)                         \
01058    xsb_abort("Trie Matching\nToo few terms for trie in "        \
01059              Function)
01060 
01061 
01062 #define TrieError_InterfaceInvariant(Function)                  \
01063    xsb_abort("Trie Interface\nImproper use of " Function)
01064 
01065 /*===========================================================================*/
01066 
01067 
01068 #endif

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