23#include "tab.macros.h"
35#ifdef GLOBAL_TRIE_FOR_SUBTERMS
40 int *, CELL **USES_REGS);
47 Term,
int *USES_REGS);
48#ifdef GLOBAL_TRIE_FOR_SUBTERMS
50subgoal_search_global_trie_terms_loop(Term,
int *, CELL **, CELL *USES_REGS);
51static inline gt_node_ptr answer_search_global_trie_terms_loop(Term,
int *,
54static inline gt_node_ptr subgoal_search_global_trie_loop(Term,
int *,
56static inline gt_node_ptr answer_search_global_trie_loop(Term,
int *USES_REGS);
58static inline CELL *load_answer_loop(
ans_node_ptr USES_REGS);
59static inline CELL *load_substitution_loop(
gt_node_ptr,
int *, CELL *USES_REGS);
60static inline CELL *exec_substitution_loop(
gt_node_ptr, CELL **,
62#ifdef MODE_DIRECTED_TABLING
71#ifdef TABLING_INNER_CUTS
79#ifdef GLOBAL_TRIE_FOR_SUBTERMS
80static void free_global_trie_branch(
gt_node_ptr,
int USES_REGS);
82static void free_global_trie_branch(
gt_node_ptr USES_REGS);
84static void traverse_subgoal_trie(
sg_node_ptr,
char *,
int,
int *,
int,
86static void traverse_answer_trie(
ans_node_ptr,
char *,
int,
int *,
int,
int,
88static void traverse_global_trie(
gt_node_ptr,
char *,
int,
int *,
int,
90static void traverse_global_trie_for_term(
gt_node_ptr,
char *,
int *,
int *,
91 int *,
int USES_REGS);
92static inline void traverse_trie_node(Term,
char *,
int *,
int *,
int *,
94static inline void traverse_update_arity(
char *,
int *,
int *);
100static struct trie_statistics {
104 long subgoals_incomplete;
105 long subgoal_trie_nodes;
107#ifdef TABLING_INNER_CUTS
112 long answer_trie_nodes;
113 long global_trie_terms;
114 long global_trie_nodes;
115 long global_trie_references;
118trie_stats[MAX_THREADS];
120#define TrStat_out trie_stats[worker_id].out
121#define TrStat_show trie_stats[worker_id].show
122#define TrStat_subgoals trie_stats[worker_id].subgoals
123#define TrStat_sg_incomplete trie_stats[worker_id].subgoals_incomplete
124#define TrStat_sg_nodes trie_stats[worker_id].subgoal_trie_nodes
125#define TrStat_answers trie_stats[worker_id].answers
126#define TrStat_answers_true trie_stats[worker_id].answers_true
127#define TrStat_answers_no trie_stats[worker_id].answers_no
128#define TrStat_answers_pruned trie_stats[worker_id].answers_pruned
129#define TrStat_ans_nodes trie_stats[worker_id].answer_trie_nodes
130#define TrStat_gt_terms trie_stats[worker_id].global_trie_terms
131#define TrStat_gt_nodes trie_stats[worker_id].global_trie_nodes
132#define TrStat_gt_refs trie_stats[worker_id].global_trie_references
136#define TrStat_out trie_stats.out
137#define TrStat_show trie_stats.show
138#define TrStat_subgoals trie_stats.subgoals
139#define TrStat_sg_incomplete trie_stats.subgoals_incomplete
140#define TrStat_sg_nodes trie_stats.subgoal_trie_nodes
141#define TrStat_answers trie_stats.answers
142#define TrStat_answers_true trie_stats.answers_true
143#define TrStat_answers_no trie_stats.answers_no
144#define TrStat_answers_pruned trie_stats.answers_pruned
145#define TrStat_ans_nodes trie_stats.answer_trie_nodes
146#define TrStat_gt_terms trie_stats.global_trie_terms
147#define TrStat_gt_nodes trie_stats.global_trie_nodes
148#define TrStat_gt_refs trie_stats.global_trie_references
151#if defined(THREADS_SUBGOAL_SHARING) || defined(THREADS_FULL_SHARING) || \
152 defined(THREADS_CONSUMER_SHARING)
153#define IF_ABOLISH_SUBGOAL_TRIE_SHARED_DATA_STRUCTURES \
154 if (GLOBAL_NOfThreads == 1)
156#define IF_ABOLISH_SUBGOAL_TRIE_SHARED_DATA_STRUCTURES
160#if defined(THREADS_FULL_SHARING) || defined(THREADS_CONSUMER_SHARING)
161#define IF_ABOLISH_ANSWER_TRIE_SHARED_DATA_STRUCTURES \
162 if (GLOBAL_NOfThreads == 1)
164#define IF_ABOLISH_ANSWER_TRIE_SHARED_DATA_STRUCTURES
167#define SHOW_TABLE_STR_ARRAY_SIZE 100000
168#define SHOW_TABLE_ARITY_ARRAY_SIZE 10000
169#define SHOW_TABLE_STRUCTURE( ...) \
170 if (TrStat_show == SHOW_MODE_STRUCTURE) \
171 fprintf(TrStat_out, __VA_ARGS__ )
173#define CHECK_DECREMENT_GLOBAL_TRIE_REFERENCE(REF, MODE) \
174 if (MODE == TRAVERSE_MODE_NORMAL && IsVarTerm(REF) && \
175 REF > VarIndexOfTableTerm(MAX_TABLE_VARS)) { \
176 register gt_node_ptr gt_node = (gt_node_ptr)(REF); \
177 TrNode_child(gt_node) = \
178 (gt_node_ptr)((uintptr_t)TrNode_child(gt_node) - 1); \
179 if (TrNode_child(gt_node) == 0) \
180 FREE_GLOBAL_TRIE_BRANCH(gt_node, TRAVERSE_MODE_NORMAL); \
182#ifdef GLOBAL_TRIE_FOR_SUBTERMS
183#define CHECK_DECREMENT_GLOBAL_TRIE_FOR_SUBTERMS_REFERENCE(REF, MODE) \
184 CHECK_DECREMENT_GLOBAL_TRIE_REFERENCE(REF, MODE)
185#define FREE_GLOBAL_TRIE_BRANCH(NODE, MODE) \
186 free_global_trie_branch(NODE, MODE PASS_REGS)
188#define CHECK_DECREMENT_GLOBAL_TRIE_FOR_SUBTERMS_REFERENCE(REF, MODE)
189#define FREE_GLOBAL_TRIE_BRANCH(NODE, MODE) \
190 free_global_trie_branch(NODE PASS_REGS)
196#ifdef TRIE_RATIONAL_TERMS
197#include "tab.rational.h"
204#define INCLUDE_SUBGOAL_TRIE_CHECK_INSERT
206#define INCLUDE_ANSWER_TRIE_CHECK_INSERT
207#define INCLUDE_GLOBAL_TRIE_CHECK_INSERT
208#include "tab.tries.h"
209#undef INCLUDE_GLOBAL_TRIE_CHECK_INSERT
210#undef INCLUDE_ANSWER_TRIE_CHECK_INSERT
211#undef INCLUDE_SUBGOAL_TRIE_CHECK_INSERT
213#define MODE_GLOBAL_TRIE_ENTRY
214#define INCLUDE_SUBGOAL_TRIE_CHECK_INSERT
216#define INCLUDE_ANSWER_TRIE_CHECK_INSERT
218#ifdef GLOBAL_TRIE_FOR_SUBTERMS
219#define INCLUDE_GLOBAL_TRIE_CHECK_INSERT
222#include "tab.tries.h"
223#undef INCLUDE_GLOBAL_TRIE_CHECK_INSERT
224#undef INCLUDE_ANSWER_TRIE_CHECK_INSERT
225#undef INCLUDE_SUBGOAL_TRIE_CHECK_INSERT
226#undef MODE_GLOBAL_TRIE_ENTRY
228#define INCLUDE_SUBGOAL_SEARCH_LOOP
229#define INCLUDE_ANSWER_SEARCH_LOOP
230#define INCLUDE_LOAD_ANSWER_LOOP
231#include "tab.tries.h"
232#undef INCLUDE_LOAD_ANSWER_LOOP
233#undef INCLUDE_ANSWER_SEARCH_LOOP
234#undef INCLUDE_SUBGOAL_SEARCH_LOOP
236#define MODE_TERMS_LOOP
237#define INCLUDE_SUBGOAL_SEARCH_LOOP
238#define INCLUDE_ANSWER_SEARCH_LOOP
239#ifdef TRIE_RATIONAL_TERMS
240#undef TRIE_RATIONAL_TERMS
241#include "tab.tries.h"
242#define TRIE_RATIONAL_TERMS
244#include "tab.tries.h"
246#undef INCLUDE_ANSWER_SEARCH_LOOP
247#undef INCLUDE_SUBGOAL_SEARCH_LOOP
248#undef MODE_TERMS_LOOP
250#define MODE_GLOBAL_TRIE_LOOP
251#define INCLUDE_SUBGOAL_SEARCH_LOOP
253#define INCLUDE_ANSWER_SEARCH_LOOP
255#define INCLUDE_LOAD_ANSWER_LOOP
256#ifdef TRIE_RATIONAL_TERMS
257#undef TRIE_RATIONAL_TERMS
258#include "tab.tries.h"
259#define TRIE_RATIONAL_TERMS
261#include "tab.tries.h"
263#undef INCLUDE_LOAD_ANSWER_LOOP
264#undef INCLUDE_ANSWER_SEARCH_LOOP
265#undef INCLUDE_SUBGOAL_SEARCH_LOOP
266#undef MODE_GLOBAL_TRIE_LOOP
268#ifdef MODE_DIRECTED_TABLING
269#define INCLUDE_ANSWER_SEARCH_MODE_DIRECTED
270#include "tab.tries.h"
271#undef INCLUDE_ANSWER_SEARCH_MODE_DIRECTED
274static inline CELL *exec_substitution_loop(
gt_node_ptr current_node,
275 CELL **stack_vars_ptr,
276 CELL *stack_terms USES_REGS) {
315 CELL *stack_vars = *stack_vars_ptr;
316 CELL *stack_terms_limit = (CELL *)TR;
317#ifdef TRIE_COMPACT_PAIRS
318#define stack_terms_base ((CELL *)LOCAL_TrailTop)
319 int stack_terms_pair_offset = 0;
321 Term t = TrNode_entry(current_node);
322 current_node = TrNode_parent(current_node);
326#ifdef GLOBAL_TRIE_FOR_SUBTERMS
327 if (t > VarIndexOfTableTerm(MAX_TABLE_VARS)) {
328 stack_terms = exec_substitution_loop((
gt_node_ptr)t, &stack_vars,
329 stack_terms PASS_REGS);
333 int var_index = VarIndexOfTableTerm(t);
334 int vars_arity = *stack_vars;
336 if (var_index >= vars_arity) {
337 while (vars_arity < var_index) {
343 *stack_vars = vars_arity;
346 CELL aux_sub, aux_var, *vars_ptr;
347 vars_ptr = stack_vars + vars_arity - var_index;
348 aux_sub = *((CELL *)t);
353 if (aux_sub > aux_var) {
354 if ((CELL *)aux_sub <= HR) {
355 Bind_Global((CELL *)aux_sub, aux_var);
356 }
else if ((CELL *)aux_var <= HR) {
357 Bind_Local((CELL *)aux_sub, aux_var);
359 Bind_Local((CELL *)aux_var, aux_sub);
363 if ((CELL *)aux_var <= HR) {
364 Bind_Global((CELL *)aux_var, aux_sub);
366 }
else if ((CELL *)aux_sub <= HR) {
367 Bind_Local((CELL *)aux_var, aux_sub);
370 Bind_Local((CELL *)aux_sub, aux_var);
375 AUX_STACK_CHECK_EXPAND(stack_terms, stack_terms_limit);
376 STACK_PUSH_UP(t, stack_terms);
378 }
else if (IsAtomOrIntTerm(t)) {
379 AUX_STACK_CHECK_EXPAND(stack_terms, stack_terms_limit);
380 STACK_PUSH_UP(t, stack_terms);
381 }
else if (IsPairTerm(t)) {
382#ifdef TRIE_COMPACT_PAIRS
383 if (t == CompactPairInit) {
384 Term *stack_aux = stack_terms_base - stack_terms_pair_offset;
385 Term head, tail = STACK_POP_UP(stack_aux);
386 while (STACK_NOT_EMPTY(stack_aux, stack_terms)) {
387 head = STACK_POP_UP(stack_aux);
388 tail = MkPairTerm(head, tail);
390 stack_terms = stack_terms_base - stack_terms_pair_offset;
391 stack_terms_pair_offset = (int)STACK_POP_DOWN(stack_terms);
392 STACK_PUSH_UP(tail, stack_terms);
395 AUX_STACK_CHECK_EXPAND(stack_terms, stack_terms_limit + 1);
396 last = STACK_POP_DOWN(stack_terms);
397 STACK_PUSH_UP(stack_terms_pair_offset, stack_terms);
398 stack_terms_pair_offset = (int)(stack_terms_base - stack_terms);
399 if (t == CompactPairEndList)
400 STACK_PUSH_UP(TermNil, stack_terms);
401 STACK_PUSH_UP(last, stack_terms);
404 Term head = STACK_POP_DOWN(stack_terms);
405 Term tail = STACK_POP_DOWN(stack_terms);
406 t = MkPairTerm(head, tail);
407 STACK_PUSH_UP(t, stack_terms);
409 }
else if (IsApplTerm(t)) {
411 if (f == FunctorDouble) {
413 Term t_dbl[
sizeof(Float) /
sizeof(Term)];
416 t = TrNode_entry(current_node);
417 current_node = TrNode_parent(current_node);
419#if SIZEOF_DOUBLE == 2 * SIZEOF_INT_P
420 t = TrNode_entry(current_node);
421 current_node = TrNode_parent(current_node);
424 current_node = TrNode_parent(current_node);
425 t = MkFloatTerm(u.dbl);
426 }
else if (f == FunctorLongInt) {
427 Int li = TrNode_entry(current_node);
428 current_node = TrNode_parent(current_node);
429 current_node = TrNode_parent(current_node);
430 t = MkLongIntTerm(li);
432 int f_arity = ArityOfFunctor(f);
433 t = Yap_MkApplTerm(f, f_arity, stack_terms);
434 stack_terms += f_arity;
436 AUX_STACK_CHECK_EXPAND(stack_terms, stack_terms_limit);
437 STACK_PUSH_UP(t, stack_terms);
439 t = TrNode_entry(current_node);
440 current_node = TrNode_parent(current_node);
441 }
while (current_node);
443 *stack_vars_ptr = stack_vars;
446#ifdef TRIE_COMPACT_PAIRS
447#undef stack_terms_base
452#ifdef TABLING_INNER_CUTS
453static int update_answer_trie_branch(
ans_node_ptr previous_node,
456 if (!IS_ANSWER_LEAF_NODE(current_node)) {
457 if (TrNode_child(current_node)) {
458 TrNode_instr(TrNode_child(current_node)) -= 1;
459 update_answer_trie_branch(NULL, TrNode_child(current_node));
460 if (TrNode_child(current_node))
461 goto update_next_trie_branch;
465 TrNode_next(previous_node) = TrNode_next(current_node);
466 FREE_ANSWER_TRIE_NODE(current_node);
467 if (TrNode_next(previous_node)) {
468 return update_answer_trie_branch(previous_node,
469 TrNode_next(previous_node));
471 TrNode_instr(previous_node) -= 2;
475 TrNode_child(TrNode_parent(current_node)) = TrNode_next(current_node);
476 if (TrNode_next(current_node)) {
477 TrNode_instr(TrNode_next(current_node)) -= 1;
478 update_answer_trie_branch(NULL, TrNode_next(current_node));
480 FREE_ANSWER_TRIE_NODE(current_node);
484update_next_trie_branch:
485 if (TrNode_next(current_node)) {
487 1 + update_answer_trie_branch(current_node, TrNode_next(current_node));
489 TrNode_instr(current_node) -= 2;
493 TrNode_or_arg(current_node) = ltt;
494 TrNode_instr(current_node) = Yap_opcode(TrNode_instr(current_node));
498static int update_answer_trie_branch(
ans_node_ptr current_node) {
500 if (!IS_ANSWER_LEAF_NODE(current_node)) {
501 TrNode_instr(TrNode_child(current_node)) -= 1;
502 update_answer_trie_branch(TrNode_child(current_node));
504 if (TrNode_next(current_node)) {
505 ltt = 1 + update_answer_trie_branch(TrNode_next(current_node));
507 TrNode_instr(current_node) -= 2;
510 TrNode_or_arg(current_node) = ltt;
511 TrNode_instr(current_node) = Yap_opcode(TrNode_instr(current_node));
516static void update_answer_trie_branch(
ans_node_ptr current_node,
int position) {
517 if (!IS_ANSWER_LEAF_NODE(current_node))
518 update_answer_trie_branch(TrNode_child(current_node),
519 TRAVERSE_POSITION_FIRST);
520 if (position == TRAVERSE_POSITION_FIRST) {
523 while (TrNode_next(next)) {
524 update_answer_trie_branch(next,
525 TRAVERSE_POSITION_NEXT);
526 next = TrNode_next(next);
528 update_answer_trie_branch(next,
529 TRAVERSE_POSITION_LAST);
531 position += TRAVERSE_POSITION_LAST;
533 TrNode_instr(current_node) =
534 Yap_opcode(TrNode_instr(current_node) - position);
540#ifdef GLOBAL_TRIE_FOR_SUBTERMS
541static void free_global_trie_branch(
gt_node_ptr current_node,
542 int mode USES_REGS) {
543 Term t = TrNode_entry(current_node);
545static void free_global_trie_branch(
gt_node_ptr current_node USES_REGS) {
549 parent_node = TrNode_parent(current_node);
550 child_node = TrNode_child(parent_node);
551 if (IS_GLOBAL_TRIE_HASH(child_node)) {
555 HASH_ENTRY(TrNode_entry(current_node), Hash_num_buckets(hash));
556 int num_nodes = --Hash_num_nodes(hash);
558 if (child_node != current_node) {
559 while (TrNode_next(child_node) != current_node)
560 child_node = TrNode_next(child_node);
561 TrNode_next(child_node) = TrNode_next(current_node);
562 CHECK_DECREMENT_GLOBAL_TRIE_FOR_SUBTERMS_REFERENCE(t, mode);
563 FREE_GLOBAL_TRIE_NODE(current_node);
565 *
bucket = TrNode_next(current_node);
566 CHECK_DECREMENT_GLOBAL_TRIE_FOR_SUBTERMS_REFERENCE(t, mode);
567 FREE_GLOBAL_TRIE_NODE(current_node);
568 if (num_nodes == 0) {
569 FREE_BUCKETS(Hash_buckets(hash));
570 FREE_GLOBAL_TRIE_HASH(hash);
571 if (parent_node != GLOBAL_root_gt) {
572#ifdef GLOBAL_TRIE_FOR_SUBTERMS
573 if (mode == TRAVERSE_MODE_NORMAL) {
576 if (f == FunctorDouble)
577 mode = TRAVERSE_MODE_DOUBLE;
578 else if (f == FunctorLongInt)
579 mode = TRAVERSE_MODE_LONGINT;
580 else if (f == FunctorBigInt || f == FunctorString)
581 mode = TRAVERSE_MODE_BIGINT_OR_STRING;
583 mode = TRAVERSE_MODE_NORMAL;
585 mode = TRAVERSE_MODE_NORMAL;
586 }
else if (mode == TRAVERSE_MODE_LONGINT)
587 mode = TRAVERSE_MODE_LONGINT_END;
588 }
else if (mode == TRAVERSE_MODE_BIGINT_OR_STRING)
589 mode = TRAVERSE_MODE_BIGINT_OR_STRING_END;
590 else if (mode == TRAVERSE_MODE_DOUBLE)
591#if SIZEOF_DOUBLE == 2 * SIZEOF_INT_P
592 mode = TRAVERSE_MODE_DOUBLE2;
593 else if (mode == TRAVERSE_MODE_DOUBLE2)
595 mode = TRAVERSE_MODE_DOUBLE_END;
597 mode = TRAVERSE_MODE_NORMAL;
599 FREE_GLOBAL_TRIE_BRANCH(parent_node, mode);
601 TrNode_child(parent_node) = NULL;
605else if (child_node != current_node) {
606 while (TrNode_next(child_node) != current_node)
607 child_node = TrNode_next(child_node);
608 TrNode_next(child_node) = TrNode_next(current_node);
609 CHECK_DECREMENT_GLOBAL_TRIE_FOR_SUBTERMS_REFERENCE(t, mode);
610 FREE_GLOBAL_TRIE_NODE(current_node);
612else if (TrNode_next(current_node) == NULL) {
613 CHECK_DECREMENT_GLOBAL_TRIE_FOR_SUBTERMS_REFERENCE(t, mode);
614 FREE_GLOBAL_TRIE_NODE(current_node);
615 if (parent_node != GLOBAL_root_gt) {
616#ifdef GLOBAL_TRIE_FOR_SUBTERMS
617 if (mode == TRAVERSE_MODE_NORMAL) {
620 if (f == FunctorDouble)
621 mode = TRAVERSE_MODE_DOUBLE;
622 else if (f == FunctorLongInt)
623 mode = TRAVERSE_MODE_LONGINT;
624 else if (f == FunctorBigInt || f == FunctorString)
625 mode = TRAVERSE_MODE_BIGINT_OR_STRING;
627 mode = TRAVERSE_MODE_NORMAL;
629 mode = TRAVERSE_MODE_NORMAL;
630 }
else if (mode == TRAVERSE_MODE_LONGINT) {
631 mode = TRAVERSE_MODE_LONGINT_END;
632 }
else if (mode == TRAVERSE_MODE_BIGINT_OR_STRING) {
633 mode = TRAVERSE_MODE_BIGINT_OR_STRING_END;
634 }
else if (mode == TRAVERSE_MODE_DOUBLE)
635#if SIZEOF_DOUBLE == 2 * SIZEOF_INT_P
636 mode = TRAVERSE_MODE_DOUBLE2;
637 else if (mode == TRAVERSE_MODE_DOUBLE2)
639 mode = TRAVERSE_MODE_DOUBLE_END;
641 mode = TRAVERSE_MODE_NORMAL;
643 FREE_GLOBAL_TRIE_BRANCH(parent_node, mode);
645 TrNode_child(parent_node) = NULL;
648 TrNode_child(parent_node) = TrNode_next(current_node);
649 CHECK_DECREMENT_GLOBAL_TRIE_FOR_SUBTERMS_REFERENCE(t, mode);
650 FREE_GLOBAL_TRIE_NODE(current_node);
655static void traverse_subgoal_trie(
sg_node_ptr current_node,
char *str,
656 int str_index,
int *arity,
int mode,
657 int position USES_REGS) {
658 int *current_arity = NULL, current_str_index = 0, current_mode = 0;
661 if (IS_SUBGOAL_TRIE_HASH(current_node)) {
665 bucket = Hash_buckets(hash);
666 last_bucket =
bucket + Hash_num_buckets(hash);
667 current_arity = (
int *)malloc(
sizeof(
int) * (arity[0] + 1));
668 memcpy(current_arity, arity,
sizeof(
int) * (arity[0] + 1));
671 traverse_subgoal_trie(*
bucket, str, str_index, arity, mode,
672 TRAVERSE_POSITION_FIRST PASS_REGS);
673 memcpy(arity, current_arity,
sizeof(
int) * (current_arity[0] + 1));
674#ifdef TRIE_COMPACT_PAIRS
675 if (arity[arity[0]] == -2 && str[str_index - 1] !=
'[')
676 str[str_index - 1] =
',';
678 if (arity[arity[0]] == -1)
679 str[str_index - 1] =
'|';
682 }
while (++
bucket != last_bucket);
688 if (position == TRAVERSE_POSITION_FIRST) {
689 current_arity = (
int *)malloc(
sizeof(
int) * (arity[0] + 1));
690 memcpy(current_arity, arity,
sizeof(
int) * (arity[0] + 1));
691 current_str_index = str_index;
697 traverse_trie_node(TrNode_entry(current_node), str, &str_index, arity, &mode,
698 TRAVERSE_TYPE_SUBGOAL PASS_REGS);
701 if (IS_SUBGOAL_LEAF_NODE(current_node)) {
702 sg_fr_ptr sg_fr = get_subgoal_frame(current_node);
706 SHOW_TABLE_STRUCTURE(
"%s.\n", str);
708 if (SgFr_first_answer(sg_fr) == NULL) {
709 if (SgFr_state(sg_fr) < complete) {
710 TrStat_sg_incomplete++;
711 SHOW_TABLE_STRUCTURE(
" ---> INCOMPLETE\n");
714 SHOW_TABLE_STRUCTURE(
" NO\n");
716 }
else if (SgFr_first_answer(sg_fr) == SgFr_answer_trie(sg_fr)) {
717 TrStat_answers_true++;
718 SHOW_TABLE_STRUCTURE(
" TRUE\n");
721 traverse_answer_trie(TrNode_child(SgFr_answer_trie(sg_fr)),
722 &str[str_index], 0, arity, 0, TRAVERSE_MODE_NORMAL,
723 TRAVERSE_POSITION_FIRST PASS_REGS);
724 if (SgFr_state(sg_fr) < complete) {
725 TrStat_sg_incomplete++;
726 SHOW_TABLE_STRUCTURE(
" ---> INCOMPLETE\n");
732 traverse_subgoal_trie(TrNode_child(current_node), str, str_index, arity,
733 mode, TRAVERSE_POSITION_FIRST PASS_REGS);
735 if (position == TRAVERSE_POSITION_FIRST) {
736 str_index = current_str_index;
738 current_node = TrNode_next(current_node);
739 while (current_node) {
740 memcpy(arity, current_arity,
sizeof(
int) * (current_arity[0] + 1));
741#ifdef TRIE_COMPACT_PAIRS
742 if (arity[arity[0]] == -2 && str[str_index - 1] !=
'[')
743 str[str_index - 1] =
',';
745 if (arity[arity[0]] == -1)
746 str[str_index - 1] =
'|';
748 traverse_subgoal_trie(current_node, str, str_index, arity, mode,
749 TRAVERSE_POSITION_NEXT PASS_REGS);
750 current_node = TrNode_next(current_node);
757static void traverse_answer_trie(
ans_node_ptr current_node,
char *str,
758 int str_index,
int *arity,
int var_index,
759 int mode,
int position USES_REGS) {
760 int *current_arity = NULL, current_str_index = 0, current_var_index = 0,
764 if (IS_ANSWER_TRIE_HASH(current_node)) {
768 bucket = Hash_buckets(hash);
769 last_bucket =
bucket + Hash_num_buckets(hash);
770 current_arity = (
int *)malloc(
sizeof(
int) * (arity[0] + 1));
771 memcpy(current_arity, arity,
sizeof(
int) * (arity[0] + 1));
774 traverse_answer_trie(*
bucket, str, str_index, arity, var_index, mode,
775 TRAVERSE_POSITION_FIRST PASS_REGS);
776 memcpy(arity, current_arity,
sizeof(
int) * (current_arity[0] + 1));
777#ifdef TRIE_COMPACT_PAIRS
778 if (arity[arity[0]] == -2 && str[str_index - 1] !=
'[')
779 str[str_index - 1] =
',';
781 if (arity[arity[0]] == -1)
782 str[str_index - 1] =
'|';
785 }
while (++
bucket != last_bucket);
791 if (position == TRAVERSE_POSITION_FIRST) {
792 current_arity = (
int *)malloc(
sizeof(
int) * (arity[0] + 1));
793 memcpy(current_arity, arity,
sizeof(
int) * (arity[0] + 1));
794 current_str_index = str_index;
795 current_var_index = var_index;
800 if (arity[0] == 0 && mode == TRAVERSE_MODE_NORMAL) {
801 str_index += sprintf(&str[str_index],
" VAR%d: ", var_index);
807 traverse_trie_node(TrNode_entry(current_node), str, &str_index, arity, &mode,
808 TRAVERSE_TYPE_ANSWER PASS_REGS);
811 if (IS_ANSWER_LEAF_NODE(current_node)) {
814 SHOW_TABLE_STRUCTURE(
"%s\n", str);
816#ifdef TABLING_INNER_CUTS
818 else if (TrNode_child(current_node) == NULL) {
820 TrStat_answers_pruned++;
825 traverse_answer_trie(TrNode_child(current_node), str, str_index, arity,
826 var_index, mode, TRAVERSE_POSITION_FIRST PASS_REGS);
829 if (position == TRAVERSE_POSITION_FIRST) {
830 str_index = current_str_index;
831 var_index = current_var_index;
833 current_node = TrNode_next(current_node);
834 while (current_node) {
835 memcpy(arity, current_arity,
sizeof(
int) * (current_arity[0] + 1));
836#ifdef TRIE_COMPACT_PAIRS
837 if (arity[arity[0]] == -2 && str[str_index - 1] !=
'[')
838 str[str_index - 1] =
',';
840 if (arity[arity[0]] == -1)
841 str[str_index - 1] =
'|';
843 traverse_answer_trie(current_node, str, str_index, arity, var_index, mode,
844 TRAVERSE_POSITION_NEXT PASS_REGS);
845 current_node = TrNode_next(current_node);
853static void traverse_global_trie(
gt_node_ptr current_node,
char *str,
854 int str_index,
int *arity,
int mode,
855 int position USES_REGS) {
856 int *current_arity = NULL, current_str_index = 0, current_mode = 0;
859 if (IS_GLOBAL_TRIE_HASH(current_node)) {
863 bucket = Hash_buckets(hash);
864 last_bucket =
bucket + Hash_num_buckets(hash);
865 current_arity = (
int *)malloc(
sizeof(
int) * (arity[0] + 1));
866 memcpy(current_arity, arity,
sizeof(
int) * (arity[0] + 1));
869 traverse_global_trie(*
bucket, str, str_index, arity, mode,
870 TRAVERSE_POSITION_FIRST PASS_REGS);
871 memcpy(arity, current_arity,
sizeof(
int) * (current_arity[0] + 1));
872#ifdef TRIE_COMPACT_PAIRS
873 if (arity[arity[0]] == -2 && str[str_index - 1] !=
'[')
874 str[str_index - 1] =
',';
876 if (arity[arity[0]] == -1)
877 str[str_index - 1] =
'|';
880 }
while (++
bucket != last_bucket);
886 if (position == TRAVERSE_POSITION_FIRST) {
887 current_arity = (
int *)malloc(
sizeof(
int) * (arity[0] + 1));
888 memcpy(current_arity, arity,
sizeof(
int) * (arity[0] + 1));
889 current_str_index = str_index;
895 traverse_trie_node(TrNode_entry(current_node), str, &str_index, arity, &mode,
896 TRAVERSE_TYPE_GT_SUBGOAL PASS_REGS);
899 if (arity[0] != 0 || mode != TRAVERSE_MODE_NORMAL)
900 traverse_global_trie(TrNode_child(current_node), str, str_index, arity,
901 mode, TRAVERSE_POSITION_FIRST PASS_REGS);
906 SHOW_TABLE_STRUCTURE(
" TERMx" UInt_FORMAT
": %s\n",
907 (CELL)TrNode_child(current_node), str);
911 if (position == TRAVERSE_POSITION_FIRST) {
912 str_index = current_str_index;
914 current_node = TrNode_next(current_node);
915 while (current_node) {
916 memcpy(arity, current_arity,
sizeof(
int) * (current_arity[0] + 1));
917#ifdef TRIE_COMPACT_PAIRS
918 if (arity[arity[0]] == -2 && str[str_index - 1] !=
'[')
919 str[str_index - 1] =
',';
921 if (arity[arity[0]] == -1)
922 str[str_index - 1] =
'|';
924 traverse_global_trie(current_node, str, str_index, arity, mode,
925 TRAVERSE_POSITION_NEXT PASS_REGS);
926 current_node = TrNode_next(current_node);
934static void traverse_global_trie_for_term(
gt_node_ptr current_node,
char *str,
935 int *str_index,
int *arity,
int *mode,
936 int type USES_REGS) {
937 if (TrNode_parent(current_node) != GLOBAL_root_gt)
938 traverse_global_trie_for_term(TrNode_parent(current_node), str, str_index,
939 arity, mode, type PASS_REGS);
940 traverse_trie_node(TrNode_entry(current_node), str, str_index, arity, mode,
945static inline void traverse_trie_node(Term t,
char *str,
int *str_index_ptr,
946 int *arity,
int *mode_ptr,
947 int type USES_REGS) {
948 int mode = *mode_ptr;
949 int str_index = *str_index_ptr;
952 if (mode == TRAVERSE_MODE_DOUBLE) {
953#if SIZEOF_DOUBLE == 2 * SIZEOF_INT_P
955 arity[arity[0]] = (int)t;
956 mode = TRAVERSE_MODE_DOUBLE2;
957 }
else if (mode == TRAVERSE_MODE_DOUBLE2) {
959 Term t_dbl[
sizeof(Float) /
sizeof(Term)];
964 u.t_dbl[1] = (Term)arity[arity[0]];
968 Term t_dbl[
sizeof(Float) /
sizeof(Term)];
973 str_index += sprintf(&str[str_index],
"%.15g", u.dbl);
974 traverse_update_arity(str, &str_index, arity);
975 if (type == TRAVERSE_TYPE_SUBGOAL)
976 mode = TRAVERSE_MODE_NORMAL;
979 mode = TRAVERSE_MODE_DOUBLE_END;
980 }
else if (mode == TRAVERSE_MODE_DOUBLE_END) {
981 mode = TRAVERSE_MODE_NORMAL;
982 }
else if (mode == TRAVERSE_MODE_LONGINT) {
984 str_index += sprintf(&str[str_index], Int_FORMAT, li);
985 traverse_update_arity(str, &str_index, arity);
986 if (type == TRAVERSE_TYPE_SUBGOAL)
987 mode = TRAVERSE_MODE_NORMAL;
990 mode = TRAVERSE_MODE_LONGINT_END;
991 }
else if (mode == TRAVERSE_MODE_LONGINT_END) {
992 mode = TRAVERSE_MODE_NORMAL;
993 }
else if (mode == TRAVERSE_MODE_BIGINT_OR_STRING) {
994 str_index += Yap_OpaqueTermToString(AbsAppl((CELL *)t), str + str_index, 0);
995 traverse_update_arity(str, &str_index, arity);
996 if (type == TRAVERSE_TYPE_SUBGOAL)
997 mode = TRAVERSE_MODE_NORMAL;
1000 mode = TRAVERSE_MODE_BIGINT_OR_STRING_END;
1001 }
else if (mode == TRAVERSE_MODE_BIGINT_OR_STRING_END) {
1002 mode = TRAVERSE_MODE_NORMAL;
1003 }
else if (IsVarTerm(t)) {
1004#ifdef TRIE_RATIONAL_TERMS
1005 if (t > VarIndexOfTableTerm(MAX_TABLE_VARS) &&
1010 str_index += sprintf(&str[str_index],
"**");
1011 traverse_update_arity(str, &str_index, arity);
1014 if (t > VarIndexOfTableTerm(MAX_TABLE_VARS)) {
1018 traverse_global_trie_for_term((
gt_node_ptr)t, str, &str_index, arity,
1019 &mode, type % 2 + 2 PASS_REGS);
1021 if (type == TRAVERSE_TYPE_SUBGOAL || type == TRAVERSE_TYPE_GT_SUBGOAL)
1022 str_index += sprintf(&str[str_index],
"VAR%d", VarIndexOfTableTerm(t));
1025 sprintf(&str[str_index],
"ANSVAR%d", VarIndexOfTableTerm(t));
1026 traverse_update_arity(str, &str_index, arity);
1028 }
else if (IsIntTerm(t)) {
1029 str_index += sprintf(&str[str_index], Int_FORMAT, IntOfTerm(t));
1030 traverse_update_arity(str, &str_index, arity);
1031 }
else if (IsAtomTerm(t)) {
1032#ifndef TRIE_COMPACT_PAIRS
1033 if (arity[arity[0]] == -1 && t == TermNil) {
1034 str[str_index - 1] =
']';
1038 str_index += sprintf(&str[str_index],
"%s", AtomName(AtomOfTerm(t)));
1039 traverse_update_arity(str, &str_index, arity);
1040 }
else if (IsPairTerm(t)) {
1041#ifdef TRIE_COMPACT_PAIRS
1042 if (t == CompactPairEndList)
1043 arity[arity[0]] = -1;
1044 else if (t == CompactPairEndTerm) {
1045 str[str_index - 1] =
'|';
1046 arity[arity[0]] = -1;
1048 if (arity[arity[0]] == -1) {
1049 str[str_index - 1] =
',';
1050 arity[arity[0]] = -2;
1053 str_index += sprintf(&str[str_index],
"[");
1055 arity[arity[0]] = -2;
1057 }
else if (IsApplTerm(t)) {
1059 if (f == FunctorDouble) {
1060 mode = TRAVERSE_MODE_DOUBLE;
1061 }
else if (f == FunctorLongInt) {
1062 mode = TRAVERSE_MODE_LONGINT;
1063 }
else if (f == FunctorBigInt || f == FunctorString) {
1064 mode = TRAVERSE_MODE_BIGINT_OR_STRING;
1065 }
else if (f == FunctorComma) {
1066 if (arity[arity[0]] != -3) {
1067 str_index += sprintf(&str[str_index],
"(");
1070 arity[arity[0]] = -4;
1072 str_index += sprintf(&str[str_index],
"%s(", AtomName(NameOfFunctor(f)));
1074 arity[arity[0]] = ArityOfFunctor(f);
1079 *str_index_ptr = str_index;
1083static inline void traverse_update_arity(
char *str,
int *str_index_ptr,
1085 int str_index = *str_index_ptr;
1087 if (arity[arity[0]] > 0) {
1089 if (arity[arity[0]] == 0) {
1090 str_index += sprintf(&str[str_index],
")");
1093 str_index += sprintf(&str[str_index],
",");
1097 if (arity[arity[0]] == -4) {
1098 str_index += sprintf(&str[str_index],
",");
1099 arity[arity[0]] = -3;
1101 }
else if (arity[arity[0]] == -3) {
1102 str_index += sprintf(&str[str_index],
")");
1104 }
else if (arity[arity[0]] == -2) {
1105#ifdef TRIE_COMPACT_PAIRS
1106 str_index += sprintf(&str[str_index],
",");
1108 str_index += sprintf(&str[str_index],
"|");
1109 arity[arity[0]] = -1;
1112 }
else if (arity[arity[0]] == -1) {
1113 str_index += sprintf(&str[str_index],
"]");
1118 *str_index_ptr = str_index;
1128 int i, subs_arity, pred_arity;
1132#ifdef MODE_DIRECTED_TABLING
1133 int *mode_directed, aux_mode_directed[MAX_TABLE_VARS];
1137 stack_vars = *Yaddr;
1139 pred_arity = preg->y_u.Otapl.s;
1140 tab_ent = preg->y_u.Otapl.te;
1141 current_sg_node = get_insert_subgoal_trie(tab_ent PASS_REGS);
1142 LOCK_SUBGOAL_TRIE(tab_ent);
1144#ifdef MODE_DIRECTED_TABLING
1145 mode_directed = TabEnt_mode_directed(tab_ent);
1146 if (mode_directed) {
1147 int old_subs_arity = subs_arity;
1148 for (i = 1; i <= pred_arity; i++) {
1149 int j = MODE_DIRECTED_GET_ARG(mode_directed[i - 1]) + 1;
1151 subgoal_search_loop(tab_ent, current_sg_node, Deref(XREGS[j]),
1152 &subs_arity, &stack_vars PASS_REGS);
1153 if (subs_arity != old_subs_arity) {
1155 MODE_DIRECTED_GET_MODE(aux_mode_directed[subs_pos - 1]) ==
1156 MODE_DIRECTED_GET_MODE(mode_directed[i - 1])) {
1159 aux_mode_directed[subs_pos - 1] +=
1160 MODE_DIRECTED_SET(subs_arity - old_subs_arity, 0);
1163 aux_mode_directed[subs_pos] =
1164 MODE_DIRECTED_SET(subs_arity - old_subs_arity,
1165 MODE_DIRECTED_GET_MODE(mode_directed[i - 1]));
1168 old_subs_arity = subs_arity;
1173 if (IsMode_GlobalTrie(TabEnt_mode(tab_ent))) {
1174 for (i = 1; i <= pred_arity; i++)
1176 subgoal_search_terms_loop(tab_ent, current_sg_node, Deref(XREGS[i]),
1177 &subs_arity, &stack_vars PASS_REGS);
1179 for (i = 1; i <= pred_arity; i++)
1181 subgoal_search_loop(tab_ent, current_sg_node, Deref(XREGS[i]),
1182 &subs_arity, &stack_vars PASS_REGS);
1185 STACK_PUSH_UP(subs_arity, stack_vars);
1186 *Yaddr = stack_vars++;
1188 while (subs_arity--) {
1189 Term t = STACK_POP_DOWN(stack_vars);
1194 get_insert_subgoal_frame_addr(current_sg_node PASS_REGS);
1196 LOCK_SUBGOAL_NODE(current_sg_node);
1198 if (*sg_fr_end == NULL) {
1200#ifdef MODE_DIRECTED_TABLING
1202 ALLOC_BLOCK(mode_directed, subs_pos *
sizeof(
int),
int);
1203 memcpy((
void *)mode_directed, (
void *)aux_mode_directed,
1204 subs_pos *
sizeof(
int));
1206 mode_directed = NULL;
1208#if !defined(THREADS_FULL_SHARING) && !defined(THREADS_CONSUMER_SHARING)
1209 new_subgoal_frame(sg_fr, preg, mode_directed);
1212 __sync_synchronize();
1214 TAG_AS_SUBGOAL_LEAF_NODE(current_sg_node);
1215 UNLOCK_SUBGOAL_NODE(current_sg_node);
1218 (
sg_ent_ptr)UNTAG_SUBGOAL_NODE(TrNode_sg_ent(current_sg_node));
1219 new_subgoal_frame(sg_fr, sg_ent);
1220#ifdef THREADS_CONSUMER_SHARING
1221 SgFr_state(sg_fr) = ready_external;
1223 SgFr_state(sg_fr) = ready;
1225 if (SgEnt_sg_ent_state(sg_ent) == ready) {
1226 LOCK(SgEnt_lock(sg_ent));
1227 if (SgEnt_sg_ent_state(sg_ent) == ready) {
1228 SgEnt_code(sg_ent) = preg;
1229 SgEnt_init_mode_directed_fields(sg_ent, mode_directed);
1230 SgEnt_sg_ent_state(sg_ent) = evaluating;
1231#ifdef THREADS_CONSUMER_SHARING
1232 SgEnt_gen_worker(sg_ent) = worker_id;
1233 SgFr_state(sg_fr) = ready;
1236 UNLOCK(SgEnt_lock(sg_ent));
1243 UNLOCK_SUBGOAL_NODE(current_sg_node);
1245 sg_fr = (
sg_fr_ptr)UNTAG_SUBGOAL_NODE(*sg_fr_end);
1247 if (SgFr_state(sg_fr) <= ready) {
1248 remove_from_global_sg_fr_list(sg_fr);
1252 UNLOCK_SUBGOAL_TRIE(tab_ent);
1257#define subs_arity *subs_ptr
1264 current_ans_node = SgFr_answer_trie(sg_fr);
1266 if (IsMode_GlobalTrie(TabEnt_mode(SgFr_tab_ent(sg_fr)))) {
1267 for (i = subs_arity; i >= 1; i--) {
1268 TABLING_ERROR_CHECKING(answer_search, IsNonVarTerm(subs_ptr[i]));
1269 current_ans_node = answer_search_terms_loop(
1270 sg_fr, current_ans_node, Deref(subs_ptr[i]), &vars_arity PASS_REGS);
1273 for (i = subs_arity; i >= 1; i--) {
1274 TABLING_ERROR_CHECKING(answer_search, IsNonVarTerm(subs_ptr[i]));
1275 current_ans_node = answer_search_loop(
1276 sg_fr, current_ans_node, Deref(subs_ptr[i]), &vars_arity PASS_REGS);
1281 stack_vars = (CELL *)TR;
1282 while (vars_arity--) {
1283 Term t = STACK_POP_DOWN(stack_vars);
1287 return current_ans_node;
1291#ifdef MODE_DIRECTED_TABLING
1293#define subs_arity *subs_ptr
1296 int i, j, vars_arity;
1301 current_ans_node = SgFr_answer_trie(sg_fr);
1302 invalid_ans_node = NULL;
1303 mode_directed = SgFr_mode_directed(sg_fr);
1307 int mode = MODE_DIRECTED_GET_MODE(mode_directed[j]);
1308 int n_subs = MODE_DIRECTED_GET_ARG(mode_directed[j]);
1310 TABLING_ERROR_CHECKING(answer_search, IsNonVarTerm(subs_ptr[i]));
1311 if (mode == MODE_DIRECTED_INDEX || mode == MODE_DIRECTED_ALL) {
1312 current_ans_node = answer_search_loop(
1313 sg_fr, current_ans_node, Deref(subs_ptr[i]), &vars_arity PASS_REGS);
1315 LOCK_ANSWER_NODE(current_ans_node);
1316 if (TrNode_child(current_ans_node) == NULL) {
1317#if defined(THREADS_FULL_SHARING) || defined(THREADS_CONSUMER_SHARING)
1322 AnsNode_init_lock_field(&virtual_ans_node);
1323 TrNode_parent(&virtual_ans_node) = NULL;
1324 TrNode_child(&virtual_ans_node) = NULL;
1326 answer_search_loop(sg_fr, &virtual_ans_node, Deref(subs_ptr[i]),
1327 &vars_arity PASS_REGS);
1328 TrNode_child(parent_ans_node) = TrNode_child(&virtual_ans_node);
1329 TrNode_parent(TrNode_child(&virtual_ans_node)) = parent_ans_node;
1332 answer_search_loop(sg_fr, current_ans_node, Deref(subs_ptr[i]),
1333 &vars_arity PASS_REGS);
1335 }
else if (mode == MODE_DIRECTED_MIN || mode == MODE_DIRECTED_MAX) {
1337 invalid_ans_node = TrNode_child(
1339 current_ans_node = answer_search_min_max(
1340 sg_fr, current_ans_node, Deref(subs_ptr[i]), mode PASS_REGS);
1341 if (invalid_ans_node ==
1342 TrNode_child(parent_ans_node))
1343 invalid_ans_node = NULL;
1344 }
else if (mode == MODE_DIRECTED_SUM) {
1345 invalid_ans_node = TrNode_child(current_ans_node);
1346 current_ans_node = answer_search_sum(sg_fr, current_ans_node,
1347 Deref(subs_ptr[i]) PASS_REGS);
1348 }
else if (mode == MODE_DIRECTED_LAST) {
1349#if defined(THREADS_FULL_SHARING) || defined(THREADS_CONSUMER_SHARING)
1354 invalid_ans_node = TrNode_child(parent_ans_node);
1355 AnsNode_init_lock_field(&virtual_ans_node);
1356 TrNode_parent(&virtual_ans_node) = NULL;
1357 TrNode_child(&virtual_ans_node) = NULL;
1359 answer_search_loop(sg_fr, &virtual_ans_node, Deref(subs_ptr[i]),
1360 &vars_arity PASS_REGS);
1361 TrNode_child(parent_ans_node) = TrNode_child(&virtual_ans_node);
1362 TrNode_parent(TrNode_child(&virtual_ans_node)) = parent_ans_node;
1364 invalid_ans_node = TrNode_child(current_ans_node);
1365 TrNode_child(current_ans_node) = NULL;
1367 answer_search_loop(sg_fr, current_ans_node, Deref(subs_ptr[i]),
1368 &vars_arity PASS_REGS);
1370 }
else if (mode == MODE_DIRECTED_FIRST) {
1371 current_ans_node = NULL;
1373 Yap_Error(SYSTEM_ERROR_INTERNAL, TermNil,
1374 "mode_directed_answer_search: unknown mode");
1375 UNLOCK_ANSWER_NODE(current_ans_node);
1379 }
while (n_subs && current_ans_node);
1380 if (current_ans_node == NULL)
1384 if (invalid_ans_node)
1385 invalidate_answer_trie(invalid_ans_node, sg_fr,
1386 TRAVERSE_POSITION_FIRST PASS_REGS);
1389 stack_vars = (CELL *)TR;
1390 while (vars_arity--) {
1391 Term t = STACK_POP_DOWN(stack_vars);
1395 return current_ans_node;
1400void load_answer(
ans_node_ptr current_ans_node, CELL *subs_ptr) {
1402#define subs_arity *subs_ptr
1406 TABLING_ERROR_CHECKING(load_answer, H < H_FZ);
1407 if (subs_arity == 0)
1410 stack_terms = load_answer_loop(current_ans_node PASS_REGS);
1412 for (i = subs_arity; i >= 1; i--) {
1413 Term t = STACK_POP_DOWN(stack_terms);
1414 YapBind((CELL *)subs_ptr[i], t);
1416 TABLING_ERROR_CHECKING(load_answer, stack_terms != (CELL *)LOCAL_TrailTop);
1422CELL *exec_substitution(
gt_node_ptr current_node, CELL *aux_stack) {
1424#define subs_arity *subs_ptr
1425 CELL *stack_terms, *subs_ptr;
1429 stack_terms = exec_substitution_loop(current_node, &aux_stack,
1430 (CELL *)LOCAL_TrailTop PASS_REGS);
1433 subs_ptr = aux_stack + aux_stack[1] + 2;
1434 t = STACK_POP_DOWN(stack_terms);
1435 YapBind((CELL *)subs_ptr[subs_arity], t);
1436 TABLING_ERROR_CHECKING(exec_substitution,
1437 stack_terms != (CELL *)LOCAL_TrailTop);
1438 *subs_ptr = subs_arity - 1;
1444void update_answer_trie(
sg_fr_ptr sg_fr) {
1447 free_answer_hash_chain(SgFr_hash_chain(sg_fr));
1448 SgFr_hash_chain(sg_fr) = NULL;
1449 SgFr_state(sg_fr) +=
1452#if defined(THREADS_FULL_SHARING) || defined(THREADS_CONSUMER_SHARING)
1453 SgFr_sg_ent_state(sg_fr) += 2;
1454#ifdef THREADS_FULL_SHARING
1455 if (IsMode_Batched(TabEnt_mode(SgFr_tab_ent(sg_fr)))) {
1458 ans_node_ptr leaf_ans_trie_node = SgFr_first_answer(sg_fr);
1459 while (TrNode_child(leaf_ans_trie_node) != NULL) {
1460 ANSWER_LEAF_NODE_INSTR_ABSOLUTE(leaf_ans_trie_node);
1461 leaf_ans_trie_node = TrNode_child(leaf_ans_trie_node);
1463 ANSWER_LEAF_NODE_INSTR_ABSOLUTE(leaf_ans_trie_node);
1467 current_node = TrNode_child(SgFr_answer_trie(sg_fr));
1470 TrNode_instr(current_node) -= 1;
1471#ifdef TABLING_INNER_CUTS
1472 update_answer_trie_branch(NULL, current_node);
1474 update_answer_trie_branch(current_node);
1477 update_answer_trie_branch(current_node, TRAVERSE_POSITION_FIRST);
1483void free_subgoal_trie(
sg_node_ptr current_node,
int mode,
int position) {
1486 if (IS_SUBGOAL_TRIE_HASH(current_node)) {
1490 bucket = Hash_buckets(hash);
1491 last_bucket =
bucket + Hash_num_buckets(hash);
1496 current_node = next_node;
1497 next_node = TrNode_next(current_node);
1498 free_subgoal_trie(current_node, mode, TRAVERSE_POSITION_NEXT);
1499 }
while (next_node);
1501 }
while (++
bucket != last_bucket);
1502 IF_ABOLISH_SUBGOAL_TRIE_SHARED_DATA_STRUCTURES {
1503 FREE_BUCKETS(Hash_buckets(hash));
1504 FREE_SUBGOAL_TRIE_HASH(hash);
1508 if (!IS_SUBGOAL_LEAF_NODE(current_node)) {
1510 if (mode == TRAVERSE_MODE_NORMAL) {
1511 Term t = TrNode_entry(current_node);
1512 if (IsApplTerm(t)) {
1514 if (f == FunctorDouble)
1515 child_mode = TRAVERSE_MODE_DOUBLE;
1516 else if (f == FunctorLongInt)
1517 child_mode = TRAVERSE_MODE_LONGINT;
1518 else if (f == FunctorBigInt || f == FunctorString)
1519 child_mode = TRAVERSE_MODE_BIGINT_OR_STRING;
1521 child_mode = TRAVERSE_MODE_NORMAL;
1523 child_mode = TRAVERSE_MODE_NORMAL;
1524 }
else if (mode == TRAVERSE_MODE_LONGINT) {
1525 child_mode = TRAVERSE_MODE_LONGINT_END;
1526 }
else if (mode == TRAVERSE_MODE_BIGINT_OR_STRING) {
1527 Yap_FreeCodeSpace((
char *)TrNode_entry(current_node));
1528 child_mode = TRAVERSE_MODE_BIGINT_OR_STRING_END;
1529 }
else if (mode == TRAVERSE_MODE_DOUBLE) {
1530#if SIZEOF_DOUBLE == 2 * SIZEOF_INT_P
1531 child_mode = TRAVERSE_MODE_DOUBLE2;
1532 }
else if (mode == TRAVERSE_MODE_DOUBLE2) {
1534 child_mode = TRAVERSE_MODE_DOUBLE_END;
1536 child_mode = TRAVERSE_MODE_NORMAL;
1538 free_subgoal_trie(TrNode_child(current_node), child_mode,
1539 TRAVERSE_POSITION_FIRST);
1541 sg_fr_ptr sg_fr = get_subgoal_frame_for_abolish(current_node PASS_REGS);
1544 free_answer_hash_chain(SgFr_hash_chain(sg_fr));
1545 ans_node = SgFr_answer_trie(sg_fr);
1546 if (TrNode_child(ans_node))
1547 free_answer_trie(TrNode_child(ans_node), TRAVERSE_MODE_NORMAL,
1548 TRAVERSE_POSITION_FIRST);
1549 IF_ABOLISH_ANSWER_TRIE_SHARED_DATA_STRUCTURES {
1550 FREE_ANSWER_TRIE_NODE(ans_node);
1551#if defined(THREADS_FULL_SHARING) || defined(THREADS_CONSUMER_SHARING)
1552#ifdef MODE_DIRECTED_TABLING
1553 if (SgEnt_mode_directed(SgFr_sg_ent(sg_fr)))
1554 FREE_BLOCK(SgEnt_mode_directed(SgFr_sg_ent(sg_fr)));
1555 if (SgFr_invalid_chain(sg_fr)) {
1558 current_node = SgFr_invalid_chain(sg_fr);
1559 SgFr_invalid_chain(sg_fr) = NULL;
1560 while (current_node) {
1561 next_node = TrNode_next(current_node);
1562 FREE_ANSWER_TRIE_NODE(current_node);
1563 current_node = next_node;
1567 FREE_SUBGOAL_ENTRY(SgFr_sg_ent(sg_fr));
1571 remove_from_global_sg_fr_list(sg_fr);
1573#if defined(MODE_DIRECTED_TABLING) && !defined(THREADS_FULL_SHARING) && \
1574 !defined(THREADS_CONSUMER_SHARING)
1575 if (SgFr_mode_directed(sg_fr))
1576 FREE_BLOCK(SgFr_mode_directed(sg_fr));
1579 FREE_SUBGOAL_FRAME(sg_fr);
1582 if (position == TRAVERSE_POSITION_FIRST) {
1583 sg_node_ptr next_node = TrNode_next(current_node);
1584 IF_ABOLISH_SUBGOAL_TRIE_SHARED_DATA_STRUCTURES {
1585 CHECK_DECREMENT_GLOBAL_TRIE_REFERENCE(TrNode_entry(current_node), mode);
1586 FREE_SUBGOAL_TRIE_NODE(current_node);
1589 current_node = next_node;
1590 next_node = TrNode_next(current_node);
1591 free_subgoal_trie(current_node, mode, TRAVERSE_POSITION_NEXT);
1594 IF_ABOLISH_SUBGOAL_TRIE_SHARED_DATA_STRUCTURES {
1595 CHECK_DECREMENT_GLOBAL_TRIE_REFERENCE(TrNode_entry(current_node), mode);
1596 FREE_SUBGOAL_TRIE_NODE(current_node);
1602void free_answer_trie(
ans_node_ptr current_node,
int mode,
int position) {
1605#ifdef TABLING_INNER_CUTS
1606 if (!IS_ANSWER_LEAF_NODE(current_node) && TrNode_child(current_node)) {
1608 if (!IS_ANSWER_LEAF_NODE(current_node)) {
1611 if (mode == TRAVERSE_MODE_NORMAL) {
1612 Term t = TrNode_entry(current_node);
1613 if (IsApplTerm(t)) {
1615 if (f == FunctorDouble)
1616 child_mode = TRAVERSE_MODE_DOUBLE;
1617 else if (f == FunctorLongInt)
1618 child_mode = TRAVERSE_MODE_LONGINT;
1619 else if (f == FunctorBigInt || f == FunctorString)
1620 child_mode = TRAVERSE_MODE_BIGINT_OR_STRING;
1622 child_mode = TRAVERSE_MODE_NORMAL;
1624 child_mode = TRAVERSE_MODE_NORMAL;
1625 }
else if (mode == TRAVERSE_MODE_LONGINT) {
1626 child_mode = TRAVERSE_MODE_LONGINT_END;
1627 }
else if (mode == TRAVERSE_MODE_BIGINT_OR_STRING) {
1628 Yap_FreeCodeSpace((
char *)TrNode_entry(current_node));
1629 child_mode = TRAVERSE_MODE_BIGINT_OR_STRING_END;
1630 }
else if (mode == TRAVERSE_MODE_DOUBLE) {
1631#if SIZEOF_DOUBLE == 2 * SIZEOF_INT_P
1632 child_mode = TRAVERSE_MODE_DOUBLE2;
1633 }
else if (mode == TRAVERSE_MODE_DOUBLE2) {
1635 child_mode = TRAVERSE_MODE_DOUBLE_END;
1637 child_mode = TRAVERSE_MODE_NORMAL;
1639 free_answer_trie(TrNode_child(current_node), child_mode,
1640 TRAVERSE_POSITION_FIRST);
1642 if (position == TRAVERSE_POSITION_FIRST) {
1644 IF_ABOLISH_ANSWER_TRIE_SHARED_DATA_STRUCTURES {
1645 CHECK_DECREMENT_GLOBAL_TRIE_REFERENCE(TrNode_entry(current_node), mode);
1646 FREE_ANSWER_TRIE_NODE(current_node);
1649 current_node = next_node;
1650 next_node = TrNode_next(current_node);
1651 free_answer_trie(current_node, mode, TRAVERSE_POSITION_NEXT);
1654 IF_ABOLISH_ANSWER_TRIE_SHARED_DATA_STRUCTURES {
1655 CHECK_DECREMENT_GLOBAL_TRIE_REFERENCE(TrNode_entry(current_node), mode);
1656 FREE_ANSWER_TRIE_NODE(current_node);
1663#if defined(THREADS_NO_SHARING) || defined(THREADS_SUBGOAL_SHARING)
1671 bucket = Hash_buckets(hash);
1672 last_bucket =
bucket + Hash_num_buckets(hash);
1676 TrNode_child((
ans_node_ptr)UNTAG_ANSWER_NODE(TrNode_parent(chain_node))) =
1678 while (++
bucket != last_bucket) {
1680 while (TrNode_next(chain_node))
1681 chain_node = TrNode_next(chain_node);
1682 TrNode_next(chain_node) = *
bucket;
1686 next_hash = Hash_next(hash);
1687 FREE_BUCKETS(Hash_buckets(hash));
1688 FREE_ANSWER_TRIE_HASH(hash);
1705 if (GLOBAL_NOfThreads == 1) {
1706 ATTACH_PAGES(_pages_tab_ent);
1707#if defined(THREADS_FULL_SHARING) || defined(THREADS_CONSUMER_SHARING)
1708 ATTACH_PAGES(_pages_sg_ent);
1710 ATTACH_PAGES(_pages_sg_fr);
1711 ATTACH_PAGES(_pages_dep_fr);
1712 ATTACH_PAGES(_pages_sg_node);
1713 ATTACH_PAGES(_pages_sg_hash);
1714 ATTACH_PAGES(_pages_ans_node);
1715 ATTACH_PAGES(_pages_ans_hash);
1716#if defined(THREADS_FULL_SHARING)
1717 ATTACH_PAGES(_pages_ans_ref_node);
1719 ATTACH_PAGES(_pages_gt_node);
1720 ATTACH_PAGES(_pages_gt_hash);
1723 sg_node = get_subgoal_trie_for_abolish(tab_ent PASS_REGS);
1725 if (TrNode_child(sg_node)) {
1726 if (TabEnt_arity(tab_ent)) {
1727 free_subgoal_trie(TrNode_child(sg_node), TRAVERSE_MODE_NORMAL,
1728 TRAVERSE_POSITION_FIRST);
1730 sg_fr_ptr sg_fr = get_subgoal_frame_for_abolish(sg_node PASS_REGS);
1732 IF_ABOLISH_ANSWER_TRIE_SHARED_DATA_STRUCTURES {
1733 FREE_ANSWER_TRIE_NODE(SgFr_answer_trie(sg_fr));
1734#if defined(THREADS_FULL_SHARING) || defined(THREADS_CONSUMER_SHARING)
1735 FREE_SUBGOAL_ENTRY(SgFr_sg_ent(sg_fr));
1739 remove_from_global_sg_fr_list(sg_fr);
1741 FREE_SUBGOAL_FRAME(sg_fr);
1744 IF_ABOLISH_SUBGOAL_TRIE_SHARED_DATA_STRUCTURES
1745 TrNode_child(sg_node) = NULL;
1747#ifdef THREADS_NO_SHARING
1748 FREE_SUBGOAL_TRIE_NODE(sg_node);
1754void showTable(
tab_ent_ptr tab_ent,
int show_mode, FILE *out) {
1759 TrStat_show = show_mode;
1760 TrStat_subgoals = 0;
1761 TrStat_sg_incomplete = 0;
1762 TrStat_sg_nodes = 1;
1764 TrStat_answers_true = 0;
1765 TrStat_answers_no = 0;
1766#ifdef TABLING_INNER_CUTS
1767 TrStat_answers_pruned = 0;
1769 TrStat_ans_nodes = 0;
1771 if (show_mode == SHOW_MODE_STATISTICS)
1772 fprintf(TrStat_out,
"Table statistics for predicate '%s",
1773 AtomName(TabEnt_atom(tab_ent)));
1775 fprintf(TrStat_out,
"Table structure for predicate '%s",
1776 AtomName(TabEnt_atom(tab_ent)));
1777#ifdef MODE_DIRECTED_TABLING
1778 if (TabEnt_mode_directed(tab_ent)) {
1779 int i, *mode_directed = TabEnt_mode_directed(tab_ent);
1780 fprintf(TrStat_out,
"(");
1781 for (i = 0; i < TabEnt_arity(tab_ent); i++) {
1782 int mode = MODE_DIRECTED_GET_MODE(mode_directed[i]);
1783 if (mode == MODE_DIRECTED_INDEX) {
1784 fprintf(TrStat_out,
"index");
1785 }
else if (mode == MODE_DIRECTED_MIN) {
1786 fprintf(TrStat_out,
"min");
1787 }
else if (mode == MODE_DIRECTED_MAX) {
1788 fprintf(TrStat_out,
"max");
1789 }
else if (mode == MODE_DIRECTED_ALL) {
1790 fprintf(TrStat_out,
"all");
1791 }
else if (mode == MODE_DIRECTED_SUM) {
1792 fprintf(TrStat_out,
"sum");
1793 }
else if (mode == MODE_DIRECTED_LAST) {
1794 fprintf(TrStat_out,
"last");
1795 }
else if (mode == MODE_DIRECTED_FIRST) {
1796 fprintf(TrStat_out,
"first");
1798 Yap_Error(SYSTEM_ERROR_INTERNAL, TermNil,
"show_table: unknown mode");
1799 if (i != MODE_DIRECTED_GET_ARG(mode_directed[i]))
1800 fprintf(TrStat_out,
"(ARG%d)",
1801 MODE_DIRECTED_GET_ARG(mode_directed[i]) + 1);
1802 if (i + 1 != TabEnt_arity(tab_ent))
1803 fprintf(TrStat_out,
",");
1805 fprintf(TrStat_out,
")'\n");
1808 fprintf(TrStat_out,
"/%d'\n", TabEnt_arity(tab_ent));
1809 sg_node = get_subgoal_trie(tab_ent);
1811 if (TrNode_child(sg_node)) {
1812 if (TabEnt_arity(tab_ent)) {
1813 char *str = (
char *)malloc(
sizeof(
char) * SHOW_TABLE_STR_ARRAY_SIZE);
1814 int *arity = (
int *)malloc(
sizeof(
int) * SHOW_TABLE_ARITY_ARRAY_SIZE);
1816 arity[1] = TabEnt_arity(tab_ent);
1818 sprintf(str,
" ?- %s(", AtomName(TabEnt_atom(tab_ent)));
1819 traverse_subgoal_trie(TrNode_child(sg_node), str, str_index, arity,
1820 TRAVERSE_MODE_NORMAL,
1821 TRAVERSE_POSITION_FIRST PASS_REGS);
1825 sg_fr_ptr sg_fr = get_subgoal_frame(sg_node);
1828 SHOW_TABLE_STRUCTURE(
" ?- %s.\n", AtomName(TabEnt_atom(tab_ent)));
1830 if (SgFr_first_answer(sg_fr) == NULL) {
1831 if (SgFr_state(sg_fr) < complete) {
1832 TrStat_sg_incomplete++;
1833 SHOW_TABLE_STRUCTURE(
" ---> INCOMPLETE\n");
1835 TrStat_answers_no++;
1836 SHOW_TABLE_STRUCTURE(
" NO\n");
1839 TrStat_answers_true++;
1840 SHOW_TABLE_STRUCTURE(
" TRUE\n");
1846 if (TrStat_subgoals == 0)
1847 SHOW_TABLE_STRUCTURE(
" EMPTY\n");
1848 if (show_mode == SHOW_MODE_STATISTICS) {
1849 fprintf(TrStat_out,
" Subgoal trie structure\n");
1850 fprintf(TrStat_out,
" Subgoals: %ld (%ld incomplete)\n", TrStat_subgoals,
1851 TrStat_sg_incomplete);
1852 fprintf(TrStat_out,
" Subgoal trie nodes: %ld\n", TrStat_sg_nodes);
1853 fprintf(TrStat_out,
" Answer trie structure(s)\n");
1854#ifdef TABLING_INNER_CUTS
1855 fprintf(TrStat_out,
" Answers: %ld (%ld pruned)\n", TrStat_answers,
1856 TrStat_answers_pruned);
1858 fprintf(TrStat_out,
" Answers: %ld\n", TrStat_answers);
1860 fprintf(TrStat_out,
" Answers 'TRUE': %ld\n", TrStat_answers_true);
1861 fprintf(TrStat_out,
" Answers 'NO': %ld\n", TrStat_answers_no);
1862 fprintf(TrStat_out,
" Answer trie nodes: %ld\n", TrStat_ans_nodes);
1863 fprintf(TrStat_out,
" Global trie references: %ld\n", TrStat_gt_refs);
1868void showGlobalTrie(
int show_mode, FILE *out) {
1872 TrStat_show = show_mode;
1873 TrStat_gt_terms = 0;
1874 TrStat_gt_nodes = 1;
1876 if (show_mode == SHOW_MODE_STATISTICS)
1877 fprintf(TrStat_out,
"Global trie statistics\n");
1879 fprintf(TrStat_out,
"Global trie structure\n");
1880 if (TrNode_child(GLOBAL_root_gt)) {
1881 char *str = (
char *)malloc(
sizeof(
char) * SHOW_TABLE_STR_ARRAY_SIZE);
1882 int *arity = (
int *)malloc(
sizeof(
int) * SHOW_TABLE_ARITY_ARRAY_SIZE);
1884 traverse_global_trie(TrNode_child(GLOBAL_root_gt), str, 0, arity,
1885 TRAVERSE_MODE_NORMAL,
1886 TRAVERSE_POSITION_FIRST PASS_REGS);
1890 SHOW_TABLE_STRUCTURE(
" EMPTY\n");
1891 if (show_mode == SHOW_MODE_STATISTICS) {
1892 fprintf(TrStat_out,
" Terms: %ld\n", TrStat_gt_terms);
1893 fprintf(TrStat_out,
" Global trie nodes: %ld\n", TrStat_gt_nodes);
1894 fprintf(TrStat_out,
" Global trie auto references: %ld\n", TrStat_gt_refs);