From 88760aa0b18fcd32d5af081c0d68a5dc9835753b Mon Sep 17 00:00:00 2001 From: Ricardo Rocha Date: Wed, 9 Nov 2011 11:00:31 +0000 Subject: [PATCH] mode directed tabling --- OPTYap/opt.config.h | 7 +- OPTYap/opt.preds.c | 203 +++++----------- OPTYap/tab.insts.i | 112 +++++---- OPTYap/tab.macros.h | 197 +++++++-------- OPTYap/tab.structs.h | 84 ++----- OPTYap/tab.tries.c | 568 +++++-------------------------------------- OPTYap/tab.tries.i | 187 +++++++++++++- pl/tabling.yap | 48 ++-- 8 files changed, 513 insertions(+), 893 deletions(-) diff --git a/OPTYap/opt.config.h b/OPTYap/opt.config.h index ac530ad52..e43cfd17f 100644 --- a/OPTYap/opt.config.h +++ b/OPTYap/opt.config.h @@ -16,7 +16,7 @@ /************************************************************************ ** General Configuration Parameters ** ************************************************************************/ -#define MODE_DIRECTED_TABLING + /****************************************************************************************** ** use shared pages memory alloc scheme for OPTYap data structures? (optional) ** ******************************************************************************************/ @@ -40,6 +40,11 @@ #define BFZ_TRAIL_SCHEME 1 /* #define BBREG_TRAIL_SCHEME 1 */ +/********************************************************* +** support mode directed tabling ? (optional) ** +*********************************************************/ +/* #define MODE_DIRECTED_TABLING 1 */ + /**************************************************** ** support early completion ? (optional) ** ****************************************************/ diff --git a/OPTYap/opt.preds.c b/OPTYap/opt.preds.c index 66221c676..ca236e42a 100644 --- a/OPTYap/opt.preds.c +++ b/OPTYap/opt.preds.c @@ -39,9 +39,6 @@ static Int p_wake_choice_point( USES_REGS1 ); static Int p_abolish_frozen_choice_points_until( USES_REGS1 ); static Int p_abolish_frozen_choice_points_all( USES_REGS1 ); static Int p_table( USES_REGS1 ); -#ifdef MODE_DIRECTED_TABLING -static Int p_table_mode_directed( USES_REGS1 ); -#endif /*MODE_DIRECTED_TABLING*/ static Int p_tabling_mode( USES_REGS1 ); static Int p_abolish_table( USES_REGS1 ); static Int p_abolish_all_tables( USES_REGS1 ); @@ -124,10 +121,7 @@ void Yap_init_optyap_preds(void) { Yap_InitCPred("wake_choice_point", 1, p_wake_choice_point, SafePredFlag|SyncPredFlag); Yap_InitCPred("abolish_frozen_choice_points", 1, p_abolish_frozen_choice_points_until, SafePredFlag|SyncPredFlag); Yap_InitCPred("abolish_frozen_choice_points", 0, p_abolish_frozen_choice_points_all, SafePredFlag|SyncPredFlag); - Yap_InitCPred("$c_table", 2, p_table, SafePredFlag|SyncPredFlag|HiddenPredFlag); -#ifdef MODE_DIRECTED_TABLING - Yap_InitCPred("$c_table_mode_directed", 3, p_table_mode_directed, SafePredFlag|SyncPredFlag|HiddenPredFlag); -#endif /*MODE_DIRECTED_TABLING*/ + Yap_InitCPred("$c_table", 3, p_table, SafePredFlag|SyncPredFlag|HiddenPredFlag); Yap_InitCPred("$c_tabling_mode", 3, p_tabling_mode, SafePredFlag|SyncPredFlag|HiddenPredFlag); Yap_InitCPred("$c_abolish_table", 2, p_abolish_table, SafePredFlag|SyncPredFlag|HiddenPredFlag); Yap_InitCPred("abolish_all_tables", 0, p_abolish_all_tables, SafePredFlag|SyncPredFlag); @@ -204,147 +198,18 @@ static Int p_abolish_frozen_choice_points_all( USES_REGS1 ) { static Int p_table( USES_REGS1 ) { - Term mod, t; - PredEntry *pe; - Atom at; - int arity; - tab_ent_ptr tab_ent; - - mod = Deref(ARG1); - t = Deref(ARG2); - if (IsAtomTerm(t)) { - at = AtomOfTerm(t); - pe = RepPredProp(PredPropByAtom(at, mod)); - arity = 0; - } else if (IsApplTerm(t)) { - at = NameOfFunctor(FunctorOfTerm(t)); - pe = RepPredProp(PredPropByFunc(FunctorOfTerm(t), mod)); - arity = ArityOfFunctor(FunctorOfTerm(t)); - } else - return (FALSE); - if (pe->PredFlags & TabledPredFlag) - return (TRUE); /* predicate already tabled */ - if (pe->cs.p_code.FirstClause) - return (FALSE); /* predicate already compiled */ - pe->PredFlags |= TabledPredFlag; -#ifdef MODE_DIRECTED_TABLING - new_table_entry(tab_ent, pe, at, arity, NULL); -#else - new_table_entry(tab_ent, pe, at, arity); -#endif /*MODE_DIRECTED_TABLING*/ - pe->TableOfPred = tab_ent; - return (TRUE); -} - -#ifdef MODE_DIRECTED_TABLING - -static Int p_table_mode_directed( USES_REGS1 ) { - - Term mod, t, list; PredEntry *pe; Atom at; int arity; tab_ent_ptr tab_ent; - +#ifdef MODE_DIRECTED_TABLING + int* mode_directed = NULL; +#endif /* MODE_DIRECTED_TABLING */ + mod = Deref(ARG1); t = Deref(ARG2); - list = ARG3; - - Functor f = FunctorOfTerm(t); - arity=ArityOfFunctor(f); - - int* aux; - int* vec; - - - int i=0,n_index=0,n_agreg=0,n_nindex=0,n_all=0,n_last=0; - - - ALLOC_BLOCK(vec,arity*sizeof(int),int); - ALLOC_BLOCK(aux,arity*sizeof(int),int); - - while(IsPairTerm(list)){ - char *str_val = &RepAtom(AtomOfTerm(HeadOfTerm(list)))->StrOfAE; - //printf("----2 %s %d\n",str_val,i); - if(! strcmp(str_val ,"index")){ - vec[i] = MODE_DIRECTED_INDEX; - n_index++; - } - else if (! strcmp(str_val ,"all")){ - vec[i] = MODE_DIRECTED_ALL; - n_all++; - } - else if(!strcmp(str_val,"last")){ - vec[i] = MODE_DIRECTED_LAST; - n_last++; - } - else if(!strcmp(str_val,"min")){ - vec[i] = MODE_DIRECTED_MIN; - n_agreg++; - } - else if(!strcmp(str_val,"max")){ - vec[i] = MODE_DIRECTED_MAX; - n_agreg++; - } - else if(!strcmp(str_val,"first")){ - vec[i] = MODE_DIRECTED_NINDEX; - } - list=TailOfTerm(list); - i++; - } - - n_nindex = n_index + n_agreg + n_all + n_last; - n_last = n_index + n_agreg + n_all; - n_all = n_index + n_agreg; - n_agreg = n_index; - n_index = 0; - - - - for(i = 0;i < arity; i++){ - if(vec[i]==MODE_DIRECTED_MAX){ - aux[n_agreg]= i << MODE_DIRECTED_TAGBITS; - aux[n_agreg]= aux[n_agreg] + MODE_DIRECTED_MAX; - n_agreg++; - } - else if(vec[i]==MODE_DIRECTED_MIN){ - aux[n_agreg]= i << MODE_DIRECTED_TAGBITS; - aux[n_agreg]= aux[n_agreg] + MODE_DIRECTED_MIN; - n_agreg++; - } - - else if(vec[i]==MODE_DIRECTED_INDEX){ - aux[n_index]= i << MODE_DIRECTED_TAGBITS; - aux[n_index]= aux[n_index] + MODE_DIRECTED_INDEX; - n_index++; - } - - else if(vec[i]==MODE_DIRECTED_NINDEX){ - aux[n_nindex]= i << MODE_DIRECTED_TAGBITS; - aux[n_nindex]= aux[n_nindex] + MODE_DIRECTED_NINDEX; - n_nindex++; - } - else if(vec[i]==MODE_DIRECTED_ALL){ - aux[n_all]= i << MODE_DIRECTED_TAGBITS; - aux[n_all]= aux[n_all] + MODE_DIRECTED_ALL; - n_all++; - } - else if(vec[i]==MODE_DIRECTED_LAST){ - aux[n_last]= i << MODE_DIRECTED_TAGBITS; - aux[n_last]= aux[n_last] + MODE_DIRECTED_LAST; - n_last++; - } - } - -/* -i=0; - while(i < arity){ - printf("aux[%d] %p \n",i,aux[i]); - i ++; - } -*/ - + list = Deref(ARG3); if (IsAtomTerm(t)) { at = AtomOfTerm(t); @@ -356,18 +221,68 @@ i=0; arity = ArityOfFunctor(FunctorOfTerm(t)); } else return (FALSE); + if (list != TermNil) { /* non-empty list */ +#ifndef MODE_DIRECTED_TABLING + Yap_Error(INTERNAL_COMPILER_ERROR, TermNil, "invalid tabling declaration for %s/%d (mode directed tabling not enabled)", AtomName(at), arity); + return(FALSE); +#else + int pos_index = 0; + int pos_agreg = 0; /* min/max */ + int pos_first = 0; + int pos_all = 0; + int pos_last = 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_ALL) + pos_all++; + else if (mode == MODE_DIRECTED_LAST) + pos_last++; + else if (mode == MODE_DIRECTED_MIN || mode == MODE_DIRECTED_MAX) + pos_agreg++; + 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_index = 0; + for (i = 0; i < arity; i++) { + int aux_pos; + 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) + 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_ALL) + aux_pos = pos_all++; + else if (aux_mode_directed[i] == MODE_DIRECTED_LAST) + aux_pos = pos_last++; + mode_directed[aux_pos] = MODE_DIRECTED_SET(i, aux_mode_directed[i]); + } + free(aux_mode_directed); +#endif /*MODE_DIRECTED_TABLING*/ + } if (pe->PredFlags & TabledPredFlag) return (TRUE); /* predicate already tabled */ if (pe->cs.p_code.FirstClause) return (FALSE); /* predicate already compiled */ pe->PredFlags |= TabledPredFlag; - new_table_entry(tab_ent, pe, at, arity, aux); + new_table_entry(tab_ent, pe, at, arity, mode_directed); pe->TableOfPred = tab_ent; return (TRUE); - } -#endif /*MODE_DIRECTED_TABLING*/ static Int p_tabling_mode( USES_REGS1 ) { Term mod, t, tvalue; diff --git a/OPTYap/tab.insts.i b/OPTYap/tab.insts.i index 145e773e4..e8e727655 100644 --- a/OPTYap/tab.insts.i +++ b/OPTYap/tab.insts.i @@ -870,9 +870,9 @@ #endif /* TABLE_LOCK_LEVEL */ ans_node = answer_search(sg_fr, subs_ptr); #ifdef MODE_DIRECTED_TABLING - if(ans_node == NULL) + if (ans_node == NULL) /* no answer inserted */ goto fail; -#endif /*MODE_DIRECTED_TABLING*/ +#endif /* MODE_DIRECTED_TABLING */ #if defined(TABLE_LOCK_AT_NODE_LEVEL) LOCK(TrNode_lock(ans_node)); #elif defined(TABLE_LOCK_AT_WRITE_LEVEL) @@ -1107,18 +1107,23 @@ dep_fr = CONS_CP(B)->cp_dep_fr; LOCK(DepFr_lock(dep_fr)); ans_node = DepFr_last_answer(dep_fr); -#ifdef MODE_DIRECTED_TABLING - ans_node_ptr aux_ans_node = ans_node; - do { - ans_node=TrNode_child(ans_node); - } while(ans_node != NULL && IS_INVALID_ANSWER_LEAF_NODE(ans_node)); - if (ans_node){ - TrNode_child(aux_ans_node)=ans_node; -#else if (TrNode_child(ans_node)) { - /* unconsumed answer */ - ans_node = DepFr_last_answer(dep_fr) = TrNode_child(ans_node); -#endif /*MODE_DIRECTED_TABLING*/ + /* unconsumed answers */ +#ifdef MODE_DIRECTED_TABLING + ans_node_ptr first_ans_node, aux_ans_node; + first_ans_node = ans_node; + do { + 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); +#endif /* MODE_DIRECTED_TABLING */ DepFr_last_answer(dep_fr) = ans_node; UNLOCK(DepFr_lock(dep_fr)); consume_answer_and_procceed(dep_fr, ans_node); @@ -1164,18 +1169,24 @@ while (YOUNGER_CP(DepFr_cons_cp(dep_fr), chain_cp)) { LOCK(DepFr_lock(dep_fr)); ans_node = DepFr_last_answer(dep_fr); + if (TrNode_child(ans_node)) { + /* dependency frame with unconsumed answers */ #ifdef MODE_DIRECTED_TABLING - ans_node_ptr aux_ans_node = ans_node; - do { - ans_node=TrNode_child(ans_node); - } while(ans_node != NULL && IS_INVALID_ANSWER_LEAF_NODE(ans_node)); - if (ans_node){ - TrNode_child(aux_ans_node)=ans_node; + ans_node_ptr first_ans_node, aux_ans_node; + first_ans_node = ans_node; + do { + 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 - if (TrNode_child(ans_node)) - /* dependency frame with unconsumed answers */ - ans_node = DepFr_last_answer(dep_fr) = TrNode_child(ans_node); -#endif /*MODE_DIRECTED_TABLING*/ + ans_node = TrNode_child(ans_node); +#endif /* MODE_DIRECTED_TABLING */ + DepFr_last_answer(dep_fr) = ans_node; #ifdef YAPOR if (YOUNGER_CP(DepFr_backchain_cp(dep_fr), top_chain_cp)) #endif /* YAPOR */ @@ -1415,18 +1426,24 @@ while (YOUNGER_CP(DepFr_cons_cp(dep_fr), B)) { LOCK(DepFr_lock(dep_fr)); ans_node = DepFr_last_answer(dep_fr); + if (TrNode_child(ans_node)) { + /* dependency frame with unconsumed answers */ #ifdef MODE_DIRECTED_TABLING - ans_node_ptr aux_ans_node = ans_node; - do { - ans_node=TrNode_child(ans_node); - } while(ans_node != NULL && IS_INVALID_ANSWER_LEAF_NODE(ans_node)); - if (ans_node){ - TrNode_child(aux_ans_node)=ans_node; + ans_node_ptr first_ans_node, aux_ans_node; + first_ans_node = ans_node; + do { + 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 - if (TrNode_child(ans_node)) - /* dependency frame with unconsumed answers */ - ans_node = DepFr_last_answer(dep_fr) = TrNode_child(ans_node); -#endif /*MODE_DIRECTED_TABLING*/ + ans_node = TrNode_child(ans_node); +#endif /* MODE_DIRECTED_TABLING */ + DepFr_last_answer(dep_fr) = ans_node; if (B->cp_ap) { #ifdef YAPOR if (YOUNGER_CP(DepFr_backchain_cp(dep_fr), B)) @@ -1581,20 +1598,25 @@ LOCK_OR_FRAME(LOCAL_top_or_fr); LOCK(DepFr_lock(LOCAL_top_dep_fr)); ans_node = DepFr_last_answer(LOCAL_top_dep_fr); -#ifdef MODE_DIRECTED_TABLING - ans_node_ptr aux_ans_node = ans_node; - do { - ans_node=TrNode_child(ans_node); - } while(ans_node != NULL && IS_INVALID_ANSWER_LEAF_NODE(ans_node)); - if (ans_node){ - TrNode_child(aux_ans_node)=ans_node; -#else if (TrNode_child(ans_node)) { - /* unconsumed answer */ - ans_node = DepFr_last_answer(dep_fr) = TrNode_child(ans_node); -#endif /*MODE_DIRECTED_TABLING*/ + /* unconsumed answers */ UNLOCK_OR_FRAME(LOCAL_top_or_fr); - ans_node = DepFr_last_answer(LOCAL_top_dep_fr) = TrNode_child(ans_node); +#ifdef MODE_DIRECTED_TABLING + ans_node_ptr first_ans_node, aux_ans_node; + first_ans_node = ans_node; + do { + 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); +#endif /* MODE_DIRECTED_TABLING */ + 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 d54bec661..d0a75008f 100644 --- a/OPTYap/tab.macros.h +++ b/OPTYap/tab.macros.h @@ -106,6 +106,19 @@ static inline tg_sol_fr_ptr CUT_prune_tg_solution_frames(tg_sol_fr_ptr, int); #define TRAVERSE_POSITION_FIRST 1 #define TRAVERSE_POSITION_LAST 2 +/* mode directed tabling */ +#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_LAST 6 +#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) + /* LowTagBits is 3 for 32 bit-machines and 7 for 64 bit-machines */ #define NumberOfLowTagBits (LowTagBits == 3 ? 2 : 3) #define MakeTableVarTerm(INDEX) ((INDEX) << NumberOfLowTagBits) @@ -141,6 +154,8 @@ static inline tg_sol_fr_ptr CUT_prune_tg_solution_frames(tg_sol_fr_ptr, int); #define TAG_AS_ANSWER_LEAF_NODE(NODE) TrNode_parent(NODE) = (ans_node_ptr)((unsigned long int) TrNode_parent(NODE) | 0x1) #define UNTAG_ANSWER_LEAF_NODE(NODE) ((ans_node_ptr)((unsigned long int) (NODE) & ~(0x1))) #define IS_ANSWER_LEAF_NODE(NODE) ((unsigned long int) TrNode_parent(NODE) & 0x1) +#define TAG_AS_INVALID_LEAF_NODE(NODE) TrNode_parent(NODE) = (ans_node_ptr)((unsigned long int) TrNode_parent(NODE) | 0x2) +#define IS_INVALID_LEAF_NODE(NODE) ((unsigned long int) TrNode_parent(NODE) & 0x2) #define MAX_NODES_PER_TRIE_LEVEL 8 #define MAX_NODES_PER_BUCKET (MAX_NODES_PER_TRIE_LEVEL / 2) @@ -239,15 +254,32 @@ static inline tg_sol_fr_ptr CUT_prune_tg_solution_frames(tg_sol_fr_ptr, int); #define DepFr_init_yapor_fields(DEP_FR, DEP_ON_STACK, TOP_OR_FR) #endif /* YAPOR */ +#ifdef MODE_DIRECTED_TABLING +#define TabEnt_init_mode_directed(TAB_ENT, MODE_ARRAY) \ + TabEnt_mode_directed(TAB_ENT) = MODE_ARRAY +#define SgFr_init_mode_directed(SG_FR, MODE_ARRAY) \ + SgFr_invalid_chain(SG_FR) = NULL; \ + SgFr_mode_directed(SG_FR) = MODE_ARRAY +#define AnsHash_init_previous_field(HASH, SG_FR) \ + if (SgFr_hash_chain(SG_FR)) \ + Hash_previous(SgFr_hash_chain(SG_FR)) = HASH; \ + Hash_previous(HASH) = NULL +#else +#define TabEnt_init_mode_directed(TAB_ENT, MODE_ARRAY) +#define SgFr_init_mode_directed(SG_FR, MODE_ARRAY) +#define AnsHash_init_previous_field(HASH, SG_FR) +#endif /* MODE_DIRECTED_TABLING */ + #ifdef TABLE_LOCK_AT_ENTRY_LEVEL #define TabEnt_init_lock_field(TAB_ENT) \ INIT_LOCK(TabEnt_lock(TAB_ENT)) #define SgHash_init_next_field(HASH, TAB_ENT) \ Hash_next(HASH) = TabEnt_hash_chain(TAB_ENT); \ TabEnt_hash_chain(TAB_ENT) = HASH -#define AnsHash_init_next_field(HASH, SG_FR) \ +#define AnsHash_init_chain_fields(HASH, SG_FR) \ + AnsHash_init_previous_field(HASH, SG_FR); \ Hash_next(HASH) = SgFr_hash_chain(SG_FR); \ - SgFr_hash_chain(SG_FR) = HASH + SgFr_hash_chain(SG_FR) = HASH #else #define TabEnt_init_lock_field(TAB_ENT) #define SgHash_init_next_field(HASH, TAB_ENT) \ @@ -255,8 +287,9 @@ static inline tg_sol_fr_ptr CUT_prune_tg_solution_frames(tg_sol_fr_ptr, int); Hash_next(HASH) = TabEnt_hash_chain(TAB_ENT); \ TabEnt_hash_chain(TAB_ENT) = HASH; \ UNLOCK(TabEnt_lock(TAB_ENT)) -#define AnsHash_init_next_field(HASH, SG_FR) \ +#define AnsHash_init_chain_fields(HASH, SG_FR) \ LOCK(SgFr_lock(SG_FR)); \ + AnsHash_init_previous_field(HASH, SG_FR); \ Hash_next(HASH) = SgFr_hash_chain(SG_FR); \ SgFr_hash_chain(SG_FR) = HASH; \ UNLOCK(SgFr_lock(SG_FR)) @@ -269,81 +302,33 @@ static inline tg_sol_fr_ptr CUT_prune_tg_solution_frames(tg_sol_fr_ptr, int); #define TrNode_init_lock_field(NODE) #endif /* TABLE_LOCK_AT_NODE_LEVEL */ -#ifdef MODE_DIRECTED_TABLING - -#define new_table_entry(TAB_ENT, PRED_ENTRY, ATOM, ARITY, MODE_DIRECTED_ARRAY)\ - { register sg_node_ptr sg_node; \ - new_subgoal_trie_node(sg_node, 0, NULL, NULL, NULL); \ - ALLOC_TABLE_ENTRY(TAB_ENT); \ - TabEnt_init_lock_field(TAB_ENT); \ - TabEnt_pe(TAB_ENT) = PRED_ENTRY; \ - TabEnt_atom(TAB_ENT) = ATOM; \ - TabEnt_arity(TAB_ENT) = ARITY; \ - TabEnt_flags(TAB_ENT) = 0; \ - SetMode_Batched(TabEnt_flags(TAB_ENT)); \ - SetMode_ExecAnswers(TabEnt_flags(TAB_ENT)); \ - SetMode_LocalTrie(TabEnt_flags(TAB_ENT)); \ - TabEnt_mode(TAB_ENT) = TabEnt_flags(TAB_ENT); \ - if (IsMode_Local(yap_flags[TABLING_MODE_FLAG])) \ - SetMode_Local(TabEnt_mode(TAB_ENT)); \ - if (IsMode_LoadAnswers(yap_flags[TABLING_MODE_FLAG])) \ - SetMode_LoadAnswers(TabEnt_mode(TAB_ENT)); \ - if (IsMode_GlobalTrie(yap_flags[TABLING_MODE_FLAG])) \ - SetMode_GlobalTrie(TabEnt_mode(TAB_ENT)); \ - TabEnt_subgoal_trie(TAB_ENT) = sg_node; \ - TabEnt_hash_chain(TAB_ENT) = NULL; \ - TabEnt_next(TAB_ENT) = GLOBAL_root_tab_ent; \ - GLOBAL_root_tab_ent = TAB_ENT; \ - TabEnt_mode_directed_array(TAB_ENT) = MODE_DIRECTED_ARRAY; \ +#define new_table_entry(TAB_ENT, PRED_ENTRY, ATOM, ARITY, MODE_ARRAY) \ + { register sg_node_ptr sg_node; \ + new_subgoal_trie_node(sg_node, 0, NULL, NULL, NULL); \ + ALLOC_TABLE_ENTRY(TAB_ENT); \ + TabEnt_init_lock_field(TAB_ENT); \ + TabEnt_pe(TAB_ENT) = PRED_ENTRY; \ + TabEnt_atom(TAB_ENT) = ATOM; \ + TabEnt_arity(TAB_ENT) = ARITY; \ + TabEnt_flags(TAB_ENT) = 0; \ + SetMode_Batched(TabEnt_flags(TAB_ENT)); \ + SetMode_ExecAnswers(TabEnt_flags(TAB_ENT)); \ + SetMode_LocalTrie(TabEnt_flags(TAB_ENT)); \ + TabEnt_mode(TAB_ENT) = TabEnt_flags(TAB_ENT); \ + if (IsMode_Local(yap_flags[TABLING_MODE_FLAG])) \ + SetMode_Local(TabEnt_mode(TAB_ENT)); \ + if (IsMode_LoadAnswers(yap_flags[TABLING_MODE_FLAG])) \ + SetMode_LoadAnswers(TabEnt_mode(TAB_ENT)); \ + if (IsMode_GlobalTrie(yap_flags[TABLING_MODE_FLAG])) \ + SetMode_GlobalTrie(TabEnt_mode(TAB_ENT)); \ + TabEnt_init_mode_directed(TAB_ENT, MODE_ARRAY); \ + TabEnt_subgoal_trie(TAB_ENT) = sg_node; \ + TabEnt_hash_chain(TAB_ENT) = NULL; \ + TabEnt_next(TAB_ENT) = GLOBAL_root_tab_ent; \ + GLOBAL_root_tab_ent = TAB_ENT; \ } -#else - -#define new_table_entry(TAB_ENT, PRED_ENTRY, ATOM, ARITY) \ - { register sg_node_ptr sg_node; \ - new_subgoal_trie_node(sg_node, 0, NULL, NULL, NULL); \ - ALLOC_TABLE_ENTRY(TAB_ENT); \ - TabEnt_init_lock_field(TAB_ENT); \ - TabEnt_pe(TAB_ENT) = PRED_ENTRY; \ - TabEnt_atom(TAB_ENT) = ATOM; \ - TabEnt_arity(TAB_ENT) = ARITY; \ - TabEnt_flags(TAB_ENT) = 0; \ - SetMode_Batched(TabEnt_flags(TAB_ENT)); \ - SetMode_ExecAnswers(TabEnt_flags(TAB_ENT)); \ - SetMode_LocalTrie(TabEnt_flags(TAB_ENT)); \ - TabEnt_mode(TAB_ENT) = TabEnt_flags(TAB_ENT); \ - if (IsMode_Local(yap_flags[TABLING_MODE_FLAG])) \ - SetMode_Local(TabEnt_mode(TAB_ENT)); \ - if (IsMode_LoadAnswers(yap_flags[TABLING_MODE_FLAG])) \ - SetMode_LoadAnswers(TabEnt_mode(TAB_ENT)); \ - if (IsMode_GlobalTrie(yap_flags[TABLING_MODE_FLAG])) \ - SetMode_GlobalTrie(TabEnt_mode(TAB_ENT)); \ - TabEnt_subgoal_trie(TAB_ENT) = sg_node; \ - TabEnt_hash_chain(TAB_ENT) = NULL; \ - TabEnt_next(TAB_ENT) = GLOBAL_root_tab_ent; \ - GLOBAL_root_tab_ent = TAB_ENT; \ - } - -#endif /*MODE_DIRECTED_TABLING*/ - -#ifdef MODE_DIRECTED_TABLING - -#define new_subgoal_frame(SG_FR, CODE, N_VARS_OPERATOR_ARRAY) \ - { register ans_node_ptr ans_node; \ - new_answer_trie_node(ans_node, 0,N_VARS_OPERATOR_ARRAY, NULL, NULL, NULL); \ - ALLOC_SUBGOAL_FRAME(SG_FR); \ - INIT_LOCK(SgFr_lock(SG_FR)); \ - SgFr_code(SG_FR) = CODE; \ - SgFr_state(SG_FR) = ready; \ - SgFr_hash_chain(SG_FR) = NULL; \ - SgFr_answer_trie(SG_FR) = ans_node; \ - SgFr_first_answer(SG_FR) = NULL; \ - SgFr_last_answer(SG_FR) = NULL; \ - SgFr_del_node(SG_FR) = NULL; \ - } -#else - -#define new_subgoal_frame(SG_FR, CODE) \ +#define new_subgoal_frame(SG_FR, CODE, MODE_ARRAY) \ { register ans_node_ptr ans_node; \ new_answer_trie_node(ans_node, 0, 0, NULL, NULL, NULL); \ ALLOC_SUBGOAL_FRAME(SG_FR); \ @@ -354,8 +339,8 @@ static inline tg_sol_fr_ptr CUT_prune_tg_solution_frames(tg_sol_fr_ptr, int); SgFr_answer_trie(SG_FR) = ans_node; \ SgFr_first_answer(SG_FR) = NULL; \ SgFr_last_answer(SG_FR) = NULL; \ + SgFr_init_mode_directed(SG_FR, MODE_ARRAY); \ } -#endif /*MODE_DIRECTED_TABLING*/ #define init_subgoal_frame(SG_FR) \ { SgFr_init_yapor_fields(SG_FR); \ @@ -434,7 +419,7 @@ static inline tg_sol_fr_ptr CUT_prune_tg_solution_frames(tg_sol_fr_ptr, int); Hash_num_buckets(HASH) = BASE_HASH_BUCKETS; \ ALLOC_HASH_BUCKETS(Hash_buckets(HASH), BASE_HASH_BUCKETS); \ Hash_num_nodes(HASH) = NUM_NODES; \ - AnsHash_init_next_field(HASH, SG_FR) + AnsHash_init_chain_fields(HASH, SG_FR) #define new_global_trie_hash(HASH, NUM_NODES) \ ALLOC_GLOBAL_TRIE_HASH(HASH); \ @@ -534,39 +519,33 @@ 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 - - //printf("complete\n"); - ans_node_ptr answer, valid_answer, elim_answer; - answer = SgFr_first_answer(sg_fr); - - while(answer && IS_INVALID_ANSWER_LEAF_NODE(answer)) - answer = TrNode_child(answer); - SgFr_first_answer(sg_fr) = answer; - valid_answer = answer; - - if(answer!= NULL) - answer = TrNode_child(valid_answer); - - while(answer != NULL){ - if (!IS_INVALID_ANSWER_LEAF_NODE(answer)){ - TrNode_child(valid_answer) = answer; - valid_answer = answer; + 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; } - answer = TrNode_child(answer); } - - //TrNode_child(valid_answer) = NULL; - SgFr_last_answer(sg_fr) = valid_answer; - - elim_answer = SgFr_del_node(sg_fr); - - while(elim_answer){ - answer= TrNode_next(elim_answer); - FREE_ANSWER_TRIE_NODE(elim_answer); - elim_answer = answer; - } - -#endif /*MODE_DIRECTED_TABLING*/ +#endif /* MODE_DIRECTED_TABLING */ SgFr_state(sg_fr) = complete; UNLOCK(SgFr_lock(sg_fr)); return; diff --git a/OPTYap/tab.structs.h b/OPTYap/tab.structs.h index e465bd1d6..a681d32c1 100644 --- a/OPTYap/tab.structs.h +++ b/OPTYap/tab.structs.h @@ -28,26 +28,24 @@ typedef struct table_entry { int pred_arity; short pred_flags; short execution_mode; /* combines yap_flags with pred_flags */ - struct subgoal_trie_node *subgoal_trie; - struct subgoal_trie_hash *hash_chain; #ifdef MODE_DIRECTED_TABLING int* mode_directed_array; #endif /*MODE_DIRECTED_TABLING*/ + struct subgoal_trie_node *subgoal_trie; + struct subgoal_trie_hash *hash_chain; struct table_entry *next; } *tab_ent_ptr; -#define TabEnt_lock(X) ((X)->lock) -#define TabEnt_pe(X) ((X)->pred_entry) -#define TabEnt_atom(X) ((X)->pred_atom) -#define TabEnt_arity(X) ((X)->pred_arity) -#define TabEnt_flags(X) ((X)->pred_flags) -#define TabEnt_mode(X) ((X)->execution_mode) -#define TabEnt_subgoal_trie(X) ((X)->subgoal_trie) -#define TabEnt_hash_chain(X) ((X)->hash_chain) -#ifdef MODE_DIRECTED_TABLING -#define TabEnt_mode_directed_array(X) ((X)->mode_directed_array) -#endif /*MODE_DIRECTED_TABLING*/ -#define TabEnt_next(X) ((X)->next) +#define TabEnt_lock(X) ((X)->lock) +#define TabEnt_pe(X) ((X)->pred_entry) +#define TabEnt_atom(X) ((X)->pred_atom) +#define TabEnt_arity(X) ((X)->pred_arity) +#define TabEnt_flags(X) ((X)->pred_flags) +#define TabEnt_mode(X) ((X)->execution_mode) +#define TabEnt_mode_directed(X) ((X)->mode_directed_array) +#define TabEnt_subgoal_trie(X) ((X)->subgoal_trie) +#define TabEnt_hash_chain(X) ((X)->hash_chain) +#define TabEnt_next(X) ((X)->next) @@ -97,9 +95,7 @@ typedef struct global_trie_node { #define TrNode_sg_fr(X) ((X)->child) #define TrNode_next(X) ((X)->next) #define TrNode_lock(X) ((X)->lock) -#ifdef MODE_DIRECTED_TABLING -#define TrNode_mode_directed_array(X) ((X)->entry) -#endif /*MODE_DIRECTED_TABLING */ + /*********************************************************************** @@ -123,10 +119,10 @@ typedef struct answer_trie_hash { int number_of_buckets; struct answer_trie_node **buckets; int number_of_nodes; - struct answer_trie_hash *next; #ifdef MODE_DIRECTED_TABLING struct answer_trie_hash *previous; #endif /*MODE_DIRECTED_TABLING*/ + struct answer_trie_hash *next; } *ans_hash_ptr; typedef struct global_trie_hash { @@ -147,10 +143,9 @@ typedef struct global_trie_hash { #define Hash_buckets(X) ((X)->buckets) #define Hash_bucket(X,N) ((X)->buckets + N) #define Hash_num_nodes(X) ((X)->number_of_nodes) +#define Hash_previous(X) ((X)->previous) #define Hash_next(X) ((X)->next) -#ifdef MODE_DIRECTED_TABLING -#define Hash_previous(X) ((X)->previous) -#endif /*MODE_DIRECTED_TABLING*/ + /************************************************************************ @@ -228,13 +223,14 @@ typedef struct subgoal_frame { #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 */ struct subgoal_frame *next; -#ifdef MODE_DIRECTED_TABLING -struct answer_trie_node *del_node; -#endif /*MODE_DIRECTED_TABLING*/ } *sg_fr_ptr; #define SgFr_lock(X) ((X)->lock) @@ -250,11 +246,11 @@ struct answer_trie_node *del_node; #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_previous(X) ((X)->previous) #define SgFr_next(X) ((X)->next) -#ifdef MODE_DIRECTED_TABLING -#define SgFr_del_node(X) ((X)->del_node) -#endif /*MODE_DIRECTED_TABLING*/ + /************************************************************************************************** SgFr_lock: spin-lock to modify the frame fields. @@ -276,6 +272,8 @@ struct answer_trie_node *del_node; 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. @@ -369,35 +367,3 @@ typedef struct suspension_frame { #define SuspFr_trail_start(X) ((X)->trail_block.block_start) #define SuspFr_trail_size(X) ((X)->trail_block.block_size) #define SuspFr_next(X) ((X)->next) - - -/* ---------------------------- ** -** MODE_DIRECTED_TABLING flags ** -** ---------------------------- */ -#ifdef MODE_DIRECTED_TABLING - -#define MODE_DIRECTED_TAGBITS 4 - -/*indexing*/ -#define MODE_DIRECTED_INDEX 6 -#define MODE_DIRECTED_NINDEX 1 -#define MODE_DIRECTED_ALL 2 - -/*agregation*/ -#define MODE_DIRECTED_MAX 3 -#define MODE_DIRECTED_MIN 4 -#define MODE_DIRECTED_SUM 5 -#define MODE_DIRECTED_LAST 0 - -/* Macros */ - -#define MODE_DIRECTED_index(X) ((X) >> MODE_DIRECTED_TAGBITS) -#define MODE_DIRECTED_n_vars(X) ((X) >> MODE_DIRECTED_TAGBITS) -#define MODE_DIRECTED_operator(X) ((((X) >> MODE_DIRECTED_TAGBITS) << MODE_DIRECTED_TAGBITS) ^ (X)) - -#define TAG_AS_INVALID_ANSWER_LEAF_NODE(NODE,SG_FR) TrNode_parent(NODE) = (ans_node_ptr)((unsigned long int)TrNode_parent(NODE) | 0x2); \ - TrNode_next(NODE) = SgFr_del_node(SG_FR);\ - SgFr_del_node(SG_FR) = NODE - -#define IS_INVALID_ANSWER_LEAF_NODE(NODE) ((unsigned long int)TrNode_parent(NODE) & 0x2) -#endif /*MODE_DIRECTED_TABLING*/ diff --git a/OPTYap/tab.tries.c b/OPTYap/tab.tries.c index 16cb48855..23ca1d540 100644 --- a/OPTYap/tab.tries.c +++ b/OPTYap/tab.tries.c @@ -21,9 +21,6 @@ #include "YapHeap.h" #include "tab.macros.h" -#ifdef MODE_DIRECTED_TABLING -static inline ans_node_ptr answer_search_loop2(sg_fr_ptr, ans_node_ptr, Term, int *,int); -#endif /*MODE_DIRECTED_TABLING*/ static inline sg_node_ptr subgoal_trie_check_insert_entry(tab_ent_ptr, sg_node_ptr, Term); static inline sg_node_ptr subgoal_trie_check_insert_gt_entry(tab_ent_ptr, sg_node_ptr, Term); static inline ans_node_ptr answer_trie_check_insert_entry(sg_fr_ptr, ans_node_ptr, Term, int); @@ -35,6 +32,10 @@ static inline gt_node_ptr global_trie_check_insert_gt_entry(gt_node_ptr, Term); static inline sg_node_ptr subgoal_search_loop(tab_ent_ptr, sg_node_ptr, Term, int *, CELL **); static inline sg_node_ptr subgoal_search_terms_loop(tab_ent_ptr, sg_node_ptr, Term, int *, CELL **); static inline ans_node_ptr answer_search_loop(sg_fr_ptr, ans_node_ptr, Term, int *); +#ifdef MODE_DIRECTED_TABLING +static inline ans_node_ptr answer_search_mode_directed_min_max(sg_fr_ptr, ans_node_ptr, Term, int); +static void invalidate_answer_trie(ans_node_ptr, sg_fr_ptr, int); +#endif /* MODE_DIRECTED_TABLING */ static inline ans_node_ptr answer_search_terms_loop(sg_fr_ptr, ans_node_ptr, Term, int *); #ifdef GLOBAL_TRIE_FOR_SUBTERMS static inline gt_node_ptr subgoal_search_global_trie_terms_loop(Term, int *, CELL **, CELL *); @@ -62,7 +63,6 @@ static void free_global_trie_branch(gt_node_ptr, int); static void free_global_trie_branch(gt_node_ptr); #endif /* GLOBAL_TRIE_FOR_SUBTERMS */ - static void traverse_subgoal_trie(sg_node_ptr, char *, int, int *, int, int); static void traverse_answer_trie(ans_node_ptr, char *, int, int *, int, int, int); static void traverse_global_trie(gt_node_ptr, char *, int, int *, int, int); @@ -70,446 +70,8 @@ static void traverse_global_trie_for_term(gt_node_ptr, char *, int *, int *, int static inline void traverse_trie_node(Term, char *, int *, int *, int *, int); static inline void traverse_update_arity(char *, int *, int *); -//---------------------------------------------------------------------------------- - -#ifdef MODE_DIRECTED_TABLING -//#define INCLUDE_ANSWER_TRIE_CHECK_INSERT -//#define INCLUDE_ANSWER_SEARCH_LOOP -#define ANSWER_CHECK_INSERT_ENTRY(SG_FR, NODE, ENTRY, INSTR) \ - NODE = answer_trie_check_insert_entry(SG_FR, NODE, ENTRY, INSTR) - -void invalidate_answer(ans_node_ptr node,sg_fr_ptr sg_fr) { - - if(node == NULL) - return; - - if(IS_ANSWER_LEAF_NODE(node)){ - TAG_AS_INVALID_ANSWER_LEAF_NODE(node,sg_fr); - return; - } - - if( IS_ANSWER_TRIE_HASH(node)){ - ans_hash_ptr hash; - ans_node_ptr *bucket, *last_bucket, *first_bucket; - hash = (ans_hash_ptr) node; - first_bucket = bucket = Hash_buckets(hash); - last_bucket = bucket + Hash_num_buckets(hash); - do { - invalidate_answer(*bucket,sg_fr); - } while (++bucket != last_bucket); - Hash_next(Hash_previous(hash)) = Hash_next(hash); - FREE_HASH_BUCKETS(first_bucket); - FREE_ANSWER_TRIE_HASH(hash); - } - - else{ - if (! IS_ANSWER_LEAF_NODE(node)) - invalidate_answer(TrNode_child(node),sg_fr); - if (TrNode_next(node)) - invalidate_answer(TrNode_next(node),sg_fr); - FREE_ANSWER_TRIE_NODE(node); - return; - } -} - - -static inline ans_node_ptr answer_search_loop2(sg_fr_ptr sg_fr, ans_node_ptr current_node, Term t, int *vars_arity_ptr,int mode) { - CACHE_REGS -#ifdef MODE_GLOBAL_TRIE_LOOP - gt_node_ptr current_node = GLOBAL_root_gt; -#endif /* MODE_GLOBAL_TRIE_LOOP */ - int vars_arity = *vars_arity_ptr; -#if ! defined(MODE_GLOBAL_TRIE_LOOP) || ! defined(GLOBAL_TRIE_FOR_SUBTERMS) - CELL *stack_terms = (CELL *) LOCAL_TrailTop; -#endif /* ! MODE_GLOBAL_TRIE_LOOP || ! GLOBAL_TRIE_FOR_SUBTERMS */ - CELL *stack_vars_base = (CELL *) TR; -#define stack_terms_limit (stack_vars_base + vars_arity) -#ifdef TRIE_COMPACT_PAIRS - int in_pair = 0; -#else -#define in_pair 0 -#endif /* TRIE_COMPACT_PAIRS */ -#ifdef MODE_DIRECTED_TABLING - ans_node_ptr child_node; - Term child_term; -#endif /*MODE_DIRECTED_TABLING*/ - AUX_STACK_CHECK_EXPAND(stack_terms, stack_terms_limit + 1); /* + 1 because initially we stiil haven't done any STACK_POP_DOWN */ - STACK_PUSH_UP(NULL, stack_terms); - -#if defined(MODE_GLOBAL_TRIE_LOOP) - /* for the global trie, it is safe to skip the IsVarTerm() and IsAtomOrIntTerm() tests in the first iteration */ - goto answer_search_loop_non_atomic; -#endif /* MODE_GLOBAL_TRIE_LOOP */ - - if(mode == MODE_DIRECTED_NINDEX && TrNode_child(current_node)) - return NULL; - - - if(mode == MODE_DIRECTED_LAST && TrNode_child(current_node)){ - invalidate_answer(TrNode_child(current_node),sg_fr); - TrNode_child(current_node) = NULL; - } - - do { - if (IsVarTerm(t)) { - t = Deref(t); - if (IsTableVarTerm(t)) { - t = MakeTableVarTerm(VarIndexOfTerm(t)); - ANSWER_CHECK_INSERT_ENTRY(sg_fr, current_node, t, _trie_retry_val + in_pair); - } else { - if (vars_arity == MAX_TABLE_VARS) - Yap_Error(INTERNAL_ERROR, TermNil, "answer_search_loop: MAX_TABLE_VARS exceeded"); - stack_vars_base[vars_arity] = t; - *((CELL *)t) = GLOBAL_table_var_enumerator(vars_arity); - t = MakeTableVarTerm(vars_arity); - ANSWER_CHECK_INSERT_ENTRY(sg_fr, current_node, t, _trie_retry_val + in_pair); - vars_arity = vars_arity + 1; - } -#ifdef TRIE_COMPACT_PAIRS - in_pair = 0; -#endif /* TRIE_COMPACT_PAIRS */ - } else if (IsAtomOrIntTerm(t)) { -#ifdef MODE_DIRECTED_TABLING - child_node = TrNode_child(current_node); - if(child_node && IsIntTerm(t) && (mode == MODE_DIRECTED_MIN || mode == MODE_DIRECTED_MAX)){ - Int it = IntOfTerm(t); - if(IsIntTerm(TrNode_entry(child_node))){ - child_term = TrNode_entry(child_node); - Int tt = IntOfTerm(child_term); - if((mode == MODE_DIRECTED_MIN && it < tt ) || (mode == MODE_DIRECTED_MAX && it > tt) ){ - invalidate_answer(child_node,sg_fr); - TrNode_child(current_node) = NULL; - ANSWER_CHECK_INSERT_ENTRY(sg_fr, current_node, t, _trie_retry_atom + in_pair); - } - else if((mode == MODE_DIRECTED_MIN && it > tt) || (mode == MODE_DIRECTED_MAX && it < tt) ){ - return NULL; - } - else if (it == tt){ - current_node = TrNode_child(current_node); - } - } - if(IsApplTerm(TrNode_entry(child_node))){ - if(RepAppl(TrNode_entry(child_node))==FunctorLongInt){ - Int tt = TrNode_entry(TrNode_child(child_node)); - if((mode == MODE_DIRECTED_MIN && it < tt ) || (mode == MODE_DIRECTED_MAX && it > tt)){ - invalidate_answer(child_node,sg_fr); - TrNode_child(current_node) = NULL; - ANSWER_CHECK_INSERT_ENTRY(sg_fr, current_node, t, _trie_retry_atom + in_pair); - } - else if(it == tt){ - current_node = TrNode_child(TrNode_child(child_node)); - } - else if((mode == MODE_DIRECTED_MIN && it > tt) || (mode == MODE_DIRECTED_MAX && it < tt) ) - return NULL; - } - else if(RepAppl(TrNode_entry(child_node))==FunctorDouble){ - union { - Term t_dbl[sizeof(Float)/sizeof(Term)]; - Float dbl; - } u; - u.t_dbl[0] = TrNode_entry(TrNode_child(child_node)); -#if SIZEOF_DOUBLE == 2 * SIZEOF_INT_P - u.t_dbl[1] = TrNode_entry(TrNode_child(TrNode_child(child_node))); -#endif /* SIZEOF_DOUBLE x SIZEOF_INT_P */ - if((mode == MODE_DIRECTED_MIN && it < u.dbl ) || (mode == MODE_DIRECTED_MAX && it > u.dbl)){ - invalidate_answer(child_node,sg_fr); - TrNode_child(current_node) = NULL; - ANSWER_CHECK_INSERT_ENTRY(sg_fr, current_node, t, _trie_retry_atom + in_pair); - } - else if(it == u.dbl){ -#if SIZEOF_DOUBLE == 2 * SIZEOF_INT_P - current_node = TrNode_child(TrNode_child(TrNode_child(child_node))); -#else - current_node = TrNode_child(TrNode_child(child_node)); -#endif /* SIZEOF_DOUBLE x SIZEOF_INT_P */ - } - else if((mode == MODE_DIRECTED_MIN && it > u.dbl) || (mode == MODE_DIRECTED_MAX && it < u.dbl)) - return NULL; - } - } - } - else -#endif /*MODE_DIRECTED_TABLING*/ - ANSWER_CHECK_INSERT_ENTRY(sg_fr, current_node, t, _trie_retry_atom + in_pair); -#ifdef TRIE_COMPACT_PAIRS - in_pair = 0; -#endif /* TRIE_COMPACT_PAIRS */ -#ifdef MODE_TERMS_LOOP - } else { - gt_node_ptr entry_node; -#ifdef GLOBAL_TRIE_FOR_SUBTERMS - entry_node = answer_search_global_trie_terms_loop(t, &vars_arity, stack_terms); -#else - entry_node = answer_search_global_trie_loop(t, &vars_arity); -#endif /* GLOBAL_TRIE_FOR_SUBTERMS */ - current_node = answer_trie_check_insert_gt_entry(sg_fr, current_node, (Term) entry_node, _trie_retry_gterm + in_pair); -#else /* ! MODE_TERMS_LOOP */ - } else -#if defined(MODE_GLOBAL_TRIE_LOOP) - /* for the global trie, it is safe to start here in the first iteration */ - answer_search_loop_non_atomic: -#endif /* MODE_GLOBAL_TRIE_LOOP */ -#ifdef TRIE_COMPACT_PAIRS - if (IsPairTerm(t)) { - CELL *aux_pair = RepPair(t); - if (aux_pair == PairTermMark) { - t = STACK_POP_DOWN(stack_terms); - if (IsPairTerm(t)) { - aux_pair = RepPair(t); - t = Deref(aux_pair[1]); - if (t == TermNil) { - ANSWER_CHECK_INSERT_ENTRY(sg_fr, current_node, CompactPairEndList, _trie_retry_pair); - } else { - /* AUX_STACK_CHECK_EXPAND(stack_terms, stack_terms_limit + 2); */ - /* AUX_STACK_CHECK_EXPAND is not necessary here because the situation of pushing ** - ** up 3 terms has already initially checked for the CompactPairInit term */ - STACK_PUSH_UP(t, stack_terms); - STACK_PUSH_UP(AbsPair(PairTermMark), stack_terms); - in_pair = 4; - } - STACK_PUSH_UP(Deref(aux_pair[0]), stack_terms); - } else { - ANSWER_CHECK_INSERT_ENTRY(sg_fr, current_node, CompactPairEndTerm, _trie_retry_null); - STACK_PUSH_UP(t, stack_terms); - } -#if defined(MODE_GLOBAL_TRIE_LOOP) && defined(GLOBAL_TRIE_FOR_SUBTERMS) - } else if (current_node != GLOBAL_root_gt) { - gt_node_ptr entry_node = answer_search_global_trie_terms_loop(t, &vars_arity, stack_terms); - current_node = global_trie_check_insert_gt_entry(current_node, (Term) entry_node); -#endif /* MODE_GLOBAL_TRIE_LOOP && GLOBAL_TRIE_FOR_SUBTERMS */ - } else { - ANSWER_CHECK_INSERT_ENTRY(sg_fr, current_node, CompactPairInit, _trie_retry_null + in_pair); - t = Deref(aux_pair[1]); - if (t == TermNil) { - ANSWER_CHECK_INSERT_ENTRY(sg_fr, current_node, CompactPairEndList, _trie_retry_pair); - in_pair = 0; - } else { - AUX_STACK_CHECK_EXPAND(stack_terms, stack_terms_limit + 2); - STACK_PUSH_UP(t, stack_terms); - STACK_PUSH_UP(AbsPair(PairTermMark), stack_terms); - in_pair = 4; - } - STACK_PUSH_UP(Deref(aux_pair[0]), stack_terms); - } -#if defined(MODE_GLOBAL_TRIE_LOOP) && defined(GLOBAL_TRIE_FOR_SUBTERMS) - } else if (current_node != GLOBAL_root_gt) { - gt_node_ptr entry_node = answer_search_global_trie_terms_loop(t, &vars_arity, stack_terms); - current_node = global_trie_check_insert_gt_entry(current_node, (Term) entry_node); -#endif /* MODE_GLOBAL_TRIE_LOOP && GLOBAL_TRIE_FOR_SUBTERMS */ -#else /* ! TRIE_COMPACT_PAIRS */ -#if defined(MODE_GLOBAL_TRIE_LOOP) && defined(GLOBAL_TRIE_FOR_SUBTERMS) - if (current_node != GLOBAL_root_gt) { - gt_node_ptr entry_node = answer_search_global_trie_terms_loop(t, &vars_arity, stack_terms); - current_node = global_trie_check_insert_gt_entry(current_node, (Term) entry_node); - } else -#endif /* MODE_GLOBAL_TRIE_LOOP && GLOBAL_TRIE_FOR_SUBTERMS */ - if (IsPairTerm(t)) { - CELL *aux_pair = RepPair(t); - ANSWER_CHECK_INSERT_ENTRY(sg_fr, current_node, AbsPair(NULL), _trie_retry_pair); - AUX_STACK_CHECK_EXPAND(stack_terms, stack_terms_limit + 1); - STACK_PUSH_UP(Deref(aux_pair[1]), stack_terms); - STACK_PUSH_UP(Deref(aux_pair[0]), stack_terms); -#endif /* TRIE_COMPACT_PAIRS */ - } else if (IsApplTerm(t)) { - Functor f = FunctorOfTerm(t); - if (f == FunctorDouble) { - union { - Term t_dbl[sizeof(Float)/sizeof(Term)]; - Float dbl; - } u; - u.dbl = FloatOfTerm(t); -#ifdef MODE_DIRECTED_TABLING - child_node = TrNode_child(current_node); - if(child_node && (mode == MODE_DIRECTED_MIN || mode == MODE_DIRECTED_MAX)){ - if(IsApplTerm(TrNode_entry(child_node))){ - if(RepAppl(TrNode_entry(child_node))==FunctorLongInt){ - Int tt = TrNode_entry(TrNode_child(child_node)); - if(( mode == MODE_DIRECTED_MIN && u.dbl < tt) || ( mode == MODE_DIRECTED_MAX && u.dbl > tt)){ - invalidate_answer(child_node,sg_fr); - TrNode_child(current_node) = NULL; - ANSWER_CHECK_INSERT_ENTRY(sg_fr, current_node, AbsAppl((Term *)f), _trie_retry_null + in_pair); -#if SIZEOF_DOUBLE == 2 * SIZEOF_INT_P - ANSWER_CHECK_INSERT_ENTRY(sg_fr, 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); - } - else if(tt == u.dbl){ - current_node = TrNode_child(TrNode_child(child_node)); - } - else if(( mode == MODE_DIRECTED_MIN && u.dbl > tt) || ( mode == MODE_DIRECTED_MAX && u.dbl < tt)) - return NULL; - } - else if(RepAppl(TrNode_entry(child_node))==FunctorDouble){ - union { - Term t_dbl[sizeof(Float)/sizeof(Term)]; - Float dbl; - } ans_u; - ans_u.t_dbl[0] = TrNode_entry(TrNode_child(child_node)); -#if SIZEOF_DOUBLE == 2 * SIZEOF_INT_P - ans_u.t_dbl[1] = TrNode_entry(TrNode_child(TrNode_child(child_node))); -#endif /* SIZEOF_DOUBLE x SIZEOF_INT_P */ - if(( mode == MODE_DIRECTED_MIN && u.dbl < ans_u.dbl) || ( mode == MODE_DIRECTED_MAX && u.dbl > ans_u.dbl)){ - invalidate_answer(child_node,sg_fr); - TrNode_child(current_node) = NULL; - ANSWER_CHECK_INSERT_ENTRY(sg_fr, current_node, AbsAppl((Term *)f), _trie_retry_null + in_pair); -#if SIZEOF_DOUBLE == 2 * SIZEOF_INT_P - ANSWER_CHECK_INSERT_ENTRY(sg_fr, 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); - } - else if(ans_u.dbl == u.dbl){ -#if SIZEOF_DOUBLE == 2 * SIZEOF_INT_P - current_node = TrNode_child(TrNode_child(TrNode_child(child_node))); -#else - current_node = TrNode_child(TrNode_child(child_node)); -#endif /* SIZEOF_DOUBLE x SIZEOF_INT_P */ - } - else if(( mode == MODE_DIRECTED_MIN && u.dbl > ans_u.dbl) || ( mode == MODE_DIRECTED_MAX && u.dbl < ans_u.dbl)) - return NULL; - } - } - else if(IsIntTerm(TrNode_entry(child_node))){ - Int tt = IntOfTerm(child_node); - if(( mode == MODE_DIRECTED_MIN && u.dbl < tt) || ( mode == MODE_DIRECTED_MAX && u.dbl > tt)){ - invalidate_answer(child_node,sg_fr); - TrNode_child(current_node) = NULL; - ANSWER_CHECK_INSERT_ENTRY(sg_fr, current_node, AbsAppl((Term *)f), _trie_retry_null + in_pair); -#if SIZEOF_DOUBLE == 2 * SIZEOF_INT_P - ANSWER_CHECK_INSERT_ENTRY(sg_fr, 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); - } - else if(IntOfTerm(child_node) == u.dbl){ - current_node = TrNode_child(TrNode_child(child_node)); - } - else if(( mode == MODE_DIRECTED_MIN && u.dbl > tt) || ( mode == MODE_DIRECTED_MAX && u.dbl < tt)) - return NULL; - } - } - else { -#endif /*MODE_DIRECTED_TABLING*/ - ANSWER_CHECK_INSERT_ENTRY(sg_fr, current_node, AbsAppl((Term *)f), _trie_retry_null + in_pair); -#if SIZEOF_DOUBLE == 2 * SIZEOF_INT_P - ANSWER_CHECK_INSERT_ENTRY(sg_fr, 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); -#ifdef MODE_DIRECTED_TABLING - } -#endif /*MODE_DIRECTED_TABLING*/ - } else if (f == FunctorLongInt) { - Int li = LongIntOfTerm (t); - child_node = TrNode_child(current_node); -#ifdef MODE_DIRECTED_TABLING - if(child_node && (mode == MODE_DIRECTED_MIN || mode == MODE_DIRECTED_MAX)){ - if(IsApplTerm(TrNode_entry(child_node))){ - if(RepAppl(TrNode_entry(child_node))==FunctorLongInt){ - Int tt = TrNode_entry(TrNode_child(child_node)); - if(( mode == MODE_DIRECTED_MIN && li < tt) || ( mode == MODE_DIRECTED_MAX && li > tt)){ - invalidate_answer(child_node,sg_fr); - TrNode_child(current_node) = NULL; - 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); - - } - else if(li == tt){ - current_node = TrNode_child(TrNode_child(child_node)); - } - else if(( mode == MODE_DIRECTED_MIN && li > tt) || ( mode == MODE_DIRECTED_MAX && li < tt)) - return NULL; - } - else if(RepAppl(TrNode_entry(child_node))==FunctorDouble){ - union { - Term t_dbl[sizeof(Float)/sizeof(Term)]; - Float dbl; - } ans_u; - ans_u.t_dbl[0] = TrNode_entry(TrNode_child(child_node)); -#if SIZEOF_DOUBLE == 2 * SIZEOF_INT_P - ans_u.t_dbl[1] = TrNode_entry(TrNode_child(TrNode_child(child_node))); -#endif /* SIZEOF_DOUBLE x SIZEOF_INT_P */ - if(( mode == MODE_DIRECTED_MIN && li < ans_u.dbl) || ( mode == MODE_DIRECTED_MAX && li > ans_u.dbl)){ - invalidate_answer(child_node,sg_fr); - TrNode_child(current_node) = NULL; - 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); - } - else if(ans_u.dbl == li){ -#if SIZEOF_DOUBLE == 2 * SIZEOF_INT_P - current_node = TrNode_child(TrNode_child(TrNode_child(child_node))); -#else - current_node = TrNode_child(TrNode_child(child_node)); -#endif /* SIZEOF_DOUBLE x SIZEOF_INT_P */ - } - else if(( mode == MODE_DIRECTED_MIN && li > ans_u.dbl) || ( mode == MODE_DIRECTED_MAX && li < ans_u.dbl)) - return NULL; - } - } - else if(IsIntTerm(TrNode_entry(child_node))){ - Int tt = IntOfTerm(child_node); - if(( mode == MODE_DIRECTED_MIN && li < tt) || ( mode == MODE_DIRECTED_MAX && li > tt)){ - invalidate_answer(child_node,sg_fr); - TrNode_child(current_node) = NULL; - 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); - } - else if(li == tt){ - current_node = TrNode_child(TrNode_child(child_node)); - } - else if(( mode == MODE_DIRECTED_MIN && li > tt) || ( mode == MODE_DIRECTED_MAX && li < tt)) - return NULL; - } - }else{ -#endif /*MODE_DIRECTED_TABLING*/ - 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); -#ifdef MODE_DIRECTED_TABLING - } -#endif/*MODE_DIRECTED_TABLING*/ - } else if (f == FunctorDBRef) { - Yap_Error(INTERNAL_ERROR, TermNil, "answer_search_loop: unsupported type tag FunctorDBRef"); - } else if (f == FunctorBigInt) { - Yap_Error(INTERNAL_ERROR, TermNil, "answer_search_loop: unsupported type tag FunctorBigInt"); - } else { - int i; - CELL *aux_appl = RepAppl(t); - ANSWER_CHECK_INSERT_ENTRY(sg_fr, current_node, AbsAppl((Term *)f), _trie_retry_appl + in_pair); - AUX_STACK_CHECK_EXPAND(stack_terms, stack_terms_limit + ArityOfFunctor(f) - 1); - for (i = ArityOfFunctor(f); i >= 1; i--) - STACK_PUSH_UP(Deref(aux_appl[i]), stack_terms); - } -#ifdef TRIE_COMPACT_PAIRS - in_pair = 0; -#endif /* TRIE_COMPACT_PAIRS */ - } else { - Yap_Error(INTERNAL_ERROR, TermNil, "answer_search_loop: unknown type tag"); -#endif /* MODE_TERMS_LOOP */ - } - t = STACK_POP_DOWN(stack_terms); - } while (t); - - *vars_arity_ptr = vars_arity; - return current_node; - -#undef stack_terms_limit -#ifndef TRIE_COMPACT_PAIRS -#undef in_pair -#endif /* TRIE_COMPACT_PAIRS */ -} - -//#undef INCLUDE_ANSWER_TRIE_CHECK_INSERT -//#undef INCLUDE_ANSWER_SEARCH_LOOP -#endif /* MODE_DIRECTED_TABLING*/ - -//----------------------------------------------------------------------------------------------------------------- /******************************* ** Structs & Macros ** *******************************/ @@ -596,7 +158,7 @@ static struct trie_statistics{ #undef MODE_GLOBAL_TRIE_ENTRY #define INCLUDE_SUBGOAL_SEARCH_LOOP /* subgoal_search_loop */ -#define INCLUDE_ANSWER_SEARCH_LOOP /* answer_search_loop */ +#define INCLUDE_ANSWER_SEARCH_LOOP /* answer_search_loop + answer_search_mode_directed_min_max + invalidate_answer_trie */ #define INCLUDE_LOAD_ANSWER_LOOP /* load_answer_loop */ #include "tab.tries.i" #undef INCLUDE_LOAD_ANSWER_LOOP @@ -1413,13 +975,16 @@ static inline void traverse_update_arity(char *str, int *str_index_ptr, int *ari *******************************/ sg_fr_ptr subgoal_search(yamop *preg, CELL **Yaddr) { -// printf("subgoal_search\n"); CACHE_REGS CELL *stack_vars; int i, subs_arity, pred_arity; tab_ent_ptr tab_ent; sg_fr_ptr sg_fr; sg_node_ptr current_sg_node; +#ifdef MODE_DIRECTED_TABLING + int *mode_directed, aux_mode_directed[MAX_TABLE_VARS]; + int subs_pos = 0; +#endif /* MODE_DIRECTED_TABLING */ stack_vars = *Yaddr; subs_arity = 0; @@ -1431,40 +996,30 @@ sg_fr_ptr subgoal_search(yamop *preg, CELL **Yaddr) { #endif /* TABLE_LOCK_LEVEL */ #ifdef MODE_DIRECTED_TABLING - int* mode_directed_array = TabEnt_mode_directed_array(tab_ent); - int* n_vars_operator_array = NULL; - int j, old_subs_arity=0; - if(mode_directed_array) - ALLOC_BLOCK(n_vars_operator_array,pred_arity*sizeof(int),int); - - // ALLOC_BLOCK(number_vars,sizeof(int),int); - //for(i=0;i= 1; i--) { TABLING_ERROR_CHECKING(answer search, IsNonVarTerm(subs_ptr[i])); @@ -1534,26 +1113,7 @@ ans_node_ptr answer_search(sg_fr_ptr sg_fr, CELL *subs_ptr) { } else { for (i = subs_arity; i >= 1; i--) { TABLING_ERROR_CHECKING(answer search, IsNonVarTerm(subs_ptr[i])); -#ifdef MODE_DIRECTED_TABLING - if(n_vars_operator_array){ - while(!MODE_DIRECTED_n_vars(n_vars_operator_array[j])) - j++; - if(!(n_vars < MODE_DIRECTED_n_vars(n_vars_operator_array[j]))){ - j++; - while(!MODE_DIRECTED_n_vars(n_vars_operator_array[j])) - j++; - n_vars = 0; - } - mode = MODE_DIRECTED_operator(n_vars_operator_array[j]); - //printf("operador %d\n",mode); - n_vars++; - } - current_ans_node = answer_search_loop2(sg_fr, current_ans_node, Deref(subs_ptr[i]), &vars_arity, mode); - if(current_ans_node == NULL) - break; -#else current_ans_node = answer_search_loop(sg_fr, current_ans_node, Deref(subs_ptr[i]), &vars_arity); -#endif /*MODE_DIRECTED_TABLING*/ } } diff --git a/OPTYap/tab.tries.i b/OPTYap/tab.tries.i index 23aad2ae9..835f8ac03 100644 --- a/OPTYap/tab.tries.i +++ b/OPTYap/tab.tries.i @@ -15,15 +15,6 @@ ** Macros ** *********************/ -#undef INCREMENT_GLOBAL_TRIE_REFERENCE -#undef NEW_SUBGOAL_TRIE_NODE -#undef NEW_ANSWER_TRIE_NODE -#undef NEW_GLOBAL_TRIE_NODE -#undef SUBGOAL_CHECK_INSERT_ENTRY -#undef ANSWER_CHECK_INSERT_ENTRY -#undef LOCK_NODE -#undef UNLOCK_NODE - #ifdef MODE_GLOBAL_TRIE_ENTRY #define INCREMENT_GLOBAL_TRIE_REFERENCE(ENTRY) \ { register gt_node_ptr entry_node = (gt_node_ptr) (ENTRY); \ @@ -1068,7 +1059,7 @@ static inline ans_node_ptr answer_search_loop(sg_fr_ptr sg_fr, ans_node_ptr curr stack_vars_base[vars_arity] = t; *((CELL *)t) = GLOBAL_table_var_enumerator(vars_arity); t = MakeTableVarTerm(vars_arity); - ANSWER_CHECK_INSERT_ENTRY(sg_fr, current_node, t, _trie_retry_val + in_pair); + ANSWER_CHECK_INSERT_ENTRY(sg_fr, current_node, t, _trie_retry_var + in_pair); vars_arity = vars_arity + 1; } #ifdef TRIE_COMPACT_PAIRS @@ -1103,7 +1094,7 @@ static inline ans_node_ptr answer_search_loop(sg_fr_ptr sg_fr, ans_node_ptr curr aux_pair = RepPair(t); t = Deref(aux_pair[1]); if (t == TermNil) { - ANSWER_CHECK_INSERT_ENTRY(sg_fr, current_node, CompactPairEndList, _trie_retry_pair); + ANSWER_CHECK_INSERT_ENTRY(sg_fr, current_node, CompactPairEndList, _trie_retry_pair); } else { /* AUX_STACK_CHECK_EXPAND(stack_terms, stack_terms_limit + 2); */ /* AUX_STACK_CHECK_EXPAND is not necessary here because the situation of pushing ** @@ -1204,6 +1195,165 @@ static inline ans_node_ptr answer_search_loop(sg_fr_ptr sg_fr, ans_node_ptr curr #undef in_pair #endif /* TRIE_COMPACT_PAIRS */ } + + + +/**************************************************************************** +** answer_search_mode_directed_min_max ** +****************************************************************************/ + +#if defined(MODE_DIRECTED_TABLING) && ! defined(MODE_TERMS_LOOP) && ! defined(MODE_GLOBAL_TRIE_LOOP) +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; + + /* 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 = FunctorOfTerm(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_mode_directed_min_max: 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_mode_directed_min_max: invalid arithmetic value"); + } + + /* worse answer */ + if ((mode == MODE_DIRECTED_MIN && term_value > trie_value) || (mode == MODE_DIRECTED_MAX && term_value < trie_value)) + return NULL; + /* equal answer */ + if (term_value == trie_value) + return child_node; + /* better answer */ + invalidate_answer_trie(child_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); + } else if (IsApplTerm(t)) { + Functor f = FunctorOfTerm(t); + if (f == FunctorDouble) { + union { + Term t_dbl[sizeof(Float)/sizeof(Term)]; + Float dbl; + } u; + u.dbl = FloatOfTerm(t); + ANSWER_CHECK_INSERT_ENTRY(sg_fr, current_node, AbsAppl((Term *)f), _trie_retry_null + in_pair); +#if SIZEOF_DOUBLE == 2 * SIZEOF_INT_P + ANSWER_CHECK_INSERT_ENTRY(sg_fr, 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); + } 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); + } + } + return current_node; +#undef in_pair +} + + + +/*************************************************************** +** invalidate_answer_trie ** +***************************************************************/ + +static void invalidate_answer_trie(ans_node_ptr current_node, sg_fr_ptr sg_fr, int position) { + if (IS_ANSWER_TRIE_HASH(current_node)) { + ans_hash_ptr hash; + ans_node_ptr *bucket, *last_bucket; + hash = (ans_hash_ptr) current_node; + bucket = Hash_buckets(hash); + last_bucket = bucket + Hash_num_buckets(hash); + do { + current_node = *bucket; + if (current_node) { + ans_node_ptr next_node = TrNode_next(current_node); + if (! IS_ANSWER_LEAF_NODE(current_node)) { + invalidate_answer_trie(TrNode_child(current_node), sg_fr, TRAVERSE_POSITION_FIRST); + FREE_ANSWER_TRIE_NODE(current_node); + } else { + TAG_AS_INVALID_LEAF_NODE(current_node); + TrNode_next(current_node) = SgFr_invalid_chain(sg_fr); + SgFr_invalid_chain(sg_fr) = current_node; + } + while (next_node) { + current_node = next_node; + next_node = TrNode_next(current_node); + invalidate_answer_trie(current_node, sg_fr, TRAVERSE_POSITION_NEXT); + } + } + } while (++bucket != last_bucket); + if (Hash_next(hash)) + Hash_previous(Hash_next(hash)) = Hash_previous(hash); + if (Hash_previous(hash)) + Hash_next(Hash_previous(hash)) = Hash_next(hash); + else + SgFr_hash_chain(sg_fr) = Hash_next(hash); + FREE_HASH_BUCKETS(Hash_buckets(hash)); + FREE_ANSWER_TRIE_HASH(hash); + } else { + if (position == TRAVERSE_POSITION_FIRST) { + ans_node_ptr next_node = TrNode_next(current_node); + if (! IS_ANSWER_LEAF_NODE(current_node)) { + invalidate_answer_trie(TrNode_child(current_node), sg_fr, TRAVERSE_POSITION_FIRST); + FREE_ANSWER_TRIE_NODE(current_node); + } else { + TAG_AS_INVALID_LEAF_NODE(current_node); + TrNode_next(current_node) = SgFr_invalid_chain(sg_fr); + SgFr_invalid_chain(sg_fr) = current_node; + } + while (next_node) { + current_node = next_node; + next_node = TrNode_next(current_node); + invalidate_answer_trie(current_node, sg_fr, TRAVERSE_POSITION_NEXT); + } + } else { + if (! IS_ANSWER_LEAF_NODE(current_node)) { + invalidate_answer_trie(TrNode_child(current_node), sg_fr, TRAVERSE_POSITION_FIRST); + FREE_ANSWER_TRIE_NODE(current_node); + } else { + TAG_AS_INVALID_LEAF_NODE(current_node); + TrNode_next(current_node) = SgFr_invalid_chain(sg_fr); + SgFr_invalid_chain(sg_fr) = current_node; + } + } + } + return; +} +#endif /* MODE_DIRECTED_TABLING && ! MODE_TERMS_LOOP && ! MODE_GLOBAL_TRIE_LOOP */ #endif /* INCLUDE_ANSWER_SEARCH_LOOP */ @@ -1358,3 +1508,18 @@ static inline CELL *load_answer_loop(ans_node_ptr current_node) { #endif /* TRIE_COMPACT_PAIRS */ } #endif /* INCLUDE_LOAD_ANSWER_LOOP */ + + + +/*************************** +** Undef Macros ** +***************************/ + +#undef INCREMENT_GLOBAL_TRIE_REFERENCE +#undef NEW_SUBGOAL_TRIE_NODE +#undef NEW_ANSWER_TRIE_NODE +#undef NEW_GLOBAL_TRIE_NODE +#undef SUBGOAL_CHECK_INSERT_ENTRY +#undef ANSWER_CHECK_INSERT_ENTRY +#undef LOCK_NODE +#undef UNLOCK_NODE diff --git a/pl/tabling.yap b/pl/tabling.yap index cd6b5beb6..0c9cbf488 100644 --- a/pl/tabling.yap +++ b/pl/tabling.yap @@ -110,36 +110,44 @@ table(Pred) :- atom(PredName), integer(PredArity), functor(PredFunctor,PredName,PredArity), !, - '$set_table'(Mod,PredFunctor). -%MODE_DIRECTED_TABLING -'$do_table'(Mod,Pred) :- - Pred=.. L, - L = [X|XS], - %writeln(X), - %writeln(XS), - length(XS,Len), - functor(PredFunctor,X,Len), !, - %writeln('antes'), - '$c_table_mode_directed'(Mod,PredFunctor,XS). -%MODE_DIRECTED_TABLING + '$set_table'(Mod,PredFunctor,[]). +'$do_table'(Mod,PredDeclaration) :- + PredDeclaration=..[PredName|PredList], + '$transl_to_mode_list'(PredList,PredModeList,PredArity), + functor(PredFunctor,PredName,PredArity), !, + '$set_table'(Mod,PredFunctor,PredModeList). '$do_table'(Mod,Pred) :- '$do_error'(type_error(callable,Mod:Pred),table(Mod:Pred)). -'$set_table'(Mod,PredFunctor) :- - '$undefined'('$c_table'(_,_),prolog), !, +'$set_table'(Mod,PredFunctor,PredModeList) :- + '$undefined'('$c_table'(_,_,_),prolog), !, functor(PredFunctor, PredName, PredArity), '$do_error'(resource_error(tabling,Mod:PredName/PredArity),table(Mod:PredName/PredArity)). -'$set_table'(Mod,PredFunctor) :- +'$set_table'(Mod,PredFunctor,PredModeList) :- '$undefined'(PredFunctor,Mod), !, - '$c_table'(Mod,PredFunctor). -'$set_table'(Mod,PredFunctor) :- + '$c_table'(Mod,PredFunctor,PredModeList). +'$set_table'(Mod,PredFunctor,PredModeList) :- '$flags'(PredFunctor,Mod,Flags,Flags), - Flags /\ 0x1991F880 =:= 0, - '$c_table'(Mod,PredFunctor), !. -'$set_table'(Mod,PredFunctor) :- + Flags /\ 0x1991F8C0 =:= 0, + '$c_table'(Mod,PredFunctor,PredModeList), !. +'$set_table'(Mod,PredFunctor,PredModeList) :- functor(PredFunctor,PredName,PredArity), '$do_error'(permission_error(modify,table,Mod:PredName/PredArity),table(Mod:PredName/PredArity)). +'$transl_to_mode_list'([],[],0) :- !. +'$transl_to_mode_list'([TextualMode|L],[Mode|ModeList],Arity) :- + '$transl_to_mode_directed_tabling'(TextualMode,Mode), + '$transl_to_mode_list'(L,ModeList,ListArity), + Arity is ListArity + 1. + +%% 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'(last,6). + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%