wfs_xsb_i.h

00001 /* File:      wfs_xsb_i.h
00002 ** Author(s): Kostis Sagonas
00003 ** Documentation added by TLS 02/02
00004 ** Contact:   xsb-contact@cs.sunysb.edu
00005 ** 
00006 ** Copyright (C) The Research Foundation of SUNY, 1986, 1993-1998
00007 ** 
00008 ** XSB is free software; you can redistribute it and/or modify it under the
00009 ** terms of the GNU Library General Public License as published by the Free
00010 ** Software Foundation; either version 2 of the License, or (at your option)
00011 ** any later version.
00012 ** 
00013 ** XSB is distributed in the hope that it will be useful, but WITHOUT ANY
00014 ** WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
00015 ** FOR A PARTICULAR PURPOSE.  See the GNU Library General Public License for
00016 ** more details.
00017 ** 
00018 ** You should have received a copy of the GNU Library General Public License
00019 ** along with XSB; if not, write to the Free Software Foundation,
00020 ** Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
00021 **
00022 ** $Id: wfs_xsb_i.h,v 1.15 2005/11/16 17:32:06 dwarren Exp $
00023 ** 
00024 */
00025 
00026 
00027 /* special debug includes */
00028 #include "debugs/debug_delay.h"
00029 
00030 /*----------------------------------------------------------------------*/
00031 
00032 #define unvisit(leader) \
00033     for (csf = leader; csf >= (ComplStackFrame)openreg; csf--) \
00034       compl_visited(csf) = FALSE
00035 
00036 /*----------------------------------------------------------------------*/
00037 
00038 #define edge_alloc_chunk_size   (1024 * sizeof(struct ascc_edge))
00039 
00040 static char *edge_space_chunk_ptr = NULL;
00041 
00042 static EPtr free_edges = NULL, free_edge_space = NULL, top_edge_space = NULL;
00043 
00044 void abolish_edge_space(void)
00045 {
00046     char *t;
00047  
00048     while (edge_space_chunk_ptr) {
00049       t = *(char **)edge_space_chunk_ptr;
00050       mem_dealloc(edge_space_chunk_ptr,edge_alloc_chunk_size+sizeof(Cell),TABLE_SPACE);
00051       edge_space_chunk_ptr = t;
00052     }
00053     free_edges = free_edge_space = top_edge_space = NULL;
00054 }
00055 
00056 static EPtr alloc_more_edge_space(void)
00057 {
00058     char *t;
00059 
00060     if ((t = (char *)mem_alloc(edge_alloc_chunk_size+sizeof(Cell),TABLE_SPACE)) == NULL)
00061       xsb_abort("No space to allocate more edges for SCC detection");
00062     *(char **)t = edge_space_chunk_ptr;
00063     edge_space_chunk_ptr = t;
00064     free_edge_space = (EPtr)(t+sizeof(Cell));
00065     top_edge_space = (EPtr)(t+edge_alloc_chunk_size+sizeof(Cell));
00066     return free_edge_space++;
00067 }
00068 
00069 #define Free_Edge(theEdge) \
00070     next_edge(theEdge) = free_edges; \
00071     free_edges = theEdge
00072 
00073 #define New_Edge(theEdge,FromEptr,ToNode) \
00074     if (free_edges) {\
00075       theEdge = free_edges; \
00076       free_edges = next_edge(free_edges); \
00077     } else { \
00078       if (free_edge_space < top_edge_space) { \
00079         theEdge = free_edge_space++; \
00080       } else { \
00081         theEdge = alloc_more_edge_space(); \
00082       } \
00083     } \
00084     edge_to_node(theEdge) = (ComplStackFrame) ToNode; \
00085     next_edge(theEdge) = FromEptr; \
00086     FromEptr = theEdge
00087 
00088 /* Add a dependency graph edge, and its transpose as long as the
00089    parent node csf2 (DG "from" node / DGT "to" node) is not completed
00090    and lies within the ASCC */
00091 
00092 #define add_ascc_edges(subgoal,cs_frame,leader_cs_frame)        \
00093     csf2 = (ComplStackFrame)subg_compl_stack_ptr(subgoal);      \
00094     if (leader_cs_frame >= csf2  && !is_completed(subgoal)) {   \
00095       New_Edge(eptr, compl_DGT_edges(cs_frame), csf2);          \
00096       New_Edge(eptr, compl_DG_edges(csf2), cs_frame);           \
00097     }
00098 
00099 static void reclaim_edge_space(ComplStackFrame csf_ptr)
00100 {
00101     EPtr e, eptr;
00102 
00103     e = compl_DG_edges(csf_ptr);
00104     while (e != NULL) {
00105       eptr = e;
00106       e = next_edge(e);
00107       Free_Edge(eptr);
00108     }
00109     compl_DG_edges(csf_ptr) = NULL;
00110     e = compl_DGT_edges(csf_ptr);
00111     while (e != NULL) {
00112       eptr = e;
00113       e = next_edge(e);
00114       Free_Edge(eptr);
00115     }
00116     compl_DGT_edges(csf_ptr) = NULL;
00117 }
00118 
00119 /*----------------------------------------------------------------------*/
00120 /* These macros abstract the fact that SLG-WAM and CHAT construct the   */
00121 /* subgoal dependency graph by looking at different data structures.    */
00122 /*----------------------------------------------------------------------*/
00123 
00124 #define first_consumer(SUBG,CSF) (subg_asf_list_ptr(SUBG))
00125 #define ptcp_of_gen(SUBG,CSF)    ((VariantSF)(tcp_ptcp(subg_cp_ptr(SUBG))))
00126 #define ptcp_of_cons(CONS_CP)    ((VariantSF)(nlcp_ptcp(CONS_CP)))
00127 #define ptcp_of_csusp(CSUSP_CP)  ((VariantSF)(csf_ptcp(CSUSP_CP)))
00128 
00129 /*----------------------------------------------------------------------*/
00130 
00131 static inline void construct_dep_graph(CTXTdeclc ComplStackFrame leader_compl_frame)
00132 {
00133     EPtr eptr;
00134     CPtr asf, nsf;
00135     VariantSF p, source_subg;
00136     ComplStackFrame csf1, csf2;
00137 
00138     csf1 = leader_compl_frame;
00139     while (csf1 >= (ComplStackFrame)openreg) {
00140       source_subg = compl_subgoal_ptr(csf1);
00141       if (!is_completed(source_subg)) {
00142         /*--- find the edge of the DepGraph due to the generator node ---*/
00143         if ((p = ptcp_of_gen(source_subg,csf1)) != NULL) {
00144           add_ascc_edges(p, csf1, leader_compl_frame);
00145         }
00146         /*--- find the edges of the DepGraph due to the consumers ---*/
00147         for (asf = first_consumer(source_subg,csf1);
00148              asf != NULL; asf = nlcp_prevlookup(asf)) {
00149           if ((p = ptcp_of_cons(asf)) != NULL) {
00150             add_ascc_edges(p, csf1, leader_compl_frame);
00151           }
00152         }
00153         /*--- find the edges of the DepGraph due to the suspended nodes ---*/
00154         for (nsf = subg_compl_susp_ptr(source_subg);
00155              nsf != NULL; nsf = csf_prevcsf(nsf)) {
00156           if ((p = ptcp_of_csusp(nsf)) != NULL) {
00157             add_ascc_edges(p, csf1, leader_compl_frame);
00158           }
00159         }
00160       }
00161       csf1 = (ComplStackFrame)next_compl_frame(csf1);
00162     }
00163 #ifdef VERBOSE_COMPLETION
00164     xsb_dbgmsg((LOG_DEBUG,"! Constructed the edges of the DepGraph"));
00165 #endif
00166 }
00167 
00168 /*----------------------------------------------------------------------*/
00169 /* The following function handles negation for Batched Scheduling.      */
00170 /*----------------------------------------------------------------------*/
00171 
00172 static void batched_compute_wfs(CTXTdeclc CPtr leader_compl_frame, 
00173                                 CPtr leader_breg, 
00174                                 VariantSF leader_subg)
00175 {  
00176   CPtr ComplStkFrame; /* CopyFrame */
00177   xsbBool sccs_needed;
00178   VariantSF curr_subg;
00179   CPtr cont_breg = leader_breg;
00180 
00181 /*----------------------------------------------------------------------*/
00182   /* Perform a check whether exact completion is needed (sccs_needed).
00183      For subgoals that are already marked as (early) completed,
00184      preclude their completion suspension frames from ever being
00185      secheduled and the memory occupied by their chat areas is
00186      properly reclaimed. 
00187   */
00188 
00189   sccs_needed = FALSE;
00190   ComplStkFrame = leader_compl_frame;
00191   while (ComplStkFrame >= openreg) {
00192     curr_subg = compl_subgoal_ptr(ComplStkFrame);
00193     if (is_completed(curr_subg)) {
00194       subg_compl_susp_ptr(curr_subg) = NULL;
00195     } else {
00196       if (subg_compl_susp_ptr(curr_subg) != NULL) sccs_needed = TRUE;
00197     }
00198     ComplStkFrame = next_compl_frame(ComplStkFrame);
00199   }
00200 
00201   /**********************************************************************/
00202   /* NOTE: many of the following assume that leader_compl_frame
00203    * remains unchanged */
00204 /*----------------------------------------------------------------------*/
00205   /* The general algorithm for exact SCC check is defined in the 1998
00206      SLGWAM TOPLAS paper. Below we will 
00207 
00208      1) Construct a dependency graph (DG) + its transpose (DGT) via
00209      construct_dep_graph((ComplStackFrame)leader_compl_frame).  Nodes
00210      of this graph are formed via cells in compretion stack frames
00211      compl_DG_edges, and compl_DGT_edges.
00212      
00213      2) Traverse that dependency graph to find an independent SCC,
00214      $SCC_1$ This is the combined purpose of DFS_DGT(), unvisit() and
00215      find_independent_scc() (see the commentary on DFS_DGT in
00216      scc_xsb.c).  At the end of this process, subgoals in the
00217      independent SCC have compl_visited marked as TRUE
00218 
00219      3) Check the independent SCC to see whether there is a negative
00220      loop --- non_lrd_stratified is TRUE if there is such a loop.
00221      This is done directly in this function, for each subgoal $S$ in
00222      the independent SCC, the completion_suspension frames if $S$ are
00223      traversed to see whether there is a ptcp (root subgoal) pointer
00224      to some subgoal $S'$ in the independet SCC.  If so,
00225      non_lrd_stratified is set to true, and the $S$ is marked as
00226      delayed.  
00227   */
00228 
00229   if (sccs_needed) {
00230     xsbBool found;
00231     CPtr nsf;
00232     CPtr CopyFrame;
00233     ComplStackFrame csf, max_finish_csf;
00234     xsbBool non_lrd_stratified;
00235 
00236 #ifdef VERBOSE_COMPLETION
00237     xsb_dbgmsg((LOG_DEBUG,"\t===> SCC detection is needed...(%d subgoals in ASCC)...",
00238                (int)((leader_compl_frame-openreg)/COMPLFRAMESIZE+1)));
00239     print_completion_stack();
00240 #endif
00241 
00242     construct_dep_graph(CTXTc (ComplStackFrame)leader_compl_frame);
00243     dbg_print_completion_stack(LOG_COMPLETION);
00244 
00245     max_finish_csf = DFS_DGT(CTXTc (ComplStackFrame)leader_compl_frame);
00246     xsb_dbgmsg((LOG_COMPLETION, 
00247                "! MAX FINISH_SUBGOAL AT COMPL STACK: %p",max_finish_csf));
00248     /* mark as not visited all subgoals in the completion stack
00249      * below leader_compl_frame */
00250     unvisit((ComplStackFrame)leader_compl_frame);
00251 
00252     /* mark as visited all subgoals in the same SCC as max_finish_csf 
00253      * by traversing the SDG */
00254     find_independent_scc(max_finish_csf);
00255     
00256     dbg_print_completion_stack(LOG_COMPLETION);
00257 
00258     /* Perform a LRD stratification check of the program-query pair     */
00259     /* and classify the completion suspensions as stratified or not.    */
00260     ComplStkFrame = leader_compl_frame;
00261     non_lrd_stratified = FALSE;
00262     
00263     while (ComplStkFrame >= openreg) {
00264       CPtr    susp_csf;
00265       VariantSF susp_subgoal;
00266 
00267       curr_subg = compl_subgoal_ptr(ComplStkFrame);
00268       if (!is_completed(curr_subg)) {
00269         if (compl_visited(ComplStkFrame) != FALSE) {
00270           curr_subg = compl_subgoal_ptr(ComplStkFrame);  
00271           for (nsf = subg_compl_susp_ptr(curr_subg);
00272                nsf != NULL; nsf = csf_prevcsf(nsf)) {
00273             if ((susp_subgoal = ptcp_of_csusp(nsf)) != NULL) {
00274               susp_csf = subg_compl_stack_ptr(susp_subgoal);      
00275               if (!is_completed(susp_subgoal) && 
00276                   susp_csf <= leader_compl_frame &&
00277                   compl_visited(susp_csf) != FALSE) {
00278                 /*--- The suspended subgoal is in the completable SCC ---*/
00279                 mark_delayed(ComplStkFrame, susp_csf, nsf);
00280                 non_lrd_stratified = TRUE;
00281                 xsb_dbgmsg((LOG_DELAY, "\t   Subgoal "));
00282                 dbg_print_subgoal(LOG_DELAY,stddbg,(VariantSF)susp_subgoal);
00283                 xsb_dbgmsg((LOG_DELAY, " depends negatively on subgoal "));
00284                 dbg_print_subgoal(LOG_DELAY, stddbg, curr_subg);
00285                 xsb_dbgmsg((LOG_DELAY, "\n"));
00286               } /*  no completed susp_subg */
00287             }
00288           } /* for each nsf */
00289         } /* not visited */
00290       } /* skip completed subgoals in the completion stack */
00291       ComplStkFrame = next_compl_frame(ComplStkFrame);
00292     } /* while */
00293   
00294 /* #define SERIOUS_DEBUGGING_NEEDED     */
00295 #ifdef SERIOUS_DEBUGGING_NEEDED
00296     print_completion_stack();
00297 #endif
00298 
00299 /*----------------------------------------------------------------------*/
00300     /* 
00301        In the case where there is no loop through negation in the
00302        independent SCC (non_lrd_stratified == FALSE, then the SLGWAM
00303        needs to find the continuation, the youngest subgoal of the
00304        ASCC that will not be completed.  
00305 
00306        If the independent SCC has a loop through negation, the
00307        continuation pointer will be the leader breg, otherwise, it
00308        will be the breg of the youngest subgoal not in the independent
00309        ASCC (I dont understand this, according to my thinking it might
00310        as well be the leader, as we will have to do SCC checks, etc
00311        again.
00312 
00313        One trick that is used is that compl_visited can now be set to
00314        DELAYED (-1), FALSE (0) or true (1).  The continuation will be
00315        set to the breg of the first subgoal whose compl_visited value
00316        is neither FALSE or delayed.  
00317 
00318        While I have not verified this, my understanding is that
00319        starting with openreg, there will be a contiguous segment of
00320        compl stack frames that are TRUE, followed by a csf that is
00321        either FALSE or DELAYED.  Apparently it should be DELAYED only
00322        if the independent SCC contains aloop through negation.
00323        Therefore, I dont see why there is a <= FALSE below --
00324        according to my theory (which could be wrong) it should ==
00325        FALSE, since non_lrd_stratified == FALSE.
00326     */
00327 
00328     if (non_lrd_stratified == FALSE) {
00329       found = FALSE;
00330       for (ComplStkFrame = openreg;
00331            !found && ComplStkFrame <= leader_compl_frame;
00332            ComplStkFrame = prev_compl_frame(ComplStkFrame)) {
00333         if (compl_visited(ComplStkFrame) <= FALSE) {
00334           cont_breg = subg_cp_ptr(compl_subgoal_ptr(ComplStkFrame));
00335           breg = cont_breg;
00336           xsb_dbgmsg((LOG_COMPLETION,
00337                      "------ Setting TBreg to %p...", cont_breg));
00338           found = TRUE;
00339         }
00340       }
00341        if (!found) {    /* case in which the ASCC contains only one SCC */
00342                         /* and all subgoals will be completed (no delay) */
00343         cont_breg = tcp_prevbreg(leader_breg);
00344       }
00345     } else {    /* the chosen SCC has a loop through negation */
00346       for (ComplStkFrame = openreg; ComplStkFrame <= leader_compl_frame;
00347            ComplStkFrame = prev_compl_frame(ComplStkFrame)) {
00348         if (compl_visited(ComplStkFrame) != FALSE)
00349           compl_visited(ComplStkFrame) = DELAYED;
00350       }
00351       cont_breg = subg_cp_ptr(compl_subgoal_ptr(leader_compl_frame));
00352       breg = cont_breg;
00353       xsb_dbgmsg((LOG_COMPLETION, "------ Setting TBreg to %p...", cont_breg));
00354     }
00355     
00356 /*----------------------------------------------------------------------*/
00357     /* 
00358        The next loop has two functions.  First, any subgoals that are
00359        completely evaluated (those that are visited but not delayed)
00360        are marked as completed.  In addition, breg will be set to
00361        point to the cP for the the youngest subgoal that has been
00362        visited (delayed or not).  The failure continuation of this CP
00363        in turn will be the continuation obtained above.  
00364 
00365        One point to make is that reclaim_incomplete_table_structs()
00366        Clears up some table structures for subsumptive tabling, and
00367        presumably the answer list for variant tabling.  It also frees
00368        consumer choice points in CHAT.  In either case, frozen local
00369        stack, heap, (and trail & cp space in the SLGWAM) will only be
00370        reclaimed upon completion of the leader.       
00371     */
00372 
00373  {
00374    for (ComplStkFrame = leader_compl_frame; ComplStkFrame >= openreg;
00375         ComplStkFrame = next_compl_frame(ComplStkFrame)) {
00376      if (compl_visited(ComplStkFrame) != FALSE) {
00377        curr_subg = compl_subgoal_ptr(ComplStkFrame);
00378        if (compl_visited(ComplStkFrame) != DELAYED) {
00379 #ifdef CONC_COMPL
00380       if( !is_completed(curr_subg) )
00381       {
00382         mark_as_completed(curr_subg);
00383         WakeDependentThreads(th, curr_subg);
00384       }
00385 #else
00386       mark_as_completed(curr_subg);
00387 #endif
00388          reclaim_incomplete_table_structs(curr_subg);
00389          if (neg_simplif_possible(curr_subg)) {
00390            simplify_neg_fails(CTXTc curr_subg);
00391          }
00392        }
00393        
00394 /*----------------------------------------------------------------------*/
00395        /* Now, its time to schedule the completion suspensions found
00396           for the youngest subgoal in the independent SCC, as found in
00397           the previous loop.  
00398 
00399           There are a couple of anomalies in this procedure, for the
00400           SLGWAM.  The first is that we have completion suspension as
00401           "single-dispatch", that is only one completion suspension is
00402           scheduled for each dependency check --- I thought that we
00403           used to dispatch completion_suspension frames for all
00404           subgoals in the independent SCC???  Second, there is a
00405           completion_suspension CP that is created.
00406           Completion_suspension CPs, as opposed to completion
00407           suspension frames, are archaic remnants of single-stack
00408           scheduling.  I believe their creation here is unnecessary.
00409           In principle, we should be able to simply set the breg to
00410           the first of the completion_suspension Frames.
00411        */
00412 
00413        if ((nsf = subg_compl_susp_ptr(curr_subg)) != NULL) {
00414          CPtr min_breg;
00415          
00416          set_min(min_breg, breg, bfreg);
00417          if (compl_visited(ComplStkFrame) != DELAYED) {
00418            save_compl_susp_cp(min_breg, cont_breg, nsf);
00419            breg = min_breg;
00420            /*-- forget these completion suspensions --*/
00421            subg_compl_susp_ptr(curr_subg) = NULL;
00422 #ifdef VERBOSE_COMPLETION
00423            xsb_dbgmsg((LOG_DEBUG,"------ Setting Breg to %p...", breg));
00424 #endif
00425          } else {       /* unsuspend only those suspensions that are delayed */
00426            CPtr dnsf = NULL, ndnsf = NULL;
00427            CPtr head_dnsf = NULL, head_ndnsf = NULL;
00428            while (nsf != NULL) {        /* partition into two lists */
00429              if (csf_neg_loop(nsf) == FALSE) {
00430                if (ndnsf == NULL) head_ndnsf = nsf; 
00431                else csf_prevcsf(ndnsf) = nsf;
00432                ndnsf = nsf;
00433                nsf = csf_prevcsf(nsf);
00434                csf_prevcsf(ndnsf) = NULL;
00435              } else {
00436                if (dnsf == NULL) head_dnsf = nsf; 
00437                else csf_prevcsf(dnsf) = nsf;
00438                dnsf = nsf;
00439                nsf = csf_prevcsf(nsf);
00440                csf_prevcsf(dnsf) = NULL;
00441              }
00442            }
00443            if (head_dnsf != NULL) {
00444              save_compl_susp_cp(min_breg, cont_breg, head_dnsf);
00445              breg = min_breg;
00446            }
00447            subg_compl_susp_ptr(curr_subg) = head_ndnsf;
00448          }
00449          cont_breg = breg; /* So that other Compl_Susp_CPs can be saved. */
00450        }
00451      }
00452    }
00453  }
00454     xsb_dbgmsg((LOG_COMPLETION, "------ Completed the chosen SCC..."));
00455 /*----------------------------------------------------------------------*/
00456     /* Finally, compact the Completion Stack (and reclaim edge 
00457        space for the dependency graphs).
00458        
00459        Might be useful to only copy the frame if CopyFrame is not
00460        == the ComplStkFrame
00461     */
00462 
00463     ComplStkFrame = CopyFrame = leader_compl_frame; 
00464     while (ComplStkFrame >= openreg) {
00465       curr_subg = compl_subgoal_ptr(ComplStkFrame);
00466       reclaim_edge_space((ComplStackFrame)ComplStkFrame);
00467       if (!is_completed(curr_subg)) {
00468         subg_compl_stack_ptr(curr_subg) = CopyFrame;
00469         /* the macro below also updates CopyFrame */
00470         compact_completion_frame(CopyFrame, ComplStkFrame, curr_subg);
00471       } else { /* this may be done 2x! */
00472         reclaim_incomplete_table_structs(curr_subg);
00473       }
00474       ComplStkFrame = next_compl_frame(ComplStkFrame);
00475     }
00476     openreg = prev_compl_frame(CopyFrame);
00477 
00478 /*----------------------------------------------------------------------*/
00479 
00480     /* 
00481        This next loop chains some of the TCPs, but does not form what
00482        I would think of as a scheduling chain -- it simply removes any
00483        pointers to completed subgoals whose space has been reclaimed.
00484 
00485        The line
00486 
00487     tcp_prevbreg(subg_cp_ptr(compl_subgoal_ptr(leader_compl_frame))) = 
00488       tcp_prevbreg(subg_cp_ptr(leader_subg));
00489 
00490       looks anomalous at first, but the leader compl_frame may have
00491       been compacted away, thus its continuation must be preserved for
00492       whoever is the new leader.
00493 
00494       However, I dont believe that the "for" loop is necessary, as it
00495       doesn't matter what the tcp_breg is for choice points that are
00496       not leaders (and if they are promoted to leaders, their
00497       tcp_prevbreg value will be adjusted anyway.
00498      */
00499 
00500     tcp_prevbreg(subg_cp_ptr(compl_subgoal_ptr(leader_compl_frame))) = 
00501       tcp_prevbreg(subg_cp_ptr(leader_subg));
00502     for (ComplStkFrame = next_compl_frame(leader_compl_frame);
00503          ComplStkFrame >= openreg;
00504          ComplStkFrame = next_compl_frame(ComplStkFrame)){
00505       tcp_prevbreg(subg_cp_ptr(compl_subgoal_ptr(ComplStkFrame))) = 
00506         subg_cp_ptr(compl_subgoal_ptr(prev_compl_frame(ComplStkFrame)));
00507     }
00508   } /* if sccs_needed */
00509   else { /* sccs not needed */
00510     ComplStkFrame = leader_compl_frame;
00511     while (ComplStkFrame >= openreg) {
00512       curr_subg = compl_subgoal_ptr(ComplStkFrame);
00513 #ifdef CONC_COMPL
00514       if( !is_completed(curr_subg) )
00515       {
00516         mark_as_completed(curr_subg);
00517         WakeDependentThreads(th, curr_subg);
00518       }
00519 #else
00520       mark_as_completed(curr_subg);
00521 #endif
00522       if (neg_simplif_possible(curr_subg)) {
00523         simplify_neg_fails(CTXTc curr_subg);
00524       }
00525       ComplStkFrame = next_compl_frame(ComplStkFrame);
00526     }
00527     
00528     ComplStkFrame = leader_compl_frame;
00529     while (ComplStkFrame >= openreg) {
00530       curr_subg = compl_subgoal_ptr(ComplStkFrame);
00531       reclaim_incomplete_table_structs(curr_subg);
00532       ComplStkFrame = next_compl_frame(ComplStkFrame);
00533     }
00534     /* point openreg to first empty space */
00535     openreg = prev_compl_frame(leader_compl_frame);     
00536   }
00537   
00538   xsb_dbgmsg((LOG_COMPLETION, "------ Completed an ASCC..."));
00539 } /* compute_wfs() */
00540 
00541 /*----------------------------------------------------------------------*/

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