Merge branch 'master' of ssh://git.dcc.fc.up.pt/yap-6.3
This commit is contained in:
commit
d1d01ddc2a
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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))
|
||||
|
@ -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;
|
||||
|
@ -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).
|
||||
|
||||
|
||||
|
||||
|
Reference in New Issue
Block a user