Merge branch 'master' of ssh://yap.git.sourceforge.net/gitroot/yap/yap-6.3

This commit is contained in:
Vítor Santos Costa 2011-11-14 14:37:22 +00:00
commit ca43587f27
7 changed files with 218 additions and 107 deletions

View File

@ -129,7 +129,7 @@ INTERFACE_HEADERS = \
IOLIB_HEADERS=$(srcdir)/os/pl-buffer.h \ IOLIB_HEADERS=$(srcdir)/os/pl-buffer.h \
$(srcdir)/os/pl-ctype.h \ $(srcdir)/os/pl-ctype.h \
$(srcdir)/H/pl-codelist.h \ $(srcdir)/os/pl-codelist.h \
$(srcdir)/os/pl-dtoa.h \ $(srcdir)/os/pl-dtoa.h \
$(srcdir)/os/dtoa.c \ $(srcdir)/os/dtoa.c \
$(srcdir)/H/pl-incl.h \ $(srcdir)/H/pl-incl.h \
@ -138,7 +138,6 @@ IOLIB_HEADERS=$(srcdir)/os/pl-buffer.h \
$(srcdir)/os/pl-option.h \ $(srcdir)/os/pl-option.h \
$(srcdir)/os/pl-os.h \ $(srcdir)/os/pl-os.h \
$(srcdir)/os/pl-privitf.h \ $(srcdir)/os/pl-privitf.h \
$(srcdir)/os/pl-stream.h \
$(srcdir)/os/pl-table.h \ $(srcdir)/os/pl-table.h \
$(srcdir)/os/pl-text.h \ $(srcdir)/os/pl-text.h \
$(srcdir)/os/pl-utf8.h \ $(srcdir)/os/pl-utf8.h \

View File

