2
** Author(s): Kostis Sagonas, Juliana Freire, Baoqiu Cui
3
** Contact: xsb-contact@cs.sunysb.edu
5
** Copyright (C) The Research Foundation of SUNY, 1986, 1993-1998
6
** Copyright (C) ECRC, Germany, 1990
8
** XSB is free software; you can redistribute it and/or modify it under the
9
** terms of the GNU Library General Public License as published by the Free
10
** Software Foundation; either version 2 of the License, or (at your option)
13
** XSB is distributed in the hope that it will be useful, but WITHOUT ANY
14
** WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
15
** FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for
18
** You should have received a copy of the GNU Library General Public License
19
** along with XSB; if not, write to the Free Software Foundation,
20
** Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
22
** $Id: slgdelay.h,v 1.24 2005/12/22 23:33:58 tswift Exp $
26
#ifndef __SLGDELAY_H__
27
#define __SLGDELAY_H__
29
/* special debug includes */
30
#include "debugs/debug_delay.h"
35
* Definitions of delay operations to be used while clause or answer
36
* resolution is performed.
39
#define delay_negatively(SUBGOAL) { \
40
Cell new_delay_cons_cell; \
42
new_delay_cons_cell = makelist(hreg); \
44
follow(hreg++) = makecs(sreg); \
45
follow(hreg++) = (delayreg == NULL) ? makenil : (Cell) delayreg; \
46
new_heap_functor(sreg, delay_psc); \
47
cell(sreg) = makeaddr(SUBGOAL); sreg++; \
48
cell(sreg) = makeaddr(NEG_DELAY); sreg++; \
49
cell(sreg) = makeaddr(NEG_DELAY); sreg++; /* NOT STRINGS */ \
51
delayreg = (CPtr) new_delay_cons_cell; \
55
* When delay_positively() is called, SUBGOAL is the subgoal frame of the
56
* delayed subgoal, ANSWER is the answer node in the trie, and MAKE_SUBSF
57
* is the pointer to the substitution factor (the ret/n functor built on
58
* the heap, or a string ret_psc[0]) of the answer of the delayed subgoal
61
* A delay element will be built on the heap according to the value in
62
* MAKE_SUBSF, and it is inserted at the head of delay list of the parent
63
* predicate (pointed by delayreg).
66
#define delay_positively(SUBGOAL, ANSWER, MAKE_SUBSF) { \
67
Cell new_delay_cons_cell; \
69
new_delay_cons_cell = makelist(hreg); \
71
follow(hreg++) = makecs(sreg); \
72
follow(hreg++) = (delayreg == NULL) ? makenil : (Cell) delayreg; \
73
new_heap_functor(sreg, delay_psc); \
74
cell(sreg++) = makeaddr(SUBGOAL); \
75
cell(sreg++) = makeaddr(ANSWER); \
76
follow(sreg++) = MAKE_SUBSF; \
78
delayreg = (CPtr) new_delay_cons_cell; \
81
/*--------------------------------------------------------------------*/
83
typedef struct delay_element *DE;
84
typedef struct delay_list *DL;
85
typedef struct pos_neg_de_list *PNDE;
87
/*--------------------------------------------------------------------*/
89
/* hangs off of answer escape node, which is main access to it, along
90
with PDES; function is vaguely analogous to subgoal frame. */
92
typedef struct AS_info {
93
PNDE pdes; /* pos DEs that refer to this answer substitution */
94
VariantSF subgoal; /* subgoal to which this answer substitution belongs */
95
DL dl_list; /* delay lists that this answer substitution has */
98
#define asi_pdes(X) (X) -> pdes
99
#define asi_subgoal(X) (X) -> subgoal
100
#define asi_dl_list(X) (X) -> dl_list
102
#define create_as_info(ANS, SUBG) \
103
asi = (ASI) mem_alloc(sizeof(struct AS_info),TABLE_SPACE); \
104
Child(ANS) = (NODEptr) asi; \
105
asi_pdes(asi) = NULL; \
106
asi_subgoal(asi) = SUBG; \
107
asi_dl_list(asi) = NULL
109
/*--------------------------------------------------------------------*/
111
struct delay_element {
112
VariantSF subgoal; /* pointer to the subgoal frame of this DE */
113
NODEptr ans_subst; /* pointer to an answer substitution leaf */
114
DE next; /* pointer to the next DE in the same DL */
115
PNDE pnde; /* pointer to the element in PDE list or NDE
116
* list, depending on what DE it is (positive or
117
* negative). Will be set in record_de_usage()
119
#ifdef DEBUG_DELAYVAR
120
NODEptr subs_fact; /* root of the delay trie for this DE */
122
NODEptr subs_fact_leaf;
125
#define de_subgoal(X) (X) -> subgoal
126
#define de_ans_subst(X) (X) -> ans_subst
127
#define de_next(X) (X) -> next
128
#define de_pnde(X) (X) -> pnde
129
#ifdef DEBUG_DELAYVAR
130
#define de_subs_fact(X) (X) -> subs_fact
132
#define de_subs_fact_leaf(X) (X) -> subs_fact_leaf
134
/*--------------------------------------------------------------------*/
138
NODEptr asl; /* answer substitution leaf */
139
DL next; /* next DL for the same AS */
142
#define dl_de_list(X) (X) -> de_list
143
#define dl_next(X) (X) -> next
144
#define dl_asl(X) (X) -> asl
146
/*--------------------------------------------------------------------*/
148
struct pos_neg_de_list {
154
#define pnde_dl(X) (X) -> dl
155
#define pnde_de(X) (X) -> de
156
#define pnde_prev(X) (X) -> prev
157
#define pnde_next(X) (X) -> next
161
* Handling of conditional answers.
164
#define UNCONDITIONAL_MARK 0x3
166
#define Delay(X) (ASI) ((word) (TN_Child(X)) & ~UNCONDITIONAL_MARK)
168
#define is_conditional_answer(ANS) \
169
(Child(ANS) && !((word) (Child(ANS)) & UNCONDITIONAL_MARK))
171
#define is_unconditional_answer(ANS) \
172
(!Child(ANS) || ((word) (Child(ANS)) & UNCONDITIONAL_MARK))
175
* Checks whether a delay element that is about to be interned was
176
* simplifiable (simplifications were already initiated for this DE).
177
* More specifically, negative delay elements were simplifiable if their
178
* subgoal failed (was completed without any answers), while positive
179
* delay elements are simplifiable if their answer substitution became
183
#define was_simplifiable(SUBG, ANS) \
184
((ANS == NULL) ? (is_completed(SUBG) && subgoal_fails(SUBG)) \
185
: (is_unconditional_answer(ANS)))
187
#define is_failing_delay_element(SUBG, ANS) \
188
((ANS == NULL) ? (is_completed(SUBG) && has_answer_code(SUBG) && \
189
subgoal_unconditionally_succeeds(SUBG)) \
190
: (IsDeletedNode(ANS)))
193
* mark_conditional_answer(ANS, SUBG, NEW_DL) will add a new delay list,
194
* NEW_DL, into the list of DLs for answer ANS, which is the answer
195
* substitution leaf in answer trie. If ANS does not have a Delay Info
196
* node, then a Delay Info node, `asi', has to be created first (that's
197
* why we call this macro definition mark_conditional_answer). `asi' has
198
* a pointer to the list of DLs for ANS.
201
#define mark_conditional_answer(ANS, SUBG, NEW_DL) \
202
if (Child(ANS) == NULL) { \
203
create_as_info(ANS, SUBG); \
208
dl_next(NEW_DL) = asi_dl_list(asi); \
209
asi_dl_list(asi) = NEW_DL; \
212
#define unmark_conditional_answer(ANS) /*-- NEEDS CHANGE --*/ \
213
Child(ANS) = (NODEptr) ((word) (Child(ANS)) | UNCONDITIONAL_MARK)
215
#define most_general_answer(ANS) IsEscapeNode(ANS)
218
* Variables used in other parts of the system.
221
extern xsbBool neg_delay;
225
* Procedures used in other parts of the system.
228
/* TLS: because of include dependencies (context -> macro_xsb ->
229
slgdelay), context.h cannot be included until the code is
230
refactored. Therefore, the CTXT-style declarations cannot yet be
233
extern xsbBool answer_is_junk(CPtr);
235
extern void abolish_wfs_space(void);
236
extern void simplify_neg_fails(VariantSF);
237
extern void do_delay_stuff(NODEptr, VariantSF, xsbBool);
240
extern void abolish_wfs_space(struct th_context *);
241
extern void simplify_neg_fails(struct th_context *, VariantSF);
242
extern void do_delay_stuff(struct th_context *, NODEptr, VariantSF, xsbBool);
244
extern unsigned long allocated_de_space(int * num_blocks);
245
extern unsigned long unused_de_space(void);
246
extern unsigned long allocated_dl_space(int * num_blocks);
247
extern unsigned long unused_dl_space(void);
249
extern void simplify_pos_unsupported(NODEptr);
251
extern void simplify_pos_unsupported(struct th_context *, NODEptr);
253
extern void release_all_dls(ASI);
256
/*---------------------- end of file slgdelay.h ------------------------*/
258
#endif /* __SLGDELAY_H__ */