diff --git a/Makefile.in b/Makefile.in index 21652ff61..e77d99a0c 100644 --- a/Makefile.in +++ b/Makefile.in @@ -129,7 +129,7 @@ INTERFACE_HEADERS = \ IOLIB_HEADERS=$(srcdir)/os/pl-buffer.h \ $(srcdir)/os/pl-ctype.h \ - $(srcdir)/H/pl-codelist.h \ + $(srcdir)/os/pl-codelist.h \ $(srcdir)/os/pl-dtoa.h \ $(srcdir)/os/dtoa.c \ $(srcdir)/H/pl-incl.h \ @@ -138,7 +138,6 @@ IOLIB_HEADERS=$(srcdir)/os/pl-buffer.h \ $(srcdir)/os/pl-option.h \ $(srcdir)/os/pl-os.h \ $(srcdir)/os/pl-privitf.h \ - $(srcdir)/os/pl-stream.h \ $(srcdir)/os/pl-table.h \ $(srcdir)/os/pl-text.h \ $(srcdir)/os/pl-utf8.h \ diff --git a/OPTYap/tab.insts.i b/OPTYap/tab.insts.i index e8e727655..1ce06fd17 100644 --- a/OPTYap/tab.insts.i +++ b/OPTYap/tab.insts.i @@ -1110,20 +1110,22 @@ if (TrNode_child(ans_node)) { /* unconsumed answers */ #ifdef MODE_DIRECTED_TABLING - ans_node_ptr first_ans_node, aux_ans_node; - first_ans_node = ans_node; - do { + if (IS_INVALID_LEAF_NODE(TrNode_child(ans_node))) { + ans_node_ptr first_ans_node, aux_ans_node; + first_ans_node = ans_node; ans_node = TrNode_child(ans_node); - } while (IS_INVALID_LEAF_NODE(ans_node)); - aux_ans_node = TrNode_child(first_ans_node); - while (aux_ans_node != ans_node) { - TrNode_child(first_ans_node) = ans_node; - first_ans_node = aux_ans_node; - aux_ans_node = TrNode_child(first_ans_node); - } -#else - ans_node = TrNode_child(ans_node); + do { + ans_node = TrNode_child(ans_node); + } while (IS_INVALID_LEAF_NODE(ans_node)); + aux_ans_node = TrNode_child(first_ans_node); + do { + TrNode_child(first_ans_node) = 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 */ + ans_node = TrNode_child(ans_node); DepFr_last_answer(dep_fr) = ans_node; UNLOCK(DepFr_lock(dep_fr)); consume_answer_and_procceed(dep_fr, ans_node); @@ -1172,20 +1174,22 @@ if (TrNode_child(ans_node)) { /* dependency frame with unconsumed answers */ #ifdef MODE_DIRECTED_TABLING - ans_node_ptr first_ans_node, aux_ans_node; - first_ans_node = ans_node; - do { + if (IS_INVALID_LEAF_NODE(TrNode_child(ans_node))) { + ans_node_ptr first_ans_node, aux_ans_node; + first_ans_node = ans_node; ans_node = TrNode_child(ans_node); - } while (IS_INVALID_LEAF_NODE(ans_node)); - aux_ans_node = TrNode_child(first_ans_node); - while (aux_ans_node != ans_node) { - TrNode_child(first_ans_node) = ans_node; - first_ans_node = aux_ans_node; + do { + ans_node = TrNode_child(ans_node); + } while (IS_INVALID_LEAF_NODE(ans_node)); aux_ans_node = TrNode_child(first_ans_node); - } -#else - ans_node = TrNode_child(ans_node); + do { + TrNode_child(first_ans_node) = 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 */ + ans_node = TrNode_child(ans_node); DepFr_last_answer(dep_fr) = ans_node; #ifdef YAPOR if (YOUNGER_CP(DepFr_backchain_cp(dep_fr), top_chain_cp)) @@ -1429,20 +1433,22 @@ if (TrNode_child(ans_node)) { /* dependency frame with unconsumed answers */ #ifdef MODE_DIRECTED_TABLING - ans_node_ptr first_ans_node, aux_ans_node; - first_ans_node = ans_node; - do { + if (IS_INVALID_LEAF_NODE(TrNode_child(ans_node))) { + ans_node_ptr first_ans_node, aux_ans_node; + first_ans_node = ans_node; ans_node = TrNode_child(ans_node); - } while (IS_INVALID_LEAF_NODE(ans_node)); - aux_ans_node = TrNode_child(first_ans_node); - while (aux_ans_node != ans_node) { - TrNode_child(first_ans_node) = ans_node; - first_ans_node = aux_ans_node; + do { + ans_node = TrNode_child(ans_node); + } while (IS_INVALID_LEAF_NODE(ans_node)); aux_ans_node = TrNode_child(first_ans_node); - } -#else - ans_node = TrNode_child(ans_node); + do { + TrNode_child(first_ans_node) = 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 */ + ans_node = TrNode_child(ans_node); DepFr_last_answer(dep_fr) = ans_node; if (B->cp_ap) { #ifdef YAPOR @@ -1602,20 +1608,22 @@ /* unconsumed answers */ UNLOCK_OR_FRAME(LOCAL_top_or_fr); #ifdef MODE_DIRECTED_TABLING - ans_node_ptr first_ans_node, aux_ans_node; - first_ans_node = ans_node; - do { + if (IS_INVALID_LEAF_NODE(TrNode_child(ans_node))) { + ans_node_ptr first_ans_node, aux_ans_node; + first_ans_node = ans_node; ans_node = TrNode_child(ans_node); - } while (IS_INVALID_LEAF_NODE(ans_node)); - aux_ans_node = TrNode_child(first_ans_node); - while (aux_ans_node != ans_node) { - TrNode_child(first_ans_node) = ans_node; - first_ans_node = aux_ans_node; + do { + ans_node = TrNode_child(ans_node); + } while (IS_INVALID_LEAF_NODE(ans_node)); aux_ans_node = TrNode_child(first_ans_node); - } -#else - ans_node = TrNode_child(ans_node); + do { + TrNode_child(first_ans_node) = 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 */ + ans_node = TrNode_child(ans_node); DepFr_last_answer(LOCAL_top_dep_fr) = ans_node; UNLOCK(DepFr_lock(LOCAL_top_dep_fr)); consume_answer_and_procceed(LOCAL_top_dep_fr, ans_node); diff --git a/OPTYap/tab.macros.h b/OPTYap/tab.macros.h index d0a75008f..8bfee9589 100644 --- a/OPTYap/tab.macros.h +++ b/OPTYap/tab.macros.h @@ -518,36 +518,38 @@ static inline void adjust_freeze_registers(void) { static inline void mark_as_completed(sg_fr_ptr 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; 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; } @@ -753,8 +755,42 @@ static inline void abolish_incomplete_subgoals(choiceptr prune_cp) { #ifdef INCOMPLETE_TABLING SgFr_state(sg_fr) = incomplete; 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 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; free_answer_hash_chain(SgFr_hash_chain(sg_fr)); 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; UNLOCK(SgFr_lock(sg_fr)); 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 */ } #ifdef LIMIT_TABLING diff --git a/OPTYap/tab.structs.h b/OPTYap/tab.structs.h index a681d32c1..28dff3422 100644 --- a/OPTYap/tab.structs.h +++ b/OPTYap/tab.structs.h @@ -220,13 +220,13 @@ typedef struct subgoal_frame { struct answer_trie_node *answer_trie; struct answer_trie_node *first_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 struct answer_trie_node *try_answer; #endif /* INCOMPLETE_TABLING */ -#ifdef MODE_DIRECTED_TABLING - struct answer_trie_node *invalid_chain; - int* mode_directed_array; -#endif /*MODE_DIRECTED_TABLING*/ #ifdef LIMIT_TABLING struct subgoal_frame *previous; #endif /* LIMIT_TABLING */ @@ -245,9 +245,9 @@ typedef struct subgoal_frame { #define SgFr_answer_trie(X) ((X)->answer_trie) #define SgFr_first_answer(X) ((X)->first_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_invalid_chain(X) ((X)->invalid_chain) +#define SgFr_try_answer(X) ((X)->try_answer) #define SgFr_previous(X) ((X)->previous) #define SgFr_next(X) ((X)->next) @@ -269,11 +269,11 @@ typedef struct subgoal_frame { 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_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. It is used when a subgoal was not completed during the previous evaluation. 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_next: a pointer to the next subgoal frame on the chain. diff --git a/OPTYap/tab.tries.c b/OPTYap/tab.tries.c index 353cf47c1..5ae9f2938 100644 --- a/OPTYap/tab.tries.c +++ b/OPTYap/tab.tries.c @@ -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); 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])) { + /* 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); } 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])); subs_pos++; } @@ -1081,23 +1083,62 @@ ans_node_ptr answer_search(sg_fr_ptr sg_fr, CELL *subs_ptr) { #ifdef MODE_DIRECTED_TABLING mode_directed = SgFr_mode_directed(sg_fr); if (mode_directed) { + ans_node_ptr invalid_ans_node = NULL; int i = subs_arity, j = 0; while (i) { int mode = MODE_DIRECTED_GET_MODE(mode_directed[j]); int n_subs = MODE_DIRECTED_GET_ARG(mode_directed[j]); do { - TABLING_ERROR_CHECKING(answer search, IsNonVarTerm(subs_ptr[i])); - if (TrNode_child(current_ans_node) == NULL || mode == MODE_DIRECTED_INDEX || mode == MODE_DIRECTED_ALL) + TABLING_ERROR_CHECKING(answer_search, IsNonVarTerm(subs_ptr[i])); + 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); - else { /* TrNode_child(current_node) != NULL && mode != MODE_DIRECTED_INDEX && mode != MODE_DIRECTED_ALL */ - if (mode == MODE_DIRECTED_FIRST) + else { +#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; - else if (mode == MODE_DIRECTED_LAST) { - invalidate_answer_trie(TrNode_child(current_ans_node), sg_fr, TRAVERSE_POSITION_FIRST); + else { /* mode == MODE_DIRECTED_LAST */ +#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; 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 */ - current_ans_node = answer_search_mode_directed_min_max(sg_fr, current_ans_node, Deref(subs_ptr[i]), mode); +#endif /* YAPOR */ + } +#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--; i--; @@ -1106,16 +1147,18 @@ ans_node_ptr answer_search(sg_fr_ptr sg_fr, CELL *subs_ptr) { break; j++; } + if (invalid_ans_node) + invalidate_answer_trie(invalid_ans_node, sg_fr, TRAVERSE_POSITION_FIRST); } else #endif /* MODE_DIRECTED_TABLING */ if (IsMode_GlobalTrie(TabEnt_mode(SgFr_tab_ent(sg_fr)))) { 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); } } else { 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); } } @@ -1234,6 +1277,18 @@ void free_subgoal_trie(sg_node_ptr current_node, int mode, int position) { if (TrNode_child(ans_node)) free_answer_trie(TrNode_child(ans_node), TRAVERSE_MODE_NORMAL, TRAVERSE_POSITION_FIRST); 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 remove_from_global_sg_fr_list(sg_fr); #endif /* LIMIT_TABLING */ diff --git a/OPTYap/tab.tries.i b/OPTYap/tab.tries.i index 0312bfbd2..c2f0cf0c1 100644 --- a/OPTYap/tab.tries.i +++ b/OPTYap/tab.tries.i @@ -56,7 +56,7 @@ #define LOCK_NODE(NODE) LOCK_TABLE(NODE) #define UNLOCK_NODE(NODE) UNLOCK_TABLE(NODE) #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)) #else /* TABLE_LOCK_AT_ENTRY_LEVEL || ! YAPOR */ #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) +#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) { -#define in_pair 0 ans_node_ptr child_node; Term child_term; 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) return child_node; /* better answer */ - invalidate_answer_trie(TrNode_child(current_node), sg_fr, TRAVERSE_POSITION_FIRST); - TrNode_child(current_node) = NULL; 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)) { Functor f = FunctorOfTerm(t); 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; } u; 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 - 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 */ - ANSWER_CHECK_INSERT_ENTRY(sg_fr, 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, u.t_dbl[0], _trie_retry_extension); + ANSWER_SAFE_INSERT_ENTRY(current_node, AbsAppl((Term *)f), _trie_retry_double); } else if (f == FunctorLongInt) { Int li = LongIntOfTerm(t); - ANSWER_CHECK_INSERT_ENTRY(sg_fr, current_node, AbsAppl((Term *)f), _trie_retry_null + in_pair); - ANSWER_CHECK_INSERT_ENTRY(sg_fr, 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_null); + ANSWER_SAFE_INSERT_ENTRY(current_node, li, _trie_retry_extension); + ANSWER_SAFE_INSERT_ENTRY(current_node, AbsAppl((Term *)f), _trie_retry_longint); } } 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); FREE_ANSWER_TRIE_NODE(current_node); } else { + LOCK_NODE(current_ans_node); TAG_AS_INVALID_LEAF_NODE(current_node); + UNLOCK_NODE(current_ans_node); TrNode_next(current_node) = SgFr_invalid_chain(sg_fr); SgFr_invalid_chain(sg_fr) = current_node; } diff --git a/include/SWI-Prolog.h b/include/SWI-Prolog.h index d6f4e1749..94c26c3fc 100644 --- a/include/SWI-Prolog.h +++ b/include/SWI-Prolog.h @@ -35,7 +35,7 @@ extern "C" { #include "YapInterface.h" #else -#include +#include #if USE_GMP #include #endif