residual.c

00001 /* File:      residual.c
00002 ** Author(s): 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: residual.c,v 1.22 2005/10/03 13:26:43 tswift Exp $
00022 ** 
00023 */
00024 
00025 
00026 #include "xsb_config.h"
00027 #include "xsb_debug.h"
00028 
00029 #include <stdio.h>
00030 
00031 
00032 /* special debug includes */
00033 #include "debugs/debug_residual.h"
00034 
00035 #include "auxlry.h"
00036 #include "cell_xsb.h"
00037 #include "memory_xsb.h"
00038 #include "psc_xsb.h"
00039 #include "register.h"
00040 #include "heap_xsb.h"
00041 #include "binding.h"
00042 #include "tries.h"
00043 #include "macro_xsb.h"
00044 #include "error_xsb.h"
00045 #include "io_builtins_xsb.h"
00046 #include "debug_xsb.h"
00047 #include "flags_xsb.h"
00048 
00049 /*----------------------------------------------------------------------*/
00050 
00051 #ifdef DEBUG_DELAYVAR
00052 #define print_trie_atom(X) {\
00053  if (isstring(X)) \
00054    printf("atom(%s)",string_val(X));\
00055  else if (isconstr(X)) \
00056    printf("atom(%s/%d)",get_name((Psc)dec_addr(X)),get_arity((Psc)dec_addr(X)));\
00057  else if (isinteger(X)) \
00058    printf("atom(%d)",int_val(X));\
00059  else if (isboxedinteger(X)) \
00060    printf("atom(%d)",boxedint_val(X));\
00061  else if (islist(X))\
00062    printf("./2");\
00063  else\
00064   printf("Unk(%x)",(int)X);\
00065  }
00066 #endif
00067 
00068 /*----------------------------------------------------------------------*/
00069 
00070 #ifndef MULTI_THREAD
00071 static Cell cell_array[500];
00072 CPtr *copy_of_var_addr;
00073 int copy_of_num_heap_term_vars;
00074 #endif
00075 
00076 /*----------------------------------------------------------------------*/
00077 
00078 #define build_subgoal_args(SUBG)        \
00079         load_solution_trie(CTXTc arity, 0, &cell_array[arity-1], subg_leaf_ptr(SUBG))
00080 
00081 
00082 /*
00083  * Function build_delay_list() is called by builtin #143 GET_DELAY_LISTS
00084  * to construct on the heap the delay list pointed by `de'.  Since XSB
00085  * 1.8.1, this function is changed to handle variables in delay list.
00086  * Basically, to construct a delayed subgoal, we have to go through three 
00087  * tries one by one: the call trie, answer trie, and delay trie of the
00088  * delayed subgoal.  Delay trie contains the substitution factor of the
00089  * answer for the delayed subgoal.
00090  */
00091 
00092 void build_delay_list(CTXTdeclc CPtr delay_list, DE de)
00093 {
00094   Psc  psc;
00095   int  i, j, arity;
00096   CPtr head, tail;
00097   VariantSF subg;
00098   BTNptr ans_subst;
00099 #ifdef DEBUG_DELAYVAR
00100   BTNptr subs_factp;
00101 #endif
00102   CPtr *tmp_var_addr;
00103   CPtr oldhreg = hreg;
00104  
00105   i = 0;
00106   if (de != NULL && !isnil(de)) {
00107     
00108     tail = hreg+1;
00109     bind_list(delay_list, hreg);
00110     hreg = hreg + 3; 
00111     build_delay_list(CTXTc tail, de_next(de)); /* recursive call */
00112     head = hreg;
00113     subg = de_subgoal(de);
00114     psc = TIF_PSC(subg_tif_ptr(subg));
00115     arity = get_arity(psc);
00116     if ((ans_subst = de_ans_subst(de)) == NULL) { /* Negative DE */
00117       follow(oldhreg) = makecs(hreg);
00118       new_heap_functor(head, tnot_psc);
00119       if (arity == 0) {
00120         bind_string(head, get_name(psc));
00121         hreg += 3;
00122       } else {
00123         sreg = head+1;
00124         follow(head++) = makecs(sreg);
00125         hreg += arity+4; /* need arity(tnot)+2+arity(psc)+1 new cells */
00126         new_heap_functor(sreg, psc);
00127         for (j = 1; j <= arity; j++) {
00128           new_heap_free(sreg);
00129           cell_array[arity-j] = cell(sreg-1);
00130         }
00131         build_subgoal_args(subg);
00132       }
00133     } else {                                    /* Positive DE */
00134       if (arity == 0) {
00135         new_heap_string(oldhreg, get_name(psc));
00136       } else {
00137 #ifdef DEBUG_DELAYVAR
00138         /*
00139          * de_subs_fact(de) is the root of de's delay trie -- the saved
00140          * substitution factor of the answer to the subgoal call of
00141          * this delayed element.
00142          */
00143         subs_factp = de_subs_fact(de);
00144 #endif
00145         sreg = head;
00146         follow(oldhreg) = makecs(head);
00147         hreg += arity+1;
00148         new_heap_functor(sreg, psc);
00149         for (j = 1; j <= arity; j++) {
00150           new_heap_free(sreg);
00151           cell_array[arity-j] = cell(sreg-1);
00152         }
00153         
00154 #ifdef DEBUG_DELAYVAR
00155         xsb_dbgmsg((LOG_DEBUG,">>>> (before build_subgoal_args) num_heap_term_vars = %d",
00156                    num_heap_term_vars));
00157 #endif
00158 
00159         /*
00160          * Function build_subgoal_args() goes through the subgoal trie
00161          * and binds all the arguments of the subgoal skeleton, which
00162          * were built in the heap (like q(_,_)), to the actual call
00163          * arguments (like X and f(Y,g(Z)) in q(X, f(Y,g(Z)))).
00164          *
00165          * After build_subgoal_args, var_addr[] contains all the
00166          * variables in the subgoal call.
00167          */
00168         build_subgoal_args(subg);
00169         
00170 #ifdef DEBUG_DELAYVAR
00171         xsb_dbgmsg((LOG_DEBUG,">>>> (after build_subgoal_args) num_heap_term_vars = %d",
00172                    num_heap_term_vars));
00173 #endif
00174         
00175         for (i = 0, j = num_heap_term_vars-1; j >= 0; j--) {
00176           cell_array[i++] = (Cell)var_addr[j];
00177 #ifdef DEBUG_DELAYVAR
00178           xsb_dbgmsg((LOG_DEBUG,">>>> var_addr[%x] = %x", j, (int)var_addr[j]));
00179 #endif
00180         }
00181         
00182         /*
00183          * Function load_solution_trie() goes through the answer trie
00184          * and binds the call substitution factor.  The substitution
00185          * factor of the answer is left in var_addr[].
00186          */
00187         load_solution_trie(CTXTc i, 0, &cell_array[i-1], ans_subst);
00188         
00189 #ifdef DEBUG_DELAYVAR
00190         xsb_dbgmsg((LOG_DEBUG,">>>> (after load_solution_trie) num_heap_term_vars = %d",
00191                    num_heap_term_vars));
00192 #endif
00193         
00194         for (i = 0, j = num_heap_term_vars-1; j >= 0; j--) {
00195           cell_array[i++] = (Cell)var_addr[j];
00196 #ifdef DEBUG_DELAYVAR
00197           xsb_dbgmsg((LOG_DEBUG,">>>> var_addr[%x] = %x", j, (int)var_addr[j]));
00198 #endif
00199         }
00200         
00201         tmp_var_addr = var_addr;
00202         
00203         /*
00204          * Restore var_addr[] to copy_of_var_addr[], which contains all
00205          * the variables in the _head_ predicate after get_returns is
00206          * called (see bineg_xsb_i.h).
00207          *
00208          * The content of copy_of_var_addr[] is used in
00209          * load_delay_trie(), and might be changed by each delay
00210          * element.  But during the whole process for one paticular
00211          * delay list, copy_of_var_addr[] will be shared by all the
00212          * delay elements.
00213          *
00214          * It is not necessary to restore copy_of_num_heap_term_vars
00215          * each time before load_delay_trie() is called for a delay
00216          * element.  Each variable in the trie can find its binding in
00217          * copy_of_var_addr[] without num_heap_term_vars.
00218          */
00219         var_addr = copy_of_var_addr; /* variables left in the head */
00220         num_heap_term_vars = copy_of_num_heap_term_vars;
00221         
00222         
00223 #ifdef DEBUG_DELAYVAR
00224         xsb_dbgmsg((LOG_DEBUG,">>>> NOW copy_of_num_heap_term_vars = %d",
00225                    copy_of_num_heap_term_vars));
00226         {
00227           int i;
00228           for(i = 0; i < num_heap_term_vars; i++)
00229             xsb_dbgmsg((LOG_DEBUG,">>>> var_addr[%d] = %x",i, (int)var_addr[i]));
00230           
00231           fprintf(stddbg, "Stored Subs Fact: <");
00232           {
00233             BTNptr x = subs_factp;
00234             if (x == NULL)
00235               xsb_dbgmsg((LOG_DEBUG,">>>> subs_factp is NULL"));
00236             while(x != NULL){
00237               print_trie_atom(Atom(x));
00238               if(Sibl(x) != NULL) 
00239                 fprintf(stddbg, "!");
00240               x = Child(x);
00241               
00242             }
00243           }
00244           fprintf(stddbg, ">\n");
00245         }
00246         xsb_dbgmsg((LOG_DEBUG,">>>> num_heap_term_vars is %d before calling load_delay_trie",
00247                    num_heap_term_vars));
00248 #endif /* DEBUG_DELAYVAR */
00249         
00250 #ifndef IGNORE_DELAYVAR
00251         load_delay_trie(CTXTc i, &cell_array[i-1], de_subs_fact_leaf(de));
00252 #endif
00253         
00254 #ifdef DEBUG_DELAYVAR
00255         xsb_dbgmsg((LOG_DEBUG,">>>> num_heap_term_vars becomes %d",
00256                    num_heap_term_vars));
00257         for (i = 0; i < num_heap_term_vars; i++)
00258           xsb_dbgmsg((LOG_DEBUG,">>>> var_addr[%d] = %x",i, (int)var_addr[i]));
00259 #endif
00260         var_addr = tmp_var_addr;
00261       }
00262     }
00263     hreg++;
00264   } else {
00265     bind_nil(delay_list);
00266   }
00267 }
00268 
00269 /*---------------------- end of file residual.c ------------------------*/

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