mode directed tabling.

This commit is contained in:
Vítor Santos Costa 2011-10-22 16:49:13 +01:00
parent 48bfaa1ce1
commit 22b0bcac14
8 changed files with 675 additions and 20 deletions

View File

@ -16,7 +16,7 @@
/************************************************************************
** General Configuration Parameters **
************************************************************************/
#define MODE_DIRECTED_TABLING
/******************************************************************************************
** use shared pages memory alloc scheme for OPTYap data structures? (optional) **
******************************************************************************************/

View File

@ -39,6 +39,9 @@ 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 );
@ -122,6 +125,9 @@ void Yap_init_optyap_preds(void) {
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_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);
@ -221,11 +227,147 @@ static Int p_table( USES_REGS1 ) {
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;
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 ++;
}
*/
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;
new_table_entry(tab_ent, pe, at, arity, aux);
pe->TableOfPred = tab_ent;
return (TRUE);
}
#endif /*MODE_DIRECTED_TABLING*/
static Int p_tabling_mode( USES_REGS1 ) {
Term mod, t, tvalue;

View File

@ -869,6 +869,10 @@
LOCK(SgFr_lock(sg_fr));
#endif /* TABLE_LOCK_LEVEL */
ans_node = answer_search(sg_fr, subs_ptr);
#ifdef MODE_DIRECTED_TABLING
if(ans_node == NULL)
goto fail;
#endif /*MODE_DIRECTED_TABLING*/
#if defined(TABLE_LOCK_AT_NODE_LEVEL)
LOCK(TrNode_lock(ans_node));
#elif defined(TABLE_LOCK_AT_WRITE_LEVEL)
@ -1103,9 +1107,19 @@
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*/
DepFr_last_answer(dep_fr) = ans_node;
UNLOCK(DepFr_lock(dep_fr));
consume_answer_and_procceed(dep_fr, ans_node);
}
@ -1150,9 +1164,18 @@
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 */
ans_node = DepFr_last_answer(dep_fr) = TrNode_child(ans_node);
#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))
/* dependency frame with unconsumed answers */
ans_node = DepFr_last_answer(dep_fr) = TrNode_child(ans_node);
#endif /*MODE_DIRECTED_TABLING*/
#ifdef YAPOR
if (YOUNGER_CP(DepFr_backchain_cp(dep_fr), top_chain_cp))
#endif /* YAPOR */
@ -1392,9 +1415,18 @@
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 */
ans_node = DepFr_last_answer(dep_fr) = TrNode_child(ans_node);
#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))
/* dependency frame with unconsumed answers */
ans_node = DepFr_last_answer(dep_fr) = TrNode_child(ans_node);
#endif /*MODE_DIRECTED_TABLING*/
if (B->cp_ap) {
#ifdef YAPOR
if (YOUNGER_CP(DepFr_backchain_cp(dep_fr), B))
@ -1549,8 +1581,18 @@
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 */
/* unconsumed answer */
ans_node = DepFr_last_answer(dep_fr) = TrNode_child(ans_node);
#endif /*MODE_DIRECTED_TABLING*/
UNLOCK_OR_FRAME(LOCAL_top_or_fr);
ans_node = DepFr_last_answer(LOCAL_top_dep_fr) = TrNode_child(ans_node);
UNLOCK(DepFr_lock(LOCAL_top_dep_fr));

View File

@ -269,6 +269,36 @@ 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; \
}
#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); \
@ -294,6 +324,25 @@ static inline tg_sol_fr_ptr CUT_prune_tg_solution_frames(tg_sol_fr_ptr, int);
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) \
{ register ans_node_ptr ans_node; \
new_answer_trie_node(ans_node, 0, 0, NULL, NULL, NULL); \
@ -306,6 +355,8 @@ static inline tg_sol_fr_ptr CUT_prune_tg_solution_frames(tg_sol_fr_ptr, int);
SgFr_first_answer(SG_FR) = NULL; \
SgFr_last_answer(SG_FR) = NULL; \
}
#endif /*MODE_DIRECTED_TABLING*/
#define init_subgoal_frame(SG_FR) \
{ SgFr_init_yapor_fields(SG_FR); \
SgFr_state(SG_FR) = evaluating; \
@ -482,6 +533,40 @@ 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;
}
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*/
SgFr_state(sg_fr) = complete;
UNLOCK(SgFr_lock(sg_fr));
return;

