12#include "core_tries.h"
23static YAP_Term get_entry(
TrNode node, YAP_Term *stack_list,
TrNode *cur_node);
24static void remove_entry(
TrNode node);
25static void remove_child_nodes(
TrNode node);
27static void traverse_and_add(
TrNode parent_dest,
TrNode parent_source);
28static void traverse_and_join(
TrNode parent_dest,
TrNode parent_source);
29static void traverse_and_intersect(
TrNode parent_dest,
TrNode parent_source);
30static YAP_Int traverse_and_count_common_entries(
TrNode parent1,
32static YAP_Int traverse_and_count_entries(
TrNode node);
33static void traverse_and_get_usage(
TrNode node, YAP_Int depth);
34static void traverse_and_save(
TrNode node, FILE *file,
int float_block);
35static void traverse_and_load(
TrNode parent, FILE *file);
36static void traverse_and_print(
TrNode node,
int *arity,
char *str,
37 int str_index,
int mode);
39static YAP_Term trie_to_list(
TrNode node);
40static YAP_Term trie_to_list_node(
TrNode node);
41static YAP_Term trie_to_list_floats(
TrNode node);
49static YAP_Int USAGE_ENTRIES, USAGE_NODES, USAGE_VIRTUAL_NODES;
50static YAP_Int CURRENT_AUXILIARY_TERM_STACK_SIZE, CURRENT_TRIE_MODE,
51 CURRENT_LOAD_VERSION, CURRENT_DEPTH, CURRENT_INDEX;
52static YAP_Term *AUXILIARY_TERM_STACK;
53YAP_Term *stack_args, *stack_args_base, *stack_vars, *stack_vars_base;
54static YAP_Functor FunctorComma;
55static void (*DATA_SAVE_FUNCTION)(
TrNode, FILE *);
56static void (*DATA_LOAD_FUNCTION)(
TrNode, YAP_Int, FILE *);
57static void (*DATA_PRINT_FUNCTION)(
TrNode);
60static void (*DATA_DESTRUCT_FUNCTION)(
TrNode);
62static YAP_Int TRIE_DISABLE_HASH_TABLE = 0;
68static TrNode trie_node_check_insert(
TrNode parent, YAP_Term t) {
72 child = TrNode_child(parent);
74 new_trie_node(child, t, parent, NULL, NULL, NULL);
75 TrNode_child(parent) = child;
76 }
else if (IS_HASH_NODE(child)) {
81 bucket = TrHash_bucket(hash, HASH_TERM(t, TrHash_seed(hash)));
85 if ((TrNode_entry(child) == t) ||
86 (((TrNode_entry(child) == PairEndTermTag) ||
87 (TrNode_entry(child) == PairEndEmptyTag)) &&
88 ((CURRENT_TRIE_MODE & TRIE_MODE_MINIMAL) == TRIE_MODE_MINIMAL)))
91 child = TrNode_next(child);
95 TrHash_num_nodes(hash)++;
96 new_trie_node(child, t, parent, NULL, *
bucket, AS_TR_NODE_NEXT(
bucket));
98 TrNode_previous(*
bucket) = child;
100 if (count > MAX_NODES_PER_BUCKET &&
101 TrHash_num_nodes(hash) > TrHash_num_buckets(hash)) {
103 TrNode chain, next, *first_bucket, *new_bucket;
105 first_bucket = TrHash_buckets(hash);
106 bucket = first_bucket + TrHash_num_buckets(hash);
107 TrHash_num_buckets(hash) *= 2;
108 new_hash_buckets(hash, TrHash_num_buckets(hash));
109 seed = TrHash_num_buckets(hash) - 1;
115 TrHash_bucket(hash, HASH_TERM(TrNode_entry(chain), seed));
116 next = TrNode_next(chain);
117 TrNode_next(chain) = *new_bucket;
118 TrNode_previous(chain) = AS_TR_NODE_NEXT(
bucket);
120 TrNode_previous(*new_bucket) = chain;
125 }
while (
bucket != first_bucket);
126 free_hash_buckets(first_bucket, TrHash_num_buckets(hash) / 2);
131 if ((TrNode_entry(child) == t) ||
132 (((TrNode_entry(child) == PairEndTermTag) ||
133 (TrNode_entry(child) == PairEndEmptyTag)) &&
134 ((CURRENT_TRIE_MODE & TRIE_MODE_MINIMAL) == TRIE_MODE_MINIMAL)))
137 child = TrNode_next(child);
139 new_trie_node(child, t, parent, NULL, TrNode_child(parent), NULL);
140 TrNode_previous(TrNode_child(parent)) = child;
141 if ((++count > MAX_NODES_PER_TRIE_LEVEL) &&
142 (TRIE_DISABLE_HASH_TABLE == 0)) {
146 new_trie_hash(hash, count, BASE_HASH_BUCKETS);
150 hash, HASH_TERM(TrNode_entry(chain), BASE_HASH_BUCKETS - 1));
151 next = TrNode_next(chain);
152 TrNode_next(chain) = *
bucket;
153 TrNode_previous(chain) = AS_TR_NODE_NEXT(
bucket);
155 TrNode_previous(*
bucket) = chain;
159 TrNode_child(parent) = (
TrNode)hash;
161 TrNode_child(parent) = child;
173 TrHash_num_nodes(hash)++;
174 bucket = TrHash_bucket(hash, HASH_TERM(t, TrHash_seed(hash)));
175 new_trie_node(child, t, parent, NULL, *
bucket, AS_TR_NODE_NEXT(
bucket));
177 TrNode_previous(*
bucket) = child;
180 new_trie_node(child, t, parent, NULL, TrNode_child(parent), NULL);
181 if (TrNode_child(parent))
182 TrNode_previous(TrNode_child(parent)) = child;
183 TrNode_child(parent) = child;
188static TrNode trie_node_check(
TrNode parent, YAP_Term t) {
191 child = TrNode_child(parent);
192 if (IS_HASH_NODE(child)) {
196 bucket = TrHash_bucket(hash, HASH_TERM(t, TrHash_seed(hash)));
202 if (TrNode_entry(child) == t)
204 child = TrNode_next(child);
209static YAP_Term trie_to_list_create_simple(
const char *atom_name,
TrNode node) {
210 YAP_Functor f = YAP_MkFunctor(YAP_LookupAtom(atom_name), 1);
211 YAP_Term child = trie_to_list(TrNode_child(node));
213 return YAP_MkApplTerm(f, 1, &child);
216static YAP_Term trie_to_list_create_simple_end(
const char *atom_name,
218 YAP_Atom atom = YAP_LookupAtom(atom_name);
220 if (IS_LEAF_TRIE_NODE(node)) {
221 return YAP_MkAtomTerm(atom);
223 YAP_Functor f = YAP_MkFunctor(atom, 1);
224 YAP_Term child = trie_to_list(TrNode_child(node));
225 return YAP_MkApplTerm(f, 1, &child);
229static YAP_Term trie_to_list_create_two(
const char *atom_name,
TrNode node,
231 YAP_Atom atom = YAP_LookupAtom(atom_name);
233 if (IS_LEAF_TRIE_NODE(node)) {
234 YAP_Functor f = YAP_MkFunctor(atom, 1);
235 return YAP_MkApplTerm(f, 1, &operand);
237 YAP_Functor f = YAP_MkFunctor(atom, 2);
238 YAP_Term args[2] = {operand, trie_to_list(TrNode_child(node))};
239 return YAP_MkApplTerm(f, 2, args);
247TrEngine core_trie_init_module(
void) {
248 static int init_once = 1;
252 new_struct(AUXILIARY_TERM_STACK, YAP_Term,
253 BASE_AUXILIARY_TERM_STACK_SIZE *
sizeof(YAP_Term));
254 CURRENT_AUXILIARY_TERM_STACK_SIZE = BASE_AUXILIARY_TERM_STACK_SIZE;
255 CURRENT_TRIE_MODE = TRIE_MODE_STANDARD;
256 FunctorComma = YAP_MkFunctor(YAP_LookupAtom(
","), 2);
259 new_trie_engine(engine);
266 CURRENT_TRIE_ENGINE = engine;
267 new_trie_node(node, 0, NULL, NULL, TrEngine_trie(engine),
268 AS_TR_NODE_NEXT(&TrEngine_trie(engine)));
269 if (TrEngine_trie(engine))
270 TrNode_previous(TrEngine_trie(engine)) = node;
271 TrEngine_trie(engine) = node;
272 INCREMENT_TRIES(CURRENT_TRIE_ENGINE);
277 void (*destruct_function)(
TrNode)) {
278 CURRENT_TRIE_ENGINE = engine;
279 DATA_DESTRUCT_FUNCTION = destruct_function;
280 if (TrNode_child(node))
281 remove_child_nodes(TrNode_child(node));
282 if (TrNode_next(node)) {
283 TrNode_previous(TrNode_next(node)) = TrNode_previous(node);
284 TrNode_next(TrNode_previous(node)) = TrNode_next(node);
286 TrNode_next(TrNode_previous(node)) = NULL;
287 free_trie_node(node);
288 DECREMENT_TRIES(CURRENT_TRIE_ENGINE);
292void core_trie_close_all(
TrEngine engine,
void (*destruct_function)(
TrNode)) {
293 while (TrEngine_trie(engine))
294 core_trie_close(engine, TrEngine_trie(engine), destruct_function);
298void core_trie_set_mode(YAP_Int mode) {
299 CURRENT_TRIE_MODE = mode;
303YAP_Int core_trie_get_mode(
void) {
return CURRENT_TRIE_MODE; }
307 CURRENT_TRIE_ENGINE = engine;
309 stack_args_base = stack_args = AUXILIARY_TERM_STACK;
310 stack_vars_base = stack_vars =
311 AUXILIARY_TERM_STACK + CURRENT_AUXILIARY_TERM_STACK_SIZE - 1;
312 node = put_entry(node, entry);
313 if (!IS_LEAF_TRIE_NODE(node)) {
314 MARK_AS_LEAF_TRIE_NODE(node);
315 INCREMENT_ENTRIES(CURRENT_TRIE_ENGINE);
318 while (STACK_NOT_EMPTY(stack_vars++, stack_vars_base)) {
319 (void)POP_DOWN(stack_vars);
320 *((YAP_Term *)*stack_vars) = *stack_vars;
323 *depth = CURRENT_DEPTH;
327TrNode core_trie_check_entry(
TrNode node, YAP_Term entry) {
328 if (!TrNode_child(node))
330 stack_args_base = stack_args = AUXILIARY_TERM_STACK;
331 stack_vars_base = stack_vars =
332 AUXILIARY_TERM_STACK + CURRENT_AUXILIARY_TERM_STACK_SIZE - 1;
333 node = check_entry(node, entry);
335 while (STACK_NOT_EMPTY(stack_vars++, stack_vars_base)) {
336 (void)POP_DOWN(stack_vars);
337 *((YAP_Term *)*stack_vars) = *stack_vars;
342YAP_Term core_trie_get_entry(
TrNode node) {
344 stack_vars_base = stack_vars = AUXILIARY_TERM_STACK;
345 stack_args_base = stack_args =
346 AUXILIARY_TERM_STACK + CURRENT_AUXILIARY_TERM_STACK_SIZE - 1;
347 return get_entry(node, stack_args, &node);
351 void (*destruct_function)(
TrNode)) {
352 CURRENT_TRIE_ENGINE = engine;
353 DATA_DESTRUCT_FUNCTION = destruct_function;
354 if (DATA_DESTRUCT_FUNCTION)
355 (*DATA_DESTRUCT_FUNCTION)(node);
356 DECREMENT_ENTRIES(CURRENT_TRIE_ENGINE);
362 void (*destruct_function)(
TrNode)) {
365 CURRENT_TRIE_ENGINE = engine;
366 DATA_DESTRUCT_FUNCTION = destruct_function;
367 parent = TrNode_parent(node);
368 remove_child_nodes(TrNode_child(parent));
369 remove_entry(parent);
375 DATA_ADD_FUNCTION = add_function;
376 if (TrNode_child(node_dest) && TrNode_child(node_source))
377 traverse_and_add(node_dest, node_source);
384 CURRENT_TRIE_ENGINE = engine;
385 DATA_ADD_FUNCTION = add_function;
386 DATA_COPY_FUNCTION = copy_function;
387 if (TrNode_child(node_dest)) {
388 if (TrNode_child(node_source))
389 traverse_and_join(node_dest, node_source);
390 }
else if (TrNode_child(node_source))
391 TrNode_child(node_dest) =
392 copy_child_nodes(node_dest, TrNode_child(node_source));
398 void (*destruct_function)(
TrNode)) {
399 CURRENT_TRIE_ENGINE = engine;
400 DATA_ADD_FUNCTION = add_function;
401 DATA_DESTRUCT_FUNCTION = destruct_function;
402 if (TrNode_child(node_dest)) {
403 if (TrNode_child(node_source))
404 traverse_and_intersect(node_dest, node_source);
406 remove_child_nodes(TrNode_child(node_dest));
407 TrNode_child(node_dest) = NULL;
413YAP_Int core_trie_count_join(
TrNode node1,
TrNode node2) {
416 if (TrNode_child(node1)) {
417 count += traverse_and_count_entries(TrNode_child(node1));
418 if (TrNode_child(node2)) {
419 count += traverse_and_count_entries(TrNode_child(node2));
420 count -= traverse_and_count_common_entries(node1, node2);
422 }
else if (TrNode_child(node2))
423 count += traverse_and_count_entries(TrNode_child(node2));
427YAP_Int core_trie_count_intersect(
TrNode node1,
TrNode node2) {
430 if (TrNode_child(node1))
431 if (TrNode_child(node2))
432 count = traverse_and_count_common_entries(node1, node2);
436void core_trie_save(
TrNode node, FILE *file,
437 void (*save_function)(
TrNode, FILE *)) {
439 DATA_SAVE_FUNCTION = save_function;
440 if (TrNode_child(node)) {
441 fprintf(file,
"BEGIN_TRIE_v2 ");
442 traverse_and_save(TrNode_child(node), file, 0);
443 fprintf(file,
"END_TRIE_v2");
450 void (*load_function)(
TrNode, YAP_Int, FILE *)) {
456 n = fscanf(file,
"%14s", version);
457 if (fgetpos(file, &curpos))
460 if (!strcmp(version,
"BEGIN_TRIE_v2")) {
461 fseek(file, -11, SEEK_END);
462 n = fscanf(file,
"%s", version);
463 if (strcmp(version,
"END_TRIE_v2")) {
464 fprintf(stderr,
"******************************************\n");
465 fprintf(stderr,
" Tries core module: trie file corrupted\n");
466 fprintf(stderr,
"******************************************\n");
470 if (fsetpos(file, &curpos))
472 CURRENT_LOAD_VERSION = 2;
473 }
else if (!strcmp(version,
"BEGIN_TRIE")) {
474 fseek(file, -8, SEEK_END);
475 n = fscanf(file,
"%s", version);
476 if (strcmp(version,
"END_TRIE")) {
477 fprintf(stderr,
"******************************************\n");
478 fprintf(stderr,
" Tries core module: trie file corrupted\n");
479 fprintf(stderr,
"******************************************\n");
483 if (fsetpos(file, &curpos))
485 CURRENT_LOAD_VERSION = 1;
487 fprintf(stderr,
"****************************************\n");
488 fprintf(stderr,
" Tries core module: invalid trie file\n");
489 fprintf(stderr,
"****************************************\n");
493 CURRENT_TRIE_ENGINE = engine;
496 DATA_LOAD_FUNCTION = load_function;
497 node = core_trie_open(engine);
498 traverse_and_load(node, file);
504void core_trie_stats(
TrEngine engine, YAP_Int *memory, YAP_Int *tries,
505 YAP_Int *entries, YAP_Int *nodes) {
506 *memory = TrEngine_memory(engine);
507 *tries = TrEngine_tries(engine);
508 *entries = TrEngine_entries(engine);
509 *nodes = TrEngine_nodes(engine);
513void core_trie_max_stats(
TrEngine engine, YAP_Int *memory, YAP_Int *tries,
514 YAP_Int *entries, YAP_Int *nodes) {
515 *memory = TrEngine_memory_max(engine);
516 *tries = TrEngine_tries_max(engine);
517 *entries = TrEngine_entries_max(engine);
518 *nodes = TrEngine_nodes_max(engine);
522void core_trie_usage(
TrNode node, YAP_Int *entries, YAP_Int *nodes,
523 YAP_Int *virtual_nodes) {
526 USAGE_VIRTUAL_NODES = 0;
527 if (TrNode_child(node))
528 traverse_and_get_usage(TrNode_child(node), 0);
529 *entries = USAGE_ENTRIES;
530 *nodes = USAGE_NODES;
531 *virtual_nodes = USAGE_VIRTUAL_NODES;
535void core_trie_print(
TrNode node,
void (*print_function)(
TrNode)) {
536 DATA_PRINT_FUNCTION = print_function;
537 if (TrNode_child(node)) {
541 traverse_and_print(TrNode_child(node), arity, str, 0, TRIE_PRINT_NORMAL);
543 fprintf(stdout,
"(empty)\n");
548void core_disable_hash_table(
void) { TRIE_DISABLE_HASH_TABLE = 1; }
550void core_enable_hash_table(
void) { TRIE_DISABLE_HASH_TABLE = 0; }
552YAP_Term core_trie_to_list(
TrNode node) {
553 TrNode root = TrNode_child(node);
556 return trie_to_list(root);
558 return YAP_MkAtomTerm(YAP_LookupAtom(
"empty"));
567 if (YAP_IsVarTerm(t)) {
568 if (IsTrieVar(t, stack_vars, stack_vars_base)) {
569 node = trie_node_check_insert(
570 node, MkTrieVar((stack_vars_base - 1 - (YAP_Term *)t) / 2));
572 node = trie_node_check_insert(
573 node, MkTrieVar((stack_vars_base - stack_vars) / 2));
574 PUSH_UP(stack_vars, t, stack_args);
575 *((YAP_Term *)t) = (YAP_Term)stack_vars;
576 PUSH_UP(stack_vars, stack_vars, stack_args);
578 }
else if (YAP_IsAtomTerm(t)) {
579 node = trie_node_check_insert(node, t);
580 }
else if (YAP_IsIntTerm(t)) {
581 node = trie_node_check_insert(node, t);
582 }
else if (YAP_IsFloatTerm(t)) {
585 YAP_Term p[SIZE_FLOAT_AS_TERM];
587 tf.f = YAP_FloatOfTerm(t);
588 node = trie_node_check_insert(node, FloatInitTag);
589 node = trie_node_check_insert(node, tf.p[0]);
590#ifdef TAG_LOW_BITS_32
591 node = trie_node_check_insert(node, tf.p[1]);
593 node = trie_node_check_insert(node, FloatEndTag);
594 }
else if (YAP_IsPairTerm(t)) {
595 node = trie_node_check_insert(node, PairInitTag);
596 if ((CURRENT_TRIE_MODE & TRIE_MODE_REVERSE) == TRIE_MODE_STANDARD) {
598 node = put_entry(node, YAP_HeadOfTerm(t));
600 }
while (YAP_IsPairTerm(t));
601 if (t == YAP_TermNil()) {
602 node = trie_node_check_insert(node, PairEndEmptyTag);
604 node = put_entry(node, t);
605 node = trie_node_check_insert(node, PairEndTermTag);
607 }
else if (CURRENT_TRIE_MODE & TRIE_MODE_REVERSE) {
608 YAP_Term *stack_list = stack_args;
610 PUSH_DOWN(stack_args, YAP_HeadOfTerm(t), stack_vars);
612 }
while (YAP_IsPairTerm(t));
613 if (t == YAP_TermNil()) {
614 while (STACK_NOT_EMPTY(stack_args, stack_list))
615 node = put_entry(node, POP_UP(stack_args));
616 node = trie_node_check_insert(node, PairEndEmptyTag);
618 PUSH_DOWN(stack_args, t, stack_vars);
619 while (STACK_NOT_EMPTY(stack_args, stack_list))
620 node = put_entry(node, POP_UP(stack_args));
621 node = trie_node_check_insert(node, PairEndTermTag);
624 }
else if (YAP_IsApplTerm(t)) {
625 YAP_Functor f = YAP_FunctorOfTerm(t);
626 if (f == FunctorComma) {
627 node = trie_node_check_insert(node, CommaInitTag);
629 node = put_entry(node, YAP_ArgOfTerm(1, t));
631 }
while (YAP_IsApplTerm(t) && YAP_FunctorOfTerm(t) == FunctorComma);
632 node = put_entry(node, t);
633 node = trie_node_check_insert(node, CommaEndTag);
636 node = trie_node_check_insert(node, ApplTag | ((YAP_Term)f));
637 for (i = 1; i <= YAP_ArityOfFunctor(f); i++)
638 node = put_entry(node, YAP_ArgOfTerm(i, t));
641 fprintf(stderr,
"***************************************\n");
642 fprintf(stderr,
" Tries core module: unknown type tag\n");
643 fprintf(stderr,
"***************************************\n");
652 if (YAP_IsVarTerm(t)) {
653 if (IsTrieVar(t, stack_vars, stack_vars_base)) {
654 if (!(node = trie_node_check(
655 node, MkTrieVar((stack_vars_base - 1 - (YAP_Term *)t) / 2))))
658 if (!(node = trie_node_check(
659 node, MkTrieVar((stack_vars_base - stack_vars) / 2))))
661 PUSH_UP(stack_vars, t, stack_args);
662 *((YAP_Term *)t) = (YAP_Term)stack_vars;
663 PUSH_UP(stack_vars, stack_vars, stack_args);
665 }
else if (YAP_IsAtomTerm(t)) {
666 if (!(node = trie_node_check(node, t)))
668 }
else if (YAP_IsIntTerm(t)) {
669 if (!(node = trie_node_check(node, t)))
671 }
else if (YAP_IsFloatTerm(t)) {
674 YAP_Term p[SIZE_FLOAT_AS_TERM];
676 tf.f = YAP_FloatOfTerm(t);
677 if (!(node = trie_node_check(node, FloatInitTag)))
679 if (!(node = trie_node_check(node, tf.p[0])))
681#ifdef TAG_LOW_BITS_32
682 if (!(node = trie_node_check(node, tf.p[1])))
685 if (!(node = trie_node_check(node, FloatEndTag)))
687 }
else if (YAP_IsPairTerm(t)) {
688 if (!(node = trie_node_check(node, PairInitTag)))
690 if ((CURRENT_TRIE_MODE & TRIE_MODE_REVERSE) == TRIE_MODE_STANDARD) {
692 if (!(node = check_entry(node, YAP_HeadOfTerm(t))))
695 }
while (YAP_IsPairTerm(t));
696 if (t == YAP_TermNil()) {
697 if (!(node = trie_node_check(node, PairEndEmptyTag)))
700 if (!(node = check_entry(node, t)))
702 if (!(node = trie_node_check(node, PairEndTermTag)))
705 }
else if (CURRENT_TRIE_MODE & TRIE_MODE_REVERSE) {
706 YAP_Term *stack_list = stack_args;
708 PUSH_DOWN(stack_args, YAP_HeadOfTerm(t), stack_vars);
710 }
while (YAP_IsPairTerm(t));
711 if (t == YAP_TermNil()) {
712 while (STACK_NOT_EMPTY(stack_args, stack_list))
713 if (!(node = check_entry(node, POP_UP(stack_args))))
715 if (!(node = trie_node_check(node, PairEndEmptyTag)))
718 PUSH_DOWN(stack_args, t, stack_vars);
719 while (STACK_NOT_EMPTY(stack_args, stack_list))
720 if (!(node = check_entry(node, POP_UP(stack_args))))
722 if (!(node = trie_node_check(node, PairEndTermTag)))
726 }
else if (YAP_IsApplTerm(t)) {
727 YAP_Functor f = YAP_FunctorOfTerm(t);
728 if (f == FunctorComma) {
729 if (!(node = trie_node_check(node, CommaInitTag)))
732 if (!(node = check_entry(node, YAP_ArgOfTerm(1, t))))
735 }
while (YAP_IsApplTerm(t) && YAP_FunctorOfTerm(t) == FunctorComma);
736 if (!(node = check_entry(node, t)))
738 if (!(node = trie_node_check(node, CommaEndTag)))
742 if (!(node = trie_node_check(node, ApplTag | ((YAP_Term)f))))
744 for (i = 1; i <= YAP_ArityOfFunctor(f); i++)
745 if (!(node = check_entry(node, YAP_ArgOfTerm(i, t))))
749 fprintf(stderr,
"***************************************\n");
750 fprintf(stderr,
" Tries core module: unknown type tag\n");
751 fprintf(stderr,
"***************************************\n");
758static YAP_Term get_entry(
TrNode node, YAP_Term *stack_mark,
TrNode *cur_node) {
759 vv++; YAP_Term t = (YAP_Term)&t;
760 while (TrNode_parent(node)) {
761 t = TrNode_entry(node);
762 if (YAP_IsVarTerm(t)) {
763 int index = TrieVarIndex(t);
764 if (
index > CURRENT_INDEX) {
766 stack_vars = &stack_vars_base[
index + 1];
767 if (stack_vars > stack_args + 1) {
768 fprintf(stderr,
"**************************************\n");
769 fprintf(stderr,
" Tries core module: term stack full\n");
770 fprintf(stderr,
"**************************************\n");
773 for (i =
index; i > CURRENT_INDEX; i--)
774 stack_vars_base[i] = 0;
775 CURRENT_INDEX =
index;
777 if (stack_vars_base[
index]) {
778 t = stack_vars_base[
index];
781 stack_vars_base[
index] = t;
783 PUSH_UP(stack_args, t, stack_vars);
784 }
else if (YAP_IsAtomTerm(t)) {
785 PUSH_UP(stack_args, t, stack_vars);
786 }
else if (YAP_IsIntTerm(t)) {
787 PUSH_UP(stack_args, t, stack_vars);
788 }
else if (YAP_IsPairTerm(t)) {
789 if (t == PairInitTag) {
791 if ((CURRENT_TRIE_MODE & TRIE_MODE_REVERSE) == TRIE_MODE_STANDARD) {
792 YAP_Term *stack_aux = stack_mark;
794 while (STACK_NOT_EMPTY(stack_aux, stack_args)) {
796 t = YAP_MkPairTerm(t2, t);
798 }
else if (CURRENT_TRIE_MODE &
800 YAP_Term *stack_aux = stack_mark;
802 if (t == YAP_TermNil())
805 t = POP_DOWN(stack_args);
806 while (STACK_NOT_EMPTY(stack_args, stack_aux)) {
807 t2 = POP_DOWN(stack_args);
808 t = YAP_MkPairTerm(t2, t);
811 stack_args = stack_mark;
814 }
else if (t == PairEndEmptyTag) {
816 PUSH_UP(stack_args, t, stack_vars);
817 node = TrNode_parent(node);
818 t = get_entry(node, &stack_args[1], &node);
819 PUSH_UP(stack_args, t, stack_vars);
820 }
else if (t == PairEndTermTag) {
821 node = TrNode_parent(node);
822 t = get_entry(node, stack_args, &node);
823 PUSH_UP(stack_args, t, stack_vars);
824 }
else if (t == CommaEndTag) {
825 node = TrNode_parent(node);
826 t = get_entry(node, stack_args, &node);
827 PUSH_UP(stack_args, t, stack_vars);
828 }
else if (t == CommaInitTag) {
829 YAP_Term *stack_aux = stack_mark;
831 while (STACK_NOT_EMPTY(stack_aux, stack_args)) {
832 t = YAP_MkApplTerm(FunctorComma, 2, stack_aux);
836 stack_args = stack_mark;
839 }
else if (t == FloatEndTag) {
842 YAP_Term p[SIZE_FLOAT_AS_TERM];
844#ifdef TAG_LOW_BITS_32
845 node = TrNode_parent(node);
846 tf.p[1] = TrNode_entry(node);
848 node = TrNode_parent(node);
849 tf.p[0] = TrNode_entry(node);
850 node = TrNode_parent(node);
851 t = YAP_MkFloatTerm(tf.f);
852 PUSH_UP(stack_args, t, stack_vars);
853 }
else if (t == FloatInitTag) {
855 }
else if (ApplTag & t) {
856 YAP_Functor f = (YAP_Functor)(~ApplTag & t);
857 int arity = YAP_ArityOfFunctor(f);
858 t = YAP_MkApplTerm(f, arity, &stack_args[1]);
860 PUSH_UP(stack_args, t, stack_vars);
862 fprintf(stderr,
"***************************************\n");
863 fprintf(stderr,
" Tries core module: unknown type tag\n");
864 fprintf(stderr,
"***************************************\n");
867 node = TrNode_parent(node);
873static void remove_entry(
TrNode node) {
874 TrNode parent = TrNode_parent(node);
876 if (TrNode_previous(node)) {
877 if (IS_HASH_NODE(TrNode_child(parent))) {
879 TrHash_num_nodes(hash)--;
880 if (TrHash_num_nodes(hash)) {
881 if (TrNode_next(node)) {
882 TrNode_next(TrNode_previous(node)) = TrNode_next(node);
883 TrNode_previous(TrNode_next(node)) = TrNode_previous(node);
885 TrNode_next(TrNode_previous(node)) = NULL;
887 free_trie_node(node);
890 free_hash_buckets(TrHash_buckets(hash), TrHash_num_buckets(hash));
891 free_trie_hash(hash);
893 if (TrNode_next(node)) {
894 TrNode_next(TrNode_previous(node)) = TrNode_next(node);
895 TrNode_previous(TrNode_next(node)) = TrNode_previous(node);
897 TrNode_next(TrNode_previous(node)) = NULL;
899 free_trie_node(node);
902 }
else if (TrNode_next(node)) {
903 TrNode_child(parent) = TrNode_next(node);
904 TrNode_previous(TrNode_next(node)) = NULL;
905 free_trie_node(node);
908 free_trie_node(node);
910 parent = TrNode_parent(node);
912 TrNode_child(node) = NULL;
916static void remove_child_nodes(
TrNode node) {
917 if (IS_HASH_NODE(node)) {
920 first_bucket = TrHash_buckets(hash);
921 bucket = first_bucket + TrHash_num_buckets(hash);
924 remove_child_nodes(*
bucket);
925 }
while (
bucket != first_bucket);
926 free_hash_buckets(first_bucket, TrHash_num_buckets(hash));
927 free_trie_hash(hash);
930 if (TrNode_next(node))
931 remove_child_nodes(TrNode_next(node));
932 if (!IS_LEAF_TRIE_NODE(node)) {
933 remove_child_nodes(TrNode_child(node));
935 if (DATA_DESTRUCT_FUNCTION)
936 (*DATA_DESTRUCT_FUNCTION)(node);
937 DECREMENT_ENTRIES(CURRENT_TRIE_ENGINE);
939 free_trie_node(node);
944 TrNode child_dest, next_dest;
946 if (IS_HASH_NODE(child_source)) {
947 TrNode *bucket_dest, *first_bucket_source, *bucket_source;
948 TrHash hash_dest, hash_source;
949 hash_source = (
TrHash)child_source;
950 first_bucket_source = TrHash_buckets(hash_source);
951 bucket_source = first_bucket_source + TrHash_num_buckets(hash_source);
952 new_trie_hash(hash_dest, TrHash_num_nodes(hash_source),
953 TrHash_num_buckets(hash_source));
954 bucket_dest = TrHash_buckets(hash_dest) + TrHash_num_buckets(hash_dest);
957 if (*--bucket_source) {
958 *bucket_dest = copy_child_nodes(parent_dest, *bucket_source);
959 TrNode_previous(*bucket_dest) = AS_TR_NODE_NEXT(bucket_dest);
962 }
while (bucket_source != first_bucket_source);
966 if (TrNode_next(child_source))
967 next_dest = copy_child_nodes(parent_dest, TrNode_next(child_source));
970 new_trie_node(child_dest, TrNode_entry(child_source), parent_dest, NULL,
973 TrNode_previous(next_dest) = child_dest;
974 if (IS_LEAF_TRIE_NODE(child_source)) {
975 MARK_AS_LEAF_TRIE_NODE(child_dest);
976 INCREMENT_ENTRIES(CURRENT_TRIE_ENGINE);
977 if (DATA_COPY_FUNCTION)
978 (*DATA_COPY_FUNCTION)(child_dest, child_source);
980 TrNode_child(child_dest) =
981 copy_child_nodes(child_dest, TrNode_child(child_source));
985static void traverse_and_add(
TrNode parent_dest,
TrNode parent_source) {
986 TrNode child_dest, child_source;
989 child_source = TrNode_child(parent_source);
990 if (IS_HASH_NODE(child_source)) {
991 TrNode *first_bucket_source, *bucket_source;
993 hash_source = (
TrHash)child_source;
994 first_bucket_source = TrHash_buckets(hash_source);
995 bucket_source = first_bucket_source + TrHash_num_buckets(hash_source);
997 child_source = *--bucket_source;
998 while (child_source) {
1000 child_dest = trie_node_check(parent_dest, TrNode_entry(child_source));
1002 if (IS_LEAF_TRIE_NODE(child_dest)) {
1004 if (DATA_ADD_FUNCTION)
1005 (*DATA_ADD_FUNCTION)(child_dest, child_source);
1008 traverse_and_add(child_dest, child_source);
1010 child_source = TrNode_next(child_source);
1012 }
while (bucket_source != first_bucket_source);
1015 while (child_source) {
1017 child_dest = trie_node_check(parent_dest, TrNode_entry(child_source));
1019 if (IS_LEAF_TRIE_NODE(child_dest)) {
1021 if (DATA_ADD_FUNCTION)
1022 (*DATA_ADD_FUNCTION)(child_dest, child_source);
1025 traverse_and_add(child_dest, child_source);
1027 child_source = TrNode_next(child_source);
1032static void traverse_and_join(
TrNode parent_dest,
TrNode parent_source) {
1033 TrNode child_dest, child_source;
1036 child_source = TrNode_child(parent_source);
1037 if (IS_HASH_NODE(child_source)) {
1038 TrNode *first_bucket_source, *bucket_source;
1040 hash_source = (
TrHash)child_source;
1041 first_bucket_source = TrHash_buckets(hash_source);
1042 bucket_source = first_bucket_source + TrHash_num_buckets(hash_source);
1044 child_source = *--bucket_source;
1045 while (child_source) {
1047 child_dest = trie_node_check(parent_dest, TrNode_entry(child_source));
1049 if (IS_LEAF_TRIE_NODE(child_dest)) {
1051 if (DATA_ADD_FUNCTION)
1052 (*DATA_ADD_FUNCTION)(child_dest, child_source);
1055 traverse_and_join(child_dest, child_source);
1058 trie_node_check_insert(parent_dest, TrNode_entry(child_source));
1059 if (IS_LEAF_TRIE_NODE(child_source)) {
1060 MARK_AS_LEAF_TRIE_NODE(child_dest);
1061 INCREMENT_ENTRIES(CURRENT_TRIE_ENGINE);
1062 if (DATA_COPY_FUNCTION)
1063 (*DATA_COPY_FUNCTION)(child_dest, child_source);
1065 TrNode_child(child_dest) =
1066 copy_child_nodes(child_dest, TrNode_child(child_source));
1068 child_source = TrNode_next(child_source);
1070 }
while (bucket_source != first_bucket_source);
1073 while (child_source) {
1075 child_dest = trie_node_check(parent_dest, TrNode_entry(child_source));
1077 if (IS_LEAF_TRIE_NODE(child_dest)) {
1079 if (DATA_ADD_FUNCTION)
1080 (*DATA_ADD_FUNCTION)(child_dest, child_source);
1083 traverse_and_join(child_dest, child_source);
1086 trie_node_check_insert(parent_dest, TrNode_entry(child_source));
1087 if (IS_LEAF_TRIE_NODE(child_source)) {
1088 MARK_AS_LEAF_TRIE_NODE(child_dest);
1089 INCREMENT_ENTRIES(CURRENT_TRIE_ENGINE);
1090 if (DATA_COPY_FUNCTION)
1091 (*DATA_COPY_FUNCTION)(child_dest, child_source);
1093 TrNode_child(child_dest) =
1094 copy_child_nodes(child_dest, TrNode_child(child_source));
1096 child_source = TrNode_next(child_source);
1101static void traverse_and_intersect(
TrNode parent_dest,
TrNode parent_source) {
1102 TrNode child_dest, child_source, child_next;
1105 child_dest = TrNode_child(parent_dest);
1106 if (IS_HASH_NODE(child_dest)) {
1107 TrNode *first_bucket_dest, *bucket_dest;
1109 hash_dest = (
TrHash)child_dest;
1110 first_bucket_dest = TrHash_buckets(hash_dest);
1111 bucket_dest = first_bucket_dest + TrHash_num_buckets(hash_dest);
1113 child_dest = *--bucket_dest;
1114 while (child_dest) {
1115 child_next = TrNode_next(child_dest);
1117 child_source = trie_node_check(parent_source, TrNode_entry(child_dest));
1119 if (IS_LEAF_TRIE_NODE(child_dest)) {
1121 if (DATA_ADD_FUNCTION)
1122 (*DATA_ADD_FUNCTION)(child_dest, child_source);
1125 traverse_and_intersect(child_dest, child_source);
1127 if (IS_LEAF_TRIE_NODE(child_dest)) {
1128 if (DATA_DESTRUCT_FUNCTION)
1129 (*DATA_DESTRUCT_FUNCTION)(child_dest);
1130 DECREMENT_ENTRIES(CURRENT_TRIE_ENGINE);
1132 remove_child_nodes(TrNode_child(child_dest));
1133 remove_entry(child_dest);
1135 child_dest = child_next;
1137 }
while (bucket_dest != first_bucket_dest);
1140 while (child_dest) {
1141 child_next = TrNode_next(child_dest);
1143 child_source = trie_node_check(parent_source, TrNode_entry(child_dest));
1145 if (IS_LEAF_TRIE_NODE(child_dest)) {
1147 if (DATA_ADD_FUNCTION)
1148 (*DATA_ADD_FUNCTION)(child_dest, child_source);
1151 traverse_and_intersect(child_dest, child_source);
1153 if (IS_LEAF_TRIE_NODE(child_dest)) {
1154 if (DATA_DESTRUCT_FUNCTION)
1155 (*DATA_DESTRUCT_FUNCTION)(child_dest);
1156 DECREMENT_ENTRIES(CURRENT_TRIE_ENGINE);
1158 remove_child_nodes(TrNode_child(child_dest));
1159 remove_entry(child_dest);
1161 child_dest = child_next;
1166static YAP_Int traverse_and_count_common_entries(
TrNode parent1,
1172 child1 = TrNode_child(parent1);
1173 if (IS_HASH_NODE(child1)) {
1177 first_bucket = TrHash_buckets(hash);
1178 bucket = first_bucket + TrHash_num_buckets(hash);
1183 child2 = trie_node_check(parent2, TrNode_entry(child1));
1185 if (IS_LEAF_TRIE_NODE(child1))
1190 count += traverse_and_count_common_entries(child1, child2);
1192 child1 = TrNode_next(child1);
1194 }
while (
bucket != first_bucket);
1199 child2 = trie_node_check(parent2, TrNode_entry(child1));
1201 if (IS_LEAF_TRIE_NODE(child1))
1206 count += traverse_and_count_common_entries(child1, child2);
1208 child1 = TrNode_next(child1);
1213static YAP_Int traverse_and_count_entries(
TrNode node) {
1216 if (IS_HASH_NODE(node)) {
1220 first_bucket = TrHash_buckets(hash);
1221 bucket = first_bucket + TrHash_num_buckets(hash);
1225 count += traverse_and_count_entries(node);
1227 }
while (
bucket != first_bucket);
1231 if (TrNode_next(node))
1232 count += traverse_and_count_entries(TrNode_next(node));
1233 if (!IS_LEAF_TRIE_NODE(node))
1234 count += traverse_and_count_entries(TrNode_child(node));
1240static void traverse_and_get_usage(
TrNode node, YAP_Int depth) {
1241 if (IS_HASH_NODE(node)) {
1245 first_bucket = TrHash_buckets(hash);
1246 bucket = first_bucket + TrHash_num_buckets(hash);
1250 traverse_and_get_usage(node, depth);
1252 }
while (
bucket != first_bucket);
1257 if (TrNode_next(node))
1258 traverse_and_get_usage(TrNode_next(node), depth);
1260 if (!IS_LEAF_TRIE_NODE(node)) {
1261 traverse_and_get_usage(TrNode_child(node), depth);
1264 USAGE_VIRTUAL_NODES += depth;
1269static void traverse_and_save(
TrNode node, FILE *file,
int float_block) {
1272 if (IS_HASH_NODE(node)) {
1276 fprintf(file, UInt_FORMAT
" %d ", HASH_SAVE_MARK, TrHash_num_buckets(hash));
1277 first_bucket = TrHash_buckets(hash);
1278 bucket = first_bucket + TrHash_num_buckets(hash);
1282 traverse_and_save(node, file, float_block);
1284 }
while (
bucket != first_bucket);
1288 if (TrNode_next(node))
1289 traverse_and_save(TrNode_next(node), file, float_block);
1291 t = TrNode_entry(node);
1294 fprintf(file, UInt_FORMAT
" " UInt_FORMAT
" ", FLOAT_SAVE_MARK, t);
1295 }
else if (YAP_IsPairTerm(t)) {
1296 if (t == FloatInitTag) {
1297#ifdef TAG_LOW_BITS_32
1302 fprintf(file, UInt_FORMAT
" ", t);
1303 }
else if (YAP_IsVarTerm(t) || YAP_IsIntTerm(t))
1304 fprintf(file, UInt_FORMAT
" ", t);
1308 if (AUXILIARY_TERM_STACK[
index] == t)
1310 if (
index > CURRENT_INDEX) {
1311 CURRENT_INDEX =
index;
1312 if (CURRENT_INDEX == CURRENT_AUXILIARY_TERM_STACK_SIZE)
1313 expand_auxiliary_term_stack();
1314 AUXILIARY_TERM_STACK[CURRENT_INDEX] = t;
1315 if (YAP_IsAtomTerm(t))
1316 fprintf(file, UInt_FORMAT
" %d %s%c ", ATOM_SAVE_MARK,
index,
1317 YAP_AtomName(YAP_AtomOfTerm(t)),
'\0');
1319 fprintf(file, UInt_FORMAT
" %d %s " UInt_FORMAT
" ", FUNCTOR_SAVE_MARK,
1321 YAP_AtomName(YAP_NameOfFunctor((YAP_Functor)(~ApplTag & t))),
1322 YAP_ArityOfFunctor((YAP_Functor)(~ApplTag & t)));
1323 }
else if (YAP_IsAtomTerm(t))
1324 fprintf(file, UInt_FORMAT
" %d ", ATOM_SAVE_MARK,
index);
1326 fprintf(file, UInt_FORMAT
" %d ", FUNCTOR_SAVE_MARK,
index);
1328 if (IS_LEAF_TRIE_NODE(node)) {
1329 fprintf(file,
"- ");
1330 if (DATA_SAVE_FUNCTION)
1331 (*DATA_SAVE_FUNCTION)(node, file);
1333 traverse_and_save(TrNode_child(node), file, float_block);
1334 fprintf(file,
"- ");
1339static void traverse_and_load(
TrNode parent, FILE *file) {
1344 if (!fscanf(file, UInt_FORMAT, &t)) {
1345 MARK_AS_LEAF_TRIE_NODE(parent);
1346 INCREMENT_ENTRIES(CURRENT_TRIE_ENGINE);
1347 if (DATA_LOAD_FUNCTION)
1348 (*DATA_LOAD_FUNCTION)(parent, CURRENT_DEPTH, file);
1352 if (t == HASH_SAVE_MARK) {
1355 n = fscanf(file,
"%d", &num_buckets);
1356 new_trie_hash(hash, 0, num_buckets);
1357 TrNode_child(parent) = (
TrNode)hash;
1358 n = fscanf(file, UInt_FORMAT, &t);
1362 if (t == ATOM_SAVE_MARK) {
1364 n = fscanf(file,
"%d", &
index);
1365 if (
index > CURRENT_INDEX) {
1367 if (CURRENT_LOAD_VERSION == 2) {
1371 while ((ch = fgetc(file)))
1374 }
else if (CURRENT_LOAD_VERSION == 1) {
1375 n = fscanf(file,
"%s", atom);
1377 CURRENT_INDEX =
index;
1378 if (CURRENT_INDEX == CURRENT_AUXILIARY_TERM_STACK_SIZE)
1379 expand_auxiliary_term_stack();
1380 AUXILIARY_TERM_STACK[CURRENT_INDEX] =
1381 YAP_MkAtomTerm(YAP_LookupAtom(atom));
1383 t = AUXILIARY_TERM_STACK[
index];
1384 }
else if (t == FUNCTOR_SAVE_MARK) {
1386 n = fscanf(file,
"%d", &
index);
1387 if (
index > CURRENT_INDEX) {
1390 n = fscanf(file,
"%s %d", atom, &arity);
1391 CURRENT_INDEX =
index;
1392 if (CURRENT_INDEX == CURRENT_AUXILIARY_TERM_STACK_SIZE)
1393 expand_auxiliary_term_stack();
1394 AUXILIARY_TERM_STACK[CURRENT_INDEX] =
1395 ApplTag | ((YAP_Term)YAP_MkFunctor(YAP_LookupAtom(atom), arity));
1397 t = AUXILIARY_TERM_STACK[
index];
1398 }
else if (t == FLOAT_SAVE_MARK)
1399 n = fscanf(file, UInt_FORMAT, &t);
1400 child = trie_node_insert(parent, t, hash);
1401 traverse_and_load(child, file);
1402 }
while (fscanf(file, UInt_FORMAT, &t));
1409static void traverse_and_print(
TrNode node,
int *arity,
char *str,
1410 int str_index,
int mode) {
1412 int last_pair_mark = -arity[arity[0]];
1414 if (IS_HASH_NODE(node)) {
1415 int *current_arity = (
int *)malloc(
sizeof(
int) * (arity[0] + 1));
1419 first_bucket = TrHash_buckets(hash);
1420 bucket = first_bucket + TrHash_num_buckets(hash);
1421 memmove(current_arity, arity,
sizeof(
int) * (arity[0] + 1));
1425 traverse_and_print(node, arity, str, str_index, mode);
1426 memmove(arity, current_arity,
sizeof(
int) * (current_arity[0] + 1));
1427 if (mode != TRIE_PRINT_FLOAT2 && arity[arity[0]] < 0) {
1430 if (str_index > 0 && str[str_index - 1] !=
'[')
1431 str[str_index - 1] =
',';
1433 if (str[last_pair_mark] ==
'|')
1434 str[last_pair_mark] =
',';
1437 }
while (
bucket != first_bucket);
1438 free(current_arity);
1442 if (TrNode_next(node)) {
1443 int *current_arity = (
int *)malloc(
sizeof(
int) * (arity[0] + 1));
1444 memmove(current_arity, arity,
sizeof(
int) * (arity[0] + 1));
1445 traverse_and_print(TrNode_next(node), arity, str, str_index, mode);
1446 memmove(arity, current_arity,
sizeof(
int) * (current_arity[0] + 1));
1447 if (mode != TRIE_PRINT_FLOAT2 && arity[arity[0]] < 0) {
1450 if (str_index > 0 && str[str_index - 1] !=
'[')
1451 str[str_index - 1] =
',';
1453 if (str[last_pair_mark] ==
'|')
1454 str[last_pair_mark] =
',';
1456 free(current_arity);
1460 if (mode != TRIE_PRINT_FLOAT2 && arity[arity[0]] < 0 && str_index > 1)
1461 arity[arity[0]] = -str_index + 1;
1463 t = TrNode_entry(node);
1464 if (mode == TRIE_PRINT_FLOAT) {
1465#ifdef TAG_LOW_BITS_32
1466 arity[arity[0]] = (YAP_Int)t;
1467 mode = TRIE_PRINT_FLOAT2;
1468 }
else if (mode == TRIE_PRINT_FLOAT2) {
1471 YAP_Term p[SIZE_FLOAT_AS_TERM];
1474 tf.p[0] = (YAP_Term)arity[arity[0]];
1475 arity[arity[0]] = -1;
1479 YAP_Term p[SIZE_FLOAT_AS_TERM];
1483 str_index += sprintf(&str[str_index],
"%.15g", tf.f);
1484 mode = TRIE_PRINT_FLOAT_END;
1485 }
else if (mode == TRIE_PRINT_FLOAT_END) {
1488 if (arity[arity[0]] == 1) {
1489 str_index += sprintf(&str[str_index],
")");
1492 if (arity[arity[0]] > 1)
1494 str_index += sprintf(&str[str_index],
",");
1498 mode = TRIE_PRINT_NORMAL;
1499 }
else if (YAP_IsVarTerm(t)) {
1500 str_index += sprintf(&str[str_index],
"VAR" UInt_FORMAT, TrieVarIndex(t));
1502 if (arity[arity[0]] == 1) {
1503 str_index += sprintf(&str[str_index],
")");
1506 if (arity[arity[0]] > 1)
1508 str_index += sprintf(&str[str_index],
",");
1512 }
else if (YAP_IsAtomTerm(t)) {
1514 sprintf(&str[str_index],
"%s", YAP_AtomName(YAP_AtomOfTerm(t)));
1516 if (arity[arity[0]] == 1) {
1517 str_index += sprintf(&str[str_index],
")");
1520 if (arity[arity[0]] > 1)
1522 str_index += sprintf(&str[str_index],
",");
1526 }
else if (YAP_IsIntTerm(t)) {
1527 str_index += sprintf(&str[str_index], UInt_FORMAT, YAP_IntOfTerm(t));
1529 if (arity[arity[0]] == 1) {
1530 str_index += sprintf(&str[str_index],
")");
1533 if (arity[arity[0]] > 1)
1535 str_index += sprintf(&str[str_index],
",");
1539 }
else if (YAP_IsPairTerm(t)) {
1540 if (t == FloatInitTag) {
1541 mode = TRIE_PRINT_FLOAT;
1543 arity[arity[0]] = -1;
1544 }
else if (t == PairInitTag) {
1545 str_index += sprintf(&str[str_index],
"[");
1547 arity[arity[0]] = -1;
1548 }
else if (t == CommaInitTag) {
1549 str_index += sprintf(&str[str_index],
"(");
1551 arity[arity[0]] = -1;
1553 if (t == PairEndEmptyTag)
1554 str[str_index - 1] =
']';
1555 else if (t == PairEndTermTag) {
1556 str[last_pair_mark] =
'|';
1557 str[str_index - 1] =
']';
1559 str[str_index - 1] =
')';
1562 if (arity[arity[0]] == 1) {
1563 str_index += sprintf(&str[str_index],
")");
1566 if (arity[arity[0]] > 1)
1568 str_index += sprintf(&str[str_index],
",");
1573 }
else if (ApplTag & t) {
1575 sprintf(&str[str_index],
"%s(",
1576 YAP_AtomName(YAP_NameOfFunctor((YAP_Functor)(~ApplTag & t))));
1578 arity[arity[0]] = YAP_ArityOfFunctor((YAP_Functor)(~ApplTag & t));
1580 fprintf(stderr,
"***************************************\n");
1581 fprintf(stderr,
" Tries core module: unknown type tag\n");
1582 fprintf(stderr,
"***************************************\n");
1587 traverse_and_print(TrNode_child(node), arity, str, str_index, mode);
1590 fprintf(stdout,
"%s\n", str);
1591 if (DATA_PRINT_FUNCTION)
1592 (*DATA_PRINT_FUNCTION)(node);
1597static YAP_Term trie_to_list(
TrNode node) {
1598 YAP_Term tail = YAP_MkAtomTerm(YAP_LookupAtom(
"[]"));
1600#define CONSUME_NODE_LIST \
1603 tail = YAP_MkPairTerm(trie_to_list_node(node), tail); \
1604 } while ((node = TrNode_next(node)));
1606 if (IS_HASH_NODE(node)) {
1610 first_bucket = TrHash_buckets(hash);
1611 bucket = first_bucket + TrHash_num_buckets(hash);
1619 }
while (
bucket != first_bucket);
1623#undef CONSUME_NODE_LIST
1629static YAP_Term trie_to_list_node(
TrNode node) {
1630 YAP_Term t = TrNode_entry(node);
1632 if (YAP_IsIntTerm(t) || YAP_IsAtomTerm(t)) {
1633 return trie_to_list_create_two(YAP_IsIntTerm(t) ?
"int" :
"atom", node, t);
1634 }
else if (YAP_IsVarTerm(t)) {
1635 int index = TrieVarIndex(t);
1636 YAP_Term index_term = YAP_MkIntTerm((YAP_Int)
index);
1637 return trie_to_list_create_two(
"var", node, index_term);
1638 }
else if (YAP_IsPairTerm(t)) {
1639 if (t == FloatInitTag) {
1640 node = TrNode_child(node);
1641 YAP_Functor f = YAP_MkFunctor(YAP_LookupAtom(
"floats"), 1);
1642 YAP_Term child = trie_to_list_floats(node);
1643 return YAP_MkApplTerm(f, 1, &child);
1644 }
else if (t == PairInitTag) {
1645 return trie_to_list_create_simple(
"list", node);
1646 }
else if (t == PairEndEmptyTag) {
1647 return trie_to_list_create_simple_end(
"endlist", node);
1648 }
else if (t == CommaInitTag) {
1649 return trie_to_list_create_simple(
"comma", node);
1650 }
else if (t == CommaEndTag) {
1651 return trie_to_list_create_simple_end(
"endcomma", node);
1653 }
else if (ApplTag & t) {
1654 YAP_Functor f = (YAP_Functor)(~ApplTag & t);
1655 int arity = YAP_ArityOfFunctor(f);
1656 YAP_Functor new_f = YAP_MkFunctor(YAP_LookupAtom(
"functor"), 3);
1657 YAP_Term args[3] = {YAP_MkAtomTerm(YAP_NameOfFunctor(f)),
1658 YAP_MkIntTerm((YAP_Int)arity),
1659 trie_to_list(TrNode_child(node))};
1660 return YAP_MkApplTerm(new_f, 3, args);
1662 fprintf(stderr,
"***************************************\n");
1663 fprintf(stderr,
" Tries core module: unknown type tag\n");
1664 fprintf(stderr,
"***************************************\n");
1667 return YAP_MkAtomTerm(YAP_LookupAtom(
"fail"));
1670#define PUSH_NEW_FLOAT_TERM(val) \
1671 result = YAP_MkPairTerm(trie_to_list_create_two("float", TrNode_child(node), \
1672 YAP_MkFloatTerm(val)), \
1675#ifdef TAG_LOW_BITS_32
1677YAP_Term trie_to_list_floats_tag_low_32(YAP_Term result,
TrNode node,
1678 volatile YAP_Term *p,
1679 volatile double *f) {
1680 if (IS_HASH_NODE(node)) {
1684 first_bucket = TrHash_buckets(hash);
1685 bucket = first_bucket + TrHash_num_buckets(hash);
1691 p[1] = TrNode_entry(node);
1692 PUSH_NEW_FLOAT_TERM(*f);
1693 }
while ((node = TrNode_next(node)));
1695 }
while (
bucket != first_bucket);
1698 p[1] = TrNode_entry(node);
1699 PUSH_NEW_FLOAT_TERM(*f);
1700 }
while ((node = TrNode_next(node)));
1707static YAP_Term trie_to_list_floats(
TrNode node) {
1710 YAP_Term p[SIZE_FLOAT_AS_TERM];
1712 YAP_Term result = YAP_MkAtomTerm(YAP_LookupAtom(
"[]"));
1714 if (IS_HASH_NODE(node)) {
1717 first_bucket = TrHash_buckets(hash);
1718 bucket = first_bucket + TrHash_num_buckets(hash);
1723 tf.p[0] = TrNode_entry(node);
1724#ifdef TAG_LOW_BITS_32
1725 result = trie_to_list_floats_tag_low_32(result, TrNode_child(node),
1728 PUSH_NEW_FLOAT_TERM(tf.f);
1730 }
while ((node = TrNode_next(node)));
1732 }
while (
bucket != first_bucket);
1735 tf.p[0] = TrNode_entry(node);
1736#ifdef TAG_LOW_BITS_32
1737 result = trie_to_list_floats_tag_low_32(result, TrNode_child(node), &tf.p,
1740 PUSH_NEW_FLOAT_TERM(tf.f);
1742 }
while ((node = TrNode_next(node)));
1747#undef PUSH_NEW_FLOAT_TERM
1749#include "core_dbtries.c"
#define YAP_Deref(t)
X_API macro.