YAP 7.1.0
tab.insts.h
1/************************************************************************
2** **
3** The YapTab/YapOr/OPTYap systems **
4** **
5** YapTab extends the Yap Prolog engine to support sequential tabling **
6** YapOr extends the Yap Prolog engine to support or-parallelism **
7** OPTYap extends the Yap Prolog engine to support or-parallel tabling **
8** **
9** **
10** Yap Prolog was developed at University of Porto, Portugal **
11** **
12************************************************************************/
13
14/************************************************************************
15** Tabling instructions: auxiliary macros **
16************************************************************************/
17
18#ifdef LOW_LEVEL_TRACER
19#define store_low_level_trace_info(CP, TAB_ENT) \
20 CP->cp_pred_entry = TabEnt_pe(TAB_ENT)
21#else
22#define store_low_level_trace_info(CP, TAB_ENT)
23#endif /* LOW_LEVEL_TRACER */
24
25#define TABLING_ERROR_CHECKING_STACK \
26 TABLING_ERROR_CHECKING(store_node, Unsigned(H) + 1024 > Unsigned(B)); \
27 TABLING_ERROR_CHECKING(store_node, Unsigned(H_FZ) + 1024 > Unsigned(B))
28
29
30#define store_generator_node(TAB_ENT, SG_FR, ARITY, AP) \
31 { register CELL *pt_args; \
32 register choiceptr gcp; \
33 /* store args */ \
34 pt_args = XREGS + (ARITY); \
35 while (pt_args > XREGS) { \
36 register CELL aux_arg = pt_args[0]; \
37 --YENV; \
38 --pt_args; \
39 *YENV = aux_arg; \
40 } \
41 /* initialize gcp and adjust subgoal frame field */ \
42 YENV = (CELL *) (GEN_CP(YENV) - 1); \
43 gcp = NORM_CP(YENV); \
44 SgFr_gen_cp(SG_FR) = gcp; \
45 /* store generator choice point */ \
46 HBREG = HR; \
47 store_yaam_reg_cpdepth(gcp); \
48 gcp->cp_tr = TR; \
49 gcp->cp_ap = (yamop *)(AP); \
50 gcp->cp_h = HR; \
51 gcp->cp_b = B; \
52 gcp->cp_env = ENV; \
53 gcp->cp_cp = CPREG; \
54 if (IsMode_Local(TabEnt_mode(TAB_ENT))) { \
55 /* go local */ \
56 register dep_fr_ptr new_dep_fr; \
57 /* adjust freeze registers */ \
58 H_FZ = HR; \
59 B_FZ = gcp; \
60 TR_FZ = TR; \
61 /* store dependency frame */ \
62 new_dependency_frame(new_dep_fr, TRUE, LOCAL_top_or_fr, gcp, \
63 gcp, SG_FR, FALSE, LOCAL_top_dep_fr); \
64 LOCAL_top_dep_fr = new_dep_fr; \
65 GEN_CP(gcp)->cp_dep_fr = LOCAL_top_dep_fr; \
66 } else { \
67 /* go batched */ \
68 GEN_CP(gcp)->cp_dep_fr = NULL; \
69 } \
70 GEN_CP(gcp)->cp_sg_fr = SG_FR; \
71 store_low_level_trace_info(GEN_CP(gcp), TAB_ENT); \
72 set_cut((CELL *)gcp, B); \
73 B = gcp; \
74 YAPOR_SET_LOAD(B); \
75 SET_BB(B); \
76 TABLING_ERROR_CHECKING_STACK; \
77 }
78
79
80#ifdef DETERMINISTIC_TABLING
81#define store_deterministic_generator_node(TAB_ENT, SG_FR) \
82 { register choiceptr gcp; \
83 /* initialize gcp and adjust subgoal frame field */ \
84 YENV = (CELL *) (DET_GEN_CP(YENV) - 1); \
85 gcp = NORM_CP(YENV); \
86 SgFr_gen_cp(SG_FR) = gcp; \
87 /* store deterministic generator choice point */ \
88 HBREG = HR; \
89 store_yaam_reg_cpdepth(gcp); \
90 gcp->cp_ap = COMPLETION; \
91 gcp->cp_b = B; \
92 gcp->cp_tr = TR; \
93 gcp->cp_h = HR; \
94 DET_GEN_CP(gcp)->cp_sg_fr = SG_FR; \
95 store_low_level_trace_info(DET_GEN_CP(gcp), TAB_ENT); \
96 set_cut((CELL *)gcp, B); \
97 B = gcp; \
98 YAPOR_SET_LOAD(B); \
99 SET_BB(B); \
100 TABLING_ERROR_CHECKING_STACK; \
101 }
102#endif /* DETERMINISTIC_TABLING */
103
104
105#ifdef THREADS_CONSUMER_SHARING
106#define store_generator_consumer_node(TAB_ENT, SG_FR, DEP_ON_STACK,ARITY) \
107 { register CELL *pt_args; \
108 register choiceptr gccp; \
109 register dep_fr_ptr new_dep_fr; \
110 /* store args */ \
111 pt_args = XREGS + (ARITY); \
112 while (pt_args > XREGS) { \
113 register CELL aux_arg = pt_args[0]; \
114 --YENV; \
115 --pt_args; \
116 *YENV = aux_arg; \
117 } \
118 /* initialize gcp and adjust subgoal frame field */ \
119 YENV = (CELL *) (GEN_CP(YENV) - 1); \
120 gccp = NORM_CP(YENV); \
121 SgFr_gen_cp(SG_FR) = gccp; \
122 /* store generator choice point */ \
123 HBREG = HR; \
124 store_yaam_reg_cpdepth(gccp); \
125 gccp->cp_tr = TR; \
126 gccp->cp_ap = ANSWER_RESOLUTION_COMPLETION; \
127 gccp->cp_h = HR; \
128 gccp->cp_b = B; \
129 gccp->cp_env = ENV; \
130 gccp->cp_cp = CPREG; \
131 /* store dependency frame */ \
132 new_dependency_frame(new_dep_fr, DEP_ON_STACK, LOCAL_top_or_fr, \
133 gccp, gccp, SG_FR, TRUE, LOCAL_top_dep_fr); \
134 LOCAL_top_dep_fr = new_dep_fr; \
135 GEN_CP(gccp)->cp_dep_fr = LOCAL_top_dep_fr; \
136 GEN_CP(gccp)->cp_sg_fr = SG_FR; \
137 /* adjust freeze registers */ \
138 H_FZ = HR; \
139 B_FZ = gccp; \
140 TR_FZ = TR; \
141 store_low_level_trace_info(GEN_CP(gccp), TAB_ENT); \
142 set_cut((CELL *)gccp, B); \
143 B = gccp; \
144 YAPOR_SET_LOAD(B); \
145 SET_BB(B); \
146 TABLING_ERROR_CHECKING_STACK; \
147 }
148#endif /* THREADS_CONSUMER_SHARING */
149
150
151#define restore_generator_node(ARITY, AP) \
152 { register CELL *pt_args, *x_args; \
153 register choiceptr gcp = B; \
154 /* restore generator choice point */ \
155 HR = HBREG = PROTECT_FROZEN_H(gcp); \
156 restore_yaam_reg_cpdepth(gcp); \
157 CPREG = gcp->cp_cp; \
158 ENV = gcp->cp_env; \
159 YAPOR_update_alternative(PREG, (yamop *) AP) \
160 gcp->cp_ap = (yamop *) AP; \
161 /* restore args */ \
162 pt_args = (CELL *)(GEN_CP(gcp) + 1) + ARITY; \
163 x_args = XREGS + 1 + ARITY; \
164 while (x_args > XREGS + 1) { \
165 register CELL x = pt_args[-1]; \
166 --x_args; \
167 --pt_args; \
168 *x_args = x; \
169 } \
170 }
171
172
173#define pop_generator_node(ARITY) \
174 { register CELL *pt_args, *x_args; \
175 register choiceptr gcp = B; \
176 /* pop generator choice point */ \
177 HR = PROTECT_FROZEN_H(gcp); \
178 pop_yaam_reg_cpdepth(gcp); \
179 CPREG = gcp->cp_cp; \
180 ENV = gcp->cp_env; \
181 TR = gcp->cp_tr; \
182 B = gcp->cp_b; \
183 HBREG = PROTECT_FROZEN_H(B); \
184 /* pop args */ \
185 x_args = XREGS + 1 ; \
186 pt_args = (CELL *)(GEN_CP(gcp) + 1); \
187 while (x_args < XREGS + 1 + ARITY) { \
188 register CELL x = pt_args[0]; \
189 pt_args++; \
190 x_args++; \
191 x_args[-1] = x; \
192 } \
193 YENV = pt_args; \
194 SET_BB(PROTECT_FROZEN_B(B)); \
195 }
196
197
198#define store_consumer_node(TAB_ENT, SG_FR, LEADER_CP, DEP_ON_STACK) \
199 { register choiceptr ccp; \
200 register dep_fr_ptr new_dep_fr; \
201 /* initialize ccp */ \
202 YENV = (CELL *) (CONS_CP(YENV) - 1); \
203 ccp = NORM_CP(YENV); \
204 /* adjust freeze registers */ \
205 H_FZ = HR; \
206 B_FZ = ccp; \
207 TR_FZ = TR; \
208 /* store dependency frame */ \
209 new_dependency_frame(new_dep_fr, DEP_ON_STACK, LOCAL_top_or_fr, \
210 LEADER_CP, ccp, SG_FR, FALSE, LOCAL_top_dep_fr); \
211 LOCAL_top_dep_fr = new_dep_fr; \
212 /* store consumer choice point */ \
213 HBREG = HR; \
214 store_yaam_reg_cpdepth(ccp); \
215 ccp->cp_tr = TR; \
216 ccp->cp_ap = ANSWER_RESOLUTION; \
217 ccp->cp_h = HR; \
218 ccp->cp_b = B; \
219 ccp->cp_env= ENV; \
220 ccp->cp_cp = CPREG; \
221 CONS_CP(ccp)->cp_dep_fr = LOCAL_top_dep_fr; \
222 store_low_level_trace_info(CONS_CP(ccp), TAB_ENT); \
223 /* set_cut((CELL *)ccp, B); --> no effect */ \
224 B = ccp; \
225 YAPOR_SET_LOAD(B); \
226 SET_BB(B); \
227 TABLING_ERROR_CHECKING_STACK; \
228 }
229
230
231#ifdef THREADS_CONSUMER_SHARING
232#define consume_answer_and_procceed(DEP_FR, ANSWER) \
233 { CELL *subs_ptr; \
234 /* restore consumer choice point */ \
235 HR = HBREG = PROTECT_FROZEN_H(B); \
236 restore_yaam_reg_cpdepth(B); \
237 CPREG = B->cp_cp; \
238 ENV = B->cp_env; \
239 /* set_cut(YENV, B->cp_b); --> no effect */ \
240 PREG = (yamop *) CPREG; \
241 PREFETCH_OP(PREG); \
242 /* load answer from table to global stack */ \
243 if (B == DepFr_leader_cp(DEP_FR) || DepFr_external(DEP_FR)) { \
244 /* B is a generator-consumer node */ \
245 TABLING_ERROR_CHECKING(generator_consumer, IS_BATCHED_GEN_CP(B)); \
246 subs_ptr = (CELL *) (GEN_CP(B) + 1); \
247 subs_ptr += SgFr_arity(GEN_CP(B)->cp_sg_fr); \
248 } else { \
249 subs_ptr = (CELL *) (CONS_CP(B) + 1); \
250 } \
251 load_answer(ANSWER, subs_ptr); \
252 /* procceed */ \
253 YENV = ENV; \
254 GONext(); \
255 }
256#else
257#define consume_answer_and_procceed(DEP_FR, ANSWER) \
258 { CELL *subs_ptr; \
259 /* restore consumer choice point */ \
260 HR = HBREG = PROTECT_FROZEN_H(B); \
261 restore_yaam_reg_cpdepth(B); \
262 CPREG = B->cp_cp; \
263 ENV = B->cp_env; \
264 /* set_cut(YENV, B->cp_b); --> no effect */ \
265 PREG = (yamop *) CPREG; \
266 PREFETCH_OP(PREG); \
267 /* load answer from table to global stack */ \
268 if (B == DepFr_leader_cp(DEP_FR)) { \
269 /* B is a generator-consumer node */ \
270 /* never here if batched scheduling */ \
271 TABLING_ERROR_CHECKING(generator_consumer, IS_BATCHED_GEN_CP(B)); \
272 subs_ptr = (CELL *) (GEN_CP(B) + 1); \
273 subs_ptr += SgFr_arity(GEN_CP(B)->cp_sg_fr); \
274 } else { \
275 subs_ptr = (CELL *) (CONS_CP(B) + 1); \
276 } \
277 load_answer(ANSWER, subs_ptr); \
278 /* procceed */ \
279 YENV = ENV; \
280 GONext(); \
281 }
282#endif /* THREADS_CONSUMER_SHARING */
283
284
285#define store_loader_node(TAB_ENT, ANSWER) \
286 { register choiceptr lcp; \
287 /* initialize lcp */ \
288 lcp = NORM_CP(LOAD_CP(YENV) - 1); \
289 /* store loader choice point */ \
290 HBREG = HR; \
291 store_yaam_reg_cpdepth(lcp); \
292 lcp->cp_tr = TR; \
293 lcp->cp_ap = LOAD_ANSWER; \
294 lcp->cp_h = HR; \
295 lcp->cp_b = B; \
296 lcp->cp_env= ENV; \
297 lcp->cp_cp = CPREG; \
298 LOAD_CP(lcp)->cp_last_answer = ANSWER; \
299 store_low_level_trace_info(LOAD_CP(lcp), TAB_ENT); \
300 /* set_cut((CELL *)lcp, B); --> no effect */ \
301 B = lcp; \
302 YAPOR_SET_LOAD(B); \
303 SET_BB(B); \
304 TABLING_ERROR_CHECKING_STACK; \
305 }
306
307
308#define restore_loader_node(ANSWER) \
309 HR = HBREG = PROTECT_FROZEN_H(B); \
310 restore_yaam_reg_cpdepth(B); \
311 CPREG = B->cp_cp; \
312 ENV = B->cp_env; \
313 LOAD_CP(B)->cp_last_answer = ANSWER; \
314 SET_BB(PROTECT_FROZEN_B(B))
315
316
317#define pop_loader_node() \
318 HR = PROTECT_FROZEN_H(B); \
319 pop_yaam_reg_cpdepth(B); \
320 CPREG = B->cp_cp; \
321 TABLING_close_alt(B); \
322 ENV = B->cp_env; \
323 B = B->cp_b; \
324 HBREG = PROTECT_FROZEN_H(B); \
325 SET_BB(PROTECT_FROZEN_B(B))
326
327
328#ifdef DEPTH_LIMIT
329#define allocate_environment() \
330 YENV[E_CP] = (CELL) CPREG; \
331 YENV[E_E] = (CELL) ENV; \
332 YENV[E_B] = (CELL) B; \
333 YENV[E_DEPTH] = (CELL)DEPTH; \
334 ENV = YENV
335#else
336#define allocate_environment() \
337 YENV[E_CP] = (CELL) CPREG; \
338 YENV[E_E] = (CELL) ENV; \
339 YENV[E_B] = (CELL) B; \
340 ENV = YENV
341#endif /* DEPTH_LIMIT */
342
343
344
345/************************************************************************
346** clause_with_cut **
347************************************************************************/
348
349#ifdef TABLING_INNER_CUTS
350 Op(clause_with_cut, e)
351 if (LOCAL_pruning_scope) {
352 if (YOUNGER_CP(LOCAL_pruning_scope, B))
353 LOCAL_pruning_scope = B;
354 } else {
355 LOCAL_pruning_scope = B;
356 PUT_IN_PRUNING(worker_id);
357 }
358 PREG = NEXTOP(PREG, e);
359 GONext();
360 ENDOp();
361#endif /* TABLING_INNER_CUTS */
362
363
364
365/************************************************************************
366** table_load_answer **
367************************************************************************/
368
369 PBOp(table_load_answer, Otapl)
370 CELL *subs_ptr;
371 ans_node_ptr ans_node;
372
373#ifdef YAPOR
374 if (SCH_top_shared_cp(B)) {
375#if 0
376 PROBLEM: cp_last_answer field is local to the cp!
377 -> we need a shared data structure to avoid redundant computations!
378 UNLOCK_OR_FRAME(LOCAL_top_or_fr);
379#else
380 fprintf(stderr, "PROBLEM: cp_last_answer field is local to the cp!\n");
381 exit(1);
382#endif
383 }
384#endif /* YAPOR */
385 subs_ptr = (CELL *) (LOAD_CP(B) + 1);
386 ans_node = TrNode_child(LOAD_CP(B)->cp_last_answer);
387 if(TrNode_child(ans_node) != NULL) {
388 restore_loader_node(ans_node);
389 } else {
390 pop_loader_node();
391 }
392 PREG = (yamop *) CPREG;
393 PREFETCH_OP(PREG);
394 load_answer(ans_node, subs_ptr);
395 YENV = ENV;
396 GONext();
397 ENDPBOp();
398
399
400
401/************************************************************************
402** table_try_answer **
403************************************************************************/
404
405 PBOp(table_try_answer, Otapl)
406#ifdef INCOMPLETE_TABLING
407 sg_fr_ptr sg_fr;
408 ans_node_ptr ans_node;
409
410 sg_fr = GEN_CP(B)->cp_sg_fr;
411 ans_node = TrNode_child(SgFr_try_answer(sg_fr));
412 if(ans_node) {
413 CELL *subs_ptr = (CELL *) (GEN_CP(B) + 1) + SgFr_arity(sg_fr);
414
415 HR = HBREG = PROTECT_FROZEN_H(B);
416 restore_yaam_reg_cpdepth(B);
417 CPREG = B->cp_cp;
418 ENV = B->cp_env;
419 SgFr_try_answer(sg_fr) = ans_node;
420#ifdef YAPOR
421 if (SCH_top_shared_cp(B))
422 UNLOCK_OR_FRAME(LOCAL_top_or_fr);
423#endif /* YAPOR */
424 SET_BB(PROTECT_FROZEN_B(B));
425
426 PREG = (yamop *) CPREG;
427 PREFETCH_OP(PREG);
428 load_answer(ans_node, subs_ptr);
429 YENV = ENV;
430 GONext();
431 } else {
432 yamop *code_ap;
433 PREG = SgFr_code(sg_fr);
434 if (PREG->opc == Yap_opcode(_table_try)) {
435 /* table_try */
436 code_ap = NEXTOP(PREG,Otapl);
437 PREG = PREG->y_u.Otapl.d;
438 } else if (PREG->opc == Yap_opcode(_table_try_single)) {
439 /* table_try_single */
440 code_ap = COMPLETION;
441 PREG = PREG->y_u.Otapl.d;
442 } else {
443 /* table_try_me */
444 code_ap = PREG->y_u.Otapl.d;
445 PREG = NEXTOP(PREG,Otapl);
446 }
447 PREFETCH_OP(PREG);
448 restore_generator_node(SgFr_arity(sg_fr), code_ap);
449 YENV = (CELL *) PROTECT_FROZEN_B(B);
450 set_cut(YENV, B->cp_b);
451 SET_BB(NORM_CP(YENV));
452 allocate_environment();
453 GONext();
454 }
455#else
456 PREG = PREG->y_u.Otapl.d;
457 PREFETCH_OP(PREG);
458 GONext();
459#endif /* INCOMPLETE_TABLING */
460 ENDPBOp();
461
462
463
464/************************************************************************
465** table_try_single **
466************************************************************************/
467
468 PBOp(table_try_single, Otapl)
469 tab_ent_ptr tab_ent;
470 sg_fr_ptr sg_fr;
471
472 check_trail(TR);
473 tab_ent = PREG->y_u.Otapl.te;
474 YENV2MEM;
475 saveregs();
476 sg_fr = subgoal_search(PREG, YENV_ADDRESS);
477 setregs();
478 MEM2YENV;
479#if defined(THREADS_FULL_SHARING) || defined(THREADS_CONSUMER_SHARING)
480 if (SgFr_state(sg_fr) <= ready) {
481 LOCK_SG_FR(sg_fr);
482 if (SgFr_sg_ent_state(sg_fr) >= complete)
483 SgFr_state(sg_fr) = SgFr_sg_ent_state(sg_fr);
484 else
485 SgFr_active_workers(sg_fr)++;
486 UNLOCK_SG_FR(sg_fr);
487 }
488#endif /* THREADS_FULL_SHARING || THREADS_CONSUMER_SHARING */
489 LOCK_SG_FR(sg_fr);
490#ifdef THREADS_CONSUMER_SHARING
491 if (SgFr_state(sg_fr) == ready_external) {
492 init_subgoal_frame(sg_fr);
493 store_generator_consumer_node(tab_ent, sg_fr, TRUE, PREG->y_u.Otapl.s);
494 PREFETCH_OP(PREG);
495 allocate_environment();
496 check_for_deadlock(sg_fr);
497 goto answer_resolution_completion;
498 } else
499#endif /* THREADS_CONSUMER_SHARING */
500 if (SgFr_state(sg_fr) == ready) {
501 /* subgoal new */
502 init_subgoal_frame(sg_fr);
503 UNLOCK_SG_FR(sg_fr);
504#ifdef DETERMINISTIC_TABLING
505 if (IsMode_Batched(TabEnt_mode(tab_ent))) {
506 store_deterministic_generator_node(tab_ent, sg_fr);
507 } else
508#endif /* DETERMINISTIC_TABLING */
509 {
510 store_generator_node(tab_ent, sg_fr, PREG->y_u.Otapl.s, COMPLETION);
511 }
512 PREG = PREG->y_u.Otapl.d; /* should work also with PREG = NEXTOP(PREG,Otapl); */
513 PREFETCH_OP(PREG);
514 allocate_environment();
515 GONext();
516#ifdef INCOMPLETE_TABLING
517 } else if (SgFr_state(sg_fr) == incomplete) {
518 if (IsMode_CoInductive(TabEnt_flags(tab_ent))) {
519 printf("Currently Unsupported\n");
520 } else {
521 /* subgoal incomplete --> start by loading the answers already found */
522 ans_node_ptr ans_node = SgFr_first_answer(sg_fr);
523 CELL *subs_ptr = YENV;
524 init_subgoal_frame(sg_fr);
525 UNLOCK_SG_FR(sg_fr);
526 SgFr_try_answer(sg_fr) = ans_node;
527 store_generator_node(tab_ent, sg_fr, PREG->y_u.Otapl.s, TRY_ANSWER);
528 PREG = (yamop *) CPREG;
529 PREFETCH_OP(PREG);
530 load_answer(ans_node, subs_ptr);
531 YENV = ENV;
532 GONext();
533 }
534#endif /* INCOMPLETE_TABLING */
535 } else if (SgFr_state(sg_fr) == evaluating) {
536 if (IsMode_CoInductive(TabEnt_flags(tab_ent))) {
537 /* Used for coinductive tabling strategy */
538 CELL *subs_ptr;
539 subs_ptr = (CELL *) (GEN_CP(SgFr_gen_cp(sg_fr)) + 1);
540 subs_ptr += SgFr_arity(sg_fr); // Points at the Parent goal Variables
541 int i;
542 for (i = 0; i < subs_ptr[0]; i++)
543 Yap_unify(subs_ptr[i+1], YENV[i+1]);
544 /* yes answer --> procceed */
545 UNLOCK_SG_FR(sg_fr);
546 PREG = (yamop *) CPREG;
547 PREFETCH_OP(PREG);
548 YENV = ENV; // Consume the variables
549 GONext(); // Succeed the goal :-D
550 } else {
551 /* subgoal in evaluation */
552 choiceptr leader_cp;
553#ifdef YAPOR
554 int leader_dep_on_stack;
555#endif
556 find_dependency_node(sg_fr, leader_cp, leader_dep_on_stack);
557 UNLOCK_SG_FR(sg_fr);
558 find_leader_node(leader_cp, leader_dep_on_stack);
559 store_consumer_node(tab_ent, sg_fr, leader_cp, leader_dep_on_stack);
560 }
561#ifdef DEBUG_OPTYAP
562 if (GLOBAL_parallel_mode == PARALLEL_MODE_RUNNING) {
563 choiceptr aux_cp;
564 aux_cp = B;
565 while (YOUNGER_CP(aux_cp, Get_LOCAL_top_cp_on_stack()))
566 aux_cp = aux_cp->cp_b;
567 OPTYAP_ERROR_CHECKING(table_try_single, aux_cp->cp_or_fr != DepFr_top_or_fr(LOCAL_top_dep_fr));
568 aux_cp = B;
569 while (YOUNGER_CP(aux_cp, DepFr_leader_cp(LOCAL_top_dep_fr)))
570 aux_cp = aux_cp->cp_b;
571 OPTYAP_ERROR_CHECKING(table_try_single, aux_cp != DepFr_leader_cp(LOCAL_top_dep_fr));
572 }
573#endif /* DEBUG_OPTYAP */
574 goto answer_resolution;
575 } else {
576 /* subgoal completed */
577 ans_node_ptr ans_node = SgFr_first_answer(sg_fr);
578 if (ans_node == NULL) {
579 /* no answers --> fail */
580 UNLOCK_SG_FR(sg_fr);
581 goto fail;
582 } else if (ans_node == SgFr_answer_trie(sg_fr)) {
583 /* yes answer --> procceed */
584 UNLOCK_SG_FR(sg_fr);
585 PREG = (yamop *) CPREG;
586 PREFETCH_OP(PREG);
587 YENV = ENV;
588 GONext();
589 } else {
590 /* answers -> get first answer */
591#ifdef LIMIT_TABLING
592 if (SgFr_state(sg_fr) == complete || SgFr_state(sg_fr) == compiled) {
593 SgFr_state(sg_fr)++; /* complete --> complete_in_use : compiled --> compiled_in_use */
594 remove_from_global_sg_fr_list(sg_fr);
595 TRAIL_FRAME(sg_fr);
596 }
597#endif /* LIMIT_TABLING */
598#if defined(THREADS_FULL_SHARING) || defined(THREADS_CONSUMER_SHARING)
599 if (IsMode_LoadAnswers(TabEnt_mode(tab_ent)) || SgFr_active_workers(sg_fr) > 0) {
600#else
601 if (IsMode_LoadAnswers(TabEnt_mode(tab_ent))) {
602#endif /* THREADS_FULL_SHARING || THREADS_CONSUMER_SHARING */
603 /* load answers from the trie */
604 UNLOCK_SG_FR(sg_fr);
605 if(TrNode_child(ans_node) != NULL) {
606 store_loader_node(tab_ent, ans_node);
607 }
608 PREG = (yamop *) CPREG;
609 PREFETCH_OP(PREG);
610 load_answer(ans_node, YENV);
611 YENV = ENV;
612 GONext();
613 } else {
614 /* execute compiled code from the trie */
615#if defined(THREADS_FULL_SHARING) || defined(THREADS_CONSUMER_SHARING)
616 if (SgFr_sg_ent_state(sg_fr) < compiled)
617#else
618 if (SgFr_state(sg_fr) < compiled)
619#endif /* THREADS_FULL_SHARING || THREADS_CONSUMER_SHARING */
620 update_answer_trie(sg_fr);
621 UNLOCK_SG_FR(sg_fr);
622 PREG = (yamop *) TrNode_child(SgFr_answer_trie(sg_fr));
623 PREFETCH_OP(PREG);
624 *--YENV = 0; /* vars_arity */
625 *--YENV = 0; /* heap_arity */
626 GONext();
627 }
628 }
629 }
630 ENDPBOp();
631
632
633
634/************************************************************************
635** table_try_me **
636************************************************************************/
637
638 PBOp(table_try_me, Otapl)
639 tab_ent_ptr tab_ent;
640 sg_fr_ptr sg_fr;
641
642 check_trail(TR);
643 tab_ent = PREG->y_u.Otapl.te;
644 YENV2MEM;
645 saveregs();
646 sg_fr = subgoal_search(PREG, YENV_ADDRESS);
647 setregs();
648 MEM2YENV;
649#if defined(THREADS_FULL_SHARING) || defined(THREADS_CONSUMER_SHARING)
650 if (SgFr_state(sg_fr) <= ready) {
651 LOCK_SG_FR(sg_fr);
652 if (SgFr_sg_ent_state(sg_fr) >= complete)
653 SgFr_state(sg_fr) = SgFr_sg_ent_state(sg_fr);
654 else
655 SgFr_active_workers(sg_fr)++;
656 UNLOCK_SG_FR(sg_fr);
657 }
658#endif /* THREADS_FULL_SHARING || THREADS_CONSUMER_SHARING */
659 LOCK_SG_FR(sg_fr);
660#ifdef THREADS_CONSUMER_SHARING
661 if (SgFr_state(sg_fr) == ready_external) {
662 init_subgoal_frame(sg_fr);
663 UNLOCK_SG_FR(sg_fr);
664 store_generator_consumer_node(tab_ent, sg_fr, TRUE, PREG->y_u.Otapl.s);
665 PREFETCH_OP(PREG);
666 allocate_environment();
667 check_for_deadlock(sg_fr);
668 goto answer_resolution_completion;
669 } else
670#endif /* THREADS_CONSUMER_SHARING */
671 if (SgFr_state(sg_fr) == ready) {
672 /* subgoal new */
673 init_subgoal_frame(sg_fr);
674 UNLOCK_SG_FR(sg_fr);
675 store_generator_node(tab_ent, sg_fr, PREG->y_u.Otapl.s, PREG->y_u.Otapl.d);
676 PREG = NEXTOP(PREG, Otapl);
677 PREFETCH_OP(PREG);
678 allocate_environment();
679 GONext();
680#ifdef INCOMPLETE_TABLING
681 } else if (SgFr_state(sg_fr) == incomplete) {
682 if (IsMode_CoInductive(TabEnt_flags(tab_ent))) {
683 printf("Currently Unsupported\n");
684 } else {
685 /* subgoal incomplete --> start by loading the answers already found */
686 ans_node_ptr ans_node = SgFr_first_answer(sg_fr);
687 CELL *subs_ptr = YENV;
688 init_subgoal_frame(sg_fr);
689 UNLOCK_SG_FR(sg_fr);
690 SgFr_try_answer(sg_fr) = ans_node;
691 store_generator_node(tab_ent, sg_fr, PREG->y_u.Otapl.s, TRY_ANSWER);
692 PREG = (yamop *) CPREG;
693 PREFETCH_OP(PREG);
694 load_answer(ans_node, subs_ptr);
695 YENV = ENV;
696 GONext();
697 }
698#endif /* INCOMPLETE_TABLING */
699 } else if (SgFr_state(sg_fr) == evaluating) {
700 if (IsMode_CoInductive(TabEnt_flags(tab_ent))) {
701 printf("Currently Unsupported\n");
702 } else {
703 /* subgoal in evaluation */
704 choiceptr leader_cp;
705#ifdef YAPOR
706 int leader_dep_on_stack;
707#endif
708 find_dependency_node(sg_fr, leader_cp, leader_dep_on_stack);
709 UNLOCK_SG_FR(sg_fr);
710 find_leader_node(leader_cp, leader_dep_on_stack);
711 store_consumer_node(tab_ent, sg_fr, leader_cp, leader_dep_on_stack);
712 }
713#ifdef DEBUG_OPTYAP
714 if (GLOBAL_parallel_mode == PARALLEL_MODE_RUNNING) {
715 choiceptr aux_cp;
716 aux_cp = B;
717 while (YOUNGER_CP(aux_cp, Get_LOCAL_top_cp_on_stack()))
718 aux_cp = aux_cp->cp_b;
719 OPTYAP_ERROR_CHECKING(table_try_me, aux_cp->cp_or_fr != DepFr_top_or_fr(LOCAL_top_dep_fr));
720 aux_cp = B;
721 while (YOUNGER_CP(aux_cp, DepFr_leader_cp(LOCAL_top_dep_fr)))
722 aux_cp = aux_cp->cp_b;
723 OPTYAP_ERROR_CHECKING(table_try_me, aux_cp != DepFr_leader_cp(LOCAL_top_dep_fr));
724 }
725#endif /* DEBUG_OPTYAP */
726 goto answer_resolution;
727 } else {
728 /* subgoal completed */
729 ans_node_ptr ans_node = SgFr_first_answer(sg_fr);
730 if (ans_node == NULL) {
731 /* no answers --> fail */
732 UNLOCK_SG_FR(sg_fr);
733 goto fail;
734 } else if (ans_node == SgFr_answer_trie(sg_fr)) {
735 /* yes answer --> procceed */
736 UNLOCK_SG_FR(sg_fr);
737 PREG = (yamop *) CPREG;
738 PREFETCH_OP(PREG);
739 YENV = ENV;
740 GONext();
741 } else {
742 /* answers -> get first answer */
743#ifdef LIMIT_TABLING
744 if (SgFr_state(sg_fr) == complete || SgFr_state(sg_fr) == compiled) {
745 SgFr_state(sg_fr)++; /* complete --> complete_in_use : compiled --> compiled_in_use */
746 remove_from_global_sg_fr_list(sg_fr);
747 TRAIL_FRAME(sg_fr);
748 }
749#endif /* LIMIT_TABLING */
750#if defined(THREADS_FULL_SHARING) || defined(THREADS_CONSUMER_SHARING)
751 if (IsMode_LoadAnswers(TabEnt_mode(tab_ent)) || SgFr_active_workers(sg_fr) > 0) {
752#else
753 if (IsMode_LoadAnswers(TabEnt_mode(tab_ent))) {
754#endif /* THREADS_FULL_SHARING || THREADS_CONSUMER_SHARING */
755 /* load answers from the trie */
756 UNLOCK_SG_FR(sg_fr);
757 if(TrNode_child(ans_node) != NULL) {
758 store_loader_node(tab_ent, ans_node);
759 }
760 PREG = (yamop *) CPREG;
761 PREFETCH_OP(PREG);
762 load_answer(ans_node, YENV);
763 YENV = ENV;
764 GONext();
765 } else {
766 /* execute compiled code from the trie */
767#if defined(THREADS_FULL_SHARING) || defined(THREADS_CONSUMER_SHARING)
768 if (SgFr_sg_ent_state(sg_fr) < compiled)
769#else
770 if (SgFr_state(sg_fr) < compiled)
771#endif /*THREADS_FULL_SHARING || THREADS_CONSUMER_SHARING*/
772 update_answer_trie(sg_fr);
773 UNLOCK_SG_FR(sg_fr);
774 PREG = (yamop *) TrNode_child(SgFr_answer_trie(sg_fr));
775 PREFETCH_OP(PREG);
776 *--YENV = 0; /* vars_arity */
777 *--YENV = 0; /* heap_arity */
778 GONext();
779 }
780 }
781 }
782 ENDPBOp();
783
784
785
786/************************************************************************
787** table_try **
788************************************************************************/
789
790 PBOp(table_try, Otapl)
791 tab_ent_ptr tab_ent;
792 sg_fr_ptr sg_fr;
793
794 check_trail(TR);
795 tab_ent = PREG->y_u.Otapl.te;
796 YENV2MEM;
797 sg_fr = subgoal_search(PREG, YENV_ADDRESS);
798 MEM2YENV;
799#if defined(THREADS_FULL_SHARING) || defined(THREADS_CONSUMER_SHARING)
800 if (SgFr_state(sg_fr) <= ready) {
801 LOCK_SG_FR(sg_fr);
802 if (SgFr_sg_ent_state(sg_fr) >= complete)
803 SgFr_state(sg_fr) = SgFr_sg_ent_state(sg_fr);
804 else
805 SgFr_active_workers(sg_fr)++;
806 UNLOCK_SG_FR(sg_fr);
807 }
808#endif /* THREADS_FULL_SHARING || THREADS_CONSUMER_SHARING */
809 LOCK_SG_FR(sg_fr);
810#ifdef THREADS_CONSUMER_SHARING
811 if (SgFr_state(sg_fr) == ready_external) {
812 init_subgoal_frame(sg_fr);
813 UNLOCK_SG_FR(sg_fr);
814 store_generator_consumer_node(tab_ent, sg_fr, TRUE , PREG->y_u.Otapl.s);
815 PREFETCH_OP(PREG);
816 allocate_environment();
817 check_for_deadlock(sg_fr);
818 goto answer_resolution_completion;
819 } else
820#endif /* THREADS_CONSUMER_SHARING */
821 if (SgFr_state(sg_fr) == ready) {
822 /* subgoal new */
823 init_subgoal_frame(sg_fr);
824 UNLOCK_SG_FR(sg_fr);
825 store_generator_node(tab_ent, sg_fr, PREG->y_u.Otapl.s, NEXTOP(PREG,Otapl));
826 PREG = PREG->y_u.Otapl.d;
827 PREFETCH_OP(PREG);
828 allocate_environment();
829 GONext();
830#ifdef INCOMPLETE_TABLING
831 } else if (SgFr_state(sg_fr) == incomplete) {
832 if (IsMode_CoInductive(TabEnt_flags(tab_ent))) {
833 printf("Currently Unsupported\n");
834 } else {
835 /* subgoal incomplete --> start by loading the answers already found */
836 ans_node_ptr ans_node = SgFr_first_answer(sg_fr);
837 CELL *subs_ptr = YENV;
838 init_subgoal_frame(sg_fr);
839 UNLOCK_SG_FR(sg_fr);
840 SgFr_try_answer(sg_fr) = ans_node;
841 store_generator_node(tab_ent, sg_fr, PREG->y_u.Otapl.s, TRY_ANSWER);
842 PREG = (yamop *) CPREG;
843 PREFETCH_OP(PREG);
844 load_answer(ans_node, subs_ptr);
845 YENV = ENV;
846 GONext();
847 }
848#endif /* INCOMPLETE_TABLING */
849 } else if (SgFr_state(sg_fr) == evaluating) {
850 if (IsMode_CoInductive(TabEnt_flags(tab_ent))) {
851 /* Used for coinductive tabling strategy */
852 CELL *subs_ptr;
853 subs_ptr = (CELL *) (GEN_CP(SgFr_gen_cp(sg_fr)) + 1);
854 subs_ptr += SgFr_arity(sg_fr); // Points at the Parent goal Variables
855 int i;
856 for (i = 0; i < subs_ptr[0]; i++)
857 Yap_unify(subs_ptr[i+1], YENV[i+1]);
858 /* yes answer --> procceed */
859 UNLOCK_SG_FR(sg_fr);
860 PREG = (yamop *) CPREG;
861 PREFETCH_OP(PREG);
862 YENV = ENV; // Consume the variables
863 GONext(); // Succeed the goal :-D
864 } else {
865 /* subgoal in evaluation */
866 choiceptr leader_cp;
867#ifdef YAPOR
868 int leader_dep_on_stack;
869#endif
870 find_dependency_node(sg_fr, leader_cp, leader_dep_on_stack);
871 UNLOCK_SG_FR(sg_fr);
872 find_leader_node(leader_cp, leader_dep_on_stack);
873 store_consumer_node(tab_ent, sg_fr, leader_cp, leader_dep_on_stack);
874 }
875#ifdef DEBUG_OPTYAP
876 if (GLOBAL_parallel_mode == PARALLEL_MODE_RUNNING) {
877 choiceptr aux_cp;
878 aux_cp = B;
879 while (YOUNGER_CP(aux_cp, Get_LOCAL_top_cp_on_stack()))
880 aux_cp = aux_cp->cp_b;
881 OPTYAP_ERROR_CHECKING(table_try, aux_cp->cp_or_fr != DepFr_top_or_fr(LOCAL_top_dep_fr));
882 aux_cp = B;
883 while (YOUNGER_CP(aux_cp, DepFr_leader_cp(LOCAL_top_dep_fr)))
884 aux_cp = aux_cp->cp_b;
885 OPTYAP_ERROR_CHECKING(table_try, aux_cp != DepFr_leader_cp(LOCAL_top_dep_fr));
886 }
887#endif /* DEBUG_OPTYAP */
888 goto answer_resolution;
889 } else {
890 /* subgoal completed */
891 ans_node_ptr ans_node = SgFr_first_answer(sg_fr);
892 if (ans_node == NULL) {
893 /* no answers --> fail */
894 UNLOCK_SG_FR(sg_fr);
895 goto fail;
896 } else if (ans_node == SgFr_answer_trie(sg_fr)) {
897 /* yes answer --> procceed */
898 UNLOCK_SG_FR(sg_fr);
899 PREG = (yamop *) CPREG;
900 PREFETCH_OP(PREG);
901 YENV = ENV;
902 GONext();
903 } else {
904 /* answers -> get first answer */
905#ifdef LIMIT_TABLING
906 if (SgFr_state(sg_fr) == complete || SgFr_state(sg_fr) == compiled) {
907 SgFr_state(sg_fr)++; /* complete --> complete_in_use : compiled --> compiled_in_use */
908 remove_from_global_sg_fr_list(sg_fr);
909 TRAIL_FRAME(sg_fr);
910 }
911#endif /* LIMIT_TABLING */
912#if defined(THREADS_FULL_SHARING) || defined(THREADS_CONSUMER_SHARING)
913 if (IsMode_LoadAnswers(TabEnt_mode(tab_ent)) || SgFr_active_workers(sg_fr) > 0) {
914#else
915 if (IsMode_LoadAnswers(TabEnt_mode(tab_ent))) {
916#endif /* THREADS_FULL_SHARING || THREADS_CONSUMER_SHARING */
917 /* load answers from the trie */
918 UNLOCK_SG_FR(sg_fr);
919 if(TrNode_child(ans_node) != NULL) {
920 store_loader_node(tab_ent, ans_node);
921 }
922 PREG = (yamop *) CPREG;
923 PREFETCH_OP(PREG);
924 load_answer(ans_node, YENV);
925 YENV = ENV;
926 GONext();
927 } else {
928 /* execute compiled code from the trie */
929#if defined(THREADS_FULL_SHARING) || defined(THREADS_CONSUMER_SHARING)
930 if (SgFr_sg_ent_state(sg_fr) < compiled)
931#else
932 if (SgFr_state(sg_fr) < compiled)
933#endif /*THREADS_FULL_SHARING || THREADS_CONSUMER_SHARING */
934 update_answer_trie(sg_fr);
935 UNLOCK_SG_FR(sg_fr);
936 PREG = (yamop *) TrNode_child(SgFr_answer_trie(sg_fr));
937 PREFETCH_OP(PREG);
938 *--YENV = 0; /* vars_arity */
939 *--YENV = 0; /* heap_arity */
940 GONext();
941 }
942 }
943 }
944 ENDPBOp();
945
946
947
948/************************************************************************
949** table_retry_me **
950************************************************************************/
951
952 Op(table_retry_me, Otapl)
953 restore_generator_node(PREG->y_u.Otapl.s, PREG->y_u.Otapl.d);
954 YENV = (CELL *) PROTECT_FROZEN_B(B);
955 set_cut(YENV, B->cp_b);
956 SET_BB(NORM_CP(YENV));
957 allocate_environment();
958 PREG = NEXTOP(PREG,Otapl);
959 GONext();
960 ENDOp();
961
962
963
964/************************************************************************
965** table_retry **
966************************************************************************/
967
968 Op(table_retry, Otapl)
969 restore_generator_node(PREG->y_u.Otapl.s, NEXTOP(PREG,Otapl));
970 YENV = (CELL *) PROTECT_FROZEN_B(B);
971 set_cut(YENV, B->cp_b);
972 SET_BB(NORM_CP(YENV));
973 allocate_environment();
974 PREG = PREG->y_u.Otapl.d;
975 GONext();
976 ENDOp();
977
978
979
980/************************************************************************
981** table_trust_me **
982************************************************************************/
983
984 Op(table_trust_me, Otapl)
985 restore_generator_node(PREG->y_u.Otapl.s, COMPLETION);
986#ifdef DETERMINISTIC_TABLING
987 if (B_FZ > B && IS_BATCHED_NORM_GEN_CP(B)) {
988 CELL *subs_ptr = (CELL *)(GEN_CP(B) + 1) + PREG->y_u.Otapl.s;
989 choiceptr gcp = NORM_CP(DET_GEN_CP(subs_ptr) - 1);
990 sg_fr_ptr sg_fr = GEN_CP(B)->cp_sg_fr;
991 DET_GEN_CP(gcp)->cp_sg_fr = sg_fr;
992 gcp->cp_h = B->cp_h;
993#ifdef DEPTH_LIMIT
994 gcp->cp_depth = B->cp_depth;
995#endif /* DEPTH_LIMIT */
996 gcp->cp_tr = B->cp_tr;
997 gcp->cp_b = B->cp_b;
998 gcp->cp_ap = B->cp_ap;
999 SgFr_gen_cp(sg_fr) = B = gcp;
1000 }
1001#endif /* DETERMINISTIC_TABLING */
1002 YENV = (CELL *) PROTECT_FROZEN_B(B);
1003 set_cut(YENV, B->cp_b);
1004 SET_BB(NORM_CP(YENV));
1005 allocate_environment();
1006 PREG = NEXTOP(PREG,Otapl);
1007 GONext();
1008 ENDOp();
1009
1010
1011
1012/************************************************************************
1013** table_trust **
1014************************************************************************/
1015
1016 Op(table_trust, Otapl)
1017 restore_generator_node(PREG->y_u.Otapl.s, COMPLETION);
1018#ifdef DETERMINISTIC_TABLING
1019 if (B_FZ > B && IS_BATCHED_NORM_GEN_CP(B)) {
1020 CELL *subs_ptr = (CELL *)(GEN_CP(B) + 1) + PREG->y_u.Otapl.s;
1021 choiceptr gcp = NORM_CP(DET_GEN_CP(subs_ptr) - 1);
1022 sg_fr_ptr sg_fr = GEN_CP(B)->cp_sg_fr;
1023 DET_GEN_CP(gcp)->cp_sg_fr = sg_fr;
1024 gcp->cp_h = B->cp_h;
1025#ifdef DEPTH_LIMIT
1026 gcp->cp_depth = B->cp_depth;
1027#endif /* DEPTH_LIMIT */
1028 gcp->cp_tr = B->cp_tr;
1029 gcp->cp_b = B->cp_b;
1030 gcp->cp_ap = B->cp_ap;
1031 SgFr_gen_cp(sg_fr) = B = gcp;
1032 }
1033#endif /* DETERMINISTIC_TABLING */
1034 YENV = (CELL *) PROTECT_FROZEN_B(B);
1035 set_cut(YENV, B->cp_b);
1036 SET_BB(NORM_CP(YENV));
1037 allocate_environment();
1038 PREG = PREG->y_u.Otapl.d;
1039 GONext();
1040 ENDOp();
1041
1042
1043
1044/************************************************************************
1045** table_new_answer **
1046************************************************************************/
1047
1048 PBOp(table_new_answer, s)
1049 CELL *subs_ptr;
1050 choiceptr gcp;
1051 sg_fr_ptr sg_fr;
1052 ans_node_ptr ans_node;
1053
1054 gcp = NORM_CP(YENV[E_B]);
1055#ifdef DETERMINISTIC_TABLING
1056 if (IS_DET_GEN_CP(gcp)){
1057 sg_fr = DET_GEN_CP(gcp)->cp_sg_fr;
1058 subs_ptr = (CELL *)(DET_GEN_CP(gcp) + 1) ;
1059 } else
1060#endif /* DETERMINISTIC_TABLING */
1061 {
1062 sg_fr = GEN_CP(gcp)->cp_sg_fr;
1063 subs_ptr = (CELL *)(GEN_CP(gcp) + 1) + PREG->y_u.s.s;
1064 }
1065#if defined(DEBUG_TABLING) && !defined(DETERMINISTIC_TABLING)
1066 {
1067 int i, j, arity_args, arity_subs;
1068 CELL *aux_args;
1069 CELL *aux_subs;
1070
1071 arity_args = PREG->y_u.s.s;
1072 arity_subs = *subs_ptr;
1073 aux_args = (CELL *)(GEN_CP(gcp) + 1);
1074 aux_subs = subs_ptr;
1075 for (i = 1; i <= arity_subs; i++) {
1076 Term term_subs = Deref(*(aux_subs + i));
1077 for (j = 0; j < arity_args; j++) {
1078 Term term_arg = Deref(*(aux_args + j));
1079 if (term_subs == term_arg) break;
1080 }
1081 TABLING_ERROR_CHECKING(table_new_answer, j == arity_args);
1082 }
1083 }
1084#endif /* DEBUG_TABLING && !DETERMINISTIC_TABLING */
1085 LOCK_ANSWER_TRIE(sg_fr);
1086#ifdef MODE_DIRECTED_TABLING
1087 if (SgFr_mode_directed(sg_fr)) {
1088 ans_node = mode_directed_answer_search(sg_fr, subs_ptr);
1089 if (ans_node == NULL) {
1090 /* no answer inserted */
1091 UNLOCK_ANSWER_TRIE(sg_fr);
1092 goto fail;
1093 }
1094 } else
1095#endif /* MODE_DIRECTED_TABLING */
1096 ans_node = answer_search(sg_fr, subs_ptr);
1097 LOCK_ANSWER_NODE(ans_node);
1098 if (! IS_ANSWER_LEAF_NODE(ans_node)) {
1099 /* new answer */
1100#ifdef TABLING_INNER_CUTS
1101 /* check for potencial prunings */
1102 if (! BITMAP_empty(GLOBAL_bm_pruning_workers)) {
1103 int until_depth, depth;
1104
1105 until_depth = OrFr_depth(SgFr_gen_top_or_fr(sg_fr));
1106 depth = OrFr_depth(LOCAL_top_or_fr);
1107 if (depth > until_depth) {
1108 int i, ltt;
1109 bitmap prune_members, members;
1110 or_fr_ptr leftmost_or_fr, or_fr, nearest_or_fr;
1111
1112 BITMAP_copy(prune_members, GLOBAL_bm_pruning_workers);
1113 BITMAP_delete(prune_members, worker_id);
1114 ltt = BRANCH_LTT(worker_id, depth);
1115 BITMAP_intersection(members, prune_members, OrFr_members(LOCAL_top_or_fr));
1116 if (members) {
1117 for (i = 0; i < GLOBAL_number_workers; i++) {
1118 if (BITMAP_member(members, i) &&
1119 BRANCH_LTT(i, depth) > ltt &&
1120 EQUAL_OR_YOUNGER_CP(Get_LOCAL_top_cp(), REMOTE_pruning_scope(i))) {
1121 leftmost_or_fr = LOCAL_top_or_fr;
1122 pending_table_new_answer:
1123 UNLOCK_ANSWER_NODE(ans_node);
1124 UNLOCK_ANSWER_TRIE(sg_fr);
1125 LOCK_OR_FRAME(leftmost_or_fr);
1126 if (Get_LOCAL_prune_request()) {
1127 UNLOCK_OR_FRAME(leftmost_or_fr);
1128 SCHEDULER_GET_WORK();
1129 } else {
1130 CUT_store_tg_answer(leftmost_or_fr, ans_node, gcp, ltt);
1131 UNLOCK_OR_FRAME(leftmost_or_fr);
1132 }
1133 if (IS_BATCHED_GEN_CP(gcp)) {
1134 /* deallocate and procceed */
1135 PREG = (yamop *) YENV[E_CP];
1136 PREFETCH_OP(PREG);
1137 CPREG = PREG;
1138 SREG = YENV;
1139 ENV = YENV = (CELL *) YENV[E_E];
1140#ifdef DEPTH_LIMIT
1141 DEPTH = YENV[E_DEPTH];
1142#endif /* DEPTH_LIMIT */
1143 GONext();
1144 } else {
1145 /* fail */
1146 goto fail;
1147 }
1148 }
1149 }
1150 BITMAP_minus(prune_members, members);
1151 }
1152 leftmost_or_fr = OrFr_nearest_leftnode(LOCAL_top_or_fr);
1153 depth = OrFr_depth(leftmost_or_fr);
1154 if (depth > until_depth) {
1155 ltt = BRANCH_LTT(worker_id, depth);
1156 BITMAP_intersection(members, prune_members, OrFr_members(leftmost_or_fr));
1157 if (members) {
1158 for (i = 0; i < GLOBAL_number_workers; i++) {
1159 if (BITMAP_member(members, i) &&
1160 BRANCH_LTT(i, depth) > ltt &&
1161 EQUAL_OR_YOUNGER_CP(GetOrFr_node(leftmost_or_fr), REMOTE_pruning_scope(i)))
1162 goto pending_table_new_answer;
1163 }
1164 BITMAP_minus(prune_members, members);
1165 }
1166 /* reaching that point we should update the nearest leftnode data */
1167 leftmost_or_fr = OrFr_nearest_leftnode(leftmost_or_fr);
1168 depth = OrFr_depth(leftmost_or_fr);
1169 while (depth > until_depth) {
1170 ltt = BRANCH_LTT(worker_id, depth);
1171 BITMAP_intersection(members, prune_members, OrFr_members(leftmost_or_fr));
1172 if (members) {
1173 for (i = 0; i < GLOBAL_number_workers; i++) {
1174 if (BITMAP_member(members, i) &&
1175 BRANCH_LTT(i, depth) > ltt &&
1176 EQUAL_OR_YOUNGER_CP(GetOrFr_node(leftmost_or_fr), REMOTE_pruning_scope(i))) {
1177 /* update nearest leftnode data */
1178 or_fr = LOCAL_top_or_fr;
1179 nearest_or_fr = OrFr_nearest_leftnode(or_fr);
1180 while (OrFr_depth(nearest_or_fr) > depth) {
1181 LOCK_OR_FRAME(or_fr);
1182 OrFr_nearest_leftnode(or_fr) = leftmost_or_fr;
1183 UNLOCK_OR_FRAME(or_fr);
1184 or_fr = nearest_or_fr;
1185 nearest_or_fr = OrFr_nearest_leftnode(or_fr);
1186 }
1187 goto pending_table_new_answer;
1188 }
1189 }
1190 BITMAP_minus(prune_members, members);
1191 }
1192 leftmost_or_fr = OrFr_nearest_leftnode(leftmost_or_fr);
1193 depth = OrFr_depth(leftmost_or_fr);
1194 }
1195 /* update nearest leftnode data */
1196 or_fr = LOCAL_top_or_fr;
1197 nearest_or_fr = OrFr_nearest_leftnode(or_fr);
1198 while (OrFr_depth(nearest_or_fr) > depth) {
1199 LOCK_OR_FRAME(or_fr);
1200 OrFr_nearest_leftnode(or_fr) = leftmost_or_fr;
1201 UNLOCK_OR_FRAME(or_fr);
1202 or_fr = nearest_or_fr;
1203 nearest_or_fr = OrFr_nearest_leftnode(or_fr);
1204 }
1205 }
1206 }
1207 }
1208
1209 /* check for prune requests */
1210 if (Get_LOCAL_prune_request()) {
1211 UNLOCK_ANSWER_NODE(ans_node);
1212 UNLOCK_ANSWER_TRIE(sg_fr);
1213 SCHEDULER_GET_WORK();
1214 }
1215#endif /* TABLING_INNER_CUTS */
1216 TAG_AS_ANSWER_LEAF_NODE(ans_node);
1217#ifdef THREADS_FULL_SHARING
1218 INFO_THREADS("new answer (1) sgfr=%p ans_node=%p",SgFr_sg_ent(sg_fr),ans_node);
1219 if (IsMode_Batched(TabEnt_mode(SgFr_tab_ent(sg_fr)))) {
1220 ANSWER_LEAF_NODE_INSTR_RELATIVE(ans_node);
1221 if (worker_id < ANSWER_LEAF_NODE_MAX_THREADS)
1222 ANSWER_LEAF_NODE_SET_WID(ans_node,worker_id);
1223 }
1224#endif /* THREADS_FULL_SHARING */
1225 UNLOCK_ANSWER_NODE(ans_node);
1226#ifndef ANSWER_TRIE_LOCK_AT_ENTRY_LEVEL
1227 LOCK_SG_FR(sg_fr);
1228#endif /* ! ANSWER_TRIE_LOCK_AT_ENTRY_LEVEL */
1229 if (SgFr_first_answer(sg_fr) == NULL)
1230 SgFr_first_answer(sg_fr) = ans_node;
1231 else
1232 TrNode_child(SgFr_last_answer(sg_fr)) = ans_node;
1233 SgFr_last_answer(sg_fr) = ans_node;
1234#ifdef DEBUG_TABLING
1235 {
1236 ans_node_ptr aux_ans_node = SgFr_first_answer(sg_fr);
1237 while (aux_ans_node != SgFr_last_answer(sg_fr)) {
1238 TABLING_ERROR_CHECKING(table_new_answer, !IS_ANSWER_LEAF_NODE(aux_ans_node));
1239 aux_ans_node = TrNode_child(aux_ans_node);
1240 }
1241 }
1242#endif /* DEBUG_TABLING */
1243 UNLOCK_SG_FR(sg_fr);
1244 if (IS_BATCHED_GEN_CP(gcp)) {
1245#ifdef THREADS_FULL_SHARING
1246 if (worker_id >= ANSWER_LEAF_NODE_MAX_THREADS)
1247 SgFr_batched_cached_answers_check_insert(sg_fr,ans_node); //add to buffer all answers except the ans_node
1248#endif /* THREADS_FULL_SHARING */
1249#ifdef TABLING_EARLY_COMPLETION
1250 if (gcp == PROTECT_FROZEN_B(B) && (*subs_ptr == 0 || gcp->cp_ap == COMPLETION)) {
1251 /* if the current generator choice point is the topmost choice point and the current */
1252 /* call is deterministic (i.e., the number of substitution variables is zero or */
1253 /* there are no more alternatives) then the current answer is deterministic and we */
1254 /* can perform an early completion and remove the current generator choice point */
1255 private_completion(sg_fr);
1256 B = B->cp_b;
1257 SET_BB(PROTECT_FROZEN_B(B));
1258 } else if (*subs_ptr == 0) {
1259 /* if the number of substitution variables is zero, an answer is sufficient to perform */
1260 /* an early completion, but the current generator choice point cannot be removed */
1261 mark_as_completed(sg_fr);
1262 if (gcp->cp_ap != NULL)
1263 gcp->cp_ap = COMPLETION;
1264 }
1265#endif /* TABLING_EARLY_COMPLETION */
1266 /* deallocate and procceed */
1267 PREG = (yamop *) YENV[E_CP];
1268 PREFETCH_OP(PREG);
1269 CPREG = PREG;
1270 SREG = YENV;
1271 ENV = YENV = (CELL *) YENV[E_E];
1272#ifdef DEPTH_LIMIT
1273 DEPTH = YENV[E_DEPTH];
1274#endif /* DEPTH_LIMIT */
1275 GONext();
1276 } else {
1277#ifdef TABLING_EARLY_COMPLETION
1278 if (*subs_ptr == 0) {
1279 /* if the number of substitution variables is zero, an answer is sufficient to perform */
1280 /* an early completion, but the current generator choice point cannot be removed */
1281 mark_as_completed(sg_fr);
1282 if (gcp->cp_ap != ANSWER_RESOLUTION)
1283 gcp->cp_ap = COMPLETION;
1284 }
1285#endif /* TABLING_EARLY_COMPLETION */
1286 /* fail */
1287 goto fail;
1288 }
1289 } else {
1290 /* repeated answer */
1291#ifdef THREADS_FULL_SHARING
1292 if (IsMode_Batched(TabEnt_mode(SgFr_tab_ent(sg_fr)))){
1293 if (worker_id >= ANSWER_LEAF_NODE_MAX_THREADS) {
1294 UNLOCK_ANSWER_NODE(ans_node);
1295 UNLOCK_ANSWER_TRIE(sg_fr);
1296 SgFr_batched_cached_answers_check_insert(sg_fr,NULL);
1297 INFO_THREADS("new answer (2) sgfr=%p ans_node=%p",SgFr_sg_ent(sg_fr),ans_node);
1298 if (SgFr_batched_cached_answers_check_remove(sg_fr , ans_node) == 1){
1299 INFO_THREADS("ans_node=%p not found", ans_node);
1300 goto fail;
1301 }
1302 /* deallocate and procceed */
1303 PREG = (yamop *) YENV[E_CP];
1304 PREFETCH_OP(PREG);
1305 CPREG = PREG;
1306 SREG = YENV;
1307 ENV = YENV = (CELL *) YENV[E_E];
1308#ifdef DEPTH_LIMIT
1309 DEPTH = YENV[E_DEPTH];
1310#endif /*DEPTH_LIMIT */
1311 GONext();
1312 } else {
1313 if (!ANSWER_LEAF_NODE_CHECK_WID(ans_node,worker_id)){
1314 ANSWER_LEAF_NODE_SET_WID(ans_node,worker_id);
1315 UNLOCK_ANSWER_NODE(ans_node);
1316 UNLOCK_ANSWER_TRIE(sg_fr);
1317 /* deallocate and procceed */
1318 INFO_THREADS("new answer (2) sgfr=%p ans_node=%p",SgFr_sg_ent(sg_fr),ans_node);
1319 PREG = (yamop *) YENV[E_CP];
1320 PREFETCH_OP(PREG);
1321 CPREG = PREG;
1322 SREG = YENV;
1323 ENV = YENV = (CELL *) YENV[E_E];
1324#ifdef DEPTH_LIMIT
1325 DEPTH = YENV[E_DEPTH];
1326#endif /*DEPTH_LIMIT */
1327 GONext();
1328 }
1329 }
1330 }
1331#else
1332 UNLOCK_ANSWER_NODE(ans_node);
1333 UNLOCK_ANSWER_TRIE(sg_fr);
1334#endif /* THREADS_FULL_SHARING */
1335#if defined(THREADS_FULL_SHARING) || defined(THREADS_CONSUMER_SHARING)
1336 INFO_THREADS("new answer(rep) sgfr=%p ans_node=%p",SgFr_sg_ent(sg_fr),ans_node);
1337#else
1338 INFO_THREADS("new answer(rep) sgfr=%p ans_node=%p",sg_fr,ans_node);
1339#endif /* THREADS_FULL_SHARING || THREADS_CONSUMER_SHARING */
1340 goto fail;
1341 }
1342 ENDPBOp();
1343
1344
1345
1346/************************************************************************
1347** table_answer_resolution **
1348************************************************************************/
1349
1350 BOp(table_answer_resolution, Otapl)
1351#ifdef YAPOR
1352 if (SCH_top_shared_cp(B)) {
1353 UNLOCK_OR_FRAME(LOCAL_top_or_fr);
1354 }
1355#endif /* YAPOR */
1356
1357
1358 answer_resolution:
1359 INIT_PREFETCH()
1360 dep_fr_ptr dep_fr;
1361 ans_node_ptr ans_node;
1362
1363 OPTYAP_ERROR_CHECKING(answer_resolution, SCH_top_shared_cp(B) && B->cp_or_fr->alternative != ANSWER_RESOLUTION);
1364 OPTYAP_ERROR_CHECKING(answer_resolution, !SCH_top_shared_cp(B) && B->cp_ap != ANSWER_RESOLUTION);
1365 dep_fr = CONS_CP(B)->cp_dep_fr;
1366 LOCK_DEP_FR(dep_fr);
1367 ans_node = DepFr_last_answer(dep_fr);
1368 if (TrNode_child(ans_node)) {
1369 /* unconsumed answers */
1370#ifdef MODE_DIRECTED_TABLING
1371 if (IS_ANSWER_INVALID_NODE(TrNode_child(ans_node))) {
1372 ans_node_ptr old_ans_node;
1373 old_ans_node = ans_node;
1374 ans_node = TrNode_child(ans_node);
1375 do {
1376 ans_node = TrNode_child(ans_node);
1377 } while (IS_ANSWER_INVALID_NODE(ans_node));
1378 TrNode_child(old_ans_node) = ans_node;
1379 } else
1380#endif /* MODE_DIRECTED_TABLING */
1381 ans_node = TrNode_child(ans_node);
1382 DepFr_last_answer(dep_fr) = ans_node;
1383 UNLOCK_DEP_FR(dep_fr);
1384 consume_answer_and_procceed(dep_fr, ans_node);
1385 }
1386 UNLOCK_DEP_FR(dep_fr);
1387
1388#ifdef YAPOR
1389 if (B == DepFr_leader_cp(LOCAL_top_dep_fr)) {
1390 /* B is a generator-consumer node **
1391 ** never here if batched scheduling */
1392 TABLING_ERROR_CHECKING(answer_resolution, IS_BATCHED_GEN_CP(B));
1393 goto completion;
1394 }
1395#endif /* YAPOR */
1396
1397 /* no unconsumed answers */
1398 if (DepFr_backchain_cp(dep_fr) == NULL) {
1399 /* normal backtrack */
1400#ifdef YAPOR
1401 if (SCH_top_shared_cp(B)) {
1402 SCHEDULER_GET_WORK();
1403 }
1404#endif /* YAPOR */
1405 B = B->cp_b;
1406 goto fail;
1407 } else {
1408 /* chain backtrack */
1409 choiceptr top_chain_cp, chain_cp;
1410#ifdef YAPOR
1411 or_fr_ptr start_or_fr, end_or_fr;
1412#endif /* YAPOR */
1413
1414 /* find chain choice point to backtrack */
1415 top_chain_cp = DepFr_backchain_cp(dep_fr);
1416 chain_cp = DepFr_leader_cp(LOCAL_top_dep_fr);
1417 if (YOUNGER_CP(top_chain_cp, chain_cp))
1418 chain_cp = top_chain_cp;
1419 TABLING_ERROR_CHECKING(answer_resolution, EQUAL_OR_YOUNGER_CP(top_chain_cp, B));
1420 TABLING_ERROR_CHECKING(answer_resolution, EQUAL_OR_YOUNGER_CP(chain_cp, B));
1421
1422 /* check for dependency frames with unconsumed answers */
1423 dep_fr = DepFr_next(dep_fr);
1424 while (YOUNGER_CP(DepFr_cons_cp(dep_fr), chain_cp)) {
1425 LOCK_DEP_FR(dep_fr);
1426 ans_node = DepFr_last_answer(dep_fr);
1427 if (TrNode_child(ans_node)) {
1428 /* dependency frame with unconsumed answers */
1429#ifdef MODE_DIRECTED_TABLING
1430 if (IS_ANSWER_INVALID_NODE(TrNode_child(ans_node))) {
1431 ans_node_ptr old_ans_node;
1432 old_ans_node = ans_node;
1433 ans_node = TrNode_child(ans_node);
1434 do {
1435 ans_node = TrNode_child(ans_node);
1436 } while (IS_ANSWER_INVALID_NODE(ans_node));
1437 TrNode_child(old_ans_node) = ans_node;
1438 } else
1439#endif /* MODE_DIRECTED_TABLING */
1440 ans_node = TrNode_child(ans_node);
1441 DepFr_last_answer(dep_fr) = ans_node;
1442#ifdef YAPOR
1443 if (YOUNGER_CP(DepFr_backchain_cp(dep_fr), top_chain_cp))
1444#endif /* YAPOR */
1445 DepFr_backchain_cp(dep_fr) = top_chain_cp;
1446 UNLOCK_DEP_FR(dep_fr);
1447
1448 chain_cp = DepFr_cons_cp(dep_fr);
1449#ifdef YAPOR
1450 /* update shared nodes */
1451 start_or_fr = LOCAL_top_or_fr;
1452 end_or_fr = DepFr_top_or_fr(dep_fr);
1453 if (start_or_fr != end_or_fr) {
1454 LOCAL_top_or_fr = end_or_fr;
1455 Set_LOCAL_top_cp(GetOrFr_node(end_or_fr));
1456 do {
1457 while (YOUNGER_CP(GetOrFr_node(start_or_fr), GetOrFr_node(end_or_fr))) {
1458 LOCK_OR_FRAME(start_or_fr);
1459 BITMAP_delete(OrFr_members(start_or_fr), worker_id);
1460 if (BITMAP_empty(OrFr_members(start_or_fr))) {
1461 if (frame_with_suspensions_not_collected(start_or_fr)) {
1462 collect_suspension_frames(start_or_fr);
1463 }
1464#ifdef TABLING_INNER_CUTS
1465 if (OrFr_tg_solutions(start_or_fr)) {
1466 tg_sol_fr_ptr tg_solutions;
1467 or_fr_ptr leftmost_until;
1468 tg_solutions = OrFr_tg_solutions(start_or_fr);
1469 leftmost_until = CUT_leftmost_until(start_or_fr, OrFr_depth(TgSolFr_gen_cp(tg_solutions)->cp_or_fr));
1470 OrFr_tg_solutions(start_or_fr) = NULL;
1471 UNLOCK_OR_FRAME(start_or_fr);
1472 if (leftmost_until) {
1473 LOCK_OR_FRAME(leftmost_until);
1474 tg_solutions = CUT_store_tg_answers(leftmost_until, tg_solutions,
1475 BRANCH_LTT(worker_id, OrFr_depth(leftmost_until)));
1476 UNLOCK_OR_FRAME(leftmost_until);
1477 }
1478 CUT_validate_tg_answers(tg_solutions);
1479 goto continue_update_loop1;
1480 }
1481#endif /* TABLING_INNER_CUTS */
1482 }
1483 UNLOCK_OR_FRAME(start_or_fr);
1484#ifdef TABLING_INNER_CUTS
1485 continue_update_loop1:
1486#endif /* TABLING_INNER_CUTS */
1487 start_or_fr = OrFr_next(start_or_fr);
1488 }
1489 while (YOUNGER_CP(GetOrFr_node(end_or_fr), GetOrFr_node(start_or_fr))) {
1490 LOCK_OR_FRAME(end_or_fr);
1491 BITMAP_insert(OrFr_members(end_or_fr), worker_id);
1492 BRANCH(worker_id, OrFr_depth(end_or_fr)) = 1;
1493 UNLOCK_OR_FRAME(end_or_fr);
1494 end_or_fr = OrFr_next(end_or_fr);
1495 }
1496 } while (start_or_fr != end_or_fr);
1497 if (Get_LOCAL_prune_request())
1498 pruning_over_tabling_data_structures();
1499 }
1500#endif /* YAPOR */
1501#ifdef DEBUG_OPTYAP
1502 if (GLOBAL_parallel_mode == PARALLEL_MODE_RUNNING) {
1503 choiceptr aux_cp;
1504 OPTYAP_ERROR_CHECKING(completion, YOUNGER_CP(Get_LOCAL_top_cp(), Get_LOCAL_top_cp_on_stack()));
1505 aux_cp = chain_cp;
1506 while (aux_cp != Get_LOCAL_top_cp()) {
1507 OPTYAP_ERROR_CHECKING(completion, YOUNGER_CP(Get_LOCAL_top_cp(), aux_cp));
1508 OPTYAP_ERROR_CHECKING(completion, EQUAL_OR_YOUNGER_CP(Get_LOCAL_top_cp_on_stack(), aux_cp));
1509 aux_cp = aux_cp->cp_b;
1510 }
1511 }
1512#endif /* DEBUG_OPTYAP */
1513 /* restore bindings, update registers, consume answer and procceed */
1514 restore_bindings(B->cp_tr, chain_cp->cp_tr);
1515 TABLING_ERROR_CHECKING(answer_resolution, TR != B->cp_tr && !IsPairTerm((CELL)TrailTerm(TR - 1)));
1516 TABLING_ERROR_CHECKING(answer_resolution, TR != B->cp_tr && (tr_fr_ptr) RepPair((CELL)TrailTerm(TR - 1)) != B->cp_tr);
1517 B = chain_cp;
1518 TR = TR_FZ;
1519 TRAIL_LINK(B->cp_tr);
1520 consume_answer_and_procceed(dep_fr, ans_node);
1521 }
1522 UNLOCK_DEP_FR(dep_fr);
1523 dep_fr = DepFr_next(dep_fr);
1524 }
1525
1526 /* no dependency frames with unconsumed answers found */
1527#ifdef YAPOR
1528 /* update shared nodes */
1529 if (EQUAL_OR_YOUNGER_CP(Get_LOCAL_top_cp_on_stack(), chain_cp)) {
1530 end_or_fr = chain_cp->cp_or_fr;
1531 start_or_fr = LOCAL_top_or_fr;
1532 if (start_or_fr != end_or_fr) {
1533 LOCAL_top_or_fr = end_or_fr;
1534 Set_LOCAL_top_cp(GetOrFr_node(end_or_fr));
1535 while (start_or_fr != end_or_fr) {
1536 LOCK_OR_FRAME(start_or_fr);
1537 BITMAP_delete(OrFr_members(start_or_fr), worker_id);
1538 if (BITMAP_empty(OrFr_members(start_or_fr))) {
1539 if (frame_with_suspensions_not_collected(start_or_fr)) {
1540 collect_suspension_frames(start_or_fr);
1541 }
1542#ifdef TABLING_INNER_CUTS
1543 if (OrFr_tg_solutions(start_or_fr)) {
1544 tg_sol_fr_ptr tg_solutions;
1545 or_fr_ptr leftmost_until;
1546 tg_solutions = OrFr_tg_solutions(start_or_fr);
1547 leftmost_until = CUT_leftmost_until(start_or_fr, OrFr_depth(TgSolFr_gen_cp(tg_solutions)->cp_or_fr));
1548 OrFr_tg_solutions(start_or_fr) = NULL;
1549 UNLOCK_OR_FRAME(start_or_fr);
1550 if (leftmost_until) {
1551 LOCK_OR_FRAME(leftmost_until);
1552 tg_solutions = CUT_store_tg_answers(leftmost_until, tg_solutions,
1553 BRANCH_LTT(worker_id, OrFr_depth(leftmost_until)));
1554 UNLOCK_OR_FRAME(leftmost_until);
1555 }
1556 CUT_validate_tg_answers(tg_solutions);
1557 goto continue_update_loop2;
1558 }
1559#endif /* TABLING_INNER_CUTS */
1560 }
1561 UNLOCK_OR_FRAME(start_or_fr);
1562#ifdef TABLING_INNER_CUTS
1563 continue_update_loop2:
1564#endif /* TABLING_INNER_CUTS */
1565 start_or_fr = OrFr_next(start_or_fr);
1566 }
1567 if (Get_LOCAL_prune_request())
1568 pruning_over_tabling_data_structures();
1569 }
1570 }
1571#endif /* YAPOR */
1572#ifdef DEBUG_OPTYAP
1573 if (GLOBAL_parallel_mode == PARALLEL_MODE_RUNNING) {
1574 choiceptr aux_cp;
1575 OPTYAP_ERROR_CHECKING(completion, YOUNGER_CP(Get_LOCAL_top_cp(), Get_LOCAL_top_cp_on_stack()));
1576 aux_cp = chain_cp;
1577 while (aux_cp != Get_LOCAL_top_cp()) {
1578 OPTYAP_ERROR_CHECKING(completion, YOUNGER_CP(Get_LOCAL_top_cp(), aux_cp));
1579 OPTYAP_ERROR_CHECKING(completion, EQUAL_OR_YOUNGER_CP(Get_LOCAL_top_cp_on_stack(), aux_cp));
1580 aux_cp = aux_cp->cp_b;
1581 }
1582 }
1583#endif /* DEBUG_OPTYAP */
1584 /* unbind variables */
1585 unbind_variables(B->cp_tr, chain_cp->cp_tr);
1586 TABLING_ERROR_CHECKING(answer_resolution, TR != B->cp_tr && !IsPairTerm((CELL)TrailTerm(TR - 1)));
1587 TABLING_ERROR_CHECKING(answer_resolution, TR != B->cp_tr && (tr_fr_ptr) RepPair((CELL)TrailTerm(TR - 1)) != B->cp_tr);
1588 if (DepFr_leader_cp(LOCAL_top_dep_fr) == chain_cp && (
1589 /* chain_cp is a leader node AND ... */
1590#ifdef YAPOR
1591 /* the leader dependency is not on stack OR ... */
1592 DepFr_leader_dep_is_on_stack(LOCAL_top_dep_fr) == FALSE ||
1593 /* the leader dependency is on stack (this means that chain_cp is a generator node) and */
1594#endif /* YAPOR */
1595 /* there are no unexploited alternatives **
1596 ** (NULL if batched scheduling OR ANSWER_RESOLUTION if local scheduling) */
1597 chain_cp->cp_ap == NULL || chain_cp->cp_ap == ANSWER_RESOLUTION)) {
1598 B = chain_cp;
1599 TR = TR_FZ;
1600 TRAIL_LINK(B->cp_tr);
1601 goto completion;
1602 }
1603 /* backtrack to chain choice point */
1604 PREG = chain_cp->cp_ap;
1605 PREFETCH_OP(PREG);
1606 B = chain_cp;
1607 TR = TR_FZ;
1608 TRAIL_LINK(B->cp_tr);
1609 GONext();
1610 }
1611 END_PREFETCH()
1612 ENDBOp();
1613
1614
1615
1616/************************************************************************
1617** table_completion **
1618************************************************************************/
1619
1620 BOp(table_completion, Otapl)
1621#ifdef YAPOR
1622 if (SCH_top_shared_cp(B)) {
1623 if (IS_BATCHED_GEN_CP(B)) {
1624 SCH_new_alternative(PREG, NULL);
1625 if (B != DepFr_leader_cp(LOCAL_top_dep_fr) && EQUAL_OR_YOUNGER_CP(B_FZ, B)) {
1626 /* not leader on that node */
1627 SCHEDULER_GET_WORK();
1628 }
1629 } else {
1630 SCH_new_alternative(PREG, ANSWER_RESOLUTION);
1631 if (B != DepFr_leader_cp(LOCAL_top_dep_fr)) {
1632 /* not leader on that node */
1633 SCHEDULER_GET_WORK();
1634 }
1635 }
1636 } else
1637#endif /* YAPOR */
1638 {
1639
1640#ifdef THREADS_CONSUMER_SHARING
1641 goto answer_resolution_completion;
1642#endif /* THREADS_CONSUMER_SHARING */
1643
1644 if (IS_BATCHED_GEN_CP(B)) {
1645 B->cp_ap = NULL;
1646 if (EQUAL_OR_YOUNGER_CP(B_FZ, B) && B != DepFr_leader_cp(LOCAL_top_dep_fr)) {
1647 /* not leader on that node */
1648 B = B->cp_b;
1649 goto fail;
1650 }
1651 } else {
1652 B->cp_ap = ANSWER_RESOLUTION;
1653 if (B != DepFr_leader_cp(LOCAL_top_dep_fr)) {
1654 /* not leader on that node */
1655 B = B->cp_b;
1656 goto fail;
1657 }
1658 }
1659 }
1660 /* leader on that node */
1661
1662
1663 completion:
1664#ifdef THREADS_CONSUMER_SHARING
1665 goto answer_resolution_completion;
1666#endif /* THREADS_CONSUMER_SHARING */
1667 INIT_PREFETCH()
1668 dep_fr_ptr dep_fr;
1669 ans_node_ptr ans_node;
1670#ifdef YAPOR
1671#ifdef TIMESTAMP_CHECK
1672 long timestamp = 0;
1673#endif /* TIMESTAMP_CHECK */
1674 int entry_owners = 0;
1675
1676 if (SCH_top_shared_cp(B)) {
1677#ifdef TIMESTAMP_CHECK
1678 timestamp = ++GLOBAL_timestamp;
1679#endif /* TIMESTAMP_CHECK */
1680 entry_owners = OrFr_owners(LOCAL_top_or_fr);
1681 }
1682#endif /* YAPOR */
1683
1684 /* check for dependency frames with unconsumed answers */
1685 dep_fr = LOCAL_top_dep_fr;
1686 while (YOUNGER_CP(DepFr_cons_cp(dep_fr), B)) {
1687 LOCK_DEP_FR(dep_fr);
1688 ans_node = DepFr_last_answer(dep_fr);
1689 if (TrNode_child(ans_node)) {
1690 /* dependency frame with unconsumed answers */
1691#ifdef MODE_DIRECTED_TABLING
1692 if (IS_ANSWER_INVALID_NODE(TrNode_child(ans_node))) {
1693 ans_node_ptr old_ans_node;
1694 old_ans_node = ans_node;
1695 ans_node = TrNode_child(ans_node);
1696 do {
1697 ans_node = TrNode_child(ans_node);
1698 } while (IS_ANSWER_INVALID_NODE(ans_node));
1699 TrNode_child(old_ans_node) = ans_node;
1700 } else
1701#endif /* MODE_DIRECTED_TABLING */
1702 ans_node = TrNode_child(ans_node);
1703 DepFr_last_answer(dep_fr) = ans_node;
1704 if (B->cp_ap) {
1705#ifdef YAPOR
1706 if (YOUNGER_CP(DepFr_backchain_cp(dep_fr), B))
1707#endif /* YAPOR */
1708 DepFr_backchain_cp(dep_fr) = B;
1709 } else {
1710#ifdef YAPOR
1711 if (YOUNGER_CP(DepFr_backchain_cp(dep_fr), B->cp_b))
1712#endif /* YAPOR */
1713 DepFr_backchain_cp(dep_fr) = B->cp_b;
1714 }
1715 UNLOCK_DEP_FR(dep_fr);
1716
1717#ifdef DEBUG_OPTYAP
1718 if (GLOBAL_parallel_mode == PARALLEL_MODE_RUNNING) {
1719 choiceptr aux_cp;
1720 OPTYAP_ERROR_CHECKING(completion, Get_LOCAL_top_cp(), Get_LOCAL_top_cp_on_stack());
1721 aux_cp = DepFr_cons_cp(dep_fr);
1722 while (YOUNGER_CP(aux_cp, Get_LOCAL_top_cp_on_stack()))
1723 aux_cp = aux_cp->cp_b;
1724 OPTYAP_ERROR_CHECKING(completion, aux_cp->cp_or_fr != DepFr_top_or_fr(dep_fr));
1725 }
1726#endif /* DEBUG_OPTYAP */
1727#ifdef YAPOR
1728 /* update shared nodes */
1729 if (YOUNGER_CP(Get_LOCAL_top_cp_on_stack(), Get_LOCAL_top_cp())) {
1730 or_fr_ptr or_frame = DepFr_top_or_fr(dep_fr);
1731 while (or_frame != LOCAL_top_or_fr) {
1732 LOCK_OR_FRAME(or_frame);
1733 BITMAP_insert(OrFr_members(or_frame), worker_id);
1734 BRANCH(worker_id, OrFr_depth(or_frame)) = 1;
1735 UNLOCK_OR_FRAME(or_frame);
1736 or_frame = OrFr_next(or_frame);
1737 }
1738 LOCAL_top_or_fr = DepFr_top_or_fr(dep_fr);
1739 Set_LOCAL_top_cp(GetOrFr_node(LOCAL_top_or_fr));
1740 }
1741#endif /* YAPOR */
1742#ifdef DEBUG_OPTYAP
1743 if (GLOBAL_parallel_mode == PARALLEL_MODE_RUNNING) {
1744 choiceptr aux_cp;
1745 OPTYAP_ERROR_CHECKING(completion, YOUNGER_CP(Get_LOCAL_top_cp(), Get_LOCAL_top_cp_on_stack()));
1746 aux_cp = DepFr_cons_cp(dep_fr);
1747 while (aux_cp != Get_LOCAL_top_cp()) {
1748 OPTYAP_ERROR_CHECKING(completion, YOUNGER_CP(Get_LOCAL_top_cp(), aux_cp));
1749 OPTYAP_ERROR_CHECKING(completion, EQUAL_OR_YOUNGER_CP(Get_LOCAL_top_cp_on_stack(), aux_cp));
1750 aux_cp = aux_cp->cp_b;
1751 }
1752 }
1753#endif /* DEBUG_OPTYAP */
1754 /* rebind variables, update registers, consume answer and procceed */
1755 TABLING_ERROR_CHECKING(completion, EQUAL_OR_YOUNGER_CP(B, DepFr_cons_cp(dep_fr)));
1756 TABLING_ERROR_CHECKING(completion, B->cp_tr > DepFr_cons_cp(dep_fr)->cp_tr);
1757 rebind_variables(DepFr_cons_cp(dep_fr)->cp_tr, B->cp_tr);
1758 TABLING_ERROR_CHECKING(completion, TR != B->cp_tr && !IsPairTerm((CELL)TrailTerm(TR - 1)));
1759 TABLING_ERROR_CHECKING(completion, TR != B->cp_tr && (tr_fr_ptr) RepPair((CELL)TrailTerm(TR - 1)) != B->cp_tr);
1760 B = DepFr_cons_cp(dep_fr);
1761 TR = TR_FZ;
1762 if (TR != B->cp_tr)
1763 TRAIL_LINK(B->cp_tr);
1764 consume_answer_and_procceed(dep_fr, ans_node);
1765 }
1766 UNLOCK_DEP_FR(dep_fr);
1767#ifdef TIMESTAMP_CHECK
1768 DepFr_timestamp(dep_fr) = timestamp;
1769#endif /* TIMESTAMP_CHECK */
1770 dep_fr = DepFr_next(dep_fr);
1771 }
1772
1773 /* no dependency frames with unconsumed answers found */
1774#ifdef YAPOR
1775 if (SCH_top_shared_cp(B)) {
1776 if (entry_owners > 1) {
1777 /* more owners when we start looking for dependency frames with unconsumed answers */
1778 if (YOUNGER_CP(B_FZ, B)) {
1779 suspend_branch();
1780 /* check for suspension frames to be resumed */
1781 while (YOUNGER_CP(GetOrFr_node(LOCAL_top_susp_or_fr), Get_LOCAL_top_cp())) {
1782 or_fr_ptr susp_or_fr;
1783 susp_fr_ptr resume_fr;
1784 susp_or_fr = LOCAL_top_susp_or_fr;
1785 LOCK_OR_FRAME(susp_or_fr);
1786#ifdef TIMESTAMP_CHECK
1787 resume_fr = suspension_frame_to_resume(susp_or_fr, timestamp);
1788#else
1789 resume_fr = suspension_frame_to_resume(susp_or_fr);
1790#endif /* TIMESTAMP_CHECK */
1791 if (resume_fr) {
1792 if (OrFr_suspensions(susp_or_fr) == NULL) {
1793 LOCAL_top_susp_or_fr = OrFr_nearest_suspnode(susp_or_fr);
1794 OrFr_nearest_suspnode(susp_or_fr) = susp_or_fr;
1795 }
1796 UNLOCK_OR_FRAME(susp_or_fr);
1797 rebind_variables(GetOrFr_node(susp_or_fr)->cp_tr, B->cp_tr);
1798 resume_suspension_frame(resume_fr, susp_or_fr);
1799 B = Get_LOCAL_top_cp();
1800 SET_BB(B_FZ);
1801 TR = TR_FZ;
1802 TRAIL_LINK(B->cp_tr);
1803 goto completion;
1804 }
1805 LOCAL_top_susp_or_fr = OrFr_nearest_suspnode(susp_or_fr);
1806 OrFr_nearest_suspnode(susp_or_fr) = NULL;
1807 UNLOCK_OR_FRAME(susp_or_fr);
1808 }
1809 }
1810 } else {
1811 /* unique owner */
1812 if (frame_with_suspensions_not_collected(LOCAL_top_or_fr))
1813 collect_suspension_frames(LOCAL_top_or_fr);
1814 /* check for suspension frames to be resumed */
1815 while (EQUAL_OR_YOUNGER_CP(GetOrFr_node(LOCAL_top_susp_or_fr), Get_LOCAL_top_cp())) {
1816 or_fr_ptr susp_or_fr;
1817 susp_fr_ptr resume_fr;
1818 susp_or_fr = LOCAL_top_susp_or_fr;
1819#ifdef TIMESTAMP_CHECK
1820 resume_fr = suspension_frame_to_resume(susp_or_fr, timestamp);
1821#else
1822 resume_fr = suspension_frame_to_resume(susp_or_fr);
1823#endif /* TIMESTAMP_CHECK */
1824 if (resume_fr) {
1825 if (OrFr_suspensions(susp_or_fr) == NULL) {
1826 LOCAL_top_susp_or_fr = OrFr_nearest_suspnode(susp_or_fr);
1827 OrFr_nearest_suspnode(susp_or_fr) = susp_or_fr;
1828 }
1829 if (YOUNGER_CP(B_FZ, B)) {
1830 suspend_branch();
1831 }
1832 rebind_variables(GetOrFr_node(susp_or_fr)->cp_tr, B->cp_tr);
1833 resume_suspension_frame(resume_fr, susp_or_fr);
1834 B = Get_LOCAL_top_cp();
1835 SET_BB(B_FZ);
1836 TR = TR_FZ;
1837 TRAIL_LINK(B->cp_tr);
1838 goto completion;
1839 }
1840 LOCAL_top_susp_or_fr = OrFr_nearest_suspnode(susp_or_fr);
1841 OrFr_nearest_suspnode(susp_or_fr) = NULL;
1842 }
1843 /* complete all */
1844 public_completion();
1845 }
1846 TABLING_ERROR_CHECKING(completion, TR != B->cp_tr && !IsPairTerm((CELL)TrailTerm(TR - 1)));
1847 TABLING_ERROR_CHECKING(completion, TR != B->cp_tr && (tr_fr_ptr) RepPair((CELL)TrailTerm(TR - 1)) != B->cp_tr);
1848 if (B == DepFr_leader_cp(LOCAL_top_dep_fr)) {
1849 /* B is a generator-consumer node */
1850 /* never here if batched scheduling */
1851 ans_node_ptr ans_node;
1852 TABLING_ERROR_CHECKING(completion, IS_BATCHED_GEN_CP(B));
1853 TR = B->cp_tr;
1854 SET_BB(B);
1855 LOCK_OR_FRAME(LOCAL_top_or_fr);
1856 LOCK_DEP_FR(LOCAL_top_dep_fr);
1857 ans_node = DepFr_last_answer(LOCAL_top_dep_fr);
1858 if (TrNode_child(ans_node)) {
1859 /* unconsumed answers */
1860 UNLOCK_OR_FRAME(LOCAL_top_or_fr);
1861#ifdef MODE_DIRECTED_TABLING
1862 if (IS_ANSWER_INVALID_NODE(TrNode_child(ans_node))) {
1863 ans_node_ptr old_ans_node;
1864 old_ans_node = ans_node;
1865 ans_node = TrNode_child(ans_node);
1866 do {
1867 ans_node = TrNode_child(ans_node);
1868 } while (IS_ANSWER_INVALID_NODE(ans_node));
1869 TrNode_child(old_ans_node) = ans_node;
1870 } else
1871#endif /* MODE_DIRECTED_TABLING */
1872 ans_node = TrNode_child(ans_node);
1873 DepFr_last_answer(LOCAL_top_dep_fr) = ans_node;
1874 UNLOCK_DEP_FR(LOCAL_top_dep_fr);
1875 consume_answer_and_procceed(LOCAL_top_dep_fr, ans_node);
1876 }
1877 /* no unconsumed answers */
1878 UNLOCK_DEP_FR(LOCAL_top_dep_fr);
1879 if (OrFr_owners(LOCAL_top_or_fr) > 1) {
1880 /* more owners -> move up one node */
1881 Set_LOCAL_top_cp_on_stack(GetOrFr_node(OrFr_next_on_stack(LOCAL_top_or_fr)));
1882 BITMAP_delete(OrFr_members(LOCAL_top_or_fr), worker_id);
1883 OrFr_owners(LOCAL_top_or_fr)--;
1884 LOCAL_top_dep_fr = DepFr_next(LOCAL_top_dep_fr);
1885 UNLOCK_OR_FRAME(LOCAL_top_or_fr);
1886 if (LOCAL_top_sg_fr && Get_LOCAL_top_cp() == SgFr_gen_cp(LOCAL_top_sg_fr)) {
1887 LOCAL_top_sg_fr = SgFr_next(LOCAL_top_sg_fr);
1888 }
1889 SCH_update_local_or_tops();
1890 CUT_reset_prune_request();
1891 adjust_freeze_registers();
1892 goto shared_fail;
1893 } else {
1894 /* free top dependency frame --> get work */
1895 OrFr_alternative(LOCAL_top_or_fr) = NULL;
1896 UNLOCK_OR_FRAME(LOCAL_top_or_fr);
1897 dep_fr = DepFr_next(LOCAL_top_dep_fr);
1898 FREE_DEPENDENCY_FRAME(LOCAL_top_dep_fr);
1899 LOCAL_top_dep_fr = dep_fr;
1900 adjust_freeze_registers();
1901 SCHEDULER_GET_WORK();
1902 }
1903 }
1904 /* goto getwork */
1905 PREG = B->cp_ap;
1906 PREFETCH_OP(PREG);
1907 TR = B->cp_tr;
1908 SET_BB(B);
1909 GONext();
1910 } else
1911#endif /* YAPOR */
1912
1913#ifdef THREADS_CONSUMER_SHARING
1914complete_all:
1915#endif /* THREADS_CONSUMER_SHARING */
1916 {
1917 /* complete all */
1918 sg_fr_ptr sg_fr;
1919
1920#ifdef DETERMINISTIC_TABLING
1921 if (IS_DET_GEN_CP(B))
1922 sg_fr = DET_GEN_CP(B)->cp_sg_fr;
1923 else
1924#endif /* DETERMINISTIC_TABLING */
1925 sg_fr = GEN_CP(B)->cp_sg_fr;
1926 private_completion(sg_fr);
1927#ifdef THREADS_CONSUMER_SHARING
1928 if (IS_BATCHED_GEN_CP(B) || SgFr_gen_worker(sg_fr) != worker_id) { /* if it is an gen_cons node then all the answers were already consumed */
1929#else
1930 if (IS_BATCHED_GEN_CP(B)) {
1931#endif /*THREADS_CONSUMER_SHARING */
1932 /* backtrack */
1933 B = B->cp_b;
1934 SET_BB(PROTECT_FROZEN_B(B));
1935 goto fail;
1936 } else {
1937 /* subgoal completed */
1938 ans_node = SgFr_first_answer(sg_fr);
1939 if (ans_node == NULL) {
1940 /* no answers --> fail */
1941 B = B->cp_b;
1942 SET_BB(PROTECT_FROZEN_B(B));
1943 goto fail;
1944 }
1945 TABLING_ERROR_CHECKING(completion, TR != B->cp_tr && !IsPairTerm((CELL)TrailTerm(TR - 1)));
1946 TABLING_ERROR_CHECKING(completion, TR != B->cp_tr && (tr_fr_ptr) RepPair((CELL)TrailTerm(TR - 1)) != B->cp_tr);
1947 pop_generator_node(SgFr_arity(sg_fr));
1948 if (ans_node == SgFr_answer_trie(sg_fr)) {
1949 /* yes answer --> procceed */
1950 PREG = (yamop *) CPREG;
1951 PREFETCH_OP(PREG);
1952 YENV = ENV;
1953 GONext();
1954 } else {
1955 /* answers -> get first answer */
1956 tab_ent_ptr tab_ent = SgFr_tab_ent(sg_fr);
1957#ifdef LIMIT_TABLING
1958 SgFr_state(sg_fr)++; /* complete --> complete_in_use */
1959 remove_from_global_sg_fr_list(sg_fr);
1960 TRAIL_FRAME(sg_fr);
1961#endif /* LIMIT_TABLING */
1962 if (IsMode_LoadAnswers(TabEnt_mode(tab_ent))) {
1963 /* load answers from the trie */
1964 if(TrNode_child(ans_node) != NULL) {
1965 store_loader_node(tab_ent, ans_node);
1966 }
1967 PREG = (yamop *) CPREG;
1968 PREFETCH_OP(PREG);
1969 load_answer(ans_node, YENV);
1970 YENV = ENV;
1971 GONext();
1972 } else {
1973#if defined(THREADS_FULL_SHARING) || defined(THREADS_CONSUMER_SHARING)
1974 LOCK_SG_FR(sg_fr);
1975 if (SgFr_active_workers(sg_fr) > 0) {
1976 /* load answers from the trie */
1977 UNLOCK_SG_FR(sg_fr);
1978 if(TrNode_child(ans_node) != NULL) {
1979 store_loader_node(tab_ent, ans_node);
1980 }
1981 PREG = (yamop *) CPREG;
1982 PREFETCH_OP(PREG);
1983 load_answer(ans_node, YENV);
1984 YENV = ENV;
1985 GONext();
1986 }
1987#endif /* THREADS_FULL_SHARING || THREADS_CONSUMER_SHARING */
1988 /* execute compiled code from the trie */
1989#if defined(THREADS_FULL_SHARING) || defined(THREADS_CONSUMER_SHARING)
1990 if (SgFr_sg_ent_state(sg_fr) < compiled)
1991#else
1992 LOCK_SG_FR(sg_fr);
1993 if (SgFr_state(sg_fr) < compiled)
1994#endif /* THREADS_FULL_SHARING || THREADS_CONSUMER_SHARING */
1995 update_answer_trie(sg_fr);
1996 UNLOCK_SG_FR(sg_fr);
1997 PREG = (yamop *) TrNode_child(SgFr_answer_trie(sg_fr));
1998 PREFETCH_OP(PREG);
1999 *--YENV = 0; /* vars_arity */
2000 *--YENV = 0; /* heap_arity */
2001 GONext();
2002 }
2003 }
2004 }
2005 }
2006 END_PREFETCH()
2007 ENDBOp();
2008
2009
2010
2011/************************************************************************
2012** table_answer_resolution_completion **
2013************************************************************************/
2014
2015#ifdef THREADS_CONSUMER_SHARING
2016 BOp(table_answer_resolution_completion, Otapl)
2017answer_resolution_completion:
2018{
2019 INIT_PREFETCH()
2020 int do_not_complete_tables;
2021 int wid = worker_id ;
2022 do {
2023 dep_fr_ptr dep_fr;
2024 ans_node_ptr ans_node;
2025
2026
2027 do_not_complete_tables = 0; /* 0 - complete all the tables 1 - do not complete all the tables */
2028 if (B->cp_ap == ANSWER_RESOLUTION_COMPLETION ){
2029 /* generator consumer node (external node) */
2030 if ((IS_BATCHED_GEN_CP(B) && (EQUAL_OR_YOUNGER_CP(B_FZ, B) && B != DepFr_leader_cp(LOCAL_top_dep_fr))) ||
2031 (B != DepFr_leader_cp(LOCAL_top_dep_fr))) {
2032 /* not leader on that node */
2033 INFO_THREADS("ans_reso_com (1) : not leader on that node dep_fr = %p leader_node =%p", LOCAL_top_dep_fr, GEN_CP(DepFr_leader_cp(LOCAL_top_dep_fr))->cp_dep_fr);
2034 ThDepFr_state(GLOBAL_th_dep_fr(wid)) = working;
2035 B->cp_ap = ANSWER_RESOLUTION;
2036 goto answer_resolution;
2037 }
2038 /* leader on that node */
2039 dep_fr = GEN_CP(B)->cp_dep_fr;
2040 ans_node = DepFr_last_answer(dep_fr);
2041 if (TrNode_child(ans_node)) {
2042 /* unconsumed answer */
2043 ThDepFr_state(GLOBAL_th_dep_fr(wid)) = working;
2044 ans_node = DepFr_last_answer(dep_fr) = TrNode_child(ans_node);
2045 INFO_THREADS("ans_reso_com (2) : consume_answer =%p dep_fr = %p leader_node =%p", ans_node, dep_fr, GEN_CP(DepFr_leader_cp(dep_fr))->cp_dep_fr);
2046 consume_answer_and_procceed(dep_fr, ans_node);
2047 }
2048
2049 sg_fr_ptr sg_fr = GEN_CP(B)->cp_sg_fr;
2050 if (SgFr_sg_ent_state(sg_fr) < complete || (SgFr_sg_ent_state(sg_fr) >= complete && TrNode_child(ans_node)!= NULL))
2051 do_not_complete_tables = 1;
2052
2053 } else { /* using the B->cp_ap == ANSWER_RESOLUTION_COMPLETION to distinguish gen_cons nodes from gen */
2054 /* generator node */
2055 if (IS_BATCHED_GEN_CP(B)) {
2056 if (EQUAL_OR_YOUNGER_CP(B_FZ, B) && B != DepFr_leader_cp(LOCAL_top_dep_fr)) {
2057 /* not leader on that node */
2058 ThDepFr_state(GLOBAL_th_dep_fr(wid)) = working;
2059 B->cp_ap = NULL;
2060 B = B->cp_b;
2061 goto fail;
2062 }
2063 } else {
2064 if (B != DepFr_leader_cp(LOCAL_top_dep_fr)) {
2065 /* not leader on that node */
2066 ThDepFr_state(GLOBAL_th_dep_fr(wid)) = working;
2067 B->cp_ap = ANSWER_RESOLUTION;
2068 B = B->cp_b;
2069 INFO_THREADS("ans_reso_com (3) : not leader on that node dep_fr = %p leader_node =%p", LOCAL_top_dep_fr, GEN_CP(DepFr_leader_cp(LOCAL_top_dep_fr))->cp_dep_fr);
2070 goto fail;
2071 }
2072 }
2073 }
2074
2075 /* leader on that node */
2076
2077 /* no unconsumed answers */
2078
2079 dep_fr = LOCAL_top_dep_fr;
2080
2081 /* check for dependency frames with unconsumed answers */
2082 while (YOUNGER_CP(DepFr_cons_cp(dep_fr), B)) {
2083 ans_node = DepFr_last_answer(dep_fr);
2084 if (TrNode_child(ans_node)) {
2085 ThDepFr_state(GLOBAL_th_dep_fr(wid)) = working;
2086 /*dependency frame with unconsumed answers */
2087 ans_node = DepFr_last_answer(dep_fr) = TrNode_child(ans_node);
2088 if (IS_BATCHED_GEN_CP(B))
2089 DepFr_backchain_cp(dep_fr) = B->cp_b;
2090 else
2091 DepFr_backchain_cp(dep_fr) = B;
2092
2093
2094
2095 /*rebind variables, update registers, consume answer and procceed */
2096
2097 TABLING_ERROR_CHECKING(answer_resolution_completion, EQUAL_OR_YOUNGER_CP(B, DepFr_cons_cp(dep_fr)));
2098 TABLING_ERROR_CHECKING(answer_resolution_completion, B->cp_tr > DepFr_cons_cp(dep_fr)->cp_tr);
2099 rebind_variables(DepFr_cons_cp(dep_fr)->cp_tr,B->cp_tr); //don't know if it is the same unbind_variables(DepFr_cons_cp(dep_fr)->cp_tr, B->cp_tr);
2100
2101 TABLING_ERROR_CHECKING(answer_resolution_completion, TR != B->cp_tr && !IsPairTerm((CELL)TrailTerm(TR - 1)));
2102 TABLING_ERROR_CHECKING(answer_resolution_completion, TR != B->cp_tr && (tr_fr_ptr) RepPair((CELL)TrailTerm(TR - 1)) != B->cp_tr);
2103 B = DepFr_cons_cp(dep_fr);
2104 TR = TR_FZ;
2105 if (TR != B->cp_tr)
2106 TRAIL_LINK(B->cp_tr);
2107 INFO_THREADS("ans_reso_com (4) : consume_answer =%p dep_fr = %p leader_node =%p", ans_node, dep_fr, GEN_CP(DepFr_leader_cp(dep_fr))->cp_dep_fr);
2108 consume_answer_and_procceed(dep_fr, ans_node);
2109 }
2110
2111
2112 if (DepFr_external(dep_fr) == TRUE){
2113 sg_fr_ptr sg_fr = GEN_CP(DepFr_cons_cp(dep_fr))->cp_sg_fr;
2114 if (SgFr_sg_ent_state(sg_fr) < complete || (SgFr_sg_ent_state(sg_fr) >= complete && TrNode_child(ans_node)!= NULL))
2115 do_not_complete_tables = 1;
2116
2117 }
2118 dep_fr = DepFr_next(dep_fr);
2119 }
2120
2121 /******************************** a terminaƧao das threads *************************************/
2122
2123 if (do_not_complete_tables == 1){
2124 /*all the dependency frames have consumed all answers and we have external tables */
2125 if (ThDepFr_next(GLOBAL_th_dep_fr(wid)) == wid)
2126 /* worker_id is not inside an SCC */
2127 continue;
2128
2129 if (ThDepFr_state(GLOBAL_th_dep_fr(wid)) == working) {
2130 int c_wid = ThDepFr_next(GLOBAL_th_dep_fr(wid));
2131 do {
2132 ThDepFr_terminator(GLOBAL_th_dep_fr(c_wid)) = 1;
2133 c_wid = ThDepFr_next(GLOBAL_th_dep_fr(c_wid));
2134 }while(c_wid != wid);
2135 ThDepFr_terminator(GLOBAL_th_dep_fr(wid)) = 1;
2136 ThDepFr_state(GLOBAL_th_dep_fr(wid)) = idle;
2137
2138 }else if (ThDepFr_state(GLOBAL_th_dep_fr(wid)) == idle){
2139 int l_wid = wid; /* leader wid */
2140 int c_wid = ThDepFr_next(GLOBAL_th_dep_fr(wid));
2141 int jump_state = TRUE;
2142 do{
2143 if (ThDepFr_state(GLOBAL_th_dep_fr(c_wid)) != idle){
2144 jump_state = FALSE;
2145 break;
2146 } else
2147 if (l_wid > c_wid)
2148 l_wid = c_wid;
2149 c_wid = ThDepFr_next(GLOBAL_th_dep_fr(c_wid));
2150 } while(c_wid != wid);
2151
2152 if (jump_state && l_wid == wid){
2153 /* wid is the current leader thread */
2154 ThDepFr_terminator(GLOBAL_th_dep_fr(wid)) = 0;
2155 c_wid = ThDepFr_next(GLOBAL_th_dep_fr(wid));
2156 do {
2157 dep_fr_ptr remote_dep_fr = REMOTE_top_dep_fr(c_wid);
2158 while(YOUNGER_CP(DepFr_cons_cp(remote_dep_fr),DepFr_leader_cp(REMOTE_top_dep_fr(c_wid)))){
2159 if (TrNode_child(DepFr_last_answer(remote_dep_fr))){
2160 /* dependency frame with unconsumed answers */
2161 jump_state = FALSE;
2162 break;
2163 }
2164 remote_dep_fr = DepFr_next(remote_dep_fr);
2165 }
2166 if (ThDepFr_state(GLOBAL_th_dep_fr(c_wid)) != idle){
2167 jump_state = FALSE;
2168 break;
2169 }
2170 c_wid = ThDepFr_next(GLOBAL_th_dep_fr(c_wid));
2171 } while(c_wid != wid);
2172 }
2173
2174 if (jump_state && ThDepFr_terminator(GLOBAL_th_dep_fr(wid)) == 0){
2175 c_wid = ThDepFr_next(GLOBAL_th_dep_fr(wid));
2176 do {
2177 ThDepFr_state(GLOBAL_th_dep_fr(c_wid)) = completing;
2178 c_wid = ThDepFr_next(GLOBAL_th_dep_fr(c_wid));
2179 }while(c_wid != wid);
2180 ThDepFr_state(GLOBAL_th_dep_fr(wid)) = completing;
2181 }
2182 }else if (ThDepFr_state(GLOBAL_th_dep_fr(wid)) == completing){
2183 INFO_THREADS("ans_reso_com (5) : completing thread_state =%d",ThDepFr_state(GLOBAL_th_dep_fr(wid)));
2184 break; /*do_not_complete_tables = 0; -- same as "break;" */
2185 }
2186 }
2187 } while(do_not_complete_tables);
2188
2189 END_PREFETCH()
2190 INFO_THREADS("ans_reso_com (6) : completing thread_state =%d",ThDepFr_state(GLOBAL_th_dep_fr(worker_id)));
2191
2192 goto complete_all;
2193}
2194
2195 ENDBOp();
2196#endif /* THREADS_CONSUMER_SHARING */
Definition: tab.structs.h:22
Definition: amidefs.h:264