@ -1110,20 +1110,22 @@
if (TrNode_child(ans_node)) { if (TrNode_child(ans_node)) {
/* unconsumed answers */ /* unconsumed answers */
#ifdef MODE_DIRECTED_TABLING #ifdef MODE_DIRECTED_TABLING
ans_node_ptr first_ans_node, aux_ans_node; if (IS_INVALID_LEAF_NODE(TrNode_child(ans_node))) {
first_ans_node = ans_node; ans_node_ptr first_ans_node, aux_ans_node;
do { first_ans_node = ans_node;
ans_node = TrNode_child(ans_node); ans_node = TrNode_child(ans_node);
} while (IS_INVALID_LEAF_NODE(ans_node)); do {
aux_ans_node = TrNode_child(first_ans_node); ans_node = TrNode_child(ans_node);
while (aux_ans_node != ans_node) { } while (IS_INVALID_LEAF_NODE(ans_node));
TrNode_child(first_ans_node) = ans_node; aux_ans_node = TrNode_child(first_ans_node);
first_ans_node = aux_ans_node; do {
aux_ans_node = TrNode_child(first_ans_node); TrNode_child(first_ans_node) = ans_node;
} first_ans_node = aux_ans_node;
#else aux_ans_node = TrNode_child(first_ans_node);
ans_node = TrNode_child(ans_node); } while (aux_ans_node != ans_node);
} else
#endif /* MODE_DIRECTED_TABLING */ #endif /* MODE_DIRECTED_TABLING */
ans_node = TrNode_child(ans_node);
DepFr_last_answer(dep_fr) = ans_node; DepFr_last_answer(dep_fr) = ans_node;
UNLOCK(DepFr_lock(dep_fr)); UNLOCK(DepFr_lock(dep_fr));
consume_answer_and_procceed(dep_fr, ans_node); consume_answer_and_procceed(dep_fr, ans_node);
@ -1172,20 +1174,22 @@
if (TrNode_child(ans_node)) { if (TrNode_child(ans_node)) {
/* dependency frame with unconsumed answers */ /* dependency frame with unconsumed answers */
#ifdef MODE_DIRECTED_TABLING #ifdef MODE_DIRECTED_TABLING
ans_node_ptr first_ans_node, aux_ans_node; if (IS_INVALID_LEAF_NODE(TrNode_child(ans_node))) {
first_ans_node = ans_node; ans_node_ptr first_ans_node, aux_ans_node;
do { first_ans_node = ans_node;
ans_node = TrNode_child(ans_node); ans_node = TrNode_child(ans_node);
} while (IS_INVALID_LEAF_NODE(ans_node)); do {
aux_ans_node = TrNode_child(first_ans_node); ans_node = TrNode_child(ans_node);
while (aux_ans_node != ans_node) { } while (IS_INVALID_LEAF_NODE(ans_node));
TrNode_child(first_ans_node) = ans_node;
first_ans_node = aux_ans_node;
aux_ans_node = TrNode_child(first_ans_node); aux_ans_node = TrNode_child(first_ans_node);
} do {
#else TrNode_child(first_ans_node) = ans_node;
ans_node = TrNode_child(ans_node); first_ans_node = aux_ans_node;
aux_ans_node = TrNode_child(first_ans_node);
} while (aux_ans_node != ans_node);
} else
#endif /* MODE_DIRECTED_TABLING */ #endif /* MODE_DIRECTED_TABLING */
ans_node = TrNode_child(ans_node);
DepFr_last_answer(dep_fr) = ans_node; DepFr_last_answer(dep_fr) = ans_node;
#ifdef YAPOR #ifdef YAPOR
if (YOUNGER_CP(DepFr_backchain_cp(dep_fr), top_chain_cp)) if (YOUNGER_CP(DepFr_backchain_cp(dep_fr), top_chain_cp))
@ -1429,20 +1433,22 @@
if (TrNode_child(ans_node)) { if (TrNode_child(ans_node)) {
/* dependency frame with unconsumed answers */ /* dependency frame with unconsumed answers */
#ifdef MODE_DIRECTED_TABLING #ifdef MODE_DIRECTED_TABLING
ans_node_ptr first_ans_node, aux_ans_node; if (IS_INVALID_LEAF_NODE(TrNode_child(ans_node))) {
first_ans_node = ans_node; ans_node_ptr first_ans_node, aux_ans_node;
do { first_ans_node = ans_node;
ans_node = TrNode_child(ans_node); ans_node = TrNode_child(ans_node);
} while (IS_INVALID_LEAF_NODE(ans_node)); do {
aux_ans_node = TrNode_child(first_ans_node); ans_node = TrNode_child(ans_node);
while (aux_ans_node != ans_node) { } while (IS_INVALID_LEAF_NODE(ans_node));
TrNode_child(first_ans_node) = ans_node;
first_ans_node = aux_ans_node;
aux_ans_node = TrNode_child(first_ans_node); aux_ans_node = TrNode_child(first_ans_node);
} do {
#else TrNode_child(first_ans_node) = ans_node;
ans_node = TrNode_child(ans_node); first_ans_node = aux_ans_node;
aux_ans_node = TrNode_child(first_ans_node);
} while (aux_ans_node != ans_node);
} else
#endif /* MODE_DIRECTED_TABLING */ #endif /* MODE_DIRECTED_TABLING */
ans_node = TrNode_child(ans_node);
DepFr_last_answer(dep_fr) = ans_node; DepFr_last_answer(dep_fr) = ans_node;
if (B->cp_ap) { if (B->cp_ap) {
#ifdef YAPOR #ifdef YAPOR
@ -1602,20 +1608,22 @@
/* unconsumed answers */ /* unconsumed answers */
UNLOCK_OR_FRAME(LOCAL_top_or_fr); UNLOCK_OR_FRAME(LOCAL_top_or_fr);
#ifdef MODE_DIRECTED_TABLING #ifdef MODE_DIRECTED_TABLING
ans_node_ptr first_ans_node, aux_ans_node; if (IS_INVALID_LEAF_NODE(TrNode_child(ans_node))) {
first_ans_node = ans_node; ans_node_ptr first_ans_node, aux_ans_node;
do { first_ans_node = ans_node;
ans_node = TrNode_child(ans_node); ans_node = TrNode_child(ans_node);
} while (IS_INVALID_LEAF_NODE(ans_node)); do {
aux_ans_node = TrNode_child(first_ans_node); ans_node = TrNode_child(ans_node);
while (aux_ans_node != ans_node) { } while (IS_INVALID_LEAF_NODE(ans_node));
TrNode_child(first_ans_node) = ans_node;
first_ans_node = aux_ans_node;
aux_ans_node = TrNode_child(first_ans_node); aux_ans_node = TrNode_child(first_ans_node);
} do {
#else TrNode_child(first_ans_node) = ans_node;
ans_node = TrNode_child(ans_node); first_ans_node = aux_ans_node;
aux_ans_node = TrNode_child(first_ans_node);
} while (aux_ans_node != ans_node);
} else
#endif /* MODE_DIRECTED_TABLING */ #endif /* MODE_DIRECTED_TABLING */
ans_node = TrNode_child(ans_node);
DepFr_last_answer(LOCAL_top_dep_fr) = ans_node; DepFr_last_answer(LOCAL_top_dep_fr) = ans_node;
UNLOCK(DepFr_lock(LOCAL_top_dep_fr)); UNLOCK(DepFr_lock(LOCAL_top_dep_fr));
consume_answer_and_procceed(LOCAL_top_dep_fr, ans_node); consume_answer_and_procceed(LOCAL_top_dep_fr, ans_node);

View File

@ -518,36 +518,38 @@ static inline void adjust_freeze_registers(void) {
static inline void mark_as_completed(sg_fr_ptr sg_fr) { static inline void mark_as_completed(sg_fr_ptr sg_fr) {
LOCK(SgFr_lock(sg_fr)); LOCK(SgFr_lock(sg_fr));
#ifdef MODE_DIRECTED_TABLING
if (SgFr_mode_directed(sg_fr) && SgFr_invalid_chain(sg_fr)) {
ans_node_ptr current_answer, next_answer;
/* first first valid answer */
current_answer = SgFr_first_answer(sg_fr);
while (IS_INVALID_LEAF_NODE(current_answer))
current_answer = TrNode_child(current_answer);
SgFr_first_answer(sg_fr) = current_answer;
/* chain next valid answers */
next_answer = TrNode_child(current_answer);
while (next_answer) {
if (! IS_INVALID_LEAF_NODE(next_answer)) {
TrNode_child(current_answer) = next_answer;
current_answer = next_answer;
}
next_answer = TrNode_child(next_answer);
}
SgFr_last_answer(sg_fr) = current_answer;
/* free invalid answer nodes */
current_answer = SgFr_invalid_chain(sg_fr);
SgFr_invalid_chain(sg_fr) = NULL;
while (current_answer) {
next_answer = TrNode_next(current_answer);
FREE_ANSWER_TRIE_NODE(current_answer);
current_answer = next_answer;
}
}
#endif /* MODE_DIRECTED_TABLING */
SgFr_state(sg_fr) = complete; SgFr_state(sg_fr) = complete;
UNLOCK(SgFr_lock(sg_fr)); UNLOCK(SgFr_lock(sg_fr));
#ifdef MODE_DIRECTED_TABLING
if (SgFr_invalid_chain(sg_fr)) {
ans_node_ptr current_node, next_node;
/* find first valid answer */
current_node = SgFr_first_answer(sg_fr);
while (IS_INVALID_LEAF_NODE(current_node))
current_node = TrNode_child(current_node);
SgFr_first_answer(sg_fr) = current_node;
/* chain next valid answers */
next_node = TrNode_child(current_node);
while (next_node) {
if (! IS_INVALID_LEAF_NODE(next_node)) {
TrNode_child(current_node) = next_node;
current_node = next_node;
}
next_node = TrNode_child(next_node);
}
SgFr_last_answer(sg_fr) = current_node;
#ifndef YAPOR
/* 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 /* ! YAPOR */
}
#endif /* MODE_DIRECTED_TABLING */
return; return;
} }
@ -753,8 +755,42 @@ static inline void abolish_incomplete_subgoals(choiceptr prune_cp) {
#ifdef INCOMPLETE_TABLING #ifdef INCOMPLETE_TABLING
SgFr_state(sg_fr) = incomplete; SgFr_state(sg_fr) = incomplete;
UNLOCK(SgFr_lock(sg_fr)); UNLOCK(SgFr_lock(sg_fr));
#ifdef MODE_DIRECTED_TABLING
if (SgFr_invalid_chain(sg_fr)) {
ans_node_ptr current_node, next_node;
/* find first valid answer */
current_node = SgFr_first_answer(sg_fr);
while (IS_INVALID_LEAF_NODE(current_node))
current_node = TrNode_child(current_node);
SgFr_first_answer(sg_fr) = current_node;
/* chain next valid answers */
next_node = TrNode_child(current_node);
while (next_node) {
if (! IS_INVALID_LEAF_NODE(next_node)) {
TrNode_child(current_node) = next_node;
current_node = next_node;
}
next_node = TrNode_child(next_node);
}
SgFr_last_answer(sg_fr) = current_node;
#ifndef YAPOR
/* 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);
FREE_ANSWER_TRIE_NODE(current_node);
current_node = node_node;
}
#endif /* ! YAPOR */
}
#endif /* MODE_DIRECTED_TABLING */
#else #else
ans_node_ptr node; 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 */
SgFr_state(sg_fr) = ready; SgFr_state(sg_fr) = ready;
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;
@ -764,6 +800,14 @@ static inline void abolish_incomplete_subgoals(choiceptr prune_cp) {
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(node, TRAVERSE_MODE_NORMAL, TRAVERSE_POSITION_FIRST); free_answer_trie(node, TRAVERSE_MODE_NORMAL, TRAVERSE_POSITION_FIRST);
#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 */ #endif /* INCOMPLETE_TABLING */
} }
#ifdef LIMIT_TABLING #ifdef LIMIT_TABLING

View File

@ -220,13 +220,13 @@ typedef struct subgoal_frame {
struct answer_trie_node *answer_trie; struct answer_trie_node *answer_trie;
struct answer_trie_node *first_answer; struct answer_trie_node *first_answer;
struct answer_trie_node *last_answer; struct answer_trie_node *last_answer;
#ifdef MODE_DIRECTED_TABLING
int* mode_directed_array;
struct answer_trie_node *invalid_chain;
#endif /*MODE_DIRECTED_TABLING*/
#ifdef INCOMPLETE_TABLING #ifdef INCOMPLETE_TABLING
struct answer_trie_node *try_answer; struct answer_trie_node *try_answer;
#endif /* INCOMPLETE_TABLING */ #endif /* INCOMPLETE_TABLING */
#ifdef MODE_DIRECTED_TABLING
struct answer_trie_node *invalid_chain;
int* mode_directed_array;
#endif /*MODE_DIRECTED_TABLING*/
#ifdef LIMIT_TABLING #ifdef LIMIT_TABLING
struct subgoal_frame *previous; struct subgoal_frame *previous;
#endif /* LIMIT_TABLING */ #endif /* LIMIT_TABLING */
@ -245,9 +245,9 @@ typedef struct subgoal_frame {
#define SgFr_answer_trie(X) ((X)->answer_trie) #define SgFr_answer_trie(X) ((X)->answer_trie)
#define SgFr_first_answer(X) ((X)->first_answer) #define SgFr_first_answer(X) ((X)->first_answer)
#define SgFr_last_answer(X) ((X)->last_answer) #define SgFr_last_answer(X) ((X)->last_answer)
#define SgFr_try_answer(X) ((X)->try_answer)
#define SgFr_invalid_chain(X) ((X)->invalid_chain)
#define SgFr_mode_directed(X) ((X)->mode_directed_array) #define SgFr_mode_directed(X) ((X)->mode_directed_array)
#define SgFr_invalid_chain(X) ((X)->invalid_chain)
#define SgFr_try_answer(X) ((X)->try_answer)
#define SgFr_previous(X) ((X)->previous) #define SgFr_previous(X) ((X)->previous)
#define SgFr_next(X) ((X)->next) #define SgFr_next(X) ((X)->next)
@ -269,11 +269,11 @@ typedef struct subgoal_frame {
It is used to check for/insert new answers. It is used to check for/insert new answers.
SgFr_first_answer: a pointer to the bottom answer trie node of the first available answer. SgFr_first_answer: a pointer to the bottom answer trie node of the first available answer.
SgFr_last_answer: a pointer to the bottom answer trie node of the last available answer. SgFr_last_answer: a pointer to the bottom answer trie node of the last available answer.
SgFr_mode_directed: a pointer to the mode directed array.
SgFr_invalid_chain: a pointer to the first invalid leaf node when using mode directed tabling.
SgFr_try_answer: a pointer to the bottom answer trie node of the last tried answer. SgFr_try_answer: a pointer to the bottom answer trie node of the last tried answer.
It is used when a subgoal was not completed during the previous evaluation. It is used when a subgoal was not completed during the previous evaluation.
Not completed subgoals start by trying the answers already found. Not completed subgoals start by trying the answers already found.
SgFr_invalid_chain: a pointer to the first invalid leaf node when using mode directed tabling.
SgFr_mode_directed: a pointer to the mode directed array.
SgFr_previous: a pointer to the previous subgoal frame on the chain. SgFr_previous: a pointer to the previous subgoal frame on the chain.
SgFr_next: a pointer to the next subgoal frame on the chain. SgFr_next: a pointer to the next subgoal frame on the chain.

View File

@ -1004,8 +1004,10 @@ sg_fr_ptr subgoal_search(yamop *preg, CELL **Yaddr) {
current_sg_node = subgoal_search_loop(tab_ent, current_sg_node, Deref(XREGS[j]), &subs_arity, &stack_vars); current_sg_node = subgoal_search_loop(tab_ent, current_sg_node, Deref(XREGS[j]), &subs_arity, &stack_vars);
if (subs_arity != old_subs_arity) { if (subs_arity != old_subs_arity) {
if (subs_pos && MODE_DIRECTED_GET_MODE(aux_mode_directed[subs_pos-1]) == MODE_DIRECTED_GET_MODE(mode_directed[i-1])) { if (subs_pos && MODE_DIRECTED_GET_MODE(aux_mode_directed[subs_pos-1]) == MODE_DIRECTED_GET_MODE(mode_directed[i-1])) {
/* same mode as before -> use the current entry in the aux_mode_directed[] array */
aux_mode_directed[subs_pos-1] += MODE_DIRECTED_SET(subs_arity - old_subs_arity, 0); aux_mode_directed[subs_pos-1] += MODE_DIRECTED_SET(subs_arity - old_subs_arity, 0);
} else { } else {
/* new mode -> init a new entry in the aux_mode_directed[] array */
aux_mode_directed[subs_pos] = MODE_DIRECTED_SET(subs_arity - old_subs_arity, MODE_DIRECTED_GET_MODE(mode_directed[i-1])); aux_mode_directed[subs_pos] = MODE_DIRECTED_SET(subs_arity - old_subs_arity, MODE_DIRECTED_GET_MODE(mode_directed[i-1]));
subs_pos++; subs_pos++;
} }
@ -1081,23 +1083,62 @@ ans_node_ptr answer_search(sg_fr_ptr sg_fr, CELL *subs_ptr) {
#ifdef MODE_DIRECTED_TABLING #ifdef MODE_DIRECTED_TABLING
mode_directed = SgFr_mode_directed(sg_fr); mode_directed = SgFr_mode_directed(sg_fr);
if (mode_directed) { if (mode_directed) {
ans_node_ptr invalid_ans_node = NULL;
int i = subs_arity, j = 0; int i = subs_arity, j = 0;
while (i) { while (i) {
int mode = MODE_DIRECTED_GET_MODE(mode_directed[j]); int mode = MODE_DIRECTED_GET_MODE(mode_directed[j]);
int n_subs = MODE_DIRECTED_GET_ARG(mode_directed[j]); int n_subs = MODE_DIRECTED_GET_ARG(mode_directed[j]);
do { do {
TABLING_ERROR_CHECKING(answer search, IsNonVarTerm(subs_ptr[i])); TABLING_ERROR_CHECKING(answer_search, IsNonVarTerm(subs_ptr[i]));
if (TrNode_child(current_ans_node) == NULL || mode == MODE_DIRECTED_INDEX || mode == MODE_DIRECTED_ALL) if (mode == MODE_DIRECTED_INDEX || mode == MODE_DIRECTED_ALL)
current_ans_node = answer_search_loop(sg_fr, current_ans_node, Deref(subs_ptr[i]), &vars_arity); current_ans_node = answer_search_loop(sg_fr, current_ans_node, Deref(subs_ptr[i]), &vars_arity);
else { /* TrNode_child(current_node) != NULL && mode != MODE_DIRECTED_INDEX && mode != MODE_DIRECTED_ALL */ else {
if (mode == MODE_DIRECTED_FIRST) #if defined(TABLE_LOCK_AT_NODE_LEVEL)
LOCK(TrNode_lock(current_ans_node));
#elif defined(TABLE_LOCK_AT_WRITE_LEVEL)
LOCK_TABLE(current_ans_node);
#endif /* TABLE_LOCK_LEVEL */
if (TrNode_child(current_ans_node) == NULL) {
#ifdef YAPOR
struct answer_trie_node virtual_ans_node;
ans_node_ptr parent_ans_node = current_ans_node;
TrNode_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);
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);
#endif /* YAPOR */
} 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_mode_directed_min_max(sg_fr, current_ans_node, Deref(subs_ptr[i]), mode);
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; current_ans_node = NULL;
else if (mode == MODE_DIRECTED_LAST) { else { /* mode == MODE_DIRECTED_LAST */
invalidate_answer_trie(TrNode_child(current_ans_node), sg_fr, TRAVERSE_POSITION_FIRST); #ifdef YAPOR
struct answer_trie_node virtual_ans_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);
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);
TrNode_child(parent_ans_node) = TrNode_child(&virtual_ans_node);
#else
invalid_ans_node = TrNode_child(current_ans_node);
TrNode_child(current_ans_node) = NULL; TrNode_child(current_ans_node) = NULL;
current_ans_node = answer_search_loop(sg_fr, current_ans_node, Deref(subs_ptr[i]), &vars_arity); current_ans_node = answer_search_loop(sg_fr, current_ans_node, Deref(subs_ptr[i]), &vars_arity);
} else /* mode == MODE_DIRECTED_MIN || mode == MODE_DIRECTED_MAX */ #endif /* YAPOR */
current_ans_node = answer_search_mode_directed_min_max(sg_fr, current_ans_node, Deref(subs_ptr[i]), mode); }
#if defined(TABLE_LOCK_AT_NODE_LEVEL)
UNLOCK(TrNode_lock(current_ans_node));
#elif defined(TABLE_LOCK_AT_WRITE_LEVEL)
UNLOCK_TABLE(current_ans_node);
#endif /* TABLE_LOCK_LEVEL */
} }
n_subs--; n_subs--;
i--; i--;
@ -1106,16 +1147,18 @@ ans_node_ptr answer_search(sg_fr_ptr sg_fr, CELL *subs_ptr) {
break; break;
j++; j++;
} }
if (invalid_ans_node)
invalidate_answer_trie(invalid_ans_node, sg_fr, TRAVERSE_POSITION_FIRST);
} else } else
#endif /* MODE_DIRECTED_TABLING */ #endif /* MODE_DIRECTED_TABLING */
if (IsMode_GlobalTrie(TabEnt_mode(SgFr_tab_ent(sg_fr)))) { if (IsMode_GlobalTrie(TabEnt_mode(SgFr_tab_ent(sg_fr)))) {
for (i = subs_arity; i >= 1; i--) { for (i = subs_arity; i >= 1; i--) {
TABLING_ERROR_CHECKING(answer search, IsNonVarTerm(subs_ptr[i])); TABLING_ERROR_CHECKING(answer_search, IsNonVarTerm(subs_ptr[i]));
current_ans_node = answer_search_terms_loop(sg_fr, current_ans_node, Deref(subs_ptr[i]), &vars_arity); current_ans_node = answer_search_terms_loop(sg_fr, current_ans_node, Deref(subs_ptr[i]), &vars_arity);
} }
} else { } else {
for (i = subs_arity; i >= 1; i--) { for (i = subs_arity; i >= 1; i--) {
TABLING_ERROR_CHECKING(answer search, IsNonVarTerm(subs_ptr[i])); TABLING_ERROR_CHECKING(answer_search, IsNonVarTerm(subs_ptr[i]));
current_ans_node = answer_search_loop(sg_fr, current_ans_node, Deref(subs_ptr[i]), &vars_arity); current_ans_node = answer_search_loop(sg_fr, current_ans_node, Deref(subs_ptr[i]), &vars_arity);
} }
} }
@ -1234,6 +1277,18 @@ void free_subgoal_trie(sg_node_ptr current_node, int mode, int position) {
if (TrNode_child(ans_node)) if (TrNode_child(ans_node))
free_answer_trie(TrNode_child(ans_node), TRAVERSE_MODE_NORMAL, TRAVERSE_POSITION_FIRST); free_answer_trie(TrNode_child(ans_node), TRAVERSE_MODE_NORMAL, TRAVERSE_POSITION_FIRST);
FREE_ANSWER_TRIE_NODE(ans_node); FREE_ANSWER_TRIE_NODE(ans_node);
#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 #ifdef LIMIT_TABLING
remove_from_global_sg_fr_list(sg_fr); remove_from_global_sg_fr_list(sg_fr);
#endif /* LIMIT_TABLING */ #endif /* LIMIT_TABLING */

View File

@ -56,7 +56,7 @@
#define LOCK_NODE(NODE) LOCK_TABLE(NODE) #define LOCK_NODE(NODE) LOCK_TABLE(NODE)
#define UNLOCK_NODE(NODE) UNLOCK_TABLE(NODE) #define UNLOCK_NODE(NODE) UNLOCK_TABLE(NODE)
#elif defined(TABLE_LOCK_AT_NODE_LEVEL) #elif defined(TABLE_LOCK_AT_NODE_LEVEL)
#define LOCK_NODE(NODE) TRIE_LOCK(TrNode_lock(NODE)) #define LOCK_NODE(NODE) LOCK(TrNode_lock(NODE))
#define UNLOCK_NODE(NODE) UNLOCK(TrNode_lock(NODE)) #define UNLOCK_NODE(NODE) UNLOCK(TrNode_lock(NODE))
#else /* TABLE_LOCK_AT_ENTRY_LEVEL || ! YAPOR */ #else /* TABLE_LOCK_AT_ENTRY_LEVEL || ! YAPOR */
#define LOCK_NODE(NODE) #define LOCK_NODE(NODE)
@ -1203,8 +1203,14 @@ static inline ans_node_ptr answer_search_loop(sg_fr_ptr sg_fr, ans_node_ptr curr
****************************************************************************/ ****************************************************************************/
#if defined(MODE_DIRECTED_TABLING) && ! defined(MODE_TERMS_LOOP) && ! defined(MODE_GLOBAL_TRIE_LOOP) #if defined(MODE_DIRECTED_TABLING) && ! defined(MODE_TERMS_LOOP) && ! defined(MODE_GLOBAL_TRIE_LOOP)
#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_mode_directed_min_max(sg_fr_ptr sg_fr, ans_node_ptr current_node, Term t, int mode) { static inline ans_node_ptr answer_search_mode_directed_min_max(sg_fr_ptr sg_fr, ans_node_ptr current_node, Term t, int mode) {
#define in_pair 0
ans_node_ptr child_node; ans_node_ptr child_node;
Term child_term; Term child_term;
Float trie_value, term_value; Float trie_value, term_value;
@ -1255,10 +1261,8 @@ static inline ans_node_ptr answer_search_mode_directed_min_max(sg_fr_ptr sg_fr,
if (term_value == trie_value) if (term_value == trie_value)
return child_node; return child_node;
/* better answer */ /* better answer */
invalidate_answer_trie(TrNode_child(current_node), sg_fr, TRAVERSE_POSITION_FIRST);
TrNode_child(current_node) = NULL;
if (IsAtomOrIntTerm(t)) { if (IsAtomOrIntTerm(t)) {
ANSWER_CHECK_INSERT_ENTRY(sg_fr, current_node, t, _trie_retry_atom + in_pair); ANSWER_SAFE_INSERT_ENTRY(current_node, t, _trie_retry_atom);
} else if (IsApplTerm(t)) { } else if (IsApplTerm(t)) {
Functor f = FunctorOfTerm(t); Functor f = FunctorOfTerm(t);
if (f == FunctorDouble) { if (f == FunctorDouble) {
@ -1267,21 +1271,20 @@ static inline ans_node_ptr answer_search_mode_directed_min_max(sg_fr_ptr sg_fr,
Float dbl; Float dbl;
} u; } u;
u.dbl = FloatOfTerm(t); u.dbl = FloatOfTerm(t);
ANSWER_CHECK_INSERT_ENTRY(sg_fr, current_node, AbsAppl((Term *)f), _trie_retry_null + in_pair); ANSWER_SAFE_INSERT_ENTRY(current_node, AbsAppl((Term *)f), _trie_retry_null);
#if SIZEOF_DOUBLE == 2 * SIZEOF_INT_P #if SIZEOF_DOUBLE == 2 * SIZEOF_INT_P
ANSWER_CHECK_INSERT_ENTRY(sg_fr, current_node, u.t_dbl[1], _trie_retry_extension); ANSWER_SAFE_INSERT_ENTRY(current_node, u.t_dbl[1], _trie_retry_extension);
#endif /* SIZEOF_DOUBLE x SIZEOF_INT_P */ #endif /* SIZEOF_DOUBLE x SIZEOF_INT_P */
ANSWER_CHECK_INSERT_ENTRY(sg_fr, current_node, u.t_dbl[0], _trie_retry_extension); ANSWER_SAFE_INSERT_ENTRY(current_node, u.t_dbl[0], _trie_retry_extension);
ANSWER_CHECK_INSERT_ENTRY(sg_fr, current_node, AbsAppl((Term *)f), _trie_retry_double); ANSWER_SAFE_INSERT_ENTRY(current_node, AbsAppl((Term *)f), _trie_retry_double);
} else if (f == FunctorLongInt) { } else if (f == FunctorLongInt) {
Int li = LongIntOfTerm(t); Int li = LongIntOfTerm(t);
ANSWER_CHECK_INSERT_ENTRY(sg_fr, current_node, AbsAppl((Term *)f), _trie_retry_null + in_pair); ANSWER_SAFE_INSERT_ENTRY(current_node, AbsAppl((Term *)f), _trie_retry_null);
ANSWER_CHECK_INSERT_ENTRY(sg_fr, current_node, li, _trie_retry_extension); ANSWER_SAFE_INSERT_ENTRY(current_node, li, _trie_retry_extension);
ANSWER_CHECK_INSERT_ENTRY(sg_fr, current_node, AbsAppl((Term *)f), _trie_retry_longint); ANSWER_SAFE_INSERT_ENTRY(current_node, AbsAppl((Term *)f), _trie_retry_longint);
} }
} }
return current_node; return current_node;
#undef in_pair
} }
@ -1305,7 +1308,9 @@ static void invalidate_answer_trie(ans_node_ptr current_node, sg_fr_ptr sg_fr, i
invalidate_answer_trie(TrNode_child(current_node), sg_fr, TRAVERSE_POSITION_FIRST); invalidate_answer_trie(TrNode_child(current_node), sg_fr, TRAVERSE_POSITION_FIRST);
FREE_ANSWER_TRIE_NODE(current_node); FREE_ANSWER_TRIE_NODE(current_node);
} else { } else {
LOCK_NODE(current_ans_node);
TAG_AS_INVALID_LEAF_NODE(current_node); TAG_AS_INVALID_LEAF_NODE(current_node);
UNLOCK_NODE(current_ans_node);
TrNode_next(current_node) = SgFr_invalid_chain(sg_fr); TrNode_next(current_node) = SgFr_invalid_chain(sg_fr);
SgFr_invalid_chain(sg_fr) = current_node; SgFr_invalid_chain(sg_fr) = current_node;
} }

View File

@ -35,7 +35,7 @@ extern "C" {
#include "YapInterface.h" #include "YapInterface.h"
#else #else
#include <Yap/config.h> #include <Yap/src/config.h>
#if USE_GMP #if USE_GMP
#include <gmp.h> #include <gmp.h>
#endif #endif