slgdelay.h

00001 /* File:      slgdelay.h
00002 ** Author(s): Kostis Sagonas, Juliana Freire, Baoqiu Cui
00003 ** Contact:   xsb-contact@cs.sunysb.edu
00004 ** 
00005 ** Copyright (C) The Research Foundation of SUNY, 1986, 1993-1998
00006 ** Copyright (C) ECRC, Germany, 1990
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: slgdelay.h,v 1.24 2005/12/22 23:33:58 tswift Exp $
00023 ** 
00024 */
00025 
00026 #ifndef __SLGDELAY_H__
00027 #define __SLGDELAY_H__
00028 
00029 /* special debug includes */
00030 #include "debugs/debug_delay.h"
00031 
00032 #define NEG_DELAY       0
00033 
00034 /*
00035  * Definitions of delay operations to be used while clause or answer
00036  * resolution is performed.
00037  */
00038 
00039 #define delay_negatively(SUBGOAL) {                                     \
00040   Cell new_delay_cons_cell;                                             \
00041                                                                         \
00042   new_delay_cons_cell = makelist(hreg);                                 \
00043   sreg = hreg+2;                                                        \
00044   follow(hreg++) = makecs(sreg);                                        \
00045   follow(hreg++) = (delayreg == NULL) ? makenil : (Cell) delayreg;      \
00046   new_heap_functor(sreg, delay_psc);                                    \
00047   cell(sreg) = makeaddr(SUBGOAL); sreg++;                               \
00048   cell(sreg) = makeaddr(NEG_DELAY); sreg++;                             \
00049   cell(sreg) = makeaddr(NEG_DELAY); sreg++; /* NOT STRINGS */           \
00050   hreg = sreg;                                                          \
00051   delayreg = (CPtr) new_delay_cons_cell;                                \
00052 }
00053     
00054 /*
00055  * When delay_positively() is called, SUBGOAL is the subgoal frame of the
00056  * delayed subgoal, ANSWER is the answer node in the trie, and MAKE_SUBSF
00057  * is the pointer to the substitution factor (the ret/n functor built on
00058  * the heap, or a string ret_psc[0]) of the answer of the delayed subgoal
00059  * call.
00060  *
00061  * A delay element will be built on the heap according to the value in
00062  * MAKE_SUBSF, and it is inserted at the head of delay list of the parent
00063  * predicate (pointed by delayreg).
00064  */
00065 
00066 #define delay_positively(SUBGOAL, ANSWER, MAKE_SUBSF) {                 \
00067   Cell new_delay_cons_cell;                                             \
00068                                                                         \
00069   new_delay_cons_cell = makelist(hreg);                                 \
00070   sreg = hreg + 2;                                                      \
00071   follow(hreg++) = makecs(sreg);                                        \
00072   follow(hreg++) = (delayreg == NULL) ? makenil : (Cell) delayreg;      \
00073   new_heap_functor(sreg, delay_psc);                                    \
00074   cell(sreg++) = makeaddr(SUBGOAL);                                     \
00075   cell(sreg++) = makeaddr(ANSWER);                                      \
00076   follow(sreg++) = MAKE_SUBSF;                                          \
00077   hreg = sreg;                                                          \
00078   delayreg = (CPtr) new_delay_cons_cell;                                \
00079 }
00080 
00081 /*--------------------------------------------------------------------*/
00082 
00083 typedef struct delay_element    *DE;
00084 typedef struct delay_list       *DL;
00085 typedef struct pos_neg_de_list  *PNDE;
00086 
00087 /*--------------------------------------------------------------------*/
00088 
00089 /* hangs off of answer escape node, which is main access to it, along
00090    with PDES; function is vaguely analogous to subgoal frame. */
00091 
00092 typedef struct AS_info {
00093   PNDE    pdes;         /* pos DEs that refer to this answer substitution */
00094   VariantSF subgoal;    /* subgoal to which this answer substitution belongs */
00095   DL      dl_list;      /* delay lists that this answer substitution has */
00096 } *ASI;
00097 
00098 #define asi_pdes(X)     (X) -> pdes
00099 #define asi_subgoal(X)  (X) -> subgoal
00100 #define asi_dl_list(X)  (X) -> dl_list
00101 
00102 #define create_as_info(ANS, SUBG)               \
00103     asi = (ASI) mem_alloc(sizeof(struct AS_info),TABLE_SPACE);  \
00104     Child(ANS) = (NODEptr) asi;                 \
00105     asi_pdes(asi) = NULL;                       \
00106     asi_subgoal(asi) = SUBG;                    \
00107     asi_dl_list(asi) = NULL
00108 
00109 /*--------------------------------------------------------------------*/
00110 
00111 struct delay_element {
00112   VariantSF subgoal;    /* pointer to the subgoal frame of this DE */
00113   NODEptr ans_subst;    /* pointer to an answer substitution leaf */
00114   DE      next;         /* pointer to the next DE in the same DL */
00115   PNDE    pnde;         /* pointer to the element in PDE list or NDE
00116                          * list, depending on what DE it is (positive or
00117                          * negative).  Will be set in record_de_usage()
00118                          */
00119 #ifdef DEBUG_DELAYVAR
00120   NODEptr subs_fact;    /* root of the delay trie for this DE */
00121 #endif
00122   NODEptr subs_fact_leaf;
00123 } ;
00124 
00125 #define de_subgoal(X)    (X) -> subgoal
00126 #define de_ans_subst(X)  (X) -> ans_subst
00127 #define de_next(X)       (X) -> next
00128 #define de_pnde(X)       (X) -> pnde
00129 #ifdef DEBUG_DELAYVAR
00130 #define de_subs_fact(X)      (X) -> subs_fact
00131 #endif
00132 #define de_subs_fact_leaf(X) (X) -> subs_fact_leaf
00133 
00134 /*--------------------------------------------------------------------*/
00135 
00136 struct delay_list {
00137   DE      de_list;      
00138   NODEptr asl;          /* answer substitution leaf */
00139   DL      next;         /* next DL for the same AS */
00140 } ;
00141 
00142 #define dl_de_list(X)   (X) -> de_list
00143 #define dl_next(X)      (X) -> next
00144 #define dl_asl(X)       (X) -> asl
00145 
00146 /*--------------------------------------------------------------------*/
00147 
00148 struct pos_neg_de_list {
00149   DL    dl;
00150   DE    de;
00151   PNDE  prev, next;
00152 } ;
00153 
00154 #define pnde_dl(X)      (X) -> dl
00155 #define pnde_de(X)      (X) -> de
00156 #define pnde_prev(X)    (X) -> prev
00157 #define pnde_next(X)    (X) -> next
00158 
00159 
00160 /*
00161  * Handling of conditional answers.                                   
00162  */
00163 
00164 #define UNCONDITIONAL_MARK 0x3
00165 
00166 #define Delay(X) (ASI) ((word) (TN_Child(X)) & ~UNCONDITIONAL_MARK)
00167 
00168 #define is_conditional_answer(ANS) \
00169   (Child(ANS) && !((word) (Child(ANS)) & UNCONDITIONAL_MARK))
00170 
00171 #define is_unconditional_answer(ANS) \
00172   (!Child(ANS) || ((word) (Child(ANS)) & UNCONDITIONAL_MARK))
00173 
00174 /*
00175  * Checks whether a delay element that is about to be interned was
00176  * simplifiable (simplifications were already initiated for this DE).
00177  * More specifically, negative delay elements were simplifiable if their
00178  * subgoal failed (was completed without any answers), while positive
00179  * delay elements are simplifiable if their answer substitution became
00180  * unconditional.
00181  */
00182 
00183 #define was_simplifiable(SUBG, ANS)                                     \
00184     ((ANS == NULL) ? (is_completed(SUBG) && subgoal_fails(SUBG))        \
00185                    : (is_unconditional_answer(ANS)))
00186 
00187 #define is_failing_delay_element(SUBG, ANS)                             \
00188     ((ANS == NULL) ? (is_completed(SUBG) && has_answer_code(SUBG) &&    \
00189                       subgoal_unconditionally_succeeds(SUBG))           \
00190                    : (IsDeletedNode(ANS)))
00191 
00192 /*
00193  * mark_conditional_answer(ANS, SUBG, NEW_DL) will add a new delay list,
00194  * NEW_DL, into the list of DLs for answer ANS, which is the answer
00195  * substitution leaf in answer trie.  If ANS does not have a Delay Info
00196  * node, then a Delay Info node, `asi', has to be created first (that's
00197  * why we call this macro definition mark_conditional_answer).  `asi' has
00198  * a pointer to the list of DLs for ANS.
00199  */
00200 
00201 #define mark_conditional_answer(ANS, SUBG, NEW_DL)                      \
00202   if (Child(ANS) == NULL) {                                             \
00203     create_as_info(ANS, SUBG);                                          \
00204   }                                                                     \
00205   else {                                                                \
00206     asi = Delay(ANS);                                                   \
00207   }                                                                     \
00208   dl_next(NEW_DL) = asi_dl_list(asi);                                   \
00209   asi_dl_list(asi) = NEW_DL;                                            \
00210   dl_asl(NEW_DL) = ANS
00211 
00212 #define unmark_conditional_answer(ANS) /*-- NEEDS CHANGE --*/           \
00213     Child(ANS) = (NODEptr) ((word) (Child(ANS)) | UNCONDITIONAL_MARK)
00214 
00215 #define most_general_answer(ANS) IsEscapeNode(ANS)
00216 
00217 /*
00218  * Variables used in other parts of the system.
00219  */
00220 
00221 extern xsbBool neg_delay;
00222 
00223 
00224 /*
00225  * Procedures used in other parts of the system.
00226  */
00227 
00228 /* TLS: because of include dependencies (context -> macro_xsb ->
00229    slgdelay), context.h cannot be included until the code is
00230    refactored.  Therefore, the CTXT-style declarations cannot yet be
00231    used. */
00232 
00233 extern xsbBool answer_is_junk(CPtr);
00234 #ifndef MULTI_THREAD
00235 extern void abolish_wfs_space(void);
00236 extern void simplify_neg_fails(VariantSF);
00237 extern void do_delay_stuff(NODEptr, VariantSF, xsbBool);
00238 #else
00239 struct th_context;
00240 extern void abolish_wfs_space(struct th_context *);
00241 extern void simplify_neg_fails(struct th_context *, VariantSF);
00242 extern void do_delay_stuff(struct th_context *, NODEptr, VariantSF, xsbBool);
00243 #endif
00244 extern unsigned long allocated_de_space(int * num_blocks);
00245 extern unsigned long unused_de_space(void);
00246 extern unsigned long allocated_dl_space(int * num_blocks);
00247 extern unsigned long unused_dl_space(void);
00248 #ifndef MULTI_THREAD
00249 extern void simplify_pos_unsupported(NODEptr);
00250 #else
00251 extern void simplify_pos_unsupported(struct th_context *, NODEptr);
00252 #endif
00253 extern void release_all_dls(ASI);
00254 
00255 
00256 /*---------------------- end of file slgdelay.h ------------------------*/
00257 
00258 #endif /* __SLGDELAY_H__ */

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