bineg_xsb_i.h

00001 /* File:      bineg_xsb_i.h
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: bineg_xsb_i.h,v 1.29 2006/02/16 18:32:49 dwarren Exp $
00022 ** 
00023 */
00024 
00025 
00026 /* special debug includes */
00027 #include "debugs/debug_delay.h"
00028 
00029 /*----------------------------------------------------------------------*/
00030 /* Contains builtin predicates for SLG negation (and tfindall/3).       */
00031 /*----------------------------------------------------------------------*/
00032 
00033 case SLG_NOT: {
00034 
00035 #ifdef DEBUG_ASSERTIONS
00036   const int Arity = 1;
00037 #endif
00038   const int regSF = 1;  /* in: variant tabled subgoal frame */
00039   VariantSF sf;
00040 
00041   sf = ptoc_addr(regSF);
00042 #ifdef DEBUG_ASSERTIONS
00043   /* Need to change for MT: smVarSF can be private or shared
00044 |  if ( ! smIsValidStructRef(smVarSF,sf) )
00045 |    xsb_abort("Invalid Table Entry Handle\n\t Argument %d of %s/%d",
00046 |             regSF, BuiltinName(SLG_NOT), Arity);
00047   */
00048 #endif
00049   if ( has_no_answers(sf) &&
00050        (is_completed(sf) || neg_delay == FALSE) )
00051     return TRUE;
00052   if ( has_unconditional_answers(sf) )
00053     return FALSE;
00054   else {
00055     delay_negatively(sf);
00056     return TRUE;
00057   }
00058 }
00059 
00060 /*----------------------------------------------------------------------*/
00061 
00062 case LRD_SUCCESS: {
00063 
00064 #ifdef DEBUG_ASSERTIONS
00065   const int Arity = 2;
00066 #endif
00067   const int regProducerSF = 1;  /* in: subsumptive producer consumed from */
00068   const int regNegSubgoal = 2;  /* in: negated subgoal for error reporting */
00069   SubProdSF sf;
00070 
00071   sf = (SubProdSF)ptoc_addr(regProducerSF);
00072 #ifdef DEBUG_ASSERTIONS
00073   if ( ! smIsValidStructRef(smProdSF,sf) )
00074     xsb_abort("Invalid Table Entry Handle\n\t Argument %d of %s/%d",
00075               regProducerSF, BuiltinName(SLG_NOT), Arity);
00076 #endif
00077   if ( is_completed(sf) || neg_delay == FALSE )
00078     return TRUE;
00079   else {
00080     /*
00081      * Using a static here prevents multiple buffers from being left
00082      * dangling when executed multiple times, as no opportunity exists
00083      * to reclaim the string after use in xsb_abort().
00084      */
00085     static XSB_StrDefine(vsNegSubgoal);
00086     XSB_StrSet(&vsNegSubgoal,"");
00087     print_pterm(CTXTc ptoc_tag(CTXTc regNegSubgoal),1,&vsNegSubgoal);
00088     xsb_abort("Illegal table operation\n\t Attempted DELAY of negative "
00089               "subsumptive literal: %s", vsNegSubgoal.string);
00090   }
00091 }
00092 
00093 /*----------------------------------------------------------------------*/
00094 
00095 case IS_INCOMPLETE: {
00096 
00097 #ifdef DEBUG_ASSERTIONS
00098   const int Arity = 2;
00099 #endif
00100   const int regSubgoalFrame = 1;  /* in: rep of a tabled subgoal */
00101   const int regRootSubgoal  = 2;  /* in: PTCPreg */
00102 
00103 #ifdef SHARED_COMPL_TABLES
00104         int table_tid ;
00105         th_context *waiting_for_thread ;
00106 #endif
00107 
00108   VariantSF producerSF = ptoc_addr(regSubgoalFrame);
00109   CPtr t_ptcp = ptoc_addr(regRootSubgoal);
00110 #ifdef DEBUG_ASSERTIONS
00111   /* Need to change for MT: smVarSF can be private or shared
00112 |  if ( ! smIsValidStructRef(smVarSF,producerSF) &&
00113 |       ! smIsValidStructRef(smProdSF,producerSF) )
00114 |    xsb_abort("Invalid Table Entry Handle\n\t Argument %d of %s/%d",
00115 |             regSubgoalFrame, BuiltinName(IS_INCOMPLETE), Arity);
00116   */
00117 #endif
00118   xsb_dbgmsg((LOG_DELAY, "Is incomplete for "));
00119   dbg_print_subgoal(LOG_DELAY, stddbg, producerSF);
00120   xsb_dbgmsg((LOG_DELAY, ", (%x)\n", (int)&subg_ans_root_ptr(producerSF)));
00121 
00122 #ifdef SHARED_COMPL_TABLES
00123 /* This allows sharing of completed tables.  */
00124      pthread_mutex_lock(&completing_mut);
00125      while( !is_completed(producerSF) )
00126      {
00127         table_tid = subg_tid(producerSF) ;
00128         /* if the thread owns the table, proceed */
00129         if (table_tid == th->tid)
00130                 break ;
00131         waiting_for_thread = find_context(table_tid) ;
00132         if( would_deadlock( waiting_for_thread, th ) )
00133         {       /* code for leader */
00134                 reset_other_threads( th, waiting_for_thread, producerSF );
00135                 th->deadlock_brk_leader = TRUE ;
00136                 pthread_cond_broadcast(&completing_cond) ;
00137                 reset_leader( th ) ;
00138                 pthread_mutex_unlock(&completing_mut) ;
00139                 return TRUE ;
00140         }
00141         th->waiting_for_subgoal = producerSF ;
00142         th->waiting_for_thread = waiting_for_thread ;
00143         pthread_cond_wait(&completing_cond,&completing_mut) ;
00144         if( th->reset_thread )
00145         {       th->reset_thread = FALSE ;
00146                 pthread_mutex_unlock(&completing_mut) ;
00147                 /* restart the tabletry instruction */
00148                 return TRUE ;
00149         }
00150      }
00151      th->waiting_for_thread = NULL ;
00152      th->waiting_for_subgoal = NULL ;
00153      pthread_mutex_unlock(&completing_mut);
00154 #endif
00155 
00156   if (is_completed(producerSF)) {
00157     neg_delay = FALSE;
00158     ptcpreg = t_ptcp;  /* restore ptcpreg as the compl. suspens. would */
00159     return TRUE;        /* succeed */
00160   }
00161   else {        /* subgoal is not completed; save a completion suspension */
00162 #ifdef SLG_GC
00163     CPtr old_cptop;
00164 #endif
00165 
00166     xsb_dbgmsg((LOG_DELAY, "... Saving a completion suspension (~"));
00167     dbg_print_subgoal(LOG_DELAY, stddbg, producerSF);
00168     xsb_dbgmsg((LOG_DELAY, " in the body of "));
00169     dbg_print_subgoal(LOG_DELAY, stddbg, (VariantSF)t_ptcp);
00170     xsb_dbgmsg((LOG_DELAY,"an UNTABLED predicate"));
00171     xsb_dbgmsg((LOG_DELAY, ")\n"));
00172 
00173     check_tcpstack_overflow;
00174 
00175     adjust_level(subg_compl_stack_ptr(producerSF));
00176     save_find_locx(ereg);
00177     efreg = ebreg;
00178     if (trreg > trfreg) trfreg = trreg;
00179     if (hfreg < hreg) hfreg = hreg;
00180     if (bfreg > breg) bfreg = breg;
00181 
00182 #ifdef SLG_GC
00183     old_cptop = bfreg;
00184 #endif
00185     save_compl_susp_frame(bfreg, ereg, (CPtr)producerSF, t_ptcp, cpreg);
00186 #ifdef SLG_GC
00187     csf_prevtop(bfreg) = old_cptop;
00188 #endif
00189     subg_compl_susp_ptr(producerSF) = bfreg;
00190     return FALSE;
00191   }
00192 }
00193 
00194 /*----------------------------------------------------------------------*/
00195 
00196     case GET_PTCP:
00197       ctop_int(CTXTc 1, (Integer)ptcpreg);
00198       break;
00199 
00200 /*----------------------------------------------------------------------*/
00201 
00202     case GET_DELAY_LISTS: {
00203       /*
00204        * When GET_DELAY_LISTS is called, we can assume that the
00205        * corresponding tabled subgoal call has been completed and so trie
00206        * code will be used to return the answer (see
00207        * trie_get_returns()).  After the execution of trie code,
00208        * var_regs[] contains the substitution factor of the _answer_ to
00209        * the call.
00210        */
00211       DL dl;
00212       DE de;
00213       BTNptr as_leaf;
00214       Cell delay_lists;
00215       CPtr dls_head, dls_tail = NULL;
00216 
00217 #ifdef DEBUG_DELAYVAR
00218       xsb_mesg(">>>> (at the beginning of GET_DELAY_LISTS");
00219       xsb_mesg(">>>> global_num_vars = %d)",global_num_vars);
00220         
00221       {
00222         int i;
00223         for (i = 0; i <= global_num_vars; i++) {
00224           Cell x;
00225           fprintf(stddbg, ">>>> var_regs[%d] =", i);
00226           x = (Cell)var_regs[i];
00227           XSB_Deref(x);
00228           printterm(stddbg, x, 25);
00229           fprintf(stddbg, "\n");
00230         }
00231       }
00232 #endif /* DEBUG_DELAYVAR */
00233 
00234       as_leaf = (NODEptr) ptoc_int(CTXTc 1);
00235       delay_lists = ptoc_tag(CTXTc 2);
00236       if (is_conditional_answer(as_leaf)) {
00237         int copy_of_var_addr_arraysz;
00238         bind_list((CPtr)delay_lists, hreg);
00239         { /*
00240            * Make copy of var_regs & global_num_vars (after get_returns,
00241            * which calls trie_get_returns).  (global_num_vars +
00242            * 1) is the number of variables left in the answer
00243            * (substitution factor of the answer)
00244            *
00245            * So, copy_of_var_addr[] is the substitution factor of the
00246            * answer for the head predicate.
00247            */
00248           int i;
00249           if (var_addr_arraysz < global_num_vars+1) 
00250             trie_expand_array(CPtr,var_addr,var_addr_arraysz,global_num_vars+1,"var_addr");
00251           copy_of_var_addr_arraysz = var_addr_arraysz;
00252           copy_of_var_addr = (CPtr *)mem_calloc(copy_of_var_addr_arraysz, sizeof(CPtr),OTHER_SPACE);
00253           if(copy_of_var_addr == NULL){
00254             xsb_exit("No enough memory to calloc copy_of_var_addr!\nBye");
00255           }
00256           for( i = 0; i <= global_num_vars; i++)
00257             copy_of_var_addr[i] = var_regs[i];
00258           
00259           copy_of_num_heap_term_vars = global_num_vars + 1;
00260         }
00261 
00262         for (dl = asi_dl_list((ASI) Delay(as_leaf)); dl != NULL; ) {
00263           dls_head = hreg;
00264           dls_tail = hreg+1;
00265           new_heap_free(hreg);
00266           new_heap_free(hreg);
00267           de = dl_de_list(dl);
00268 
00269           xsb_dbgmsg((LOG_DELAY, "orig_delayed_term("));
00270           dbg_print_subgoal(LOG_DELAY, stddbg, de_subgoal(de)); 
00271           xsb_dbgmsg((LOG_DELAY, ").\n"));
00272           /*
00273            * This answer may have more than one delay list.  We have to
00274            * restore copy_of_num_heap_term_vars for each of them.  But,
00275            * among delay elements of each delay list, it is not necessary
00276            * to restore this value.
00277            *
00278            * Note that global_num_vars is always set back to
00279            * copy_of_num_heap_term_vars at the end of build_delay_list().
00280            */
00281           copy_of_num_heap_term_vars = global_num_vars + 1;
00282           build_delay_list(CTXTc dls_head, de);
00283           if ((dl = dl_next(dl)) != NULL) {
00284             bind_list(dls_tail, hreg);
00285           }
00286         }
00287         bind_nil(dls_tail);
00288         mem_dealloc(copy_of_var_addr,copy_of_var_addr_arraysz*sizeof(CPtr),OTHER_SPACE);
00289       } else {
00290         bind_nil((CPtr)delay_lists);
00291       }
00292       break;
00293     }
00294 
00295 /*----------------------------------------------------------------------*/
00296 

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