fix recursive functions that manipulate tries

This commit is contained in:
Ricardo Rocha 2009-08-05 05:48:00 +01:00
parent f68cc92bce
commit cf5d68edda
5 changed files with 461 additions and 399 deletions

View File

@ -52,7 +52,7 @@ extern int Yap_page_size;
#define UPDATE_STATS(STAT, VALUE) STAT += VALUE #define UPDATE_STATS(STAT, VALUE) STAT += VALUE
#ifdef MALLOC_MEMORY_ALLOC_SCHEME /* ------------------------------------------------ */ #ifdef MALLOC_MEMORY_ALLOC_SCHEME /* ---------------------------------------------------------------- */
#define ALLOC_STRUCT(STR, STR_PAGES, STR_TYPE) \ #define ALLOC_STRUCT(STR, STR_PAGES, STR_TYPE) \
UPDATE_STATS(Pg_str_in_use(STR_PAGES), 1); \ UPDATE_STATS(Pg_str_in_use(STR_PAGES), 1); \
if ((STR = (STR_TYPE *)malloc(sizeof(STR_TYPE))) == NULL) \ if ((STR = (STR_TYPE *)malloc(sizeof(STR_TYPE))) == NULL) \
@ -62,7 +62,7 @@ extern int Yap_page_size;
#define FREE_STRUCT(STR, STR_PAGES, STR_TYPE) \ #define FREE_STRUCT(STR, STR_PAGES, STR_TYPE) \
UPDATE_STATS(Pg_str_in_use(STR_PAGES), -1); \ UPDATE_STATS(Pg_str_in_use(STR_PAGES), -1); \
free(STR) free(STR)
#elif YAP_MEMORY_ALLOC_SCHEME /* ---------------------------------------------------- */ #elif YAP_MEMORY_ALLOC_SCHEME /* -------------------------------------------------------------------- */
#define ALLOC_STRUCT(STR, STR_PAGES, STR_TYPE) \ #define ALLOC_STRUCT(STR, STR_PAGES, STR_TYPE) \
{ char *ptr = Yap_AllocCodeSpace(sizeof(STR_TYPE) + sizeof(CELL)); \ { char *ptr = Yap_AllocCodeSpace(sizeof(STR_TYPE) + sizeof(CELL)); \
if (ptr) { \ if (ptr) { \
@ -92,7 +92,7 @@ extern int Yap_page_size;
free(ptr); \ free(ptr); \
UPDATE_STATS(Pg_str_in_use(STR_PAGES), -1); \ UPDATE_STATS(Pg_str_in_use(STR_PAGES), -1); \
} }
#elif SHM_MEMORY_ALLOC_SCHEME /* ---------------------------------------------------- */ #elif SHM_MEMORY_ALLOC_SCHEME /* -------------------------------------------------------------------- */
#ifdef LIMIT_TABLING #ifdef LIMIT_TABLING
#define INIT_PAGE(PG_HD, STR_PAGES, STR_TYPE) \ #define INIT_PAGE(PG_HD, STR_PAGES, STR_TYPE) \
{ int i; \ { int i; \
@ -152,7 +152,7 @@ extern int Yap_page_size;
SgFr_hash_chain(sg_fr) = NULL; \ SgFr_hash_chain(sg_fr) = NULL; \
SgFr_first_answer(sg_fr) = NULL; \ SgFr_first_answer(sg_fr) = NULL; \
SgFr_last_answer(sg_fr) = NULL; \ SgFr_last_answer(sg_fr) = NULL; \
free_answer_trie_branch(TrNode_child(SgFr_answer_trie(sg_fr))); \ free_answer_trie_branch(TrNode_child(SgFr_answer_trie(sg_fr)), TRAVERSE_POSITION_FIRST); \
TrNode_child(SgFr_answer_trie(sg_fr)) = NULL; \ TrNode_child(SgFr_answer_trie(sg_fr)) = NULL; \
} \ } \
} while (Pg_free_pg(GLOBAL_PAGES_void) == Pg_free_pg(STR_PAGES)); \ } while (Pg_free_pg(GLOBAL_PAGES_void) == Pg_free_pg(STR_PAGES)); \
@ -357,7 +357,7 @@ extern int Yap_page_size;
UNLOCK(Pg_lock(STR_PAGES)); \ UNLOCK(Pg_lock(STR_PAGES)); \
} \ } \
} }
#endif /* --------------------------- MEMORY_ALLOC_SCHEME ---------------------------- */ #endif /* --------------------------- MEMORY_ALLOC_SCHEME -------------------------------------------- */

View File