View File

@ -30,6 +30,9 @@ typedef struct table_entry {
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 table_entry *next;
} *tab_ent_ptr;
@ -41,6 +44,9 @@ typedef struct table_entry {
#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)
@ -91,7 +97,9 @@ 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 */
/***********************************************************************
@ -116,6 +124,9 @@ typedef struct answer_trie_hash {
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*/
} *ans_hash_ptr;
typedef struct global_trie_hash {
@ -137,7 +148,9 @@ typedef struct global_trie_hash {
#define Hash_bucket(X,N) ((X)->buckets + N)
#define Hash_num_nodes(X) ((X)->number_of_nodes)
#define Hash_next(X) ((X)->next)
#ifdef MODE_DIRECTED_TABLING
#define Hash_previous(X) ((X)->previous)
#endif /*MODE_DIRECTED_TABLING*/
/************************************************************************
@ -219,6 +232,9 @@ typedef struct subgoal_frame {
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)
@ -236,7 +252,9 @@ typedef struct subgoal_frame {
#define SgFr_try_answer(X) ((X)->try_answer)
#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.
@ -351,3 +369,35 @@ 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*/

View File

@ -21,6 +21,9 @@
#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);
@ -29,7 +32,6 @@ static inline gt_node_ptr global_trie_check_insert_entry(gt_node_ptr, Term);
#ifdef GLOBAL_TRIE_FOR_SUBTERMS
static inline gt_node_ptr global_trie_check_insert_gt_entry(gt_node_ptr, Term);
#endif /* GLOBAL_TRIE_FOR_SUBTERMS */
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 *);
@ -60,6 +62,7 @@ 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);
@ -67,7 +70,266 @@ 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 childnode;
Term childterm;
#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
//printf("++++++++++++ operador %d \n", mode);
childnode = TrNode_child(current_node);
if(childnode && IsIntTerm(t) && (mode == MODE_DIRECTED_MIN || mode == MODE_DIRECTED_MAX)){
Int it = IntOfTerm(t);
if(IsIntTerm(TrNode_entry(childnode))){
childterm = TrNode_entry(childnode);
Int tt = IntOfTerm(childterm);
if((mode ==MODE_DIRECTED_MIN && it < tt ) || (mode ==MODE_DIRECTED_MAX && it > tt) ){
invalidate_answer(childnode,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) ){
printf("NULL\n");
return NULL;
}
else if(it == tt){
current_node = TrNode_child(current_node);
}
}
}
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);
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);
} 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 **
*******************************/
@ -971,6 +1233,7 @@ 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;
@ -987,12 +1250,41 @@ sg_fr_ptr subgoal_search(yamop *preg, CELL **Yaddr) {
LOCK(TabEnt_lock(tab_ent));
#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<pred_arity;i++)
// printf("sub_search %p\n",mode_directed_array[i]);
#endif /*MODE_DIRECTED_TABLING*/
if (IsMode_GlobalTrie(TabEnt_mode(tab_ent))) {
for (i = 1; i <= pred_arity; i++)
current_sg_node = subgoal_search_terms_loop(tab_ent, current_sg_node, Deref(XREGS[i]), &subs_arity, &stack_vars);
} else {
for (i = 1; i <= pred_arity; i++)
for (i = 1; i <= pred_arity; i++){
#ifdef MODE_DIRECTED_TABLING
if(mode_directed_array){
j = MODE_DIRECTED_index(mode_directed_array[i-1])+1;
}
else
j = i;
current_sg_node = subgoal_search_loop(tab_ent, current_sg_node, Deref(XREGS[j]), &subs_arity, &stack_vars);
if(mode_directed_array){
n_vars_operator_array[i-1] = subs_arity - old_subs_arity;
//printf("vars %d\n", subs_arity);
old_subs_arity = subs_arity;
n_vars_operator_array[i-1] = (n_vars_operator_array[i-1]<< MODE_DIRECTED_TAGBITS) + MODE_DIRECTED_operator(mode_directed_array[i-1]);
}
#else
current_sg_node = subgoal_search_loop(tab_ent, current_sg_node, Deref(XREGS[i]), &subs_arity, &stack_vars);
#endif /*MODE_DIRECTED_TABLING*/
}
}
STACK_PUSH_UP(subs_arity, stack_vars);
@ -1002,7 +1294,9 @@ sg_fr_ptr subgoal_search(yamop *preg, CELL **Yaddr) {
Term t = STACK_POP_DOWN(stack_vars);
RESET_VARIABLE(t);
}
// for(i=0;i<pred_arity;i++)
//printf("2sub_search %p\n",n_vars_operator_array[i]);
#if defined(TABLE_LOCK_AT_NODE_LEVEL)
LOCK(TrNode_lock(current_sg_node));
#elif defined(TABLE_LOCK_AT_WRITE_LEVEL)
@ -1010,7 +1304,9 @@ sg_fr_ptr subgoal_search(yamop *preg, CELL **Yaddr) {
#endif /* TABLE_LOCK_LEVEL */
if (TrNode_sg_fr(current_sg_node) == NULL) {
/* new tabled subgoal */
new_subgoal_frame(sg_fr, preg);
#ifdef MODE_DIRECTED_TABLING
new_subgoal_frame(sg_fr, preg,n_vars_operator_array);
#endif /*MODE_DIRECTED_TABLING*/
TrNode_sg_fr(current_sg_node) = (sg_node_ptr) sg_fr;
TAG_AS_SUBGOAL_LEAF_NODE(current_sg_node);
} else {
@ -1042,6 +1338,14 @@ ans_node_ptr answer_search(sg_fr_ptr sg_fr, CELL *subs_ptr) {
vars_arity = 0;
current_ans_node = SgFr_answer_trie(sg_fr);
#ifdef MODE_DIRECTED_TABLING
int* n_vars_operator_array = TrNode_mode_directed_array(current_ans_node);
int j=0,n_vars=0, mode=-1;
// for(i=0;i<3;i++)
//printf("sub_search %p\n",n_vars_operator_array[i]);
#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]));
@ -1050,7 +1354,26 @@ 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*/
}
}
@ -1392,4 +1715,6 @@ void show_global_trie(int show_mode, IOSTREAM *out) {
}
return;
}
#endif /* TABLING */
#endif /* TABLING */

View File

@ -51,7 +51,7 @@
#ifdef MODE_GLOBAL_TRIE_LOOP
#define SUBGOAL_CHECK_INSERT_ENTRY(TAB_ENT, NODE, ENTRY) \
NODE = global_trie_check_insert_entry(NODE, ENTRY)
#define ANSWER_CHECK_INSERT_ENTRY(SG_FR, NODE, ENTRY, INSTR) \
#define ANSWER_CHECK_INSERT_ENTRY(SG_FR, NODE, ENTRY, INSTR) \
NODE = global_trie_check_insert_entry(NODE, ENTRY)
#else
#define SUBGOAL_CHECK_INSERT_ENTRY(TAB_ENT, NODE, ENTRY) \
@ -1061,14 +1061,14 @@ static inline ans_node_ptr answer_search_loop(sg_fr_ptr sg_fr, ans_node_ptr curr
t = Deref(t);
if (IsTableVarTerm(t)) {
t = MakeTableVarTerm(VarIndexOfTerm(t));
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_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_var + in_pair);
ANSWER_CHECK_INSERT_ENTRY(sg_fr, current_node, t, _trie_retry_val + in_pair);
vars_arity = vars_arity + 1;
}
#ifdef TRIE_COMPACT_PAIRS

View File

@ -111,6 +111,17 @@ table(Pred) :-
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
'$do_table'(Mod,Pred) :-
'$do_error'(type_error(callable,Mod:Pred),table(Mod:Pred)).
@ -335,4 +346,4 @@ table_statistics(Stream,Pred) :-
'$do_table_statistics'(_,Mod,Pred) :-
'$do_error'(type_error(callable,Mod:Pred),table_statistics(Mod:Pred)).
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%