tr_code_xsb_i.h

00001 /* File:      tr_code_xsb_i.h
00002 ** Author(s): Prasad Rao, Kostis Sagonas, Baoqiu Cui
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: tr_code_xsb_i.h,v 1.11 2005/10/03 13:26:43 tswift Exp $
00022 ** 
00023 */
00024 
00025 
00026 #define opatom Atom(NodePtr)
00027 #define opsucc ((byte *)(Child(NodePtr)))
00028 #define opfail ((byte *)(Sibl(NodePtr)))
00029 
00030 #define FIRST_HASH_NODE  -1
00031 #define NO_MORE_IN_HASH  -2
00032 #define HASH_IS_FREE     -3
00033 #define HASH_IS_NOT_FREE -4
00034 
00035 /*----------------------------------------------------------------------*/
00036 
00037 /* These are used only in instruction "hash_handle"
00038    ------------------------------------------------ */
00039 /*
00040  *  Calculate the bucket number in which Subterm would be located,
00041  *  should it exist in the trie.
00042  */
00043 #define hash_nonvar_subterm(Subterm, pBTHT, BucketNum) {        \
00044                                                                 \
00045    Cell symbol = 0;     /* eliminate compiler warning */        \
00046                                                                 \
00047    switch (cell_tag(Subterm)) {                                 \
00048    case XSB_STRING:                                            \
00049    case XSB_INT:                                               \
00050    case XSB_FLOAT:                                              \
00051      symbol = EncodeTrieConstant(Subterm);                      \
00052      break;                                                     \
00053    case XSB_LIST:                                               \
00054      symbol = EncodeTrieList(Subterm);                          \
00055      break;                                                     \
00056    case XSB_STRUCT:                                             \
00057      symbol = EncodeTrieFunctor(Subterm);                       \
00058      break;                                                     \
00059    default:                                                     \
00060      fprintf(stderr,"Bad tag :Type %ld ",cell_tag(Subterm));    \
00061      xsb_exit("In instruction hash_handle");                    \
00062      break;                                                     \
00063    }                                                            \
00064    BucketNum = TrieHash(symbol,BTHT_GetHashSeed(pBTHT));        \
00065  }
00066 
00067 #define find_next_nonempty_bucket(pBTHT, pTable, BucketNum) {   \
00068    long TableSize = BTHT_NumBuckets(pBTHT);                     \
00069                                                                 \
00070    while (TRUE) {                                               \
00071      BucketNum++;                                               \
00072      if (BucketNum >= TableSize) {                              \
00073        BucketNum = NO_MORE_IN_HASH;                             \
00074        break;                                                   \
00075      }                                                          \
00076      else if ( IsNonNULL(*(pTable + BucketNum)) )               \
00077        break;                                                   \
00078    }                                                            \
00079  }
00080 
00081 /*----------------------------------------------------------------------*/
00082 
00083 /*
00084  * Decide how to proceed from current node.  Used in variable-containing
00085  * nodes since it is unclear from the context (embedded instruction)
00086  * whether we are at a leaf node.  Only variables or constants can be
00087  * leaves of the trie, but constants have special instructions when they
00088  * appear as leaves.
00089  */
00090 #define next_lpcreg {                           \
00091    if ( IsLeafNode(NodePtr) )                   \
00092      proceed_lpcreg                             \
00093    else                                         \
00094      non_ftag_lpcreg;                           \
00095  }
00096 
00097 /*
00098  * Use when current node is known to be a leaf of the trie.  If we're in
00099  * an answer trie, then check for and handle conditional answers.
00100  */
00101 #define proceed_lpcreg {                        \
00102    if( IsInAnswerTrie(NodePtr) && delay_it )    \
00103      handle_conditional_answers;                \
00104    global_num_vars = num_vars_in_var_regs;      \
00105    num_vars_in_var_regs = -1;                   \
00106    Last_Nod_Sav = NodePtr;                      \
00107    lpcreg = cpreg;                              \
00108    TRIE_R_UNLOCK();                             \
00109  }
00110 
00111 /*
00112  * Use when the current node is known NOT to be a leaf of the trie.
00113  * Continue by going to the child of the current node.
00114  */
00115 #define non_ftag_lpcreg         lpcreg = opsucc
00116 
00117 /*----------------------------------------------------------------------*/
00118 /* Global variables -- should really be made local ones...              */
00119 /*----------------------------------------------------------------------*/
00120 
00121 #ifndef MULTI_THREAD
00122 
00123 /* TLS: 08/05 documentation of reg_array and var_regs.
00124  * 
00125  * reg_array is a stack used for unificiation by trie instructions
00126  * from a completed table and asserted tries.  In the former case, the
00127  * reg_array is init'd by tabletry; in the latter by trie_assert_inst.
00128  * After initialization, the values of reg_array point to the
00129  * dereferenced values of the answer_template (for tables) or of the
00130  * registers of the call (for asserted tries).  These values are
00131  * placed in reg_array in reverse order, so that at the end of
00132  * initialization the first argument of the call or answer template is
00133  * at the top of the stack.  Actions are then as follows: 
00134  * 
00135  * 1) When a structure/list is encountered, and the symbol unifies
00136  * with the top of reg_array, additional cells are pushed onto
00137  * reg_array.  In the case where the trie is unifying with a variable,
00138  * a WAM build-type operation is performed so that these new reg_array
00139  * cells point to new heap cells.  In the case where the trie is
00140  * unifying with a structure on the heap, the new cells point to the
00141  * arguments of the structure, in preparation for further
00142  * unifications. 
00143  * 
00144  * 2) When a constant/number is encountered, an attempt is made to
00145  * unify this value with the referent of reg_array.  If it unifies,
00146  * the cell is popped off of reg_array, and the algorithm continues.
00147  * 
00148  * 3) When a variable is encountered in the trie it is handled like a
00149  * constant from the perspective of reg_array, but now the var_regs
00150  * array comes into play.
00151  * 
00152  * Variables in the path of a trie are numbered sequentially in the
00153  * order of their occurrence in a LR traversal of the trie.  Trie
00154  * instructions distinguish first occurrences (_vars) from subsequent
00155  * occurrences (_vals).  When a _var numbered N is encountered while
00156  * traversing a trie path, the Nth cell of var_regs is set to the
00157  * value of the top of the reg_array stack, and the unification
00158  * (binding) performed.  If a _val N is later encountered, a
00159  * unification is attempted between the top of the reg_array stack,
00160  * and the value of var_regs(N).
00161  */
00162 
00163 Cell *reg_array;
00164 CPtr reg_arrayptr;
00165 int  reg_array_size = DEFAULT_ARRAYSIZ;
00166 
00167 #define MAX_TRIE_REGS 500
00168 CPtr var_regs[MAX_TRIE_REGS];
00169 int  num_vars_in_var_regs = -1;
00170 
00171 BTNptr NodePtr, Last_Nod_Sav;
00172 
00173 /*
00174  * Variable delay_it decides whether we should delay an answer after we
00175  * have gone though a branch of an answer trie and reached the answer
00176  * leaf.  If delay_it == 1, then macro handle_conditional_answers() will
00177  * be called (in proceed_lpcreg).
00178  *
00179  * In return_table_code, we need to set delay_it to 1. But in
00180  * get_returns/2, we need to set it to 0.
00181  */
00182 int     delay_it;
00183 
00184 #endif /* MULTI_THREAD */
00185 
00186 /*----------------------------------------------------------------------*/
00187 
00188 #define restore_regs_and_vars(tbreg,offset)     \
00189     undo_bindings(tbreg);                       \
00190     delayreg = cp_pdreg(tbreg);                 \
00191     restore_some_wamregs(tbreg, ereg);          \
00192     restore_trie_registers(tbreg + offset) 
00193 
00194 /*----------------------------------------------------------------------*/
00195 /* Garbage collection strongly prefers tagged integers in CP stack...   */
00196 /*       PLEASE PRESERVE THIS IVNARIANT --- Kostis & Bart !             */
00197 /*----------------------------------------------------------------------*/
00198 
00199 #define save_trie_registers(tbreg) {                            \
00200   CPtr temp_arrayptr;                                           \
00201   int reg_count = 0, i;                                         \
00202                                                                 \
00203   i = num_vars_in_var_regs;                                     \
00204   while (i >= 0) {                                              \
00205     *(--tbreg) = (Cell)var_regs[i];                             \
00206     i--;                                                        \
00207   }                                                             \
00208   *(--tbreg) = makeint(num_vars_in_var_regs);                   \
00209   temp_arrayptr = reg_arrayptr;                                 \
00210   while (temp_arrayptr >= reg_array) {                          \
00211     /* INV: temp_array_ptr + reg_count == reg_arrayptr */       \
00212     *(--tbreg) = *temp_arrayptr;                                \
00213     reg_count++;                                                \
00214     temp_arrayptr--;                                            \
00215   }                                                             \
00216   (*--tbreg) = makeint(reg_count);                              \
00217 }
00218 
00219 #define restore_trie_registers(temp) {                  \
00220     int i;                                              \
00221     CPtr treg = temp;                                   \
00222                                                         \
00223     reg_arrayptr = reg_array - 1;                       \
00224     i = cell(treg);                                     \
00225     i = int_val(i);                                     \
00226     while (i > 0) {                                     \
00227       reg_arrayptr++;                                   \
00228       *reg_arrayptr = *(++treg);                        \
00229       i--;                                              \
00230     }                                                   \
00231     i = *(++treg);                                      \
00232     num_vars_in_var_regs = int_val(i);                  \
00233     for (i = 0; i <= num_vars_in_var_regs; i++) {       \
00234       var_regs[i] = (CPtr)*(++treg);                    \
00235     }                                                   \
00236 }
00237 
00238 /*----------------------------------------------------------------------*/
00239 
00240 #define unify_with_trie_numcon {                                        \
00241   XSB_Deref(*reg_arrayptr);                                             \
00242   if (isref(*reg_arrayptr)) {                                           \
00243     bind_ref((CPtr)*reg_arrayptr, opatom);                               \
00244   }                                                                     \
00245   else if (isattv(*reg_arrayptr)) {                                     \
00246     attv_dbgmsg(">>>> add_interrupt in unify_with_trie_numcon\n");      \
00247     add_interrupt(CTXTc cell(((CPtr)dec_addr(*reg_arrayptr) + 1)), opatom);\
00248     bind_int_tagged((CPtr)dec_addr(*reg_arrayptr), opatom);                     \
00249   }                                                                     \
00250   else {                                                                \
00251     if (*reg_arrayptr != opatom) {                                      \
00252       Fail1;                                                            \
00253       XSB_Next_Instr();                                                 \
00254     }                                                                   \
00255   }                                                                     \
00256 }
00257 
00258 #define unify_with_trie_str {                                   \
00259   Psc psc;                                                      \
00260   int i, arity;                                                 \
00261                                                                 \
00262   XSB_Deref(*reg_arrayptr);                                     \
00263   psc = (Psc) cs_val(opatom);                                   \
00264   arity = (int) get_arity(psc);                                 \
00265   will_overflow_reg_array(reg_arrayptr + arity);                \
00266   if (isref(*reg_arrayptr)) {                                   \
00267     bind_ref((CPtr) *reg_arrayptr, makecs(hreg));               \
00268     reg_arrayptr--;                                             \
00269     *(hreg++) = (Cell) psc;                                     \
00270     for (i = arity; i >= 1; i--) {                              \
00271       *(reg_arrayptr + i) = (Cell) hreg;                        \
00272       new_heap_free(hreg);                                      \
00273     }                                                           \
00274     reg_arrayptr += arity;                                      \
00275   }                                                             \
00276   else if (isattv(*reg_arrayptr)) {                             \
00277     attv_dbgmsg(">>>> add_interrupt in unify_with_trie_str\n"); \
00278     add_interrupt(CTXTc cell(((CPtr)dec_addr(*reg_arrayptr) + 1)), makecs(hreg));       \
00279     bind_copy((CPtr)dec_addr(*reg_array), makecs(hreg));                       \
00280     reg_arrayptr--;                                             \
00281     *(hreg++) = (Cell) psc;                                     \
00282     for (i = arity; i >= 1; i--) {                              \
00283       *(reg_arrayptr + i) = (Cell) hreg;                        \
00284       new_heap_free(hreg);                                      \
00285     }                                                           \
00286     reg_arrayptr += arity;                                      \
00287   }                                                             \
00288   else {                                                        \
00289     CPtr temp = (CPtr)*reg_arrayptr;                            \
00290     if ((isconstr(temp)) && (psc == get_str_psc(temp))) {       \
00291       reg_arrayptr--;                                           \
00292       temp = (CPtr)cs_val(temp);                                \
00293       for (i = arity; i >= 1; i--) {                            \
00294         *(reg_arrayptr+i) = *(temp+arity-i+1);                  \
00295       }                                                         \
00296       reg_arrayptr += arity;                                    \
00297     }                                                           \
00298     else {                                                      \
00299       Fail1;                                                    \
00300       XSB_Next_Instr();                                         \
00301     }                                                           \
00302   }                                                             \
00303 }
00304 
00305 #define unify_with_trie_list {                                          \
00306   XSB_Deref(*reg_arrayptr);                                             \
00307   if (isref(*reg_arrayptr)) {                                           \
00308     bind_ref((CPtr) *reg_arrayptr, (Cell) makelist(hreg));              \
00309     *reg_arrayptr = (Cell)(hreg+1);         /* head of list */          \
00310     will_overflow_reg_array(reg_arrayptr + 1);                          \
00311     *(++reg_arrayptr) = (Cell) hreg;        /* tail of list */          \
00312     new_heap_free(hreg);                                                \
00313     new_heap_free(hreg);                                                \
00314   }                                                                     \
00315   else if (isattv(*reg_arrayptr)) {                                     \
00316     attv_dbgmsg(">>>> add_interrupt in unify_with_trie_list\n");        \
00317     add_interrupt(CTXTc cell(((CPtr)dec_addr(*reg_arrayptr) + 1)), makelist(hreg));     \
00318     bind_copy((CPtr)dec_addr(*reg_arrayptr), makelist(hreg));       \
00319     *reg_arrayptr = (Cell)(hreg+1);         /* tail of list */          \
00320     will_overflow_reg_array(reg_arrayptr + 1);                          \
00321     *(++reg_arrayptr) = (Cell) hreg;        /* head of list */          \
00322     new_heap_free(hreg);                                                \
00323     new_heap_free(hreg);                                                \
00324   }                                                                     \
00325   else {                                                                \
00326     CPtr temp = (CPtr)*reg_arrayptr;                                    \
00327     if (islist(temp)) {                                                 \
00328       will_overflow_reg_array(reg_arrayptr + 1);                        \
00329       *reg_arrayptr++ = (Cell)(clref_val(temp)+1);                      \
00330       *reg_arrayptr = (Cell)(clref_val(temp));                          \
00331     } else {                                                            \
00332       Fail1;                                                            \
00333       XSB_Next_Instr();                                                 \
00334     }                                                                   \
00335   }                                                                     \
00336 }
00337 
00338 /*
00339  * In clp(Q,R), most (or all) of the attvs in the call are updated in the
00340  * answer.  So we have a set of *new* attvs in the answer trie.  This set
00341  * of new attvs will be copied into the answer trie when the *first* attv
00342  * in the call is copied into the answer trie (since most/all of the other
00343  * attvs are related to the first one).  The later occurrences of the
00344  * *other* attvs are encoded as `unify_with_trie_val', but we don't want
00345  * to trigger attv interrupts when we update the attvs in the call.
00346  */
00347 
00348 #define unify_with_trie_val {                                           \
00349   Cell cell2deref;                                                      \
00350   XSB_Deref(*reg_arrayptr);                                             \
00351   if (isref(*reg_arrayptr)) {                                           \
00352     cell2deref = (Cell)var_regs[(int)int_val(opatom)];                  \
00353     XSB_Deref(cell2deref);                                              \
00354     if (cell2deref != *reg_arrayptr)                                    \
00355       bind_ref((CPtr) *reg_arrayptr, cell2deref);                       \
00356   }                                                                     \
00357   else if (isattv(*reg_arrayptr)) {                                     \
00358     cell2deref = (Cell) var_regs[(int)int_val(opatom)];                 \
00359     XSB_Deref(cell2deref);                                              \
00360     if (*reg_arrayptr != cell2deref) {                                  \
00361       /* Do not trigger attv interrupt! */                              \
00362       bind_ref(clref_val(*reg_arrayptr), cell2deref);                   \
00363     }                                                                   \
00364     else {                                                              \
00365       attv_dbgmsg(">>>> keep old attr in unify_with_trie_val\n");       \
00366     }                                                                   \
00367   }                                                                     \
00368   else {                                                                \
00369     op1 = (Cell)*reg_arrayptr;                                          \
00370     op2 = (Cell) var_regs[(int)int_val(opatom)];                        \
00371     if (unify(CTXTc op1,op2) == FALSE) {                                \
00372       Fail1;                                                            \
00373       XSB_Next_Instr();                                                 \
00374     }                                                                   \
00375   }                                                                     \
00376   reg_arrayptr--;                                                       \
00377 }
00378 
00379 #define unify_with_trie_attv {                                          \
00380   XSB_Deref(*reg_arrayptr);                                             \
00381   num_vars_in_var_regs = (int)int_val(opatom) &0xffff;                  \
00382   if (isref(*reg_arrayptr)) {                                           \
00383     bind_ref((CPtr) *reg_arrayptr, makeattv(hreg));                     \
00384   }                                                                     \
00385   else if (isattv(*reg_arrayptr)) {                                     \
00386     add_interrupt(CTXTc cell(((CPtr)dec_addr(*reg_arrayptr) + 1)),makeattv(hreg));   \
00387     bind_ref((CPtr)dec_addr(*reg_arrayptr), makeattv(hreg));    \
00388   }                                                                     \
00389   else {                                                                \
00390     attv_dbgmsg(">>>> add_interrupt in unify_with_trie_attv\n");        \
00391     add_interrupt(CTXTc makeattv(hreg), *reg_arrayptr);                 \
00392   }                                                                     \
00393   var_regs[num_vars_in_var_regs] = (CPtr) makeattv(hreg);               \
00394   new_heap_free(hreg);                                                  \
00395   *reg_arrayptr = (Cell) hreg;                                          \
00396   new_heap_free(hreg);                                                  \
00397 }
00398 
00399 /*----------------------------------------------------------------------*/

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