@ -684,7 +684,7 @@ Int p_abolish_table(void) {
sg_node = TrNode_child(TabEnt_subgoal_trie(tab_ent)); sg_node = TrNode_child(TabEnt_subgoal_trie(tab_ent));
if (sg_node) { if (sg_node) {
TrNode_child(TabEnt_subgoal_trie(tab_ent)) = NULL; TrNode_child(TabEnt_subgoal_trie(tab_ent)) = NULL;
free_subgoal_trie_branch(sg_node, TabEnt_arity(tab_ent), 0); free_subgoal_trie_branch(sg_node, TabEnt_arity(tab_ent), 0, TRAVERSE_POSITION_FIRST);
} }
return (TRUE); return (TRUE);
} }
@ -704,7 +704,7 @@ Int p_abolish_all_tables(void) {
sg_node = TrNode_child(TabEnt_subgoal_trie(tab_ent)); sg_node = TrNode_child(TabEnt_subgoal_trie(tab_ent));
if (sg_node) { if (sg_node) {
TrNode_child(TabEnt_subgoal_trie(tab_ent)) = NULL; TrNode_child(TabEnt_subgoal_trie(tab_ent)) = NULL;
free_subgoal_trie_branch(sg_node, TabEnt_arity(tab_ent), 0); free_subgoal_trie_branch(sg_node, TabEnt_arity(tab_ent), 0, TRAVERSE_POSITION_FIRST);
} }
tab_ent = TabEnt_next(tab_ent); tab_ent = TabEnt_next(tab_ent);
} }

View File

@ -67,8 +67,8 @@ sg_fr_ptr subgoal_search(yamop *preg, CELL **Yaddr);
ans_node_ptr answer_search(sg_fr_ptr sg_fr, CELL *subs_ptr); ans_node_ptr answer_search(sg_fr_ptr sg_fr, CELL *subs_ptr);
void load_answer_trie(ans_node_ptr ans_node, CELL *subs_ptr); void load_answer_trie(ans_node_ptr ans_node, CELL *subs_ptr);
void private_completion(sg_fr_ptr sg_fr); void private_completion(sg_fr_ptr sg_fr);
void free_subgoal_trie_branch(sg_node_ptr node, int nodes_left, int nodes_extra); void free_subgoal_trie_branch(sg_node_ptr node, int nodes_left, int nodes_extra, int position);
void free_answer_trie_branch(ans_node_ptr node); void free_answer_trie_branch(ans_node_ptr node, int position);
void update_answer_trie(sg_fr_ptr sg_fr); void update_answer_trie(sg_fr_ptr sg_fr);
void traverse_table(tab_ent_ptr tab_ent, int show_table); void traverse_table(tab_ent_ptr tab_ent, int show_table);
void table_stats(void); void table_stats(void);

View File

