Merge branch 'master' of ssh://yap.git.sourceforge.net/gitroot/yap/yap-6.3
This commit is contained in:
commit
c637863616
@ -3113,7 +3113,7 @@ p_undefined( USES_REGS1 )
|
||||
if (EndOfPAEntr(pe))
|
||||
return TRUE;
|
||||
PELOCK(36,pe);
|
||||
if (pe->PredFlags & (CPredFlag|UserCPredFlag|TestPredFlag|AsmPredFlag|DynamicPredFlag|LogUpdatePredFlag)) {
|
||||
if (pe->PredFlags & (CPredFlag|UserCPredFlag|TestPredFlag|AsmPredFlag|DynamicPredFlag|LogUpdatePredFlag|TabledPredFlag)) {
|
||||
UNLOCKPE(57,pe);
|
||||
return FALSE;
|
||||
}
|
||||
|
@ -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) **
|
||||
****************************************************/
|
||||
|
@ -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;
|
||||
|
@ -47,7 +47,7 @@ static void share_private_nodes(int worker_q);
|
||||
#if INCREMENTAL_COPY
|
||||
#define COMPUTE_SEGMENTS_TO_COPY_TO(Q) \
|
||||
if (REMOTE_top_cp(Q) == GLOBAL_root_cp) \
|
||||
REMOTE_start_global_copy(Q) = (CELL) (H0); \
|
||||
REMOTE_start_global_copy(Q) = (CELL) (H0); \
|
||||
else \
|
||||
REMOTE_start_global_copy(Q) = (CELL) (REMOTE_top_cp(Q)->cp_h); \
|
||||
REMOTE_end_global_copy(Q) = (CELL) (B->cp_h); \
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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*/
|
||||
|
@ -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<pred_arity;i++)
|
||||
// printf("sub_search %p\n",mode_directed_array[i]);
|
||||
#endif /*MODE_DIRECTED_TABLING*/
|
||||
|
||||
|
||||
mode_directed = TabEnt_mode_directed(tab_ent);
|
||||
if (mode_directed) {
|
||||
int old_subs_arity = subs_arity;
|
||||
for (i = 1; i <= pred_arity; i++) {
|
||||
int j = MODE_DIRECTED_GET_ARG(mode_directed[i-1]) + 1;
|
||||
current_sg_node = subgoal_search_loop(tab_ent, current_sg_node, Deref(XREGS[j]), &subs_arity, &stack_vars);
|
||||
if (subs_arity != old_subs_arity) {
|
||||
if (subs_pos && MODE_DIRECTED_GET_MODE(aux_mode_directed[subs_pos-1]) == MODE_DIRECTED_GET_MODE(mode_directed[i-1])) {
|
||||
aux_mode_directed[subs_pos-1] += MODE_DIRECTED_SET(subs_arity - old_subs_arity, 0);
|
||||
} else {
|
||||
aux_mode_directed[subs_pos] = MODE_DIRECTED_SET(subs_arity - old_subs_arity, MODE_DIRECTED_GET_MODE(mode_directed[i-1]));
|
||||
subs_pos++;
|
||||
}
|
||||
old_subs_arity = subs_arity;
|
||||
}
|
||||
}
|
||||
} else
|
||||
#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++){
|
||||
#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
|
||||
for (i = 1; i <= pred_arity; i++)
|
||||
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);
|
||||
@ -1474,8 +1029,6 @@ 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));
|
||||
@ -1485,8 +1038,13 @@ sg_fr_ptr subgoal_search(yamop *preg, CELL **Yaddr) {
|
||||
if (TrNode_sg_fr(current_sg_node) == NULL) {
|
||||
/* new tabled subgoal */
|
||||
#ifdef MODE_DIRECTED_TABLING
|
||||
new_subgoal_frame(sg_fr, preg,n_vars_operator_array);
|
||||
#endif /*MODE_DIRECTED_TABLING*/
|
||||
if (subs_pos) {
|
||||
ALLOC_BLOCK(mode_directed, subs_pos*sizeof(int), int);
|
||||
memcpy((void *)mode_directed, (void *)aux_mode_directed, subs_pos*sizeof(int));
|
||||
} else
|
||||
mode_directed = NULL;
|
||||
#endif /* MODE_DIRECTED_TABLING */
|
||||
new_subgoal_frame(sg_fr, preg, mode_directed);
|
||||
TrNode_sg_fr(current_sg_node) = (sg_node_ptr) sg_fr;
|
||||
TAG_AS_SUBGOAL_LEAF_NODE(current_sg_node);
|
||||
} else {
|
||||
@ -1514,18 +1072,42 @@ ans_node_ptr answer_search(sg_fr_ptr sg_fr, CELL *subs_ptr) {
|
||||
CELL *stack_vars;
|
||||
int i, vars_arity;
|
||||
ans_node_ptr current_ans_node;
|
||||
#ifdef MODE_DIRECTED_TABLING
|
||||
int *mode_directed;
|
||||
#endif /* MODE_DIRECTED_TABLING */
|
||||
|
||||
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*/
|
||||
|
||||
mode_directed = SgFr_mode_directed(sg_fr);
|
||||
if (mode_directed) {
|
||||
int i = subs_arity, j = 0;
|
||||
while (i) {
|
||||
int mode = MODE_DIRECTED_GET_MODE(mode_directed[j]);
|
||||
int n_subs = MODE_DIRECTED_GET_ARG(mode_directed[j]);
|
||||
do {
|
||||
TABLING_ERROR_CHECKING(answer search, IsNonVarTerm(subs_ptr[i]));
|
||||
if (TrNode_child(current_ans_node) == NULL || mode == MODE_DIRECTED_INDEX || mode == MODE_DIRECTED_ALL)
|
||||
current_ans_node = answer_search_loop(sg_fr, current_ans_node, Deref(subs_ptr[i]), &vars_arity);
|
||||
else { /* TrNode_child(current_node) != NULL && mode != MODE_DIRECTED_INDEX && mode != MODE_DIRECTED_ALL */
|
||||
if (mode == MODE_DIRECTED_FIRST)
|
||||
current_ans_node = NULL;
|
||||
else if (mode == MODE_DIRECTED_LAST) {
|
||||
invalidate_answer_trie(TrNode_child(current_ans_node), sg_fr, TRAVERSE_POSITION_FIRST);
|
||||
TrNode_child(current_ans_node) = NULL;
|
||||
current_ans_node = answer_search_loop(sg_fr, current_ans_node, Deref(subs_ptr[i]), &vars_arity);
|
||||
} else /* mode == MODE_DIRECTED_MIN || mode == MODE_DIRECTED_MAX */
|
||||
current_ans_node = answer_search_mode_directed_min_max(sg_fr, current_ans_node, Deref(subs_ptr[i]), mode);
|
||||
}
|
||||
n_subs--;
|
||||
i--;
|
||||
} while (n_subs && current_ans_node);
|
||||
if (current_ans_node == NULL) /* no answer inserted */
|
||||
break;
|
||||
j++;
|
||||
}
|
||||
} else
|
||||
#endif /* MODE_DIRECTED_TABLING */
|
||||
if (IsMode_GlobalTrie(TabEnt_mode(SgFr_tab_ent(sg_fr)))) {
|
||||
for (i = subs_arity; i >= 1; i--) {
|
||||
TABLING_ERROR_CHECKING(answer search, IsNonVarTerm(subs_ptr[i]));
|
||||
@ -1534,26 +1116,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*/
|
||||
}
|
||||
}
|
||||
|
||||
@ -1814,10 +1377,37 @@ void show_table(tab_ent_ptr tab_ent, int show_mode, IOSTREAM *out) {
|
||||
#endif /* TABLING_INNER_CUTS */
|
||||
TrStat_ans_nodes = 0;
|
||||
TrStat_gt_refs = 0;
|
||||
Sfprintf(TrStat_out, "Table statistics for predicate '%s/%d'\n", AtomName(TabEnt_atom(tab_ent)), TabEnt_arity(tab_ent));
|
||||
Sfprintf(TrStat_out, "Table statistics for predicate '%s", AtomName(TabEnt_atom(tab_ent)));
|
||||
} else { /* SHOW_MODE_STRUCTURE */
|
||||
Sfprintf(TrStat_out, "Table structure for predicate '%s/%d'\n", AtomName(TabEnt_atom(tab_ent)), TabEnt_arity(tab_ent));
|
||||
Sfprintf(TrStat_out, "Table structure for predicate '%s", AtomName(TabEnt_atom(tab_ent)));
|
||||
}
|
||||
#ifdef MODE_DIRECTED_TABLING
|
||||
if (TabEnt_mode_directed(tab_ent)) {
|
||||
int i, *mode_directed = TabEnt_mode_directed(tab_ent);
|
||||
Sfprintf(TrStat_out, "(");
|
||||
for (i = 0; i < TabEnt_arity(tab_ent); i++) {
|
||||
int mode = MODE_DIRECTED_GET_MODE(mode_directed[i]);
|
||||
if (mode == MODE_DIRECTED_INDEX) {
|
||||
Sfprintf(TrStat_out, "index");
|
||||
} else if (mode == MODE_DIRECTED_FIRST) {
|
||||
Sfprintf(TrStat_out, "first");
|
||||
} else if (mode == MODE_DIRECTED_ALL) {
|
||||
Sfprintf(TrStat_out, "all");
|
||||
} else if (mode == MODE_DIRECTED_MAX) {
|
||||
Sfprintf(TrStat_out, "max");
|
||||
} else if (mode == MODE_DIRECTED_MIN) {
|
||||
Sfprintf(TrStat_out, "min");
|
||||
} else /* MODE_DIRECTED_LAST */
|
||||
Sfprintf(TrStat_out, "last");
|
||||
if (i != MODE_DIRECTED_GET_ARG(mode_directed[i]))
|
||||
Sfprintf(TrStat_out, "(ARG%d)", MODE_DIRECTED_GET_ARG(mode_directed[i]) + 1);
|
||||
if (i + 1 != TabEnt_arity(tab_ent))
|
||||
Sfprintf(TrStat_out, ",");
|
||||
}
|
||||
Sfprintf(TrStat_out, ")'\n");
|
||||
} else
|
||||
#endif /* MODE_DIRECTED_TABLING */
|
||||
Sfprintf(TrStat_out, "/%d'\n", TabEnt_arity(tab_ent));
|
||||
sg_node = TrNode_child(TabEnt_subgoal_trie(tab_ent));
|
||||
if (sg_node) {
|
||||
if (TabEnt_arity(tab_ent)) {
|
||||
|
@ -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 = (Functor) RepAppl(child_term);
|
||||
child_node = TrNode_child(child_node);
|
||||
if (f == FunctorLongInt) {
|
||||
trie_value = (Float) TrNode_entry(child_node);
|
||||
} else if (f == FunctorDouble) {
|
||||
union {
|
||||
Term t_dbl[sizeof(Float)/sizeof(Term)];
|
||||
Float dbl;
|
||||
} u;
|
||||
u.t_dbl[0] = TrNode_entry(child_node);
|
||||
#if SIZEOF_DOUBLE == 2 * SIZEOF_INT_P
|
||||
child_node = TrNode_child(child_node);
|
||||
u.t_dbl[1] = TrNode_entry(child_node);
|
||||
#endif /* SIZEOF_DOUBLE x SIZEOF_INT_P */
|
||||
trie_value = u.dbl;
|
||||
} else
|
||||
Yap_Error(INTERNAL_ERROR, TermNil, "answer_search_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(TrNode_child(current_node), sg_fr, TRAVERSE_POSITION_FIRST);
|
||||
TrNode_child(current_node) = NULL;
|
||||
if (IsAtomOrIntTerm(t)) {
|
||||
ANSWER_CHECK_INSERT_ENTRY(sg_fr, current_node, t, _trie_retry_atom + in_pair);
|
||||
} 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
|
||||
|
@ -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).
|
||||
|
||||
|
||||
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
Reference in New Issue
Block a user