1 /*************************************************************************
2 * *
3 * YAP Prolog %W% %G% *
4 * *
5 * Yap Prolog was developed at NCCUP - Universidade do Porto *
6 * *
7 * Copyright L.Damas, V.S.Costa and Universidade do Porto 1985-1997 *
8 * *
9 **************************************************************************
10 * *
11 * File: clause.h *
12 * Last rev: *
13 * mods: *
14 * comments: clause info *
15 * *
16 *************************************************************************/
17
18 #include "Yatom.h"
19 #include "YapHeap.h"
20
21 /* consulting files */
22
23 typedef union CONSULT_OBJ {
24 char *filename;
25 int mode;
26 Prop p;
27 UInt c;
28 } consult_obj;
29
30 /* Either we are assembling clauses or indexing code */
31
32 #define ASSEMBLING_CLAUSE 0
33 #define ASSEMBLING_INDEX 1
34 #define ASSEMBLING_EINDEX 2
35
36 #define NextDynamicClause(X) (((yamop *)X)->u.Otapl.d)
37
38 #define PredFirstClause 0
39 #define PredMiddleClause 1
40 #define PredLastClause 2
41
42 typedef struct logic_upd_index {
43 CELL ClFlags;
44 UInt ClRefCount;
45 #if defined(YAPOR) || defined(THREADS)
46 /* A lock for manipulating the clause */
47 // lockvar ClLock;
48 #endif
49 UInt ClSize;
50 struct logic_upd_index *ParentIndex;
51 struct logic_upd_index *SiblingIndex;
52 struct logic_upd_index *PrevSiblingIndex;
53 struct logic_upd_index *ChildIndex;
54 /* The instructions, at least one of the form sl */
55 PredEntry *ClPred;
56 yamop ClCode[MIN_ARRAY];
57 } LogUpdIndex;
58
59 /* The ordering of the first 3 fields should be compatible with dbrefs */
60 typedef struct logic_upd_clause {
61 Functor Id; /* allow pointers to this struct to id */
62 /* as dbref */
63 /* A set of flags describing info on the clause */
64 /* A set of flags describing info on the clause */
65 CELL ClFlags;
66 #if defined(YAPOR) || defined(THREADS)
67 /* A lock for manipulating the clause */
68 // lockvar ClLock;
69 #endif
70 UInt ClSize;
71 /* extra clause information for logical update indices and facts */
72 /* indices that may still backtrack to this clause */
73 UInt ClRefCount;
74 /* data for clauses with environments */
75 yamop *ClExt;
76 DBTerm *ClSource;
77 /* doubly linked list of clauses */
78 struct logic_upd_clause *ClPrev, *ClNext;
79 /* parent pointer */
80 PredEntry *ClPred;
81 UInt ClTimeStart, ClTimeEnd;
82 /* The instructions, at least one of the form sl */
83 yamop ClCode[MIN_ARRAY];
84 } LogUpdClause;
85
86 inline EXTERN int VALID_TIMESTAMP(UInt, struct logic_upd_clause *);
87
88 inline EXTERN int
VALID_TIMESTAMP(UInt timestamp,struct logic_upd_clause * cl)89 VALID_TIMESTAMP(UInt timestamp, struct logic_upd_clause *cl)
90 {
91 return IN_BETWEEN(cl->ClTimeStart, timestamp, cl->ClTimeEnd);
92 }
93
94 typedef struct dynamic_clause {
95 /* A set of flags describing info on the clause */
96 CELL ClFlags;
97 #if defined(YAPOR) || defined(THREADS)
98 /* A lock for manipulating the clause */
99 lockvar ClLock;
100 #endif
101 UInt ClSize;
102 UInt ClRefCount;
103 yamop *ClPrevious; /* immediate update clause */
104 /* The instructions, at least one of the form sl */
105 yamop ClCode[MIN_ARRAY];
106 } DynamicClause;
107
108 typedef struct static_index {
109 /* A set of flags describing info on the clause */
110 CELL ClFlags;
111 UInt ClSize;
112 struct static_index *SiblingIndex;
113 struct static_index *ChildIndex;
114 /* The instructions, at least one of the form sl */
115 PredEntry *ClPred;
116 yamop ClCode[MIN_ARRAY];
117 } StaticIndex;
118
119 typedef struct static_clause {
120 /* A set of flags describing info on the clause */
121 CELL ClFlags;
122 UInt ClSize;
123 union {
124 DBTerm *ClSource;
125 PredEntry *ClPred;
126 } usc;
127 struct static_clause *ClNext;
128 /* The instructions, at least one of the form sl */
129 yamop ClCode[MIN_ARRAY];
130 } StaticClause;
131
132 typedef struct static_mega_clause {
133 /* A set of flags describing info on the clause */
134 CELL ClFlags;
135 UInt ClSize;
136 PredEntry *ClPred;
137 UInt ClItemSize;
138 struct static_mega_clause *ClNext;
139 /* The instructions, at least one of the form sl */
140 yamop ClCode[MIN_ARRAY];
141 } MegaClause;
142
143 typedef union clause_obj {
144 struct logic_upd_clause luc;
145 struct logic_upd_index lui;
146 struct dynamic_clause ic;
147 struct static_clause sc;
148 struct static_mega_clause mc;
149 struct static_index si;
150 } ClauseUnion;
151
152 typedef union clause_ptr {
153 struct logic_upd_clause *luc;
154 struct logic_upd_index *lui;
155 struct dynamic_clause *ic;
156 struct static_clause *sc;
157 struct static_mega_clause *mc;
158 struct static_index *si;
159 } ClausePointer;
160
161 typedef struct dbterm_list {
162 /* a list of dbterms associated with a clause */
163 DBTerm *dbterms;
164 yamop *clause_code;
165 PredEntry *p;
166 struct dbterm_list *next_dbl;
167 } DBTermList;
168
169 #define ClauseCodeToDynamicClause(p) ((DynamicClause *)((CODEADDR)(p)-(CELL)(((DynamicClause *)NULL)->ClCode)))
170 #define ClauseCodeToStaticClause(p) ((StaticClause *)((CODEADDR)(p)-(CELL)(((StaticClause *)NULL)->ClCode)))
171 #define ClauseCodeToLogUpdClause(p) ((LogUpdClause *)((CODEADDR)(p)-(CELL)(((LogUpdClause *)NULL)->ClCode)))
172 #define ClauseCodeToMegaClause(p) ((MegaClause *)((CODEADDR)(p)-(CELL)(((MegaClause *)NULL)->ClCode)))
173 #define ClauseCodeToLogUpdIndex(p) ((LogUpdIndex *)((CODEADDR)(p)-(CELL)(((LogUpdIndex *)NULL)->ClCode)))
174 #define ClauseCodeToStaticIndex(p) ((StaticIndex *)((CODEADDR)(p)-(CELL)(((StaticIndex *)NULL)->ClCode)))
175
176 #define ClauseFlagsToDynamicClause(p) ((DynamicClause *)(p))
177 #define ClauseFlagsToLogUpdClause(p) ((LogUpdClause *)((CODEADDR)(p)-(CELL)(&(((LogUpdClause *)NULL)->ClFlags))))
178 #define ClauseFlagsToLogUpdIndex(p) ((LogUpdIndex *)((CODEADDR)(p)-(CELL)(&(((LogUpdIndex *)NULL)->ClFlags))))
179 #define ClauseFlagsToStaticClause(p) ((StaticClause *)(p))
180
181 #define DynamicFlags(X) (ClauseCodeToDynamicClause(X)->ClFlags)
182
183 #define DynamicLock(X) (ClauseCodeToDynamicClause(X)->ClLock)
184
185 #if defined(YAPOR) || defined(THREADS)
186 #define INIT_CLREF_COUNT(X) (X)->ClRefCount = 0
187 #define INC_CLREF_COUNT(X) (X)->ClRefCount++
188 #define DEC_CLREF_COUNT(X) (X)->ClRefCount--
189
190 #define CL_IN_USE(X) ((X)->ClRefCount)
191 #else
192 #define INIT_CLREF_COUNT(X)
193 #define INC_CLREF_COUNT(X)
194 #define DEC_CLREF_COUNT(X)
195 #define CL_IN_USE(X) ((X)->ClFlags & InUseMask || (X)->ClRefCount)
196 #endif
197
198 /* amasm.c */
199 wamreg STD_PROTO(Yap_emit_x,(CELL));
200 COUNT STD_PROTO(Yap_compile_cmp_flags,(PredEntry *));
201 void STD_PROTO(Yap_InitComma,(void));
202
203 /* cdmgr.c */
204 void STD_PROTO(Yap_IPred,(PredEntry *, UInt, yamop *));
205 int STD_PROTO(Yap_addclause,(Term,yamop *,int,Term,Term*));
206 void STD_PROTO(Yap_add_logupd_clause,(PredEntry *,LogUpdClause *,int));
207 void STD_PROTO(Yap_kill_iblock,(ClauseUnion *,ClauseUnion *,PredEntry *));
208 void STD_PROTO(Yap_EraseStaticClause,(StaticClause *, Term));
209 ClauseUnion *STD_PROTO(Yap_find_owner_index,(yamop *, PredEntry *));
210
211 /* dbase.c */
212 void STD_PROTO(Yap_ErCl,(DynamicClause *));
213 void STD_PROTO(Yap_ErLogUpdCl,(LogUpdClause *));
214 void STD_PROTO(Yap_ErLogUpdIndex,(LogUpdIndex *));
215 Int STD_PROTO(Yap_Recordz,(Atom, Term));
216
217 /* exec.c */
218 Term STD_PROTO(Yap_cp_as_integer,(choiceptr));
219
220 /* index.c */
221 yamop *STD_PROTO(Yap_PredIsIndexable,(PredEntry *, UInt, yamop *));
222 yamop *STD_PROTO(Yap_ExpandIndex,(PredEntry *, UInt));
223 void STD_PROTO(Yap_CleanUpIndex,(struct logic_upd_index *));
224 void STD_PROTO(Yap_CleanKids,(struct logic_upd_index *));
225 void STD_PROTO(Yap_AddClauseToIndex,(PredEntry *,yamop *,int));
226 void STD_PROTO(Yap_RemoveClauseFromIndex,(PredEntry *,yamop *));
227 LogUpdClause *STD_PROTO(Yap_NthClause,(PredEntry *,Int));
228 LogUpdClause *STD_PROTO(Yap_FollowIndexingCode,(PredEntry *,yamop *, Term *, yamop *,yamop *));
229
230 #if USE_THREADED_CODE
231
232 #define OP_HASH_SIZE 2048
233
234 static inline int
rtable_hash_op(OPCODE opc,int hash_mask)235 rtable_hash_op(OPCODE opc, int hash_mask) {
236 return((((CELL)opc) >> 3) & hash_mask);
237 }
238
239 /* given an opcode find the corresponding opnumber. This should make
240 switches on ops a much easier operation */
241 static inline op_numbers
Yap_op_from_opcode(OPCODE opc)242 Yap_op_from_opcode(OPCODE opc)
243 {
244 int j = rtable_hash_op(opc,OP_HASH_SIZE-1);
245
246 while (OP_RTABLE[j].opc != opc) {
247 if (!OP_RTABLE[j].opc)
248 return _Nstop;
249 if (j == OP_HASH_SIZE-1) {
250 j = 0;
251 } else {
252 j++;
253 }
254 }
255 return OP_RTABLE[j].opnum;
256 }
257 #else
258 static inline op_numbers
Yap_op_from_opcode(OPCODE opc)259 Yap_op_from_opcode(OPCODE opc)
260 {
261 return((op_numbers)opc);
262 }
263 #endif /* USE_THREADED_CODE */
264
265 #if defined(YAPOR) || defined(THREADS)
266 static inline int same_lu_block(yamop **, yamop *);
267
268 static inline int
same_lu_block(yamop ** paddr,yamop * p)269 same_lu_block(yamop **paddr, yamop *p)
270 {
271 yamop *np = *paddr;
272 if (np != p) {
273 OPCODE jmp_op = Yap_opcode(_jump_if_nonvar);
274
275 while (np->opc == jmp_op) {
276 np = NEXTOP(np, xll);
277 if (np == p) return TRUE;
278 }
279 return FALSE;
280 } else {
281 return TRUE;
282 }
283 }
284 #endif
285
286 static inline Term
Yap_MkStaticRefTerm(StaticClause * cp)287 Yap_MkStaticRefTerm(StaticClause *cp)
288 {
289 Term t[1];
290 t[0] = MkIntegerTerm((Int)cp);
291 return Yap_MkApplTerm(FunctorStaticClause,1,t);
292 }
293
294 static inline StaticClause *
Yap_ClauseFromTerm(Term t)295 Yap_ClauseFromTerm(Term t)
296 {
297 return (StaticClause *)IntegerOfTerm(ArgOfTerm(1,t));
298 }
299
300 static inline Term
Yap_MkMegaRefTerm(PredEntry * ap,yamop * ipc)301 Yap_MkMegaRefTerm(PredEntry *ap,yamop *ipc)
302 {
303 Term t[2];
304 t[0] = MkIntegerTerm((Int)ap);
305 t[1] = MkIntegerTerm((Int)ipc);
306 return Yap_MkApplTerm(FunctorMegaClause,2,t);
307 }
308
309 static inline yamop *
Yap_MegaClauseFromTerm(Term t)310 Yap_MegaClauseFromTerm(Term t)
311 {
312 return (yamop *)IntegerOfTerm(ArgOfTerm(2,t));
313 }
314
315 static inline PredEntry *
Yap_MegaClausePredicateFromTerm(Term t)316 Yap_MegaClausePredicateFromTerm(Term t)
317 {
318 return (PredEntry *)IntegerOfTerm(ArgOfTerm(1,t));
319 }
320
321 typedef enum {
322 FIND_PRED_FROM_ANYWHERE,
323 FIND_PRED_FROM_CP,
324 FIND_PRED_FROM_ENV
325 } find_pred_type;
326
327 Int STD_PROTO(Yap_PredForCode,(yamop *, find_pred_type, Atom *, UInt *, Term *));
328 PredEntry *STD_PROTO(Yap_PredEntryForCode,(yamop *, find_pred_type, CODEADDR *, CODEADDR *));
329 LogUpdClause *STD_PROTO(Yap_new_ludbe,(Term, PredEntry *, UInt));
330 Term STD_PROTO(Yap_LUInstance,(LogUpdClause *, UInt));
331
332 /* udi.c */
333 void STD_PROTO(Yap_udi_init,(void));
334 yamop *STD_PROTO(Yap_udi_search,(PredEntry *));
335 int STD_PROTO(Yap_new_udi_clause,(PredEntry *, yamop *, Term));
336
337 #ifdef DEBUG
338 void STD_PROTO(Yap_bug_location,(yamop *));
339 #endif
340
341 #if LOW_PROF
342 void STD_PROTO(Yap_InformOfRemoval,(CODEADDR));
343 void STD_PROTO(Yap_dump_code_area_for_profiler,(void));
344 #else
345 #define Yap_InformOfRemoval(X)
346 #endif
347