@ -57,6 +57,23 @@ STD_PROTO(static inline tg_sol_fr_ptr CUT_prune_tg_solution_frames, (tg_sol_fr_p
/* ----------------- **
** Defines **
** ----------------- */
#define TRAVERSE_MODE_NORMAL 0
#define TRAVERSE_MODE_FLOAT 1
#define TRAVERSE_MODE_FLOAT2 2
#define TRAVERSE_MODE_FLOAT_END 3
#define TRAVERSE_MODE_LONG 4
#define TRAVERSE_MODE_LONG_END 5
/* do not change order !!! */
#define TRAVERSE_POSITION_NEXT 0
#define TRAVERSE_POSITION_FIRST 1
#define TRAVERSE_POSITION_LAST 2
/* ----------------------- ** /* ----------------------- **
** Tabling Macros ** ** Tabling Macros **
** ----------------------- */ ** ----------------------- */
@ -609,7 +626,7 @@ void abolish_incomplete_subgoals(choiceptr prune_cp) {
node = TrNode_child(SgFr_answer_trie(sg_fr)); node = TrNode_child(SgFr_answer_trie(sg_fr));
TrNode_child(SgFr_answer_trie(sg_fr)) = NULL; TrNode_child(SgFr_answer_trie(sg_fr)) = NULL;
UNLOCK(SgFr_lock(sg_fr)); UNLOCK(SgFr_lock(sg_fr));
free_answer_trie_branch(node); free_answer_trie_branch(node, TRAVERSE_POSITION_FIRST);
#endif /* INCOMPLETE_TABLING */ #endif /* INCOMPLETE_TABLING */
} }
#ifdef LIMIT_TABLING #ifdef LIMIT_TABLING

View File

@ -25,19 +25,6 @@
#include "tab.macros.h" #include "tab.macros.h"
/* ----------------- **
** Defines **
** ----------------- */
#define TRAVERSE_NORMAL 0
#define TRAVERSE_FLOAT 1
#define TRAVERSE_FLOAT2 2
#define TRAVERSE_FLOAT_END 3
#define TRAVERSE_LONG 4
#define TRAVERSE_LONG_END 5
/* ------------------------------------- ** /* ------------------------------------- **
** Local functions declaration ** ** Local functions declaration **
** ------------------------------------- */ ** ------------------------------------- */
@ -49,10 +36,10 @@ static int update_answer_trie_branch(ans_node_ptr previous_node, ans_node_ptr no
static int update_answer_trie_branch(ans_node_ptr node); static int update_answer_trie_branch(ans_node_ptr node);
#endif /* TABLING_INNER_CUTS */ #endif /* TABLING_INNER_CUTS */
#else #else
static void update_answer_trie_branch(ans_node_ptr node); static void update_answer_trie_branch(ans_node_ptr node, int position);
#endif /* YAPOR */ #endif /* YAPOR */
static void traverse_subgoal_trie(sg_node_ptr sg_node, char *str, int str_index, int *arity, int depth, int mode); static void traverse_subgoal_trie(sg_node_ptr sg_node, char *str, int str_index, int *arity, int depth, int mode, int position);
static void traverse_answer_trie(ans_node_ptr ans_node, char *str, int str_index, int *arity, int var_index, int depth, int mode); static void traverse_answer_trie(ans_node_ptr ans_node, char *str, int str_index, int *arity, int var_index, int depth, int mode, int position);
@ -1104,9 +1091,14 @@ void private_completion(sg_fr_ptr sg_fr) {
} }
void free_subgoal_trie_branch(sg_node_ptr node, int nodes_left, int nodes_extra) { void free_subgoal_trie_branch(sg_node_ptr node, int nodes_left, int nodes_extra, int position) {
if (TrNode_next(node)) int current_nodes_left = 0, current_nodes_extra = 0;
free_subgoal_trie_branch(TrNode_next(node), nodes_left, nodes_extra);
/* save current state if first sibling node */
if (position == TRAVERSE_POSITION_FIRST) {
current_nodes_left = nodes_left;
current_nodes_extra = nodes_extra;
}
if (nodes_extra) { if (nodes_extra) {
#ifdef TRIE_COMPACT_PAIRS #ifdef TRIE_COMPACT_PAIRS
@ -1148,7 +1140,7 @@ void free_subgoal_trie_branch(sg_node_ptr node, int nodes_left, int nodes_extra)
} }
} }
if (nodes_left) if (nodes_left)
free_subgoal_trie_branch(TrNode_child(node), nodes_left, nodes_extra); free_subgoal_trie_branch(TrNode_child(node), nodes_left, nodes_extra, TRAVERSE_POSITION_FIRST);
else { else {
sg_fr_ptr sg_fr; sg_fr_ptr sg_fr;
ans_node_ptr ans_node; ans_node_ptr ans_node;
@ -1156,7 +1148,7 @@ void free_subgoal_trie_branch(sg_node_ptr node, int nodes_left, int nodes_extra)
free_answer_hash_chain(SgFr_hash_chain(sg_fr)); free_answer_hash_chain(SgFr_hash_chain(sg_fr));
ans_node = SgFr_answer_trie(sg_fr); ans_node = SgFr_answer_trie(sg_fr);
if (TrNode_child(ans_node)) if (TrNode_child(ans_node))
free_answer_trie_branch(TrNode_child(ans_node)); free_answer_trie_branch(TrNode_child(ans_node), TRAVERSE_POSITION_FIRST);
FREE_ANSWER_TRIE_NODE(ans_node); FREE_ANSWER_TRIE_NODE(ans_node);
#ifdef LIMIT_TABLING #ifdef LIMIT_TABLING
remove_from_global_sg_fr_list(sg_fr); remove_from_global_sg_fr_list(sg_fr);
@ -1164,20 +1156,40 @@ void free_subgoal_trie_branch(sg_node_ptr node, int nodes_left, int nodes_extra)
FREE_SUBGOAL_FRAME(sg_fr); FREE_SUBGOAL_FRAME(sg_fr);
} }
if (position == TRAVERSE_POSITION_FIRST) {
sg_node_ptr next = TrNode_next(node);
FREE_SUBGOAL_TRIE_NODE(node);
/* restore the initial state */
nodes_left = current_nodes_left;
nodes_extra = current_nodes_extra;
while (next) {
node = next;
next = TrNode_next(node);
free_subgoal_trie_branch(node, nodes_left, nodes_extra, TRAVERSE_POSITION_NEXT);
}
} else
FREE_SUBGOAL_TRIE_NODE(node); FREE_SUBGOAL_TRIE_NODE(node);
return; return;
} }
void free_answer_trie_branch(ans_node_ptr node) { void free_answer_trie_branch(ans_node_ptr node, int position) {
#ifdef TABLING_INNER_CUTS #ifdef TABLING_INNER_CUTS
if (TrNode_child(node) && ! IS_ANSWER_LEAF_NODE(node)) if (TrNode_child(node) && ! IS_ANSWER_LEAF_NODE(node))
#else #else
if (! IS_ANSWER_LEAF_NODE(node)) if (! IS_ANSWER_LEAF_NODE(node))
#endif /* TABLING_INNER_CUTS */ #endif /* TABLING_INNER_CUTS */
free_answer_trie_branch(TrNode_child(node)); free_answer_trie_branch(TrNode_child(node), TRAVERSE_POSITION_FIRST);
if (TrNode_next(node))
free_answer_trie_branch(TrNode_next(node)); if (position == TRAVERSE_POSITION_FIRST) {
ans_node_ptr next = TrNode_next(node);
FREE_ANSWER_TRIE_NODE(node);
while (next) {
node = next;
next = TrNode_next(node);
free_answer_trie_branch(node, TRAVERSE_POSITION_NEXT);
}
} else
FREE_ANSWER_TRIE_NODE(node); FREE_ANSWER_TRIE_NODE(node);
return; return;
} }
@ -1188,16 +1200,20 @@ void update_answer_trie(sg_fr_ptr sg_fr) {
free_answer_hash_chain(SgFr_hash_chain(sg_fr)); free_answer_hash_chain(SgFr_hash_chain(sg_fr));
SgFr_hash_chain(sg_fr) = NULL; SgFr_hash_chain(sg_fr) = NULL;
SgFr_state(sg_fr) += 2; /* complete --> compiled : complete_in_use --> compiled_in_use */
node = TrNode_child(SgFr_answer_trie(sg_fr)); node = TrNode_child(SgFr_answer_trie(sg_fr));
if (node) { if (node) {
#ifdef YAPOR
TrNode_instr(node) -= 1; TrNode_instr(node) -= 1;
#ifdef TABLING_INNER_CUTS #ifdef TABLING_INNER_CUTS
update_answer_trie_branch(NULL, node); update_answer_trie_branch(NULL, node);
#else #else
update_answer_trie_branch(node); update_answer_trie_branch(node);
#endif /* TABLING_INNER_CUTS */ #endif /* TABLING_INNER_CUTS */
#else /* TABLING */
update_answer_trie_branch(node, TRAVERSE_POSITION_FIRST);
#endif /* YAPOR */
} }
SgFr_state(sg_fr) += 2; /* complete --> compiled : complete_in_use --> compiled_in_use */
return; return;
} }
@ -1265,7 +1281,7 @@ void traverse_table(tab_ent_ptr tab_ent, int show_table) {
int *arity = (int *) malloc(sizeof(int) * ARITY_ARRAY_SIZE); int *arity = (int *) malloc(sizeof(int) * ARITY_ARRAY_SIZE);
arity[0] = 1; arity[0] = 1;
arity[1] = TabEnt_arity(tab_ent); arity[1] = TabEnt_arity(tab_ent);
traverse_subgoal_trie(sg_node, str, str_index, arity, 1, TRAVERSE_NORMAL); traverse_subgoal_trie(sg_node, str, str_index, arity, 1, TRAVERSE_MODE_NORMAL, TRAVERSE_POSITION_FIRST);
free(str); free(str);
free(arity); free(arity);
} else { } else {
@ -1399,39 +1415,43 @@ int update_answer_trie_branch(ans_node_ptr node) {
#endif /* TABLING_INNER_CUTS */ #endif /* TABLING_INNER_CUTS */
#else /* TABLING */ #else /* TABLING */
static static
void update_answer_trie_branch(ans_node_ptr node) { void update_answer_trie_branch(ans_node_ptr node, int position) {
if (! IS_ANSWER_LEAF_NODE(node)) { if (! IS_ANSWER_LEAF_NODE(node))
TrNode_instr(TrNode_child(node)) -= 1; /* retry --> try */ update_answer_trie_branch(TrNode_child(node), TRAVERSE_POSITION_FIRST); /* retry --> try */
update_answer_trie_branch(TrNode_child(node)); if (position == TRAVERSE_POSITION_FIRST) {
ans_node_ptr next = TrNode_next(node);
if (next) {
while (TrNode_next(next)) {
update_answer_trie_branch(next, TRAVERSE_POSITION_NEXT); /* retry --> retry */
next = TrNode_next(next);
} }
if (TrNode_next(node)) { update_answer_trie_branch(next, TRAVERSE_POSITION_LAST); /* retry --> trust */
update_answer_trie_branch(TrNode_next(node)); } else
} else { position += TRAVERSE_POSITION_LAST; /* try --> do */
TrNode_instr(node) -= 2; /* retry --> trust : try --> do */
} }
TrNode_instr(node) = Yap_opcode(TrNode_instr(node)); TrNode_instr(node) = Yap_opcode(TrNode_instr(node) - position);
return; return;
} }
#endif /* YAPOR */ #endif /* YAPOR */
static static
void traverse_subgoal_trie(sg_node_ptr sg_node, char *str, int str_index, int *arity, int depth, int mode) { void traverse_subgoal_trie(sg_node_ptr sg_node, char *str, int str_index, int *arity, int depth, int mode, int position) {
int *current_arity = NULL, current_str_index = 0, current_mode = 0;
Term t; Term t;
/* test if hashing */ /* test if hashing */
if (IS_SUBGOAL_HASH(sg_node)) { if (IS_SUBGOAL_HASH(sg_node)) {
sg_node_ptr *bucket, *last_bucket; sg_node_ptr *bucket, *last_bucket;
sg_hash_ptr hash; sg_hash_ptr hash;
int *current_arity = (int *) malloc(sizeof(int) * (arity[0] + 1));
memcpy(current_arity, arity, sizeof(int) * (arity[0] + 1));
hash = (sg_hash_ptr) sg_node; hash = (sg_hash_ptr) sg_node;
bucket = Hash_buckets(hash); bucket = Hash_buckets(hash);
last_bucket = bucket + Hash_num_buckets(hash); last_bucket = bucket + Hash_num_buckets(hash);
current_arity = (int *) malloc(sizeof(int) * (arity[0] + 1));
memcpy(current_arity, arity, sizeof(int) * (arity[0] + 1));
do { do {
if (*bucket) { if (*bucket) {
sg_node = *bucket; traverse_subgoal_trie(*bucket, str, str_index, arity, depth, mode, TRAVERSE_POSITION_FIRST);
traverse_subgoal_trie(sg_node, str, str_index, arity, depth, mode);
memcpy(arity, current_arity, sizeof(int) * (current_arity[0] + 1)); memcpy(arity, current_arity, sizeof(int) * (current_arity[0] + 1));
#ifdef TRIE_COMPACT_PAIRS #ifdef TRIE_COMPACT_PAIRS
if (arity[arity[0]] == -2 && str[str_index - 1] != '[') if (arity[arity[0]] == -2 && str[str_index - 1] != '[')
@ -1446,37 +1466,29 @@ void traverse_subgoal_trie(sg_node_ptr sg_node, char *str, int str_index, int *a
return; return;
} }
/* test if sibling node */ /* save current state if first sibling node */
if (TrNode_next(sg_node)) { if (position == TRAVERSE_POSITION_FIRST) {
int *current_arity = (int *) malloc(sizeof(int) * (arity[0] + 1)); current_arity = (int *) malloc(sizeof(int) * (arity[0] + 1));
memcpy(current_arity, arity, sizeof(int) * (arity[0] + 1)); memcpy(current_arity, arity, sizeof(int) * (arity[0] + 1));
traverse_subgoal_trie(TrNode_next(sg_node), str, str_index, arity, depth, mode); current_str_index = str_index;
memcpy(arity, current_arity, sizeof(int) * (current_arity[0] + 1)); current_mode = mode;
free(current_arity);
#ifdef TRIE_COMPACT_PAIRS
if (arity[arity[0]] == -2 && str[str_index - 1] != '[')
str[str_index - 1] = ',';
#else
if (arity[arity[0]] == -1)
str[str_index - 1] = '|';
#endif /* TRIE_COMPACT_PAIRS */
} }
/* test the node type */ /* test the node type */
t = TrNode_entry(sg_node); t = TrNode_entry(sg_node);
#if SIZEOF_DOUBLE == 2 * SIZEOF_INT_P #if SIZEOF_DOUBLE == 2 * SIZEOF_INT_P
if (mode == TRAVERSE_FLOAT) { if (mode == TRAVERSE_MODE_FLOAT) {
arity[0]++; arity[0]++;
arity[arity[0]] = (int) t; arity[arity[0]] = (int) t;
mode = TRAVERSE_FLOAT2; mode = TRAVERSE_MODE_FLOAT2;
} else if (mode == TRAVERSE_FLOAT2) { } else if (mode == TRAVERSE_MODE_FLOAT2) {
volatile Float dbl; volatile Float dbl;
volatile Term *t_dbl = (Term *)((void *) &dbl); volatile Term *t_dbl = (Term *)((void *) &dbl);
*t_dbl = t; *t_dbl = t;
*(t_dbl + 1) = (Term) arity[arity[0]]; *(t_dbl + 1) = (Term) arity[arity[0]];
arity[0]--; arity[0]--;
#else /* SIZEOF_DOUBLE == SIZEOF_INT_P */ #else /* SIZEOF_DOUBLE == SIZEOF_INT_P */
if (mode == TRAVERSE_FLOAT) { if (mode == TRAVERSE_MODE_FLOAT) {
volatile Float dbl; volatile Float dbl;
volatile Term *t_dbl = (Term *)((void *) &dbl); volatile Term *t_dbl = (Term *)((void *) &dbl);
*t_dbl = t; *t_dbl = t;
@ -1507,8 +1519,8 @@ void traverse_subgoal_trie(sg_node_ptr sg_node, char *str, int str_index, int *a
} }
} }
} }
mode = TRAVERSE_NORMAL; mode = TRAVERSE_MODE_NORMAL;
} else if (mode == TRAVERSE_LONG) { } else if (mode == TRAVERSE_MODE_LONG) {
Int li = (Int) t; Int li = (Int) t;
#if SHORT_INTS #if SHORT_INTS
str_index += sprintf(& str[str_index], "%ld", li); str_index += sprintf(& str[str_index], "%ld", li);
@ -1540,7 +1552,7 @@ void traverse_subgoal_trie(sg_node_ptr sg_node, char *str, int str_index, int *a
} }
} }
} }
mode = TRAVERSE_NORMAL; mode = TRAVERSE_MODE_NORMAL;
} else if (IsVarTerm(t)) { } else if (IsVarTerm(t)) {
#if SHORT_INTS #if SHORT_INTS
str_index += sprintf(& str[str_index], "VAR%ld", VarIndexOfTableTerm(t)); str_index += sprintf(& str[str_index], "VAR%ld", VarIndexOfTableTerm(t));
@ -1656,9 +1668,9 @@ void traverse_subgoal_trie(sg_node_ptr sg_node, char *str, int str_index, int *a
} else if (IsApplTerm(t)) { } else if (IsApplTerm(t)) {
Functor f = (Functor) RepAppl(t); Functor f = (Functor) RepAppl(t);
if (f == FunctorDouble) { if (f == FunctorDouble) {
mode = TRAVERSE_FLOAT; mode = TRAVERSE_MODE_FLOAT;
} else if (f == FunctorLongInt) { } else if (f == FunctorLongInt) {
mode = TRAVERSE_LONG; mode = TRAVERSE_MODE_LONG;
} else { } else {
str_index += sprintf(& str[str_index], "%s(", AtomName(NameOfFunctor(f))); str_index += sprintf(& str[str_index], "%s(", AtomName(NameOfFunctor(f)));
arity[0]++; arity[0]++;
@ -1702,39 +1714,59 @@ void traverse_subgoal_trie(sg_node_ptr sg_node, char *str, int str_index, int *a
SHOW_TABLE(" TRUE\n"); SHOW_TABLE(" TRUE\n");
} else { } else {
arity[0] = 0; arity[0] = 0;
traverse_answer_trie(TrNode_child(SgFr_answer_trie(sg_fr)), &str[str_index], 0, arity, 0, 1, TRAVERSE_NORMAL); traverse_answer_trie(TrNode_child(SgFr_answer_trie(sg_fr)), &str[str_index], 0, arity, 0, 1, TRAVERSE_MODE_NORMAL, TRAVERSE_POSITION_FIRST);
if (SgFr_state(sg_fr) < complete) { if (SgFr_state(sg_fr) < complete) {
TrStat_sg_incomplete++; TrStat_sg_incomplete++;
SHOW_TABLE(" ---> INCOMPLETE\n"); SHOW_TABLE(" ---> INCOMPLETE\n");
} }
} }
} }
/* ... or continue with child node */ /* ... or continue with child node */
else else
traverse_subgoal_trie(TrNode_child(sg_node), str, str_index, arity, depth + 1, mode); traverse_subgoal_trie(TrNode_child(sg_node), str, str_index, arity, depth + 1, mode, TRAVERSE_POSITION_FIRST);
/* continue iteratively with sibling nodes */
if (position == TRAVERSE_POSITION_FIRST) {
/* restore the initial state */
str_index = current_str_index;
mode = current_mode;
sg_node = TrNode_next(sg_node);
while (sg_node) {
memcpy(arity, current_arity, sizeof(int) * (current_arity[0] + 1));
#ifdef TRIE_COMPACT_PAIRS
if (arity[arity[0]] == -2 && str[str_index - 1] != '[')
str[str_index - 1] = ',';
#else
if (arity[arity[0]] == -1)
str[str_index - 1] = '|';
#endif /* TRIE_COMPACT_PAIRS */
traverse_subgoal_trie(sg_node, str, str_index, arity, depth, mode, TRAVERSE_POSITION_NEXT);
sg_node = TrNode_next(sg_node);
}
free(current_arity);
}
return; return;
} }
static static
void traverse_answer_trie(ans_node_ptr ans_node, char *str, int str_index, int *arity, int var_index, int depth, int mode) { void traverse_answer_trie(ans_node_ptr ans_node, char *str, int str_index, int *arity, int var_index, int depth, int mode, int position) {
int *current_arity = NULL, current_str_index = 0, current_var_index = 0, current_mode = 0;
Term t; Term t;
/* test if hashing */ /* test if hashing */
if (IS_ANSWER_HASH(ans_node)) { if (IS_ANSWER_HASH(ans_node)) {
ans_node_ptr *bucket, *last_bucket; ans_node_ptr *bucket, *last_bucket;
ans_hash_ptr hash; ans_hash_ptr hash;
int *current_arity = (int *) malloc(sizeof(int) * (arity[0] + 1));
memcpy(current_arity, arity, sizeof(int) * (arity[0] + 1));
hash = (ans_hash_ptr) ans_node; hash = (ans_hash_ptr) ans_node;
bucket = Hash_buckets(hash); bucket = Hash_buckets(hash);
last_bucket = bucket + Hash_num_buckets(hash); last_bucket = bucket + Hash_num_buckets(hash);
current_arity = (int *) malloc(sizeof(int) * (arity[0] + 1));
memcpy(current_arity, arity, sizeof(int) * (arity[0] + 1));
do { do {
if (*bucket) { if (*bucket) {
ans_node = *bucket; traverse_answer_trie(*bucket, str, str_index, arity, var_index, depth, mode, TRAVERSE_POSITION_FIRST);
traverse_answer_trie(ans_node, str, str_index, arity, var_index, depth, mode);
memcpy(arity, current_arity, sizeof(int) * (current_arity[0] + 1)); memcpy(arity, current_arity, sizeof(int) * (current_arity[0] + 1));
#ifdef TRIE_COMPACT_PAIRS #ifdef TRIE_COMPACT_PAIRS
if (arity[arity[0]] == -2 && str[str_index - 1] != '[') if (arity[arity[0]] == -2 && str[str_index - 1] != '[')
@ -1749,36 +1781,29 @@ void traverse_answer_trie(ans_node_ptr ans_node, char *str, int str_index, int *
return; return;
} }
/* test if sibling node */ /* save current state if first sibling node */
if (TrNode_next(ans_node)) { if (position == TRAVERSE_POSITION_FIRST) {
int *current_arity = (int *) malloc(sizeof(int) * (arity[0] + 1)); current_arity = (int *) malloc(sizeof(int) * (arity[0] + 1));
memcpy(current_arity, arity, sizeof(int) * (arity[0] + 1)); memcpy(current_arity, arity, sizeof(int) * (arity[0] + 1));
traverse_answer_trie(TrNode_next(ans_node), str, str_index, arity, var_index, depth, mode); current_str_index = str_index;
memcpy(arity, current_arity, sizeof(int) * (current_arity[0] + 1)); current_var_index = var_index;
free(current_arity); current_mode = mode;
#ifdef TRIE_COMPACT_PAIRS
if (arity[arity[0]] == -2 && str[str_index - 1] != '[')
str[str_index - 1] = ',';
#else
if (arity[arity[0]] == -1)
str[str_index - 1] = '|';
#endif /* TRIE_COMPACT_PAIRS */
} }
/* print VAR when starting a term */ /* print VAR when starting a term */
if (arity[0] == 0 && mode == TRAVERSE_NORMAL) { if (arity[0] == 0 && mode == TRAVERSE_MODE_NORMAL) {
str_index += sprintf(& str[str_index], " VAR%d: ", var_index); str_index += sprintf(& str[str_index], " VAR%d: ", var_index);
var_index++; var_index++;
} }
/* test the node type */ /* test the node type */
t = TrNode_entry(ans_node); t = TrNode_entry(ans_node);
if (mode == TRAVERSE_FLOAT) { if (mode == TRAVERSE_MODE_FLOAT) {
#if SIZEOF_DOUBLE == 2 * SIZEOF_INT_P #if SIZEOF_DOUBLE == 2 * SIZEOF_INT_P
arity[0]++; arity[0]++;
arity[arity[0]] = (int) t; arity[arity[0]] = (int) t;
mode = TRAVERSE_FLOAT2; mode = TRAVERSE_MODE_FLOAT2;
} else if (mode == TRAVERSE_FLOAT2) { } else if (mode == TRAVERSE_MODE_FLOAT2) {
volatile Float dbl; volatile Float dbl;
volatile Term *t_dbl = (Term *)((void *) &dbl); volatile Term *t_dbl = (Term *)((void *) &dbl);
*t_dbl = t; *t_dbl = t;
@ -1815,10 +1840,10 @@ void traverse_answer_trie(ans_node_ptr ans_node, char *str, int str_index, int *
} }
} }
} }
mode = TRAVERSE_FLOAT_END; mode = TRAVERSE_MODE_FLOAT_END;
} else if (mode == TRAVERSE_FLOAT_END) { } else if (mode == TRAVERSE_MODE_FLOAT_END) {
mode = TRAVERSE_NORMAL; mode = TRAVERSE_MODE_NORMAL;
} else if (mode == TRAVERSE_LONG) { } else if (mode == TRAVERSE_MODE_LONG) {
Int li = (Int) t; Int li = (Int) t;
#if SHORT_INTS #if SHORT_INTS
str_index += sprintf(& str[str_index], "%ld", li); str_index += sprintf(& str[str_index], "%ld", li);
@ -1850,9 +1875,9 @@ void traverse_answer_trie(ans_node_ptr ans_node, char *str, int str_index, int *
} }
} }
} }
mode = TRAVERSE_LONG_END; mode = TRAVERSE_MODE_LONG_END;
} else if (mode == TRAVERSE_LONG_END) { } else if (mode == TRAVERSE_MODE_LONG_END) {
mode = TRAVERSE_NORMAL; mode = TRAVERSE_MODE_NORMAL;
} else if (IsVarTerm(t)) { } else if (IsVarTerm(t)) {
#if SHORT_INTS #if SHORT_INTS
str_index += sprintf(& str[str_index], "ANSVAR%ld", VarIndexOfTableTerm(t)); str_index += sprintf(& str[str_index], "ANSVAR%ld", VarIndexOfTableTerm(t));
@ -1968,9 +1993,9 @@ void traverse_answer_trie(ans_node_ptr ans_node, char *str, int str_index, int *
} else if (IsApplTerm(t)) { } else if (IsApplTerm(t)) {
Functor f = (Functor) RepAppl(t); Functor f = (Functor) RepAppl(t);
if (f == FunctorDouble) { if (f == FunctorDouble) {
mode = TRAVERSE_FLOAT; mode = TRAVERSE_MODE_FLOAT;
} else if (f == FunctorLongInt) { } else if (f == FunctorLongInt) {
mode = TRAVERSE_LONG; mode = TRAVERSE_MODE_LONG;
} else { } else {
str_index += sprintf(& str[str_index], "%s(", AtomName(NameOfFunctor(f))); str_index += sprintf(& str[str_index], "%s(", AtomName(NameOfFunctor(f)));
arity[0]++; arity[0]++;
@ -1992,16 +2017,36 @@ void traverse_answer_trie(ans_node_ptr ans_node, char *str, int str_index, int *
else if (depth > TrStat_ans_max_depth) else if (depth > TrStat_ans_max_depth)
TrStat_ans_max_depth = depth; TrStat_ans_max_depth = depth;
} }
#ifdef TABLING_INNER_CUTS #ifdef TABLING_INNER_CUTS
/* ... or continue with pruned node */ /* ... or continue with pruned node */
else if (TrNode_child(ans_node) == NULL) else if (TrNode_child(ans_node) == NULL)
TrStat_ans_pruned++; TrStat_ans_pruned++;
#endif /* TABLING_INNER_CUTS */ #endif /* TABLING_INNER_CUTS */
/* ... or continue with child node */ /* ... or continue with child node */
else else
traverse_answer_trie(TrNode_child(ans_node), str, str_index, arity, var_index, depth + 1, mode); traverse_answer_trie(TrNode_child(ans_node), str, str_index, arity, var_index, depth + 1, mode, TRAVERSE_POSITION_FIRST);
/* continue iteratively with sibling nodes */
if (position == TRAVERSE_POSITION_FIRST) {
/* restore the initial state */
str_index = current_str_index;
var_index = current_var_index;
mode = current_mode;
ans_node = TrNode_next(ans_node);
while (ans_node) {
memcpy(arity, current_arity, sizeof(int) * (current_arity[0] + 1));
#ifdef TRIE_COMPACT_PAIRS
if (arity[arity[0]] == -2 && str[str_index - 1] != '[')
str[str_index - 1] = ',';
#else
if (arity[arity[0]] == -1)
str[str_index - 1] = '|';
#endif /* TRIE_COMPACT_PAIRS */
traverse_answer_trie(ans_node, str, str_index, arity, var_index, depth, mode, TRAVERSE_POSITION_NEXT);
ans_node = TrNode_next(ans_node);
}
free(current_arity);
}
return; return;
} }