diff --git a/OPTYap/opt.config.h b/OPTYap/opt.config.h index 75a3ebac9..d1868dc7f 100644 --- a/OPTYap/opt.config.h +++ b/OPTYap/opt.config.h @@ -344,8 +344,11 @@ #endif #if defined(YAPOR) || defined(THREADS) -#undef MODE_DIRECTED_TABLING #undef INCOMPLETE_TABLING #undef LIMIT_TABLING #undef DETERMINISTIC_TABLING #endif + +#if defined(YAPOR) +#undef MODE_DIRECTED_TABLING +#endif diff --git a/OPTYap/opt.preds.c b/OPTYap/opt.preds.c index 05e60b9e1..60b7c4862 100644 --- a/OPTYap/opt.preds.c +++ b/OPTYap/opt.preds.c @@ -307,48 +307,60 @@ static Int p_table( USES_REGS1 ) { Yap_Error(INTERNAL_COMPILER_ERROR, TermNil, "invalid tabling declaration for %s/%d (mode directed tabling not enabled)", AtomName(at), arity); return(FALSE); #else + /************************************************************************************* + The mode operator declaration is reordered as follows: + 1. arguments with mode 'index' (any number) + 2. arguments with mode 'min' and 'max' (any number, following the original order) + 3. arguments with mode 'all' (any number) + 4. arguments with mode 'sum' or 'last' (only one of the two is allowed) + 5. arguments with mode 'first' (any number) + *************************************************************************************/ int pos_index = 0; - int pos_agreg = 0; /* min/max */ - int pos_first = 0; + int pos_min_max = 0; int pos_all = 0; - int pos_last = 0; + int pos_sum_last = 0; + int pos_first = 0; int i; int *aux_mode_directed; aux_mode_directed = malloc(arity * sizeof(int)); - ALLOC_BLOCK(mode_directed, arity * sizeof(int), int); for (i = 0; i < arity; i++) { int mode = IntOfTerm(HeadOfTerm(list)); if (mode == MODE_DIRECTED_INDEX) pos_index++; + else if (mode == MODE_DIRECTED_MIN || mode == MODE_DIRECTED_MAX) + pos_min_max++; else if (mode == MODE_DIRECTED_ALL) pos_all++; - else if (mode == MODE_DIRECTED_LAST) - pos_last++; - else if (mode == MODE_DIRECTED_MIN || mode == MODE_DIRECTED_MAX) - pos_agreg++; + else if (mode == MODE_DIRECTED_SUM || mode == MODE_DIRECTED_LAST) { + if (pos_sum_last) { + free(aux_mode_directed); + Yap_Error(INTERNAL_COMPILER_ERROR, TermNil, "invalid tabling declaration for %s/%d (more than one argument with modes 'sum' and/or 'last')", AtomName(at), arity); + return(FALSE); + } else + pos_sum_last = 1; + } aux_mode_directed[i] = mode; list = TailOfTerm(list); - } - pos_first = pos_index + pos_agreg + pos_all + pos_last; - pos_last = pos_index + pos_agreg + pos_all; - pos_all = pos_index + pos_agreg; - pos_agreg = pos_index; + } + pos_first = pos_index + pos_min_max + pos_all + pos_sum_last; + pos_sum_last = pos_index + pos_min_max + pos_all; + pos_all = pos_index + pos_min_max; + pos_min_max = pos_index; pos_index = 0; + ALLOC_BLOCK(mode_directed, arity * sizeof(int), int); for (i = 0; i < arity; i++) { int aux_pos = 0; - if (aux_mode_directed[i] == MODE_DIRECTED_MAX) - aux_pos = pos_agreg++; - else if (aux_mode_directed[i] == MODE_DIRECTED_MIN) - aux_pos = pos_agreg++; - else if (aux_mode_directed[i] == MODE_DIRECTED_INDEX) + if (aux_mode_directed[i] == MODE_DIRECTED_INDEX) aux_pos = pos_index++; - else if(aux_mode_directed[i] == MODE_DIRECTED_FIRST) - aux_pos = pos_first++; + else if (aux_mode_directed[i] == MODE_DIRECTED_MIN || aux_mode_directed[i] == MODE_DIRECTED_MAX) + aux_pos = pos_min_max++; else if (aux_mode_directed[i] == MODE_DIRECTED_ALL) aux_pos = pos_all++; - else if (aux_mode_directed[i] == MODE_DIRECTED_LAST) - aux_pos = pos_last++; + else if (aux_mode_directed[i] == MODE_DIRECTED_SUM || aux_mode_directed[i] == MODE_DIRECTED_LAST) + aux_pos = pos_sum_last++; + else if(aux_mode_directed[i] == MODE_DIRECTED_FIRST) + aux_pos = pos_first++; mode_directed[aux_pos] = MODE_DIRECTED_SET(i, aux_mode_directed[i]); } free(aux_mode_directed); diff --git a/OPTYap/tab.macros.h b/OPTYap/tab.macros.h index 9843934f0..bd1e626dc 100644 --- a/OPTYap/tab.macros.h +++ b/OPTYap/tab.macros.h @@ -131,11 +131,12 @@ static inline tg_sol_fr_ptr CUT_prune_tg_solution_frames(tg_sol_fr_ptr, int); #define MODE_DIRECTED_TAGBITS 0xF #define MODE_DIRECTED_NUMBER_TAGBITS 4 #define MODE_DIRECTED_INDEX 1 -#define MODE_DIRECTED_FIRST 2 -#define MODE_DIRECTED_ALL 3 -#define MODE_DIRECTED_MAX 4 -#define MODE_DIRECTED_MIN 5 +#define MODE_DIRECTED_MIN 2 +#define MODE_DIRECTED_MAX 3 +#define MODE_DIRECTED_ALL 4 +#define MODE_DIRECTED_SUM 5 #define MODE_DIRECTED_LAST 6 +#define MODE_DIRECTED_FIRST 7 #define MODE_DIRECTED_SET(ARG,MODE) (((ARG) << MODE_DIRECTED_NUMBER_TAGBITS) + MODE) #define MODE_DIRECTED_GET_ARG(X) ((X) >> MODE_DIRECTED_NUMBER_TAGBITS) #define MODE_DIRECTED_GET_MODE(X) ((X) & MODE_DIRECTED_TAGBITS) @@ -1032,9 +1033,9 @@ static inline void adjust_freeze_registers(void) { static inline void mark_as_completed(sg_fr_ptr sg_fr) { -#ifdef OUTPUT_THREADS_TABLING +#if defined(MODE_DIRECTED_TABLING) && !defined(THREADS_FULL_SHARING) && !defined(THREADS_CONSUMER_SHARING) CACHE_REGS -#endif /* OUTPUT_THREADS_TABLING */ +#endif /* MODE_DIRECTED_TABLING && !THREADS_FULL_SHARING && !THREADS_CONSUMER_SHARING */ LOCK_SG_FR(sg_fr); #if defined(THREADS_FULL_SHARING) || defined(THREADS_CONSUMER_SHARING) @@ -1063,7 +1064,7 @@ static inline void mark_as_completed(sg_fr_ptr sg_fr) { next_node = TrNode_child(next_node); } SgFr_last_answer(sg_fr) = current_node; -#ifndef YAPOR +#if !defined(THREADS_FULL_SHARING) && !defined(THREADS_CONSUMER_SHARING) /* free invalid answer nodes */ current_node = SgFr_invalid_chain(sg_fr); SgFr_invalid_chain(sg_fr) = NULL; @@ -1072,7 +1073,7 @@ static inline void mark_as_completed(sg_fr_ptr sg_fr) { FREE_ANSWER_TRIE_NODE(current_node); current_node = next_node; } -#endif /* ! YAPOR */ +#endif /* !THREADS_FULL_SHARING && !THREADS_CONSUMER_SHARING */ } #endif /* MODE_DIRECTED_TABLING */ return; @@ -1298,24 +1299,33 @@ static inline void abolish_incomplete_subgoals(choiceptr prune_cp) { next_node = TrNode_child(next_node); } SgFr_last_answer(sg_fr) = current_node; -#ifndef YAPOR +#if !defined(THREADS_FULL_SHARING) && !defined(THREADS_CONSUMER_SHARING) /* free invalid answer nodes */ current_node = SgFr_invalid_chain(sg_fr); SgFr_invalid_chain(sg_fr) = NULL; while (current_node) { - next_node = TrNode_next(invalid_node); + next_node = TrNode_next(current_node); FREE_ANSWER_TRIE_NODE(current_node); - current_node = node_node; + current_node = next_node; } -#endif /* ! YAPOR */ +#endif /* !THREADS_FULL_SHARING && !THREADS_CONSUMER_SHARING */ } #endif /* MODE_DIRECTED_TABLING */ #else ans_node_ptr node; -#ifdef MODE_DIRECTED_TABLING - ans_node_ptr invalid_node = SgFr_invalid_chain(sg_fr); - SgFr_invalid_chain(sg_fr) = NULL; -#endif /* MODE_DIRECTED_TABLING */ +#if defined(MODE_DIRECTED_TABLING) && !defined(THREADS_FULL_SHARING) && !defined(THREADS_CONSUMER_SHARING) + if (SgFr_invalid_chain(sg_fr)) { + ans_node_ptr current_node, next_node; + /* free invalid answer nodes */ + current_node = SgFr_invalid_chain(sg_fr); + SgFr_invalid_chain(sg_fr) = NULL; + while (current_node) { + next_node = TrNode_next(current_node); + FREE_ANSWER_TRIE_NODE(current_node); + current_node = next_node; + } + } +#endif /* MODE_DIRECTED_TABLING && !THREADS_FULL_SHARING && !THREADS_CONSUMER_SHARING */ SgFr_state(sg_fr) = ready; #if defined(THREADS_FULL_SHARING) || defined(THREADS_CONSUMER_SHARING) if (SgFr_active_workers(sg_fr) == 0) { @@ -1339,7 +1349,7 @@ static inline void abolish_incomplete_subgoals(choiceptr prune_cp) { local_uncons_ans = SgFr_batched_cached_answers(sg_fr); } } - } else{ /* SgFr_active_workers(sg_fr) != 0 */ + } else { /* SgFr_active_workers(sg_fr) != 0 */ if (IsMode_Batched(TabEnt_mode(SgFr_tab_ent(sg_fr)))){ SgFr_batched_last_answer(sg_fr) = NULL; if ( worker_id >= ANSWER_LEAF_NODE_MAX_THREADS ) { @@ -1361,14 +1371,6 @@ static inline void abolish_incomplete_subgoals(choiceptr prune_cp) { #if defined(THREADS_FULL_SHARING) || defined(THREADS_CONSUMER_SHARING) } #endif /* THREADS_FULL_SHARING || THREADS_CONSUMER_SHARING */ -#if defined(MODE_DIRECTED_TABLING) && ! defined(YAPOR) - /* free invalid answer nodes */ - while (invalid_node) { - node = TrNode_next(invalid_node); - FREE_ANSWER_TRIE_NODE(invalid_node); - invalid_node = node; - } -#endif /* MODE_DIRECTED_TABLING && ! YAPOR */ #endif /* INCOMPLETE_TABLING */ } #ifdef LIMIT_TABLING diff --git a/OPTYap/tab.tries.c b/OPTYap/tab.tries.c index 7d922213a..aed6e875b 100644 --- a/OPTYap/tab.tries.c +++ b/OPTYap/tab.tries.c @@ -45,6 +45,7 @@ static inline CELL *load_substitution_loop(gt_node_ptr, int *, CELL * USES_REGS) static inline CELL *exec_substitution_loop(gt_node_ptr, CELL **, CELL * USES_REGS); #ifdef MODE_DIRECTED_TABLING static inline ans_node_ptr answer_search_min_max(sg_fr_ptr, ans_node_ptr, Term, int USES_REGS); +static inline ans_node_ptr answer_search_sum(sg_fr_ptr, ans_node_ptr, Term USES_REGS); static void invalidate_answer_trie(ans_node_ptr, sg_fr_ptr, int USES_REGS); #endif /* MODE_DIRECTED_TABLING */ @@ -216,7 +217,7 @@ static struct trie_statistics{ #ifdef MODE_DIRECTED_TABLING #define INCLUDE_ANSWER_SEARCH_MODE_DIRECTED -#include "tab.tries.i" /* answer_search_min_max + invalidate_answer_trie */ +#include "tab.tries.i" /* answer_search_min_max + answer_search_sum + invalidate_answer_trie */ #undef INCLUDE_ANSWER_SEARCH_MODE_DIRECTED #endif /* MODE_DIRECTED_TABLING */ @@ -1185,31 +1186,32 @@ ans_node_ptr mode_directed_answer_search(sg_fr_ptr sg_fr, CELL *subs_ptr) { } else { LOCK_ANSWER_NODE(current_ans_node); if (TrNode_child(current_ans_node) == NULL) { -#ifdef YAPOR - struct answer_trie_node virtual_ans_node; +#ifdef THREADS + struct answer_trie_node virtual_ans_node; /* necessary because the answer_search_loop() procedure also locks the parent node */ ans_node_ptr parent_ans_node = current_ans_node; - TrNode_init_lock_field(&virtual_ans_node); + AnsNode_init_lock_field(&virtual_ans_node); TrNode_parent(&virtual_ans_node) = NULL; TrNode_child(&virtual_ans_node) = NULL; current_ans_node = answer_search_loop(sg_fr, &virtual_ans_node, Deref(subs_ptr[i]), &vars_arity PASS_REGS); TrNode_child(parent_ans_node) = TrNode_child(&virtual_ans_node); #else current_ans_node = answer_search_loop(sg_fr, current_ans_node, Deref(subs_ptr[i]), &vars_arity PASS_REGS); -#endif /* YAPOR */ +#endif /* THREADS */ } else if (mode == MODE_DIRECTED_MIN || mode == MODE_DIRECTED_MAX) { ans_node_ptr parent_ans_node = current_ans_node; invalid_ans_node = TrNode_child(parent_ans_node); /* by default, assume a better answer */ current_ans_node = answer_search_min_max(sg_fr, current_ans_node, Deref(subs_ptr[i]), mode PASS_REGS); if (invalid_ans_node == TrNode_child(parent_ans_node)) /* worse or equal answer */ invalid_ans_node = NULL; - } else if (mode == MODE_DIRECTED_FIRST) - current_ans_node = NULL; - else { /* mode == MODE_DIRECTED_LAST */ -#ifdef YAPOR - struct answer_trie_node virtual_ans_node; + } else if (mode == MODE_DIRECTED_SUM) { + invalid_ans_node = TrNode_child(current_ans_node); + current_ans_node = answer_search_sum(sg_fr, current_ans_node, Deref(subs_ptr[i]) PASS_REGS); + } else if (mode == MODE_DIRECTED_LAST) { +#ifdef THREADS + struct answer_trie_node virtual_ans_node; /* necessary because the answer_search_loop() procedure also locks the parent node */ ans_node_ptr parent_ans_node = current_ans_node; invalid_ans_node = TrNode_child(parent_ans_node); - TrNode_init_lock_field(&virtual_ans_node); + AnsNode_init_lock_field(&virtual_ans_node); TrNode_parent(&virtual_ans_node) = NULL; TrNode_child(&virtual_ans_node) = NULL; current_ans_node = answer_search_loop(sg_fr, &virtual_ans_node, Deref(subs_ptr[i]), &vars_arity PASS_REGS); @@ -1218,8 +1220,11 @@ ans_node_ptr mode_directed_answer_search(sg_fr_ptr sg_fr, CELL *subs_ptr) { invalid_ans_node = TrNode_child(current_ans_node); TrNode_child(current_ans_node) = NULL; current_ans_node = answer_search_loop(sg_fr, current_ans_node, Deref(subs_ptr[i]), &vars_arity PASS_REGS); -#endif /* YAPOR */ - } +#endif /* THREADS */ + } else if (mode == MODE_DIRECTED_FIRST) { + current_ans_node = NULL; + } else + Yap_Error(INTERNAL_ERROR, TermNil, "mode_directed_answer_search: unknown mode"); UNLOCK_ANSWER_NODE(current_ans_node); } n_subs--; @@ -1388,24 +1393,31 @@ void free_subgoal_trie(sg_node_ptr current_node, int mode, int position) { IF_ABOLISH_ANSWER_TRIE_SHARED_DATA_STRUCTURES { FREE_ANSWER_TRIE_NODE(ans_node); #if defined(THREADS_FULL_SHARING) || defined(THREADS_CONSUMER_SHARING) +#ifdef MODE_DIRECTED_TABLING + if (SgEnt_mode_directed(SgFr_sg_ent(sg_fr))) + FREE_BLOCK(SgEnt_mode_directed(SgFr_sg_ent(sg_fr))); + if (SgFr_invalid_chain(sg_fr)) { + ans_node_ptr current_node, next_node; + /* free invalid answer nodes */ + current_node = SgFr_invalid_chain(sg_fr); + SgFr_invalid_chain(sg_fr) = NULL; + while (current_node) { + next_node = TrNode_next(current_node); + FREE_ANSWER_TRIE_NODE(current_node); + current_node = next_node; + } + } +#endif /* MODE_DIRECTED_TABLING */ FREE_SUBGOAL_ENTRY(SgFr_sg_ent(sg_fr)); #endif /* THREADS_FULL_SHARING || THREADS_CONSUMER_SHARING */ } -#if defined(MODE_DIRECTED_TABLING) && defined(YAPOR) - if (SgFr_invalid_chain(sg_fr)) { - ans_node_ptr next_node, invalid_node = SgFr_invalid_chain(sg_fr); - SgFr_invalid_chain(sg_fr) = NULL; - /* free invalid answer nodes */ - while (invalid_node) { - next_node = TrNode_next(invalid_node); - FREE_ANSWER_TRIE_NODE(invalid_node); - invalid_node = next_node; - } - } -#endif /* MODE_DIRECTED_TABLING && YAPOR */ #ifdef LIMIT_TABLING remove_from_global_sg_fr_list(sg_fr); #endif /* LIMIT_TABLING */ +#if defined(MODE_DIRECTED_TABLING) && !defined(THREADS_FULL_SHARING) && !defined(THREADS_CONSUMER_SHARING) + if (SgFr_mode_directed(sg_fr)) + FREE_BLOCK(SgFr_mode_directed(sg_fr)); +#endif /* MODE_DIRECTED_TABLING && !THREADS_FULL_SHARING && !THREADS_CONSUMER_SHARING */ FREE_SUBGOAL_FRAME(sg_fr); } } @@ -1603,16 +1615,20 @@ void show_table(tab_ent_ptr tab_ent, int show_mode, IOSTREAM *out) { int mode = MODE_DIRECTED_GET_MODE(mode_directed[i]); if (mode == MODE_DIRECTED_INDEX) { Sfprintf(TrStat_out, "index"); - } else if (mode == MODE_DIRECTED_FIRST) { - Sfprintf(TrStat_out, "first"); - } else if (mode == MODE_DIRECTED_ALL) { - Sfprintf(TrStat_out, "all"); - } else if (mode == MODE_DIRECTED_MAX) { - Sfprintf(TrStat_out, "max"); } else if (mode == MODE_DIRECTED_MIN) { Sfprintf(TrStat_out, "min"); - } else /* MODE_DIRECTED_LAST */ + } else if (mode == MODE_DIRECTED_MAX) { + Sfprintf(TrStat_out, "max"); + } else if (mode == MODE_DIRECTED_ALL) { + Sfprintf(TrStat_out, "all"); + } else if (mode == MODE_DIRECTED_SUM) { + Sfprintf(TrStat_out, "sum"); + } else if (mode == MODE_DIRECTED_LAST) { Sfprintf(TrStat_out, "last"); + } else if (mode == MODE_DIRECTED_FIRST) { + Sfprintf(TrStat_out, "first"); + } else + Yap_Error(INTERNAL_ERROR, TermNil, "show_table: unknown mode"); if (i != MODE_DIRECTED_GET_ARG(mode_directed[i])) Sfprintf(TrStat_out, "(ARG%d)", MODE_DIRECTED_GET_ARG(mode_directed[i]) + 1); if (i + 1 != TabEnt_arity(tab_ent)) diff --git a/OPTYap/tab.tries.i b/OPTYap/tab.tries.i index fc90e06e1..a02984888 100644 --- a/OPTYap/tab.tries.i +++ b/OPTYap/tab.tries.i @@ -52,6 +52,28 @@ #endif /* MODE_GLOBAL_TRIE_LOOP */ +#ifdef INCLUDE_ANSWER_SEARCH_MODE_DIRECTED +#define ANSWER_SAFE_INSERT_ENTRY(NODE, ENTRY, INSTR) \ + { ans_node_ptr new_node; \ + NEW_ANSWER_TRIE_NODE(new_node, INSTR, ENTRY, NULL, NODE, NULL); \ + TrNode_child(NODE) = new_node; \ + NODE = new_node; \ + } +#ifdef THREADS +#define INVALIDATE_ANSWER_TRIE_NODE(NODE, SG_FR) \ + TrNode_next(NODE) = SgFr_invalid_chain(SG_FR); \ + SgFr_invalid_chain(SG_FR) = NODE +#else +#define INVALIDATE_ANSWER_TRIE_NODE(NODE, SG_FR) \ + FREE_ANSWER_TRIE_NODE(NODE) +#endif /* THREADS */ +#define INVALIDATE_ANSWER_TRIE_LEAF_NODE(NODE, SG_FR) \ + TAG_AS_ANSWER_INVALID_NODE(NODE); \ + TrNode_next(NODE) = SgFr_invalid_chain(SG_FR); \ + SgFr_invalid_chain(SG_FR) = NODE +#endif /* INCLUDE_ANSWER_SEARCH_MODE_DIRECTED */ + + /************************************************************************ ** subgoal_trie_check_insert_(gt)_entry ** @@ -1391,13 +1413,6 @@ static inline ans_node_ptr answer_search_loop(sg_fr_ptr sg_fr, ans_node_ptr curr **************************************************************/ #ifdef INCLUDE_ANSWER_SEARCH_MODE_DIRECTED -#define ANSWER_SAFE_INSERT_ENTRY(NODE, ENTRY, INSTR) \ - { ans_node_ptr new_node; \ - NEW_ANSWER_TRIE_NODE(new_node, INSTR, ENTRY, NULL, NODE, NULL); \ - TrNode_child(NODE) = new_node; \ - NODE = new_node; \ - } - static inline ans_node_ptr answer_search_min_max(sg_fr_ptr sg_fr, ans_node_ptr current_node, Term t, int mode USES_REGS) { ans_node_ptr child_node; Term child_term; @@ -1478,24 +1493,83 @@ static inline ans_node_ptr answer_search_min_max(sg_fr_ptr sg_fr, ans_node_ptr c +/********************************************************** +** answer_search_sum ** +**********************************************************/ + +#ifdef INCLUDE_ANSWER_SEARCH_MODE_DIRECTED +static inline ans_node_ptr answer_search_sum(sg_fr_ptr sg_fr, ans_node_ptr current_node, Term t USES_REGS) { + ans_node_ptr child_node; + Term child_term; + Float trie_value = 0, term_value = 0, sum_value = 0; + int sum_value_as_int; + + /* start by computing the current value on the trie (trie_value) */ + child_node = TrNode_child(current_node); + child_term = TrNode_entry(child_node); + if (IsIntTerm(child_term)) { + trie_value = (Float) IntOfTerm(child_term); + } else if (IsApplTerm(child_term)) { + Functor f = (Functor) RepAppl(child_term); + child_node = TrNode_child(child_node); + if (f == FunctorLongInt) { + trie_value = (Float) TrNode_entry(child_node); + } else if (f == FunctorDouble) { + union { + Term t_dbl[sizeof(Float)/sizeof(Term)]; + Float dbl; + } u; + u.t_dbl[0] = TrNode_entry(child_node); +#if SIZEOF_DOUBLE == 2 * SIZEOF_INT_P + child_node = TrNode_child(child_node); + u.t_dbl[1] = TrNode_entry(child_node); +#endif /* SIZEOF_DOUBLE x SIZEOF_INT_P */ + trie_value = u.dbl; + } else + Yap_Error(INTERNAL_ERROR, TermNil, "answer_search_sum: invalid arithmetic value"); + child_node = TrNode_child(child_node); + } + + /* then compute the value for the new term (term_value) */ + if (IsAtomOrIntTerm(t)) + term_value = (Float) IntOfTerm(t); + else if (IsApplTerm(t)) { + Functor f = FunctorOfTerm(t); + if (f == FunctorLongInt) + term_value = (Float) LongIntOfTerm(t); + else if (f == FunctorDouble) + term_value = FloatOfTerm(t); + else + Yap_Error(INTERNAL_ERROR, TermNil, "answer_search_sum: invalid arithmetic value"); + } + sum_value = trie_value + term_value; + sum_value_as_int = (int) sum_value; + if (sum_value == (float) sum_value_as_int && IntInBnd(sum_value_as_int)) { + ANSWER_SAFE_INSERT_ENTRY(current_node, MkIntegerTerm(sum_value_as_int), _trie_retry_atom); + } else { + union { + Term t_dbl[sizeof(Float)/sizeof(Term)]; + Float dbl; + } u; + u.dbl = sum_value; + ANSWER_SAFE_INSERT_ENTRY(current_node, AbsAppl((Term *)FunctorDouble), _trie_retry_null); +#if SIZEOF_DOUBLE == 2 * SIZEOF_INT_P + ANSWER_SAFE_INSERT_ENTRY(current_node, u.t_dbl[1], _trie_retry_extension); +#endif /* SIZEOF_DOUBLE x SIZEOF_INT_P */ + ANSWER_SAFE_INSERT_ENTRY(current_node, u.t_dbl[0], _trie_retry_extension); + ANSWER_SAFE_INSERT_ENTRY(current_node, AbsAppl((Term *)FunctorDouble), _trie_retry_double); + } + return current_node; +} +#endif /* INCLUDE_ANSWER_SEARCH_MODE_DIRECTED */ + + + /*************************************************************** ** invalidate_answer_trie ** ***************************************************************/ #ifdef INCLUDE_ANSWER_SEARCH_MODE_DIRECTED -#ifdef YAPOR -#define INVALIDATE_ANSWER_TRIE_NODE(NODE, SG_FR) \ - TrNode_next(NODE) = SgFr_invalid_chain(SG_FR); \ - SgFr_invalid_chain(SG_FR) = NODE -#else -#define INVALIDATE_ANSWER_TRIE_NODE(NODE, SG_FR) \ - FREE_ANSWER_TRIE_NODE(NODE) -#endif /* YAPOR */ -#define INVALIDATE_ANSWER_TRIE_LEAF_NODE(NODE, SG_FR) \ - TAG_AS_ANSWER_INVALID_NODE(NODE); \ - TrNode_next(NODE) = SgFr_invalid_chain(SG_FR); \ - SgFr_invalid_chain(SG_FR) = NODE - static void invalidate_answer_trie(ans_node_ptr current_node, sg_fr_ptr sg_fr, int position USES_REGS) { if (IS_ANSWER_TRIE_HASH(current_node)) { ans_hash_ptr hash; diff --git a/pl/tabling.yap b/pl/tabling.yap index af2749a2e..161f2af99 100644 --- a/pl/tabling.yap +++ b/pl/tabling.yap @@ -146,11 +146,16 @@ table(Pred) :- %% should match with code in OPTYap/tab.macros.h '$transl_to_mode_directed_tabling'(index,1). -'$transl_to_mode_directed_tabling'(first,2). -'$transl_to_mode_directed_tabling'(all,3). -'$transl_to_mode_directed_tabling'(max,4). -'$transl_to_mode_directed_tabling'(min,5). +'$transl_to_mode_directed_tabling'(min,2). +'$transl_to_mode_directed_tabling'(max,3). +'$transl_to_mode_directed_tabling'(all,4). +'$transl_to_mode_directed_tabling'(sum,5). '$transl_to_mode_directed_tabling'(last,6). +'$transl_to_mode_directed_tabling'(first,7). +%% B-Prolog compatibility +'$transl_to_mode_directed_tabling'(+,1). +'$transl_to_mode_directed_tabling'(@,4). +'$transl_to_mode_directed_tabling'(-,7).