2015-01-26 07:38:36 +00:00
/************************************************************************
* * * *
* * The YapTab / YapOr / OPTYap systems * *
* * * *
* * YapTab extends the Yap Prolog engine to support sequential tabling * *
* * YapOr extends the Yap Prolog engine to support or - parallelism * *
* * OPTYap extends the Yap Prolog engine to support or - parallel tabling * *
* * * *
* * * *
* * Yap Prolog was developed at University of Porto , Portugal * *
* * * *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/*********************
* * Macros * *
* * * * * * * * * * * * * * * * * * * * */
# ifdef MODE_GLOBAL_TRIE_ENTRY
# define INCREMENT_GLOBAL_TRIE_REFERENCE(ENTRY) \
{ register gt_node_ptr entry_node = ( gt_node_ptr ) ( ENTRY ) ; \
TrNode_child ( entry_node ) = ( gt_node_ptr ) ( ( UInt ) TrNode_child ( entry_node ) + 1 ) ; \
}
# define NEW_SUBGOAL_TRIE_NODE(NODE, ENTRY, CHILD, PARENT, NEXT) \
INCREMENT_GLOBAL_TRIE_REFERENCE ( ENTRY ) ; \
new_subgoal_trie_node ( NODE , ENTRY , CHILD , PARENT , NEXT )
# define NEW_ANSWER_TRIE_NODE(NODE, INSTR, ENTRY, CHILD, PARENT, NEXT) \
INCREMENT_GLOBAL_TRIE_REFERENCE ( ENTRY ) ; \
new_answer_trie_node ( NODE , INSTR , ENTRY , CHILD , PARENT , NEXT )
# define NEW_GLOBAL_TRIE_NODE(NODE, ENTRY, CHILD, PARENT, NEXT) \
INCREMENT_GLOBAL_TRIE_REFERENCE ( ENTRY ) ; \
new_global_trie_node ( NODE , ENTRY , CHILD , PARENT , NEXT )
# else
# define NEW_SUBGOAL_TRIE_NODE(NODE, ENTRY, CHILD, PARENT, NEXT) \
new_subgoal_trie_node ( NODE , ENTRY , CHILD , PARENT , NEXT )
# define NEW_ANSWER_TRIE_NODE(NODE, INSTR, ENTRY, CHILD, PARENT, NEXT) \
new_answer_trie_node ( NODE , INSTR , ENTRY , CHILD , PARENT , NEXT )
# define NEW_GLOBAL_TRIE_NODE(NODE, ENTRY, CHILD, PARENT, NEXT) \
new_global_trie_node ( NODE , ENTRY , CHILD , PARENT , NEXT )
# endif /* MODE_GLOBAL_TRIE_ENTRY */
# ifdef MODE_GLOBAL_TRIE_LOOP
# define SUBGOAL_CHECK_INSERT_ENTRY(TAB_ENT, NODE, ENTRY) \
NODE = global_trie_check_insert_entry ( NODE , ENTRY PASS_REGS )
# define ANSWER_CHECK_INSERT_ENTRY(SG_FR, NODE, ENTRY, INSTR) \
NODE = global_trie_check_insert_entry ( NODE , ENTRY PASS_REGS )
# else
# define SUBGOAL_CHECK_INSERT_ENTRY(TAB_ENT, NODE, ENTRY) \
NODE = subgoal_trie_check_insert_entry ( TAB_ENT , NODE , ENTRY PASS_REGS )
# define ANSWER_CHECK_INSERT_ENTRY(SG_FR, NODE, ENTRY, INSTR) \
NODE = answer_trie_check_insert_entry ( SG_FR , NODE , ENTRY , INSTR PASS_REGS )
# endif /* MODE_GLOBAL_TRIE_LOOP */
# ifdef INCLUDE_ANSWER_SEARCH_MODE_DIRECTED
# define ANSWER_SAFE_INSERT_ENTRY(NODE, ENTRY, INSTR) \
{ ans_node_ptr new_node ; \
NEW_ANSWER_TRIE_NODE ( new_node , INSTR , ENTRY , NULL , NODE , NULL ) ; \
TrNode_child ( NODE ) = new_node ; \
NODE = new_node ; \
}
# ifdef THREADS
# define INVALIDATE_ANSWER_TRIE_NODE(NODE, SG_FR) \
TrNode_next ( NODE ) = SgFr_invalid_chain ( SG_FR ) ; \
SgFr_invalid_chain ( SG_FR ) = NODE
# else
# define INVALIDATE_ANSWER_TRIE_NODE(NODE, SG_FR) \
FREE_ANSWER_TRIE_NODE ( NODE )
# endif /* THREADS */
# define INVALIDATE_ANSWER_TRIE_LEAF_NODE(NODE, SG_FR) \
TAG_AS_ANSWER_INVALID_NODE ( NODE ) ; \
TrNode_next ( NODE ) = SgFr_invalid_chain ( SG_FR ) ; \
SgFr_invalid_chain ( SG_FR ) = NODE
# endif /* INCLUDE_ANSWER_SEARCH_MODE_DIRECTED */
/************************************************************************
* * subgoal_trie_check_insert_ ( gt ) _entry * *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
# ifdef INCLUDE_SUBGOAL_TRIE_CHECK_INSERT
# ifndef SUBGOAL_TRIE_LOCK_AT_WRITE_LEVEL /* SUBGOAL_TRIE_LOCK_AT_ENTRY_LEVEL || SUBGOAL_TRIE_LOCK_AT_NODE_LEVEL || ! YAPOR */
# ifdef MODE_GLOBAL_TRIE_ENTRY
static inline sg_node_ptr subgoal_trie_check_insert_gt_entry ( tab_ent_ptr tab_ent , sg_node_ptr parent_node , Term t USES_REGS ) {
# else
static inline sg_node_ptr subgoal_trie_check_insert_entry ( tab_ent_ptr tab_ent , sg_node_ptr parent_node , Term t USES_REGS ) {
# endif /* MODE_GLOBAL_TRIE_ENTRY */
sg_node_ptr child_node ;
LOCK_SUBGOAL_NODE ( parent_node ) ;
child_node = TrNode_child ( parent_node ) ;
if ( child_node = = NULL ) {
NEW_SUBGOAL_TRIE_NODE ( child_node , t , NULL , parent_node , NULL ) ;
TrNode_child ( parent_node ) = child_node ;
UNLOCK_SUBGOAL_NODE ( parent_node ) ;
return child_node ;
}
if ( ! IS_SUBGOAL_TRIE_HASH ( child_node ) ) {
int count_nodes = 0 ;
do {
if ( TrNode_entry ( child_node ) = = t ) {
UNLOCK_SUBGOAL_NODE ( parent_node ) ;
return child_node ;
}
count_nodes + + ;
child_node = TrNode_next ( child_node ) ;
} while ( child_node ) ;
NEW_SUBGOAL_TRIE_NODE ( child_node , t , NULL , parent_node , TrNode_child ( parent_node ) ) ;
count_nodes + + ;
if ( count_nodes > = MAX_NODES_PER_TRIE_LEVEL ) {
/* alloc a new hash */
sg_hash_ptr hash ;
sg_node_ptr chain_node , next_node , * bucket ;
new_subgoal_trie_hash ( hash , count_nodes , tab_ent ) ;
chain_node = child_node ;
do {
bucket = Hash_buckets ( hash ) + HASH_ENTRY ( TrNode_entry ( chain_node ) , BASE_HASH_BUCKETS ) ;
next_node = TrNode_next ( chain_node ) ;
TrNode_next ( chain_node ) = * bucket ;
* bucket = chain_node ;
chain_node = next_node ;
} while ( chain_node ) ;
TrNode_child ( parent_node ) = ( sg_node_ptr ) hash ;
} else {
TrNode_child ( parent_node ) = child_node ;
}
UNLOCK_SUBGOAL_NODE ( parent_node ) ;
return child_node ;
}
{ /* trie nodes with hashing */
sg_hash_ptr hash ;
sg_node_ptr * bucket ;
int count_nodes = 0 ;
hash = ( sg_hash_ptr ) child_node ;
bucket = Hash_buckets ( hash ) + HASH_ENTRY ( t , Hash_num_buckets ( hash ) ) ;
child_node = * bucket ;
while ( child_node ) {
if ( TrNode_entry ( child_node ) = = t ) {
UNLOCK_SUBGOAL_NODE ( parent_node ) ;
return child_node ;
}
count_nodes + + ;
child_node = TrNode_next ( child_node ) ;
}
NEW_SUBGOAL_TRIE_NODE ( child_node , t , NULL , parent_node , * bucket ) ;
* bucket = child_node ;
Hash_num_nodes ( hash ) + + ;
count_nodes + + ;
if ( count_nodes > = MAX_NODES_PER_BUCKET & & Hash_num_nodes ( hash ) > Hash_num_buckets ( hash ) ) {
/* expand current hash */
sg_node_ptr chain_node , next_node , * old_bucket , * old_hash_buckets , * new_hash_buckets ;
int num_buckets ;
num_buckets = Hash_num_buckets ( hash ) * 2 ;
ALLOC_BUCKETS ( new_hash_buckets , num_buckets ) ;
old_hash_buckets = Hash_buckets ( hash ) ;
old_bucket = old_hash_buckets + Hash_num_buckets ( hash ) ;
do {
if ( * - - old_bucket ) {
chain_node = * old_bucket ;
do {
bucket = new_hash_buckets + HASH_ENTRY ( TrNode_entry ( chain_node ) , num_buckets ) ;
next_node = TrNode_next ( chain_node ) ;
TrNode_next ( chain_node ) = * bucket ;
* bucket = chain_node ;
chain_node = next_node ;
} while ( chain_node ) ;
}
} while ( old_bucket ! = old_hash_buckets ) ;
Hash_buckets ( hash ) = new_hash_buckets ;
Hash_num_buckets ( hash ) = num_buckets ;
FREE_BUCKETS ( old_hash_buckets ) ;
}
UNLOCK_SUBGOAL_NODE ( parent_node ) ;
return child_node ;
}
}
# else /* SUBGOAL_TRIE_LOCK_AT_WRITE_LEVEL */
# ifdef MODE_GLOBAL_TRIE_ENTRY
static inline sg_node_ptr subgoal_trie_check_insert_gt_entry ( tab_ent_ptr tab_ent , sg_node_ptr parent_node , Term t USES_REGS ) {
# else
static inline sg_node_ptr subgoal_trie_check_insert_entry ( tab_ent_ptr tab_ent , sg_node_ptr parent_node , Term t USES_REGS ) {
# endif /* MODE_GLOBAL_TRIE_ENTRY */
sg_node_ptr child_node ;
sg_hash_ptr hash ;
child_node = TrNode_child ( parent_node ) ;
if ( child_node = = NULL ) {
# ifdef SUBGOAL_TRIE_ALLOC_BEFORE_CHECK
NEW_SUBGOAL_TRIE_NODE ( child_node , t , NULL , parent_node , NULL ) ;
# endif /* SUBGOAL_TRIE_ALLOC_BEFORE_CHECK */
LOCK_SUBGOAL_NODE ( parent_node ) ;
if ( TrNode_child ( parent_node ) ) {
sg_node_ptr chain_node = TrNode_child ( parent_node ) ;
if ( IS_SUBGOAL_TRIE_HASH ( chain_node ) ) {
# ifdef SUBGOAL_TRIE_ALLOC_BEFORE_CHECK
FREE_SUBGOAL_TRIE_NODE ( child_node ) ;
# endif /* SUBGOAL_TRIE_ALLOC_BEFORE_CHECK */
UNLOCK_SUBGOAL_NODE ( parent_node ) ;
hash = ( sg_hash_ptr ) chain_node ;
goto subgoal_trie_hash ;
}
do {
if ( TrNode_entry ( chain_node ) = = t ) {
# ifdef SUBGOAL_TRIE_ALLOC_BEFORE_CHECK
FREE_SUBGOAL_TRIE_NODE ( child_node ) ;
# endif /* SUBGOAL_TRIE_ALLOC_BEFORE_CHECK */
UNLOCK_SUBGOAL_NODE ( parent_node ) ;
return chain_node ;
}
chain_node = TrNode_next ( chain_node ) ;
} while ( chain_node ) ;
# ifdef SUBGOAL_TRIE_ALLOC_BEFORE_CHECK
TrNode_next ( child_node ) = TrNode_child ( parent_node ) ;
# else
NEW_SUBGOAL_TRIE_NODE ( child_node , t , NULL , parent_node , TrNode_child ( parent_node ) ) ;
} else {
NEW_SUBGOAL_TRIE_NODE ( child_node , t , NULL , parent_node , NULL ) ;
# endif /* SUBGOAL_TRIE_ALLOC_BEFORE_CHECK */
}
TrNode_child ( parent_node ) = child_node ;
UNLOCK_SUBGOAL_NODE ( parent_node ) ;
return child_node ;
}
if ( ! IS_SUBGOAL_TRIE_HASH ( child_node ) ) {
sg_node_ptr first_node = child_node ;
int count_nodes = 0 ;
do {
if ( TrNode_entry ( child_node ) = = t )
return child_node ;
count_nodes + + ;
child_node = TrNode_next ( child_node ) ;
} while ( child_node ) ;
# ifdef SUBGOAL_TRIE_ALLOC_BEFORE_CHECK
NEW_SUBGOAL_TRIE_NODE ( child_node , t , NULL , parent_node , first_node ) ;
# endif /* SUBGOAL_TRIE_ALLOC_BEFORE_CHECK */
LOCK_SUBGOAL_NODE ( parent_node ) ;
if ( first_node ! = TrNode_child ( parent_node ) ) {
sg_node_ptr chain_node = TrNode_child ( parent_node ) ;
if ( IS_SUBGOAL_TRIE_HASH ( chain_node ) ) {
# ifdef SUBGOAL_TRIE_ALLOC_BEFORE_CHECK
FREE_SUBGOAL_TRIE_NODE ( child_node ) ;
# endif /* SUBGOAL_TRIE_ALLOC_BEFORE_CHECK */
UNLOCK_SUBGOAL_NODE ( parent_node ) ;
hash = ( sg_hash_ptr ) chain_node ;
goto subgoal_trie_hash ;
}
do {
if ( TrNode_entry ( chain_node ) = = t ) {
# ifdef SUBGOAL_TRIE_ALLOC_BEFORE_CHECK
FREE_SUBGOAL_TRIE_NODE ( child_node ) ;
# endif /* SUBGOAL_TRIE_ALLOC_BEFORE_CHECK */
UNLOCK_SUBGOAL_NODE ( parent_node ) ;
return chain_node ;
}
count_nodes + + ;
chain_node = TrNode_next ( chain_node ) ;
} while ( chain_node ! = first_node ) ;
# ifdef SUBGOAL_TRIE_ALLOC_BEFORE_CHECK
TrNode_next ( child_node ) = TrNode_child ( parent_node ) ;
# else
NEW_SUBGOAL_TRIE_NODE ( child_node , t , NULL , parent_node , TrNode_child ( parent_node ) ) ;
} else {
NEW_SUBGOAL_TRIE_NODE ( child_node , t , NULL , parent_node , first_node ) ;
# endif /* SUBGOAL_TRIE_ALLOC_BEFORE_CHECK */
}
count_nodes + + ;
if ( count_nodes > = MAX_NODES_PER_TRIE_LEVEL ) {
/* alloc a new hash */
sg_node_ptr chain_node , next_node , * bucket ;
new_subgoal_trie_hash ( hash , count_nodes , tab_ent ) ;
chain_node = child_node ;
do {
bucket = Hash_buckets ( hash ) + HASH_ENTRY ( TrNode_entry ( chain_node ) , BASE_HASH_BUCKETS ) ;
next_node = TrNode_next ( chain_node ) ;
TrNode_next ( chain_node ) = * bucket ;
* bucket = chain_node ;
chain_node = next_node ;
} while ( chain_node ) ;
TrNode_child ( parent_node ) = ( sg_node_ptr ) hash ;
} else {
TrNode_child ( parent_node ) = child_node ;
}
UNLOCK_SUBGOAL_NODE ( parent_node ) ;
return child_node ;
}
hash = ( sg_hash_ptr ) child_node ;
subgoal_trie_hash :
{ /* trie nodes with hashing */
sg_node_ptr * bucket , first_node ;
int num_buckets , count_nodes = 0 ;
do {
num_buckets = Hash_num_buckets ( hash ) ;
// __sync_synchronize();
bucket = Hash_buckets ( hash ) + HASH_ENTRY ( t , num_buckets ) ;
first_node = child_node = * bucket ;
} while ( num_buckets ! = Hash_num_buckets ( hash ) ) ;
while ( child_node ) {
if ( TrNode_entry ( child_node ) = = t )
return child_node ;
count_nodes + + ;
child_node = TrNode_next ( child_node ) ;
}
# ifdef SUBGOAL_TRIE_ALLOC_BEFORE_CHECK
NEW_SUBGOAL_TRIE_NODE ( child_node , t , NULL , parent_node , first_node ) ;
# endif /* SUBGOAL_TRIE_ALLOC_BEFORE_CHECK */
LOCK_SUBGOAL_NODE ( parent_node ) ;
if ( num_buckets ! = Hash_num_buckets ( hash ) ) {
/* the hash has been expanded */
# ifdef SUBGOAL_TRIE_ALLOC_BEFORE_CHECK
FREE_SUBGOAL_TRIE_NODE ( child_node ) ;
# endif /* SUBGOAL_TRIE_ALLOC_BEFORE_CHECK */
UNLOCK_SUBGOAL_NODE ( parent_node ) ;
goto subgoal_trie_hash ;
}
if ( first_node ! = * bucket ) {
sg_node_ptr chain_node = * bucket ;
do {
if ( TrNode_entry ( chain_node ) = = t ) {
# ifdef SUBGOAL_TRIE_ALLOC_BEFORE_CHECK
FREE_SUBGOAL_TRIE_NODE ( child_node ) ;
# endif /* SUBGOAL_TRIE_ALLOC_BEFORE_CHECK */
UNLOCK_SUBGOAL_NODE ( parent_node ) ;
return chain_node ;
}
count_nodes + + ;
chain_node = TrNode_next ( chain_node ) ;
} while ( chain_node ! = first_node ) ;
# ifdef SUBGOAL_TRIE_ALLOC_BEFORE_CHECK
TrNode_next ( child_node ) = * bucket ;
# else
NEW_SUBGOAL_TRIE_NODE ( child_node , t , NULL , parent_node , * bucket ) ;
} else {
NEW_SUBGOAL_TRIE_NODE ( child_node , t , NULL , parent_node , first_node ) ;
# endif /* SUBGOAL_TRIE_ALLOC_BEFORE_CHECK */
}
* bucket = child_node ;
Hash_num_nodes ( hash ) + + ;
count_nodes + + ;
if ( count_nodes > = MAX_NODES_PER_BUCKET & & Hash_num_nodes ( hash ) > Hash_num_buckets ( hash ) ) {
/* expand current hash */
sg_node_ptr chain_node , next_node , * old_bucket , * old_hash_buckets , * new_hash_buckets ;
num_buckets = Hash_num_buckets ( hash ) * 2 ;
ALLOC_BUCKETS ( new_hash_buckets , num_buckets ) ;
old_hash_buckets = Hash_buckets ( hash ) ;
old_bucket = old_hash_buckets + Hash_num_buckets ( hash ) ;
do {
if ( * - - old_bucket ) {
chain_node = * old_bucket ;
do {
bucket = new_hash_buckets + HASH_ENTRY ( TrNode_entry ( chain_node ) , num_buckets ) ;
next_node = TrNode_next ( chain_node ) ;
TrNode_next ( chain_node ) = * bucket ;
* bucket = chain_node ;
chain_node = next_node ;
} while ( chain_node ) ;
}
} while ( old_bucket ! = old_hash_buckets ) ;
Hash_buckets ( hash ) = new_hash_buckets ;
Hash_num_buckets ( hash ) = num_buckets ;
FREE_BUCKETS ( old_hash_buckets ) ;
}
UNLOCK_SUBGOAL_NODE ( parent_node ) ;
return child_node ;
}
}
# endif /* SUBGOAL_TRIE_LOCK_LEVEL */
# endif /* INCLUDE_SUBGOAL_TRIE_CHECK_INSERT */
/************************************************************************
* * answer_trie_check_insert_ ( gt ) _entry * *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
# ifdef INCLUDE_ANSWER_TRIE_CHECK_INSERT
# ifndef ANSWER_TRIE_LOCK_AT_WRITE_LEVEL /* ANSWER_TRIE_LOCK_AT_ENTRY_LEVEL || ANSWER_TRIE_LOCK_AT_NODE_LEVEL || ! YAPOR */
# ifdef MODE_GLOBAL_TRIE_ENTRY
static inline ans_node_ptr answer_trie_check_insert_gt_entry ( sg_fr_ptr sg_fr , ans_node_ptr parent_node , Term t , int instr USES_REGS ) {
# else
static inline ans_node_ptr answer_trie_check_insert_entry ( sg_fr_ptr sg_fr , ans_node_ptr parent_node , Term t , int instr USES_REGS ) {
# endif /* MODE_GLOBAL_TRIE_ENTRY */
ans_node_ptr child_node ;
TABLING_ERROR_CHECKING ( answer_trie_check_insert_ ( gt ) _entry , IS_ANSWER_LEAF_NODE ( parent_node ) ) ;
LOCK_ANSWER_NODE ( parent_node ) ;
child_node = TrNode_child ( parent_node ) ;
if ( child_node = = NULL ) {
NEW_ANSWER_TRIE_NODE ( child_node , instr , t , NULL , parent_node , NULL ) ;
TrNode_child ( parent_node ) = child_node ;
UNLOCK_ANSWER_NODE ( parent_node ) ;
return child_node ;
}
if ( ! IS_ANSWER_TRIE_HASH ( child_node ) ) {
int count_nodes = 0 ;
do {
if ( TrNode_entry ( child_node ) = = t ) {
UNLOCK_ANSWER_NODE ( parent_node ) ;
return child_node ;
}
count_nodes + + ;
child_node = TrNode_next ( child_node ) ;
} while ( child_node ) ;
NEW_ANSWER_TRIE_NODE ( child_node , instr , t , NULL , parent_node , TrNode_child ( parent_node ) ) ;
count_nodes + + ;
if ( count_nodes > = MAX_NODES_PER_TRIE_LEVEL ) {
/* alloc a new hash */
ans_hash_ptr hash ;
ans_node_ptr chain_node , next_node , * bucket ;
new_answer_trie_hash ( hash , count_nodes , sg_fr ) ;
chain_node = child_node ;
do {
bucket = Hash_buckets ( hash ) + HASH_ENTRY ( TrNode_entry ( chain_node ) , BASE_HASH_BUCKETS ) ;
next_node = TrNode_next ( chain_node ) ;
TrNode_next ( chain_node ) = * bucket ;
* bucket = chain_node ;
chain_node = next_node ;
} while ( chain_node ) ;
TrNode_child ( parent_node ) = ( ans_node_ptr ) hash ;
} else {
TrNode_child ( parent_node ) = child_node ;
}
UNLOCK_ANSWER_NODE ( parent_node ) ;
return child_node ;
}
{ /* trie nodes with hashing */
ans_hash_ptr hash ;
ans_node_ptr * bucket ;
int count_nodes = 0 ;
hash = ( ans_hash_ptr ) child_node ;
bucket = Hash_buckets ( hash ) + HASH_ENTRY ( t , Hash_num_buckets ( hash ) ) ;
child_node = * bucket ;
while ( child_node ) {
if ( TrNode_entry ( child_node ) = = t ) {
UNLOCK_ANSWER_NODE ( parent_node ) ;
return child_node ;
}
count_nodes + + ;
child_node = TrNode_next ( child_node ) ;
}
NEW_ANSWER_TRIE_NODE ( child_node , instr , t , NULL , parent_node , * bucket ) ;
* bucket = child_node ;
Hash_num_nodes ( hash ) + + ;
count_nodes + + ;
if ( count_nodes > = MAX_NODES_PER_BUCKET & & Hash_num_nodes ( hash ) > Hash_num_buckets ( hash ) ) {
/* expand current hash */
ans_node_ptr chain_node , next_node , * old_bucket , * old_hash_buckets , * new_hash_buckets ;
int num_buckets ;
num_buckets = Hash_num_buckets ( hash ) * 2 ;
ALLOC_BUCKETS ( new_hash_buckets , num_buckets ) ;
old_hash_buckets = Hash_buckets ( hash ) ;
old_bucket = old_hash_buckets + Hash_num_buckets ( hash ) ;
do {
if ( * - - old_bucket ) {
chain_node = * old_bucket ;
do {
bucket = new_hash_buckets + HASH_ENTRY ( TrNode_entry ( chain_node ) , num_buckets ) ;
next_node = TrNode_next ( chain_node ) ;
TrNode_next ( chain_node ) = * bucket ;
* bucket = chain_node ;
chain_node = next_node ;
} while ( chain_node ) ;
}
} while ( old_bucket ! = old_hash_buckets ) ;
Hash_buckets ( hash ) = new_hash_buckets ;
Hash_num_buckets ( hash ) = num_buckets ;
FREE_BUCKETS ( old_hash_buckets ) ;
}
UNLOCK_ANSWER_NODE ( parent_node ) ;
return child_node ;
}
}
# else /* ANSWER_TRIE_LOCK_AT_WRITE_LEVEL */
# ifdef MODE_GLOBAL_TRIE_ENTRY
static inline ans_node_ptr answer_trie_check_insert_gt_entry ( sg_fr_ptr sg_fr , ans_node_ptr parent_node , Term t , int instr USES_REGS ) {
# else
static inline ans_node_ptr answer_trie_check_insert_entry ( sg_fr_ptr sg_fr , ans_node_ptr parent_node , Term t , int instr USES_REGS ) {
# endif /* MODE_GLOBAL_TRIE_ENTRY */
ans_node_ptr child_node ;
ans_hash_ptr hash ;
TABLING_ERROR_CHECKING ( answer_trie_check_insert_ ( gt ) _entry , IS_ANSWER_LEAF_NODE ( parent_node ) ) ;
child_node = TrNode_child ( parent_node ) ;
if ( child_node = = NULL ) {
# ifdef ANSWER_TRIE_ALLOC_BEFORE_CHECK
NEW_ANSWER_TRIE_NODE ( child_node , instr , t , NULL , parent_node , NULL ) ;
# endif /* ANSWER_TRIE_ALLOC_BEFORE_CHECK */
LOCK_ANSWER_NODE ( parent_node ) ;
if ( TrNode_child ( parent_node ) ) {
ans_node_ptr chain_node = TrNode_child ( parent_node ) ;
if ( IS_ANSWER_TRIE_HASH ( chain_node ) ) {
# ifdef ANSWER_TRIE_ALLOC_BEFORE_CHECK
FREE_ANSWER_TRIE_NODE ( child_node ) ;
# endif /* ANSWER_TRIE_ALLOC_BEFORE_CHECK */
UNLOCK_ANSWER_NODE ( parent_node ) ;
hash = ( ans_hash_ptr ) chain_node ;
goto answer_trie_hash ;
}
do {
if ( TrNode_entry ( chain_node ) = = t ) {
# ifdef ANSWER_TRIE_ALLOC_BEFORE_CHECK
FREE_ANSWER_TRIE_NODE ( child_node ) ;
# endif /* ANSWER_TRIE_ALLOC_BEFORE_CHECK */
UNLOCK_ANSWER_NODE ( parent_node ) ;
return chain_node ;
}
chain_node = TrNode_next ( chain_node ) ;
} while ( chain_node ) ;
# ifdef ANSWER_TRIE_ALLOC_BEFORE_CHECK
TrNode_next ( child_node ) = TrNode_child ( parent_node ) ;
# else
NEW_ANSWER_TRIE_NODE ( child_node , instr , t , NULL , parent_node , TrNode_child ( parent_node ) ) ;
} else {
NEW_ANSWER_TRIE_NODE ( child_node , instr , t , NULL , parent_node , NULL ) ;
# endif /* ANSWER_TRIE_ALLOC_BEFORE_CHECK */
}
TrNode_child ( parent_node ) = child_node ;
UNLOCK_ANSWER_NODE ( parent_node ) ;
return child_node ;
}
if ( ! IS_ANSWER_TRIE_HASH ( child_node ) ) {
ans_node_ptr first_node = child_node ;
int count_nodes = 0 ;
do {
if ( TrNode_entry ( child_node ) = = t )
return child_node ;
count_nodes + + ;
child_node = TrNode_next ( child_node ) ;
} while ( child_node ) ;
# ifdef ANSWER_TRIE_ALLOC_BEFORE_CHECK
NEW_ANSWER_TRIE_NODE ( child_node , instr , t , NULL , parent_node , first_node ) ;
# endif /* ANSWER_TRIE_ALLOC_BEFORE_CHECK */
LOCK_ANSWER_NODE ( parent_node ) ;
if ( first_node ! = TrNode_child ( parent_node ) ) {
ans_node_ptr chain_node = TrNode_child ( parent_node ) ;
if ( IS_ANSWER_TRIE_HASH ( chain_node ) ) {
# ifdef ANSWER_TRIE_ALLOC_BEFORE_CHECK
FREE_ANSWER_TRIE_NODE ( child_node ) ;
# endif /* ANSWER_TRIE_ALLOC_BEFORE_CHECK */
UNLOCK_ANSWER_NODE ( parent_node ) ;
hash = ( ans_hash_ptr ) chain_node ;
goto answer_trie_hash ;
}
do {
if ( TrNode_entry ( chain_node ) = = t ) {
# ifdef ANSWER_TRIE_ALLOC_BEFORE_CHECK
FREE_ANSWER_TRIE_NODE ( child_node ) ;
# endif /* ANSWER_TRIE_ALLOC_BEFORE_CHECK */
UNLOCK_ANSWER_NODE ( parent_node ) ;
return chain_node ;
}
count_nodes + + ;
chain_node = TrNode_next ( chain_node ) ;
} while ( chain_node ! = first_node ) ;
# ifdef ANSWER_TRIE_ALLOC_BEFORE_CHECK
TrNode_next ( child_node ) = TrNode_child ( parent_node ) ;
# else
NEW_ANSWER_TRIE_NODE ( child_node , instr , t , NULL , parent_node , TrNode_child ( parent_node ) ) ;
} else {
NEW_ANSWER_TRIE_NODE ( child_node , instr , t , NULL , parent_node , first_node ) ;
# endif /* ANSWER_TRIE_ALLOC_BEFORE_CHECK */
}
count_nodes + + ;
if ( count_nodes > = MAX_NODES_PER_TRIE_LEVEL ) {
/* alloc a new hash */
ans_node_ptr chain_node , next_node , * bucket ;
new_answer_trie_hash ( hash , count_nodes , sg_fr ) ;
chain_node = child_node ;
do {
bucket = Hash_buckets ( hash ) + HASH_ENTRY ( TrNode_entry ( chain_node ) , BASE_HASH_BUCKETS ) ;
next_node = TrNode_next ( chain_node ) ;
TrNode_next ( chain_node ) = * bucket ;
* bucket = chain_node ;
chain_node = next_node ;
} while ( chain_node ) ;
TrNode_child ( parent_node ) = ( ans_node_ptr ) hash ;
} else {
TrNode_child ( parent_node ) = child_node ;
}
UNLOCK_ANSWER_NODE ( parent_node ) ;
return child_node ;
}
hash = ( ans_hash_ptr ) child_node ;
answer_trie_hash :
{ /* trie nodes with hashing */
ans_node_ptr * bucket , first_node ;
int num_buckets , count_nodes = 0 ;
do {
num_buckets = Hash_num_buckets ( hash ) ;
// __sync_synchronize();
bucket = Hash_buckets ( hash ) + HASH_ENTRY ( t , num_buckets ) ;
first_node = child_node = * bucket ;
} while ( num_buckets ! = Hash_num_buckets ( hash ) ) ;
while ( child_node ) {
if ( TrNode_entry ( child_node ) = = t )
return child_node ;
count_nodes + + ;
child_node = TrNode_next ( child_node ) ;
}
# ifdef ANSWER_TRIE_ALLOC_BEFORE_CHECK
NEW_ANSWER_TRIE_NODE ( child_node , instr , t , NULL , parent_node , first_node ) ;
# endif /* ANSWER_TRIE_ALLOC_BEFORE_CHECK */
LOCK_ANSWER_NODE ( parent_node ) ;
if ( num_buckets ! = Hash_num_buckets ( hash ) ) {
/* the hash has been expanded */
# ifdef ANSWER_TRIE_ALLOC_BEFORE_CHECK
FREE_ANSWER_TRIE_NODE ( child_node ) ;
# endif /* ANSWER_TRIE_ALLOC_BEFORE_CHECK */
UNLOCK_ANSWER_NODE ( parent_node ) ;
goto answer_trie_hash ;
}
if ( first_node ! = * bucket ) {
ans_node_ptr chain_node = * bucket ;
do {
if ( TrNode_entry ( chain_node ) = = t ) {
# ifdef ANSWER_TRIE_ALLOC_BEFORE_CHECK
FREE_ANSWER_TRIE_NODE ( child_node ) ;
# endif /* ANSWER_TRIE_ALLOC_BEFORE_CHECK */
UNLOCK_ANSWER_NODE ( parent_node ) ;
return chain_node ;
}
count_nodes + + ;
chain_node = TrNode_next ( chain_node ) ;
} while ( chain_node ! = first_node ) ;
# ifdef ANSWER_TRIE_ALLOC_BEFORE_CHECK
TrNode_next ( child_node ) = * bucket ;
# else
NEW_ANSWER_TRIE_NODE ( child_node , instr , t , NULL , parent_node , * bucket ) ;
} else {
NEW_ANSWER_TRIE_NODE ( child_node , instr , t , NULL , parent_node , first_node ) ;
# endif /* ANSWER_TRIE_ALLOC_BEFORE_CHECK */
}
* bucket = child_node ;
Hash_num_nodes ( hash ) + + ;
count_nodes + + ;
if ( count_nodes > = MAX_NODES_PER_BUCKET & & Hash_num_nodes ( hash ) > Hash_num_buckets ( hash ) ) {
/* expand current hash */
ans_node_ptr chain_node , next_node , * old_bucket , * old_hash_buckets , * new_hash_buckets ;
num_buckets = Hash_num_buckets ( hash ) * 2 ;
ALLOC_BUCKETS ( new_hash_buckets , num_buckets ) ;
old_hash_buckets = Hash_buckets ( hash ) ;
old_bucket = old_hash_buckets + Hash_num_buckets ( hash ) ;
do {
if ( * - - old_bucket ) {
chain_node = * old_bucket ;
do {
bucket = new_hash_buckets + HASH_ENTRY ( TrNode_entry ( chain_node ) , num_buckets ) ;
next_node = TrNode_next ( chain_node ) ;
TrNode_next ( chain_node ) = * bucket ;
* bucket = chain_node ;
chain_node = next_node ;
} while ( chain_node ) ;
}
} while ( old_bucket ! = old_hash_buckets ) ;
Hash_buckets ( hash ) = new_hash_buckets ;
Hash_num_buckets ( hash ) = num_buckets ;
FREE_BUCKETS ( old_hash_buckets ) ;
}
UNLOCK_ANSWER_NODE ( parent_node ) ;
return child_node ;
}
}
# endif /* ANSWER_TRIE_LOCK_LEVEL */
# endif /* INCLUDE_ANSWER_TRIE_CHECK_INSERT */
/************************************************************************
* * global_trie_check_insert_ ( gt ) _entry * *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
# ifdef INCLUDE_GLOBAL_TRIE_CHECK_INSERT
# ifndef GLOBAL_TRIE_LOCK_AT_WRITE_LEVEL /* GLOBAL_TRIE_LOCK_AT_NODE_LEVEL || ! YAPOR */
# ifdef MODE_GLOBAL_TRIE_ENTRY
static inline gt_node_ptr global_trie_check_insert_gt_entry ( gt_node_ptr parent_node , Term t USES_REGS ) {
# else
static inline gt_node_ptr global_trie_check_insert_entry ( gt_node_ptr parent_node , Term t USES_REGS ) {
# endif /* MODE_GLOBAL_TRIE_ENTRY */
gt_node_ptr child_node ;
LOCK_GLOBAL_NODE ( parent_node ) ;
child_node = TrNode_child ( parent_node ) ;
if ( child_node = = NULL ) {
NEW_GLOBAL_TRIE_NODE ( child_node , t , NULL , parent_node , NULL ) ;
TrNode_child ( parent_node ) = child_node ;
UNLOCK_GLOBAL_NODE ( parent_node ) ;
return child_node ;
}
if ( ! IS_GLOBAL_TRIE_HASH ( child_node ) ) {
int count_nodes = 0 ;
do {
if ( TrNode_entry ( child_node ) = = t ) {
UNLOCK_GLOBAL_NODE ( parent_node ) ;
return child_node ;
}
count_nodes + + ;
child_node = TrNode_next ( child_node ) ;
} while ( child_node ) ;
NEW_GLOBAL_TRIE_NODE ( child_node , t , NULL , parent_node , TrNode_child ( parent_node ) ) ;
count_nodes + + ;
if ( count_nodes > = MAX_NODES_PER_TRIE_LEVEL ) {
/* alloc a new hash */
gt_hash_ptr hash ;
gt_node_ptr chain_node , next_node , * bucket ;
new_global_trie_hash ( hash , count_nodes ) ;
chain_node = child_node ;
do {
bucket = Hash_buckets ( hash ) + HASH_ENTRY ( TrNode_entry ( chain_node ) , BASE_HASH_BUCKETS ) ;
next_node = TrNode_next ( chain_node ) ;
TrNode_next ( chain_node ) = * bucket ;
* bucket = chain_node ;
chain_node = next_node ;
} while ( chain_node ) ;
TrNode_child ( parent_node ) = ( gt_node_ptr ) hash ;
} else {
TrNode_child ( parent_node ) = child_node ;
}
UNLOCK_GLOBAL_NODE ( parent_node ) ;
return child_node ;
}
{ /* trie nodes with hashing */
gt_hash_ptr hash ;
gt_node_ptr * bucket ;
int count_nodes = 0 ;
hash = ( gt_hash_ptr ) child_node ;
bucket = Hash_buckets ( hash ) + HASH_ENTRY ( t , Hash_num_buckets ( hash ) ) ;
child_node = * bucket ;
while ( child_node ) {
if ( TrNode_entry ( child_node ) = = t ) {
UNLOCK_GLOBAL_NODE ( parent_node ) ;
return child_node ;
}
count_nodes + + ;
child_node = TrNode_next ( child_node ) ;
}
NEW_GLOBAL_TRIE_NODE ( child_node , t , NULL , parent_node , * bucket ) ;
* bucket = child_node ;
Hash_num_nodes ( hash ) + + ;
count_nodes + + ;
if ( count_nodes > = MAX_NODES_PER_BUCKET & & Hash_num_nodes ( hash ) > Hash_num_buckets ( hash ) ) {
/* expand current hash */
gt_node_ptr chain_node , next_node , * old_bucket , * old_hash_buckets , * new_hash_buckets ;
int num_buckets ;
num_buckets = Hash_num_buckets ( hash ) * 2 ;
ALLOC_BUCKETS ( new_hash_buckets , num_buckets ) ;
old_hash_buckets = Hash_buckets ( hash ) ;
old_bucket = old_hash_buckets + Hash_num_buckets ( hash ) ;
do {
if ( * - - old_bucket ) {
chain_node = * old_bucket ;
do {
bucket = new_hash_buckets + HASH_ENTRY ( TrNode_entry ( chain_node ) , num_buckets ) ;
next_node = TrNode_next ( chain_node ) ;
TrNode_next ( chain_node ) = * bucket ;
* bucket = chain_node ;
chain_node = next_node ;
} while ( chain_node ) ;
}
} while ( old_bucket ! = old_hash_buckets ) ;
Hash_buckets ( hash ) = new_hash_buckets ;
Hash_num_buckets ( hash ) = num_buckets ;
FREE_BUCKETS ( old_hash_buckets ) ;
}
UNLOCK_GLOBAL_NODE ( parent_node ) ;
return child_node ;
}
}
# else /* GLOBAL_TRIE_LOCK_AT_WRITE_LEVEL */
# ifdef MODE_GLOBAL_TRIE_ENTRY
static inline gt_node_ptr global_trie_check_insert_gt_entry ( gt_node_ptr parent_node , Term t USES_REGS ) {
# else
static inline gt_node_ptr global_trie_check_insert_entry ( gt_node_ptr parent_node , Term t USES_REGS ) {
# endif /* MODE_GLOBAL_TRIE_ENTRY */
gt_node_ptr child_node ;
gt_hash_ptr hash ;
child_node = TrNode_child ( parent_node ) ;
if ( child_node = = NULL ) {
# ifdef GLOBAL_TRIE_ALLOC_BEFORE_CHECK
NEW_GLOBAL_TRIE_NODE ( child_node , t , NULL , parent_node , NULL ) ;
# endif /* GLOBAL_TRIE_ALLOC_BEFORE_CHECK */
LOCK_GLOBAL_NODE ( parent_node ) ;
if ( TrNode_child ( parent_node ) ) {
gt_node_ptr chain_node = TrNode_child ( parent_node ) ;
if ( IS_GLOBAL_TRIE_HASH ( chain_node ) ) {
# ifdef GLOBAL_TRIE_ALLOC_BEFORE_CHECK
FREE_GLOBAL_TRIE_NODE ( child_node ) ;
# endif /* GLOBAL_TRIE_ALLOC_BEFORE_CHECK */
UNLOCK_GLOBAL_NODE ( parent_node ) ;
hash = ( gt_hash_ptr ) chain_node ;
goto global_trie_hash ;
}
do {
if ( TrNode_entry ( chain_node ) = = t ) {
# ifdef GLOBAL_TRIE_ALLOC_BEFORE_CHECK
FREE_GLOBAL_TRIE_NODE ( child_node ) ;
# endif /* GLOBAL_TRIE_ALLOC_BEFORE_CHECK */
UNLOCK_GLOBAL_NODE ( parent_node ) ;
return chain_node ;
}
chain_node = TrNode_next ( chain_node ) ;
} while ( chain_node ) ;
# ifdef GLOBAL_TRIE_ALLOC_BEFORE_CHECK
TrNode_next ( child_node ) = TrNode_child ( parent_node ) ;
# else
NEW_GLOBAL_TRIE_NODE ( child_node , t , NULL , parent_node , TrNode_child ( parent_node ) ) ;
} else {
NEW_GLOBAL_TRIE_NODE ( child_node , t , NULL , parent_node , NULL ) ;
# endif /* GLOBAL_TRIE_ALLOC_BEFORE_CHECK */
}
TrNode_child ( parent_node ) = child_node ;
UNLOCK_GLOBAL_NODE ( parent_node ) ;
return child_node ;
}
if ( ! IS_GLOBAL_TRIE_HASH ( child_node ) ) {
gt_node_ptr first_node = child_node ;
int count_nodes = 0 ;
do {
if ( TrNode_entry ( child_node ) = = t )
return child_node ;
count_nodes + + ;
child_node = TrNode_next ( child_node ) ;
} while ( child_node ) ;
# ifdef GLOBAL_TRIE_ALLOC_BEFORE_CHECK
NEW_GLOBAL_TRIE_NODE ( child_node , t , NULL , parent_node , first_node ) ;
# endif /* GLOBAL_TRIE_ALLOC_BEFORE_CHECK */
LOCK_GLOBAL_NODE ( parent_node ) ;
if ( first_node ! = TrNode_child ( parent_node ) ) {
gt_node_ptr chain_node = TrNode_child ( parent_node ) ;
if ( IS_GLOBAL_TRIE_HASH ( chain_node ) ) {
# ifdef GLOBAL_TRIE_ALLOC_BEFORE_CHECK
FREE_GLOBAL_TRIE_NODE ( child_node ) ;
# endif /* GLOBAL_TRIE_ALLOC_BEFORE_CHECK */
UNLOCK_GLOBAL_NODE ( parent_node ) ;
hash = ( gt_hash_ptr ) chain_node ;
goto global_trie_hash ;
}
do {
if ( TrNode_entry ( chain_node ) = = t ) {
# ifdef GLOBAL_TRIE_ALLOC_BEFORE_CHECK
FREE_GLOBAL_TRIE_NODE ( child_node ) ;
# endif /* GLOBAL_TRIE_ALLOC_BEFORE_CHECK */
UNLOCK_GLOBAL_NODE ( parent_node ) ;
return chain_node ;
}
count_nodes + + ;
chain_node = TrNode_next ( chain_node ) ;
} while ( chain_node ! = first_node ) ;
# ifdef GLOBAL_TRIE_ALLOC_BEFORE_CHECK
TrNode_next ( child_node ) = TrNode_child ( parent_node ) ;
# else
NEW_GLOBAL_TRIE_NODE ( child_node , t , NULL , parent_node , TrNode_child ( parent_node ) ) ;
} else {
NEW_GLOBAL_TRIE_NODE ( child_node , t , NULL , parent_node , first_node ) ;
# endif /* GLOBAL_TRIE_ALLOC_BEFORE_CHECK */
}
count_nodes + + ;
if ( count_nodes > = MAX_NODES_PER_TRIE_LEVEL ) {
/* alloc a new hash */
gt_node_ptr chain_node , next_node , * bucket ;
new_global_trie_hash ( hash , count_nodes ) ;
chain_node = child_node ;
do {
bucket = Hash_buckets ( hash ) + HASH_ENTRY ( TrNode_entry ( chain_node ) , BASE_HASH_BUCKETS ) ;
next_node = TrNode_next ( chain_node ) ;
TrNode_next ( chain_node ) = * bucket ;
* bucket = chain_node ;
chain_node = next_node ;
} while ( chain_node ) ;
TrNode_child ( parent_node ) = ( gt_node_ptr ) hash ;
} else {
TrNode_child ( parent_node ) = child_node ;
}
UNLOCK_GLOBAL_NODE ( parent_node ) ;
return child_node ;
}
hash = ( gt_hash_ptr ) child_node ;
global_trie_hash :
{ /* trie nodes with hashing */
gt_node_ptr * bucket , first_node ;
int num_buckets , count_nodes = 0 ;
do {
num_buckets = Hash_num_buckets ( hash ) ;
// __sync_synchronize();
bucket = Hash_buckets ( hash ) + HASH_ENTRY ( t , num_buckets ) ;
first_node = child_node = * bucket ;
} while ( num_buckets ! = Hash_num_buckets ( hash ) ) ;
while ( child_node ) {
if ( TrNode_entry ( child_node ) = = t )
return child_node ;
count_nodes + + ;
child_node = TrNode_next ( child_node ) ;
}
# ifdef GLOBAL_TRIE_ALLOC_BEFORE_CHECK
NEW_GLOBAL_TRIE_NODE ( child_node , t , NULL , parent_node , first_node ) ;
# endif /* GLOBAL_TRIE_ALLOC_BEFORE_CHECK */
LOCK_GLOBAL_NODE ( parent_node ) ;
if ( num_buckets ! = Hash_num_buckets ( hash ) ) {
/* the hash has been expanded */
# ifdef GLOBAL_TRIE_ALLOC_BEFORE_CHECK
FREE_GLOBAL_TRIE_NODE ( child_node ) ;
# endif /* GLOBAL_TRIE_ALLOC_BEFORE_CHECK */
UNLOCK_GLOBAL_NODE ( parent_node ) ;
goto global_trie_hash ;
}
if ( first_node ! = * bucket ) {
gt_node_ptr chain_node = * bucket ;
do {
if ( TrNode_entry ( chain_node ) = = t ) {
# ifdef GLOBAL_TRIE_ALLOC_BEFORE_CHECK
FREE_GLOBAL_TRIE_NODE ( child_node ) ;
# endif /* GLOBAL_TRIE_ALLOC_BEFORE_CHECK */
UNLOCK_GLOBAL_NODE ( parent_node ) ;
return chain_node ;
}
count_nodes + + ;
chain_node = TrNode_next ( chain_node ) ;
} while ( chain_node ! = first_node ) ;
# ifdef GLOBAL_TRIE_ALLOC_BEFORE_CHECK
TrNode_next ( child_node ) = * bucket ;
# else
NEW_GLOBAL_TRIE_NODE ( child_node , t , NULL , parent_node , * bucket ) ;
} else {
NEW_GLOBAL_TRIE_NODE ( child_node , t , NULL , parent_node , first_node ) ;
# endif /* GLOBAL_TRIE_ALLOC_BEFORE_CHECK */
}
* bucket = child_node ;
Hash_num_nodes ( hash ) + + ;
count_nodes + + ;
if ( count_nodes > = MAX_NODES_PER_BUCKET & & Hash_num_nodes ( hash ) > Hash_num_buckets ( hash ) ) {
/* expand current hash */
gt_node_ptr chain_node , next_node , * old_bucket , * old_hash_buckets , * new_hash_buckets ;
num_buckets = Hash_num_buckets ( hash ) * 2 ;
ALLOC_BUCKETS ( new_hash_buckets , num_buckets ) ;
old_hash_buckets = Hash_buckets ( hash ) ;
old_bucket = old_hash_buckets + Hash_num_buckets ( hash ) ;
do {
if ( * - - old_bucket ) {
chain_node = * old_bucket ;
do {
bucket = new_hash_buckets + HASH_ENTRY ( TrNode_entry ( chain_node ) , num_buckets ) ;
next_node = TrNode_next ( chain_node ) ;
TrNode_next ( chain_node ) = * bucket ;
* bucket = chain_node ;
chain_node = next_node ;
} while ( chain_node ) ;
}
} while ( old_bucket ! = old_hash_buckets ) ;
Hash_buckets ( hash ) = new_hash_buckets ;
Hash_num_buckets ( hash ) = num_buckets ;
FREE_BUCKETS ( old_hash_buckets ) ;
}
UNLOCK_GLOBAL_NODE ( parent_node ) ;
return child_node ;
}
}
# endif /* GLOBAL_TRIE_LOCK_LEVEL */
# endif /* INCLUDE_GLOBAL_TRIE_CHECK_INSERT */
/************************************************************************
* * subgoal_search ( _global_trie ) ( _terms ) _loop * *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
# ifdef INCLUDE_SUBGOAL_SEARCH_LOOP
# ifdef MODE_GLOBAL_TRIE_LOOP
# ifdef GLOBAL_TRIE_FOR_SUBTERMS
static inline gt_node_ptr subgoal_search_global_trie_terms_loop ( Term t , int * subs_arity_ptr , CELL * * stack_vars_ptr , CELL * stack_terms USES_REGS ) {
# else
static inline gt_node_ptr subgoal_search_global_trie_loop ( Term t , int * subs_arity_ptr , CELL * * stack_vars_ptr USES_REGS ) {
# endif /* GLOBAL_TRIE_FOR_SUBTERMS */
# else
# ifdef MODE_TERMS_LOOP
static inline sg_node_ptr subgoal_search_terms_loop ( tab_ent_ptr tab_ent , sg_node_ptr current_node , Term t , int * subs_arity_ptr , CELL * * stack_vars_ptr USES_REGS ) {
# else
static inline sg_node_ptr subgoal_search_loop ( tab_ent_ptr tab_ent , sg_node_ptr current_node , Term t , int * subs_arity_ptr , CELL * * stack_vars_ptr USES_REGS ) {
# endif /* MODE_TERMS_LOOP */
# endif /* MODE_GLOBAL_TRIE_LOOP */
/************************************************************************
= = = = = = = = = = =
| |
| . . . |
| |
- - - - - - - - - - -
| VAR_N | < - - stack_vars
- - - - - - - - - - - *
| . . . | / | \
- - - - - - - - - - - | subs_arity ( N + 1 )
| VAR_0 | \ | /
- - - - - - - - - - - *
YENV - - > | |
- - - - - - - - - - -
| |
| . . . |
| |
= = = = = = = = = = =
| |
| . . . |
| |
- - - - - - - - - - -
TR - - > | | < - - stack_terms_limit
- - - - - - - - - - -
| |
| . . . |
| |
- - - - - - - - - - |
| TERM_N | < - - stack_terms
- - - - - - - - - - | *
| . . . | / | \
- - - - - - - - - - | |
| TERM_1 | |
- - - - - - - - - - | |
| NULL | \ | /
= = = = = = = = = = = *
LOCAL_TrailTop - - > | |
- - - - - - - - - - -
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
# ifdef MODE_GLOBAL_TRIE_LOOP
gt_node_ptr current_node = GLOBAL_root_gt ;
# endif /* MODE_GLOBAL_TRIE_LOOP */
int subs_arity = * subs_arity_ptr ;
CELL * stack_vars = * stack_vars_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_terms_limit = ( CELL * ) TR ;
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 subgoal_search_loop_non_atomic ;
# endif /* MODE_GLOBAL_TRIE_LOOP */
# ifdef TRIE_RATIONAL_TERMS
/* Needed structures, variables to support rational terms */
term_array Ts ;
void * CyclicTerm ;
term_array_init ( & Ts , 10 ) ;
# endif /* RATIONAL TERM SUPPORT FOR TRIES */
do {
if ( IsVarTerm ( t ) ) {
if ( IsTableVarTerm ( t ) ) {
t = MakeTableVarTerm ( VarIndexOfTerm ( t ) ) ;
SUBGOAL_CHECK_INSERT_ENTRY ( tab_ent , current_node , t ) ;
} else {
if ( subs_arity = = MAX_TABLE_VARS )
2015-09-25 10:57:26 +01:00
Yap_Error ( SYSTEM_ERROR_INTERNAL , TermNil , " subgoal_search_loop: MAX_TABLE_VARS exceeded " ) ;
2015-01-26 07:38:36 +00:00
STACK_PUSH_UP ( t , stack_vars ) ;
* ( ( CELL * ) t ) = GLOBAL_table_var_enumerator ( subs_arity ) ;
t = MakeTableVarTerm ( subs_arity ) ;
subs_arity = subs_arity + 1 ;
SUBGOAL_CHECK_INSERT_ENTRY ( tab_ent , current_node , t ) ;
}
} else if ( IsAtomOrIntTerm ( t ) ) {
SUBGOAL_CHECK_INSERT_ENTRY ( tab_ent , current_node , t ) ;
# ifdef MODE_TERMS_LOOP
} else {
gt_node_ptr entry_node ;
# ifdef GLOBAL_TRIE_FOR_SUBTERMS
entry_node = subgoal_search_global_trie_terms_loop ( t , & subs_arity , & stack_vars , stack_terms PASS_REGS ) ;
# else
entry_node = subgoal_search_global_trie_loop ( t , & subs_arity , & stack_vars PASS_REGS ) ;
# endif /* GLOBAL_TRIE_FOR_SUBTERMS */
current_node = subgoal_trie_check_insert_gt_entry ( tab_ent , current_node , ( Term ) entry_node PASS_REGS ) ;
# else /* ! MODE_TERMS_LOOP */
} else
# ifdef TRIE_RATIONAL_TERMS
if ( IsRationalTerm ( t ) ) {
t = STACK_POP_DOWN ( stack_terms ) ;
SUBGOAL_CHECK_INSERT_ENTRY ( tab_ent , current_node , t ) ;
} else
# endif /* RATIONAL TERM SUPPORT FOR TRIES */
# if defined(MODE_GLOBAL_TRIE_LOOP)
/* for the global trie, it is safe to start here in the first iteration */
subgoal_search_loop_non_atomic :
# endif /* MODE_GLOBAL_TRIE_LOOP */
# ifdef TRIE_COMPACT_PAIRS
if ( IsPairTerm ( t ) ) {
# ifdef TRIE_RATIONAL_TERMS
CyclicTerm = NULL ;
# endif /* RATIONAL TERM SUPPORT FOR TRIES */
CELL * aux_pair = RepPair ( t ) ;
if ( aux_pair = = PairTermMark ) {
t = STACK_POP_DOWN ( stack_terms ) ;
# ifdef TRIE_RATIONAL_TERMS
if ( IsPairTerm ( t ) & & ! IsRationalTerm ( t ) ) {
term_array_push ( & Ts , ( void * ) t , ( void * ) current_node ) ;
# else
if ( IsPairTerm ( t ) ) {
# endif /* RATIONAL TERM SUPPORT FOR TRIES */
aux_pair = RepPair ( t ) ;
t = Deref ( aux_pair [ 1 ] ) ;
# ifdef TRIE_RATIONAL_TERMS
if ( IsVarTerm ( aux_pair [ 1 ] ) | | IsPairTerm ( aux_pair [ 1 ] ) ) {
CyclicTerm = term_array_member ( Ts , ( void * ) t ) ;
}
if ( CyclicTerm ! = NULL ) {
STACK_PUSH_UP ( ( Term ) CyclicTerm , stack_terms ) ;
STACK_PUSH_UP ( ( Term ) RationalMark , stack_terms ) ;
STACK_PUSH_UP ( AbsPair ( PairTermMark ) , stack_terms ) ;
} else
# endif /* RATIONAL TERM SUPPORT FOR TRIES */
if ( t = = TermNil ) {
SUBGOAL_CHECK_INSERT_ENTRY ( tab_ent , current_node , CompactPairEndList ) ;
} 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 ) ;
}
# ifdef TRIE_RATIONAL_TERMS
CyclicTerm = NULL ;
if ( IsVarTerm ( aux_pair [ 0 ] ) | | IsPairTerm ( aux_pair [ 0 ] ) )
CyclicTerm = term_array_member ( Ts , ( void * ) Deref ( aux_pair [ 0 ] ) ) ;
if ( CyclicTerm ! = NULL ) {
STACK_PUSH_UP ( ( Term ) CyclicTerm , stack_terms ) ;
STACK_PUSH_UP ( ( Term ) RationalMark , stack_terms ) ;
} else
# endif /* RATIONAL TERM SUPPORT FOR TRIES */
STACK_PUSH_UP ( Deref ( aux_pair [ 0 ] ) , stack_terms ) ;
} else {
SUBGOAL_CHECK_INSERT_ENTRY ( tab_ent , current_node , CompactPairEndTerm ) ;
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 = subgoal_search_global_trie_terms_loop ( t , & subs_arity , & stack_vars , stack_terms PASS_REGS ) ;
current_node = global_trie_check_insert_gt_entry ( current_node , ( Term ) entry_node PASS_REGS ) ;
# endif /* MODE_GLOBAL_TRIE_LOOP && GLOBAL_TRIE_FOR_SUBTERMS */
} else {
# ifdef TRIE_RATIONAL_TERMS
term_array_push ( & Ts , ( void * ) t , ( void * ) current_node ) ;
# endif /* RATIONAL TERM SUPPORT FOR TRIES */
SUBGOAL_CHECK_INSERT_ENTRY ( tab_ent , current_node , CompactPairInit ) ;
t = Deref ( aux_pair [ 1 ] ) ;
# ifdef TRIE_RATIONAL_TERMS
if ( IsVarTerm ( aux_pair [ 1 ] ) | | IsPairTerm ( aux_pair [ 1 ] ) ) {
CyclicTerm = term_array_member ( Ts , ( void * ) t ) ;
}
if ( CyclicTerm ! = NULL ) {
STACK_PUSH_UP ( ( Term ) CyclicTerm , stack_terms ) ;
STACK_PUSH_UP ( ( Term ) RationalMark , stack_terms ) ;
STACK_PUSH_UP ( AbsPair ( PairTermMark ) , stack_terms ) ;
} else
# endif /* RATIONAL TERM SUPPORT FOR TRIES */
if ( t = = TermNil ) {
SUBGOAL_CHECK_INSERT_ENTRY ( tab_ent , current_node , CompactPairEndList ) ;
} else {
AUX_STACK_CHECK_EXPAND ( stack_terms , stack_terms_limit + 2 ) ;
STACK_PUSH_UP ( t , stack_terms ) ;
STACK_PUSH_UP ( AbsPair ( PairTermMark ) , stack_terms ) ;
}
# ifdef TRIE_RATIONAL_TERMS
CyclicTerm = NULL ;
if ( IsVarTerm ( aux_pair [ 0 ] ) | | IsPairTerm ( aux_pair [ 0 ] ) )
CyclicTerm = term_array_member ( Ts , ( void * ) Deref ( aux_pair [ 0 ] ) ) ;
if ( CyclicTerm ! = NULL ) {
STACK_PUSH_UP ( ( Term ) CyclicTerm , stack_terms ) ;
STACK_PUSH_UP ( ( Term ) RationalMark , stack_terms ) ;
} else
# endif /* RATIONAL TERM SUPPORT FOR TRIES */
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 = subgoal_search_global_trie_terms_loop ( t , & subs_arity , & stack_vars , stack_terms PASS_REGS ) ;
current_node = global_trie_check_insert_gt_entry ( current_node , ( Term ) entry_node PASS_REGS ) ;
# 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 = subgoal_search_global_trie_terms_loop ( t , & subs_arity , & stack_vars , stack_terms PASS_REGS ) ;
current_node = global_trie_check_insert_gt_entry ( current_node , ( Term ) entry_node PASS_REGS ) ;
} else
# endif /* MODE_GLOBAL_TRIE_LOOP && GLOBAL_TRIE_FOR_SUBTERMS */
if ( IsPairTerm ( t ) ) {
CELL * aux_pair = RepPair ( t ) ;
SUBGOAL_CHECK_INSERT_ENTRY ( tab_ent , current_node , AbsPair ( NULL ) ) ;
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 ) ;
SUBGOAL_CHECK_INSERT_ENTRY ( tab_ent , current_node , AbsAppl ( ( Term * ) f ) ) ;
# if SIZEOF_DOUBLE == 2 * SIZEOF_INT_P
SUBGOAL_CHECK_INSERT_ENTRY ( tab_ent , current_node , u . t_dbl [ 1 ] ) ;
# endif /* SIZEOF_DOUBLE x SIZEOF_INT_P */
SUBGOAL_CHECK_INSERT_ENTRY ( tab_ent , current_node , u . t_dbl [ 0 ] ) ;
# ifdef MODE_GLOBAL_TRIE_LOOP
SUBGOAL_CHECK_INSERT_ENTRY ( tab_ent , current_node , AbsAppl ( ( Term * ) f ) ) ;
# endif /* MODE_GLOBAL_TRIE_LOOP */
} else if ( f = = FunctorLongInt ) {
Int li = LongIntOfTerm ( t ) ;
SUBGOAL_CHECK_INSERT_ENTRY ( tab_ent , current_node , AbsAppl ( ( Term * ) f ) ) ;
SUBGOAL_CHECK_INSERT_ENTRY ( tab_ent , current_node , li ) ;
# ifdef MODE_GLOBAL_TRIE_LOOP
SUBGOAL_CHECK_INSERT_ENTRY ( tab_ent , current_node , AbsAppl ( ( Term * ) f ) ) ;
# endif /* MODE_GLOBAL_TRIE_LOOP */
} else if ( f = = FunctorBigInt | | f = = FunctorString ) {
CELL * new = Yap_HeapStoreOpaqueTerm ( t ) ;
SUBGOAL_CHECK_INSERT_ENTRY ( tab_ent , current_node , AbsAppl ( ( Term * ) f ) ) ;
SUBGOAL_CHECK_INSERT_ENTRY ( tab_ent , current_node , ( CELL ) new ) ;
# ifdef MODE_GLOBAL_TRIE_LOOP
SUBGOAL_CHECK_INSERT_ENTRY ( tab_ent , current_node , AbsAppl ( ( Term * ) f ) ) ;
# endif /* MODE_GLOBAL_TRIE_LOOP */
} else if ( f = = FunctorDBRef ) {
2015-09-25 10:57:26 +01:00
Yap_Error ( SYSTEM_ERROR_INTERNAL , TermNil , " subgoal_search_loop: unsupported type tag FunctorDBRef " ) ;
2015-01-26 07:38:36 +00:00
} else {
# ifdef TRIE_RATIONAL_TERMS
term_array_push ( & Ts , ( void * ) t , ( void * ) current_node ) ;
# endif /* RATIONAL TERM SUPPORT FOR TRIES */
int i ;
CELL * aux_appl = RepAppl ( t ) ;
SUBGOAL_CHECK_INSERT_ENTRY ( tab_ent , current_node , AbsAppl ( ( Term * ) f ) ) ;
AUX_STACK_CHECK_EXPAND ( stack_terms , stack_terms_limit + ArityOfFunctor ( f ) - 1 ) ;
for ( i = ArityOfFunctor ( f ) ; i > = 1 ; i - - ) {
# ifdef TRIE_RATIONAL_TERMS
CyclicTerm = NULL ;
if ( IsVarTerm ( aux_appl [ i ] ) | | IsApplTerm ( aux_appl [ i ] ) )
CyclicTerm = term_array_member ( Ts , ( void * ) Deref ( aux_appl [ i ] ) ) ;
if ( CyclicTerm ! = NULL ) {
STACK_PUSH_UP ( ( Term ) CyclicTerm , stack_terms ) ;
STACK_PUSH_UP ( ( Term ) RationalMark , stack_terms ) ;
} else
# endif /* RATIONAL TERM SUPPORT FOR TRIES */
STACK_PUSH_UP ( Deref ( aux_appl [ i ] ) , stack_terms ) ;
}
}
} else {
2015-09-25 10:57:26 +01:00
Yap_Error ( SYSTEM_ERROR_INTERNAL , TermNil , " subgoal_search_loop: unknown type tag " ) ;
2015-01-26 07:38:36 +00:00
# endif /* MODE_TERMS_LOOP */
}
t = STACK_POP_DOWN ( stack_terms ) ;
} while ( t ) ;
# ifdef TRIE_RATIONAL_TERMS
term_array_free ( & Ts ) ;
# endif /* RATIONAL TERM SUPPORT FOR TRIES */
* subs_arity_ptr = subs_arity ;
* stack_vars_ptr = stack_vars ;
return current_node ;
}
# endif /* INCLUDE_SUBGOAL_SEARCH_LOOP */
/************************************************************************
* * answer_search ( _global_trie ) ( _terms ) _loop * *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
# ifdef INCLUDE_ANSWER_SEARCH_LOOP
# ifdef MODE_GLOBAL_TRIE_LOOP
# ifdef GLOBAL_TRIE_FOR_SUBTERMS
static inline gt_node_ptr answer_search_global_trie_terms_loop ( Term t , int * vars_arity_ptr , CELL * stack_terms USES_REGS ) {
# else
static inline gt_node_ptr answer_search_global_trie_loop ( Term t , int * vars_arity_ptr USES_REGS ) {
# endif /* GLOBAL_TRIE_FOR_SUBTERMS */
# else
# ifdef MODE_TERMS_LOOP
static inline ans_node_ptr answer_search_terms_loop ( sg_fr_ptr sg_fr , ans_node_ptr current_node , Term t , int * vars_arity_ptr USES_REGS ) {
# else
static inline ans_node_ptr answer_search_loop ( sg_fr_ptr sg_fr , ans_node_ptr current_node , Term t , int * vars_arity_ptr USES_REGS ) {
# endif /* MODE_TERMS_LOOP */
# endif /* MODE_GLOBAL_TRIE_LOOP */
/************************************************************************
= = = = = = = = = = =
| |
| . . . |
| |
- - - - - - - - - - -
TR - - > | VAR_0 | < - - stack_vars_base
- - - - - - - - - - - *
| . . . | / | \
- - - - - - - - - - - | vars_arity ( N + 1 )
| VAR_N | \ | /
- - - - - - - - - - - *
| | < - - stack_terms_limit
- - - - - - - - - - -
| |
| . . . |
| |
- - - - - - - - - - |
| TERM_N | < - - stack_terms
- - - - - - - - - - | *
| . . . | / | \
- - - - - - - - - - | |
| TERM_1 | |
- - - - - - - - - - | |
| NULL | \ | /
= = = = = = = = = = = *
LOCAL_TrailTop - - > | |
- - - - - - - - - - -
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
# 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 */
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 */
# ifdef TRIE_RATIONAL_TERMS
term_array Ts ;
void * CyclicTerm ;
term_array_init ( & Ts , 10 ) ;
# endif /* RATIONAL TERM SUPPORT FOR TRIES */
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 )
2015-09-25 10:57:26 +01:00
Yap_Error ( SYSTEM_ERROR_INTERNAL , TermNil , " answer_search_loop: MAX_TABLE_VARS exceeded " ) ;
2015-01-26 07:38:36 +00:00
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 ) ;
vars_arity = vars_arity + 1 ;
}
# ifdef TRIE_COMPACT_PAIRS
in_pair = 0 ;
# endif /* TRIE_COMPACT_PAIRS */
} else if ( IsAtomOrIntTerm ( t ) ) {
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 PASS_REGS ) ;
# else
entry_node = answer_search_global_trie_loop ( t , & vars_arity PASS_REGS ) ;
# 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 PASS_REGS ) ;
# else /* ! MODE_TERMS_LOOP */
} else
# ifdef TRIE_RATIONAL_TERMS
if ( IsRationalTerm ( t ) ) {
t = STACK_POP_DOWN ( stack_terms ) ;
ANSWER_CHECK_INSERT_ENTRY ( sg_fr , current_node , t , _trie_retry_var + in_pair ) ; //TODO create _trie_.._rational
} else
# endif /* RATIONAL TERM SUPPORT FOR TRIES */
# 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 ) ) {
# ifdef TRIE_RATIONAL_TERMS
CyclicTerm = NULL ;
# endif /* RATIONAL TERM SUPPORT FOR TRIES */
CELL * aux_pair = RepPair ( t ) ;
if ( aux_pair = = PairTermMark ) {
t = STACK_POP_DOWN ( stack_terms ) ;
# ifdef TRIE_RATIONAL_TERMS
if ( IsPairTerm ( t ) & & ! IsRationalTerm ( t ) ) {
term_array_push ( & Ts , ( void * ) t , ( void * ) current_node ) ;
# else
if ( IsPairTerm ( t ) ) {
# endif /* RATIONAL TERM SUPPORT FOR TRIES */
aux_pair = RepPair ( t ) ;
t = Deref ( aux_pair [ 1 ] ) ;
# ifdef TRIE_RATIONAL_TERMS
if ( IsVarTerm ( aux_pair [ 1 ] ) | | IsPairTerm ( aux_pair [ 1 ] ) ) {
CyclicTerm = term_array_member ( Ts , ( void * ) t ) ;
}
if ( CyclicTerm ! = NULL ) {
STACK_PUSH_UP ( ( Term ) CyclicTerm , stack_terms ) ; // CyclicTerm
STACK_PUSH_UP ( ( Term ) RationalMark , stack_terms ) ;
STACK_PUSH_UP ( AbsPair ( PairTermMark ) , stack_terms ) ;
in_pair = 4 ;
} else
# endif /* RATIONAL TERM SUPPORT FOR TRIES */
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 ;
}
# ifdef TRIE_RATIONAL_TERMS
CyclicTerm = NULL ;
if ( IsVarTerm ( aux_pair [ 0 ] ) | | IsPairTerm ( aux_pair [ 0 ] ) )
CyclicTerm = term_array_member ( Ts , ( void * ) Deref ( aux_pair [ 0 ] ) ) ;
if ( CyclicTerm ! = NULL ) {
STACK_PUSH_UP ( ( Term ) CyclicTerm , stack_terms ) ;
STACK_PUSH_UP ( ( Term ) RationalMark , stack_terms ) ;
} else
# endif /* RATIONAL TERM SUPPORT FOR TRIES */
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 PASS_REGS ) ;
current_node = global_trie_check_insert_gt_entry ( current_node , ( Term ) entry_node PASS_REGS ) ;
# endif /* MODE_GLOBAL_TRIE_LOOP && GLOBAL_TRIE_FOR_SUBTERMS */
} else {
# ifdef TRIE_RATIONAL_TERMS
term_array_push ( & Ts , ( void * ) t , ( void * ) current_node ) ;
# endif /* RATIONAL TERM SUPPORT FOR TRIES */
ANSWER_CHECK_INSERT_ENTRY ( sg_fr , current_node , CompactPairInit , _trie_retry_null + in_pair ) ;
t = Deref ( aux_pair [ 1 ] ) ;
# ifdef TRIE_RATIONAL_TERMS
if ( IsVarTerm ( aux_pair [ 1 ] ) | | IsPairTerm ( aux_pair [ 1 ] ) ) {
CyclicTerm = term_array_member ( Ts , ( void * ) t ) ;
}
if ( CyclicTerm ! = NULL ) {
STACK_PUSH_UP ( ( Term ) CyclicTerm , stack_terms ) ;
STACK_PUSH_UP ( ( Term ) RationalMark , stack_terms ) ;
STACK_PUSH_UP ( AbsPair ( PairTermMark ) , stack_terms ) ;
in_pair = 4 ;
} else
# endif /* RATIONAL TERM SUPPORT FOR TRIES */
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 ;
}
# ifdef TRIE_RATIONAL_TERMS
CyclicTerm = NULL ;
if ( IsVarTerm ( aux_pair [ 0 ] ) | | IsPairTerm ( aux_pair [ 0 ] ) )
CyclicTerm = term_array_member ( Ts , ( void * ) Deref ( aux_pair [ 0 ] ) ) ;
if ( CyclicTerm ! = NULL ) {
STACK_PUSH_UP ( ( Term ) CyclicTerm , stack_terms ) ;
STACK_PUSH_UP ( ( Term ) RationalMark , stack_terms ) ;
} else
# endif /* RATIONAL TERM SUPPORT FOR TRIES */
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 PASS_REGS ) ;
current_node = global_trie_check_insert_gt_entry ( current_node , ( Term ) entry_node PASS_REGS ) ;
# 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 PASS_REGS ) ;
current_node = global_trie_check_insert_gt_entry ( current_node , ( Term ) entry_node PASS_REGS ) ;
} 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 ) ;
2016-02-19 20:46:20 +00:00
} else if ( f = = FunctorBigInt | | f = = FunctorString ) {
2015-01-26 07:38:36 +00:00
CELL * opq = Yap_HeapStoreOpaqueTerm ( 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 , ( CELL ) opq , _trie_retry_extension ) ;
ANSWER_CHECK_INSERT_ENTRY ( sg_fr , current_node , AbsAppl ( ( Term * ) f ) , _trie_retry_bigint ) ;
} else if ( f = = FunctorDBRef ) {
2015-09-25 10:57:26 +01:00
Yap_Error ( SYSTEM_ERROR_INTERNAL , TermNil , " answer_search_loop: unsupported type tag FunctorDBRef " ) ;
2015-01-26 07:38:36 +00:00
} else {
# ifdef TRIE_RATIONAL_TERMS
term_array_push ( & Ts , ( void * ) t , ( void * ) current_node ) ;
# endif /* RATIONAL TERM SUPPORT FOR TRIES */
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 - - ) {
# ifdef TRIE_RATIONAL_TERMS
CyclicTerm = NULL ;
if ( IsVarTerm ( aux_appl [ i ] ) | | IsApplTerm ( aux_appl [ i ] ) )
CyclicTerm = term_array_member ( Ts , ( void * ) Deref ( aux_appl [ i ] ) ) ;
if ( CyclicTerm ! = NULL ) {
STACK_PUSH_UP ( ( Term ) CyclicTerm , stack_terms ) ;
STACK_PUSH_UP ( ( Term ) RationalMark , stack_terms ) ;
} else
# endif /* RATIONAL TERM SUPPORT FOR TRIES */
STACK_PUSH_UP ( Deref ( aux_appl [ i ] ) , stack_terms ) ;
}
}
# ifdef TRIE_COMPACT_PAIRS
in_pair = 0 ;
# endif /* TRIE_COMPACT_PAIRS */
} else {
2015-09-25 10:57:26 +01:00
Yap_Error ( SYSTEM_ERROR_INTERNAL , TermNil , " answer_search_loop: unknown type tag " ) ;
2015-01-26 07:38:36 +00:00
# endif /* MODE_TERMS_LOOP */
}
t = STACK_POP_DOWN ( stack_terms ) ;
} while ( t ) ;
# ifdef TRIE_RATIONAL_TERMS
term_array_free ( & Ts ) ;
# endif /* RATIONAL TERM SUPPORT FOR TRIES */
* vars_arity_ptr = vars_arity ;
return current_node ;
# undef stack_terms_limit
# ifndef TRIE_COMPACT_PAIRS
# undef in_pair
# endif /* TRIE_COMPACT_PAIRS */
}
# endif /* INCLUDE_ANSWER_SEARCH_LOOP */
/**************************************************************
* * answer_search_min_max * *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
# ifdef INCLUDE_ANSWER_SEARCH_MODE_DIRECTED
static inline ans_node_ptr answer_search_min_max ( sg_fr_ptr sg_fr , ans_node_ptr current_node , Term t , int mode USES_REGS ) {
ans_node_ptr child_node ;
Term child_term ;
Term trie_value = 0 , term_value = t ;
int cmp ;
/* 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 = child_term ;
} else if ( IsApplTerm ( child_term ) ) {
Functor f = ( Functor ) RepAppl ( child_term ) ;
child_node = TrNode_child ( child_node ) ;
if ( f = = FunctorLongInt ) {
trie_value = MkLongIntTerm ( ( Int ) 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 = MkFloatTerm ( u . dbl ) ;
} else if ( f = = FunctorBigInt ) {
trie_value = AbsAppl ( ( CELL * ) TrNode_entry ( child_node ) ) ;
} else
2015-09-25 10:57:26 +01:00
Yap_Error ( SYSTEM_ERROR_INTERNAL , TermNil , " answer_search_min_max: invalid arithmetic value " ) ;
2015-01-26 07:38:36 +00:00
child_node = TrNode_child ( child_node ) ;
}
cmp = Yap_acmp ( term_value , trie_value PASS_REGS ) ;
/* worse answer */
if ( ( mode = = MODE_DIRECTED_MIN & & cmp > 0 ) | | ( mode = = MODE_DIRECTED_MAX & & cmp < 0 ) )
return NULL ;
/* equal answer */
if ( cmp = = 0 )
return child_node ;
/* better answer */
if ( IsAtomOrIntTerm ( t ) ) {
ANSWER_SAFE_INSERT_ENTRY ( current_node , t , _trie_retry_atom ) ;
} 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_SAFE_INSERT_ENTRY ( current_node , AbsAppl ( ( Term * ) f ) , _trie_retry_null ) ;
# if SIZEOF_DOUBLE == 2 * SIZEOF_INT_P
ANSWER_SAFE_INSERT_ENTRY ( current_node , u . t_dbl [ 1 ] , _trie_retry_extension ) ;
# endif /* SIZEOF_DOUBLE x SIZEOF_INT_P */
ANSWER_SAFE_INSERT_ENTRY ( current_node , u . t_dbl [ 0 ] , _trie_retry_extension ) ;
ANSWER_SAFE_INSERT_ENTRY ( current_node , AbsAppl ( ( Term * ) f ) , _trie_retry_double ) ;
} else if ( f = = FunctorLongInt ) {
Int li = LongIntOfTerm ( t ) ;
ANSWER_SAFE_INSERT_ENTRY ( current_node , AbsAppl ( ( Term * ) f ) , _trie_retry_null ) ;
ANSWER_SAFE_INSERT_ENTRY ( current_node , li , _trie_retry_extension ) ;
ANSWER_SAFE_INSERT_ENTRY ( current_node , AbsAppl ( ( Term * ) f ) , _trie_retry_longint ) ;
} else if ( f = = FunctorBigInt ) {
CELL * li = Yap_HeapStoreOpaqueTerm ( t ) ;
ANSWER_SAFE_INSERT_ENTRY ( current_node , AbsAppl ( ( Term * ) f ) , _trie_retry_null ) ;
ANSWER_SAFE_INSERT_ENTRY ( current_node , ( CELL ) li , _trie_retry_extension ) ;
ANSWER_SAFE_INSERT_ENTRY ( current_node , AbsAppl ( ( Term * ) f ) , _trie_retry_bigint ) ;
}
}
return current_node ;
}
# endif /* INCLUDE_ANSWER_SEARCH_MODE_DIRECTED */
/**********************************************************
* * answer_search_sum * *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
# ifdef INCLUDE_ANSWER_SEARCH_MODE_DIRECTED
static inline ans_node_ptr answer_search_sum ( sg_fr_ptr sg_fr , ans_node_ptr current_node , Term t USES_REGS ) {
ans_node_ptr child_node ;
Term child_term ;
Term trie_value = 0 , term_value = t , sum_value = 0 ;
/* 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 = child_term ;
} else if ( IsApplTerm ( child_term ) ) {
Functor f = ( Functor ) RepAppl ( child_term ) ;
child_node = TrNode_child ( child_node ) ;
if ( f = = FunctorLongInt ) {
trie_value = MkLongIntTerm ( ( Int ) 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 = MkFloatTerm ( u . dbl ) ;
} else if ( f = = FunctorBigInt ) {
trie_value = AbsAppl ( ( CELL * ) TrNode_entry ( child_node ) ) ;
} else
2015-09-25 10:57:26 +01:00
Yap_Error ( SYSTEM_ERROR_INTERNAL , TermNil , " answer_search_min_max: invalid arithmetic value " ) ;
2015-01-26 07:38:36 +00:00
child_node = TrNode_child ( child_node ) ;
}
sum_value = p_plus ( trie_value , term_value PASS_REGS ) ;
if ( IsAtomOrIntTerm ( sum_value ) ) {
ANSWER_SAFE_INSERT_ENTRY ( current_node , sum_value , _trie_retry_atom ) ;
} else if ( IsApplTerm ( sum_value ) ) {
Functor f = FunctorOfTerm ( sum_value ) ;
if ( f = = FunctorDouble ) {
union {
Term t_dbl [ sizeof ( Float ) / sizeof ( Term ) ] ;
Float dbl ;
} u ;
u . dbl = FloatOfTerm ( sum_value ) ;
ANSWER_SAFE_INSERT_ENTRY ( current_node , AbsAppl ( ( Term * ) f ) , _trie_retry_null ) ;
# if SIZEOF_DOUBLE == 2 * SIZEOF_INT_P
ANSWER_SAFE_INSERT_ENTRY ( current_node , u . t_dbl [ 1 ] , _trie_retry_extension ) ;
# endif /* SIZEOF_DOUBLE x SIZEOF_INT_P */
ANSWER_SAFE_INSERT_ENTRY ( current_node , u . t_dbl [ 0 ] , _trie_retry_extension ) ;
ANSWER_SAFE_INSERT_ENTRY ( current_node , AbsAppl ( ( Term * ) f ) , _trie_retry_double ) ;
} else if ( f = = FunctorLongInt ) {
Int li = LongIntOfTerm ( sum_value ) ;
ANSWER_SAFE_INSERT_ENTRY ( current_node , AbsAppl ( ( Term * ) f ) , _trie_retry_null ) ;
ANSWER_SAFE_INSERT_ENTRY ( current_node , li , _trie_retry_extension ) ;
ANSWER_SAFE_INSERT_ENTRY ( current_node , AbsAppl ( ( Term * ) f ) , _trie_retry_longint ) ;
} else if ( f = = FunctorBigInt ) {
CELL * li = Yap_HeapStoreOpaqueTerm ( sum_value ) ;
ANSWER_SAFE_INSERT_ENTRY ( current_node , AbsAppl ( ( Term * ) f ) , _trie_retry_null ) ;
ANSWER_SAFE_INSERT_ENTRY ( current_node , ( CELL ) li , _trie_retry_extension ) ;
ANSWER_SAFE_INSERT_ENTRY ( current_node , AbsAppl ( ( Term * ) f ) , _trie_retry_bigint ) ;
}
}
return current_node ;
}
# endif /* INCLUDE_ANSWER_SEARCH_MODE_DIRECTED */
/***************************************************************
* * invalidate_answer_trie * *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
# ifdef INCLUDE_ANSWER_SEARCH_MODE_DIRECTED
static void invalidate_answer_trie ( ans_node_ptr current_node , sg_fr_ptr sg_fr , int position USES_REGS ) {
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_LEAF_NODE ( current_node , sg_fr ) ;
} else {
invalidate_answer_trie ( TrNode_child ( current_node ) , sg_fr , TRAVERSE_POSITION_FIRST PASS_REGS ) ;
INVALIDATE_ANSWER_TRIE_NODE ( current_node , sg_fr ) ;
}
while ( next_node ) {
current_node = next_node ;
next_node = TrNode_next ( current_node ) ;
invalidate_answer_trie ( current_node , sg_fr , TRAVERSE_POSITION_NEXT PASS_REGS ) ;
}
}
} 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_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_LEAF_NODE ( current_node , sg_fr ) ;
} else {
invalidate_answer_trie ( TrNode_child ( current_node ) , sg_fr , TRAVERSE_POSITION_FIRST PASS_REGS ) ;
INVALIDATE_ANSWER_TRIE_NODE ( current_node , sg_fr ) ;
}
while ( next_node ) {
current_node = next_node ;
next_node = TrNode_next ( current_node ) ;
invalidate_answer_trie ( current_node , sg_fr , TRAVERSE_POSITION_NEXT PASS_REGS ) ;
}
} else {
if ( IS_ANSWER_LEAF_NODE ( current_node ) ) {
INVALIDATE_ANSWER_TRIE_LEAF_NODE ( current_node , sg_fr ) ;
} else {
invalidate_answer_trie ( TrNode_child ( current_node ) , sg_fr , TRAVERSE_POSITION_FIRST PASS_REGS ) ;
INVALIDATE_ANSWER_TRIE_NODE ( current_node , sg_fr ) ;
}
}
}
return ;
}
# endif /* INCLUDE_ANSWER_SEARCH_MODE_DIRECTED */
/************************************************************************
* * load_ ( answer | substitution ) _loop * *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
# ifdef INCLUDE_LOAD_ANSWER_LOOP
# ifdef MODE_GLOBAL_TRIE_LOOP
static inline CELL * load_substitution_loop ( gt_node_ptr current_node , int * vars_arity_ptr , CELL * stack_terms USES_REGS ) {
# else
static inline CELL * load_answer_loop ( ans_node_ptr current_node USES_REGS ) {
# endif /* MODE_GLOBAL_TRIE_LOOP */
/************************************************************************
= = = = = = = = = = =
| |
| . . . |
| |
- - - - - - - - - - -
TR - - > | VAR_0 | < - - stack_vars_base
- - - - - - - - - - - *
| . . . | / | \
- - - - - - - - - - - | vars_arity ( N + 1 )
| VAR_N | \ | /
- - - - - - - - - - - *
| | < - - stack_terms_limit
- - - - - - - - - - -
| |
| . . . |
| |
- - - - - - - - - - |
| TERM_N | < - - stack_terms
- - - - - - - - - - | *
| . . . | / | \
- - - - - - - - - - | | stack_terms_pair_offset ( TRIE_COMPACT_PAIRS )
| TERM_1 | \ | /
= = = = = = = = = = = *
LOCAL_TrailTop - - > | | < - - stack_terms_base ( TRIE_COMPACT_PAIRS )
- - - - - - - - - - -
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
# ifdef MODE_GLOBAL_TRIE_LOOP
int vars_arity = * vars_arity_ptr ;
# else
int vars_arity = 0 ;
CELL * stack_terms = ( CELL * ) LOCAL_TrailTop ;
# endif /* MODE_GLOBAL_TRIE_LOOP */
CELL * stack_vars_base = ( CELL * ) TR ;
# define stack_terms_limit (stack_vars_base + vars_arity)
# ifdef TRIE_COMPACT_PAIRS
# define stack_terms_base ((CELL *) LOCAL_TrailTop)
int stack_terms_pair_offset = 0 ;
# endif /* TRIE_COMPACT_PAIRS */
Term t = TrNode_entry ( current_node ) ;
# ifdef MODE_GLOBAL_TRIE_LOOP
current_node = TrNode_parent ( current_node ) ;
# else
current_node = ( ans_node_ptr ) UNTAG_ANSWER_NODE ( TrNode_parent ( current_node ) ) ;
# endif /* MODE_GLOBAL_TRIE_LOOP */
# ifdef TRIE_RATIONAL_TERMS
term_array Ts ;
void * CyclicTerm ;
term_array_init ( & Ts , 10 ) ;
Term RationalTermTMP ; // a temporary temp to be used from the rational code
# endif /* RATIONAL TERM SUPPORT FOR TRIES */
do {
# ifdef TRIE_RATIONAL_TERMS
CyclicTerm = term_array_member ( Ts , ( void * ) current_node ) ;
# endif /* RATIONAL TERM SUPPORT FOR TRIES */
if ( IsVarTerm ( t ) ) {
# ifdef TRIE_RATIONAL_TERMS
if ( t > VarIndexOfTableTerm ( MAX_TABLE_VARS ) & & TrNode_child ( ( gt_node_ptr ) t ) ! = ( gt_node_ptr ) ( 1 ) ) { //TODO: substitute the != 1 test to something more appropriate
/* Rational term */
RationalTermTMP = ( Term ) term_array_member ( Ts , ( void * ) t ) ;
if ( RationalTermTMP ) {
/* rational term is assigned a variable already */
AUX_STACK_CHECK_EXPAND ( stack_terms , stack_terms_limit ) ;
STACK_PUSH_UP ( RationalTermTMP , stack_terms ) ;
} else {
RationalTermTMP = MkVarTerm ( ) ;
STACK_PUSH_UP ( RationalTermTMP , stack_terms ) ;
/* memorize the rational term and assign it a variable */
term_array_push ( & Ts , ( void * ) t , ( void * ) RationalTermTMP ) ;
}
} else
# endif /* RATIONAL TERM SUPPORT FOR TRIES */
{
# if ! defined(MODE_GLOBAL_TRIE_LOOP) || defined(GLOBAL_TRIE_FOR_SUBTERMS)
if ( t > VarIndexOfTableTerm ( MAX_TABLE_VARS ) ) {
stack_terms = load_substitution_loop ( ( gt_node_ptr ) t , & vars_arity , stack_terms PASS_REGS ) ;
} else
# endif /* ! MODE_GLOBAL_TRIE_LOOP || GLOBAL_TRIE_FOR_SUBTERMS */
{ int var_index = VarIndexOfTableTerm ( t ) ;
AUX_STACK_CHECK_EXPAND ( stack_terms , stack_terms_limit - vars_arity + var_index + 1 ) ;
if ( var_index > = vars_arity ) {
while ( vars_arity < var_index )
stack_vars_base [ vars_arity + + ] = 0 ;
stack_vars_base [ vars_arity + + ] = MkVarTerm ( ) ;
} else if ( stack_vars_base [ var_index ] = = 0 )
stack_vars_base [ var_index ] = MkVarTerm ( ) ;
STACK_PUSH_UP ( stack_vars_base [ var_index ] , stack_terms ) ;
}
}
} else if ( IsAtomOrIntTerm ( t ) ) {
AUX_STACK_CHECK_EXPAND ( stack_terms , stack_terms_limit ) ;
# ifdef TRIE_RATIONAL_TERMS
if ( CyclicTerm ) {
AUX_STACK_CHECK_EXPAND ( stack_terms , stack_terms_limit + 4 ) ;
STACK_PUSH_UP ( ( Term ) RationalMark , stack_terms ) ; // Add a rational term marker necessary as we read both ways the stack //
STACK_PUSH_UP ( t , stack_terms ) ; // Add the term //
STACK_PUSH_UP ( CyclicTerm , stack_terms ) ; // Add the variable that the term will unify with //
STACK_PUSH_UP ( ( Term ) RationalMark , stack_terms ) ; // Add a rational term marker necessary as we read both ways the stack //
} else
# endif /* RATIONAL TERM SUPPORT FOR TRIES */
STACK_PUSH_UP ( t , stack_terms ) ;
} else if ( IsPairTerm ( t ) ) {
# ifdef TRIE_COMPACT_PAIRS
if ( t = = CompactPairInit ) {
Term * stack_aux = stack_terms_base - stack_terms_pair_offset ;
Term head , tail = STACK_POP_UP ( stack_aux ) ;
# ifdef TRIE_RATIONAL_TERMS
if ( IsRationalTerm ( tail ) ) {
2015-09-25 10:57:26 +01:00
Yap_Error ( SYSTEM_ERROR_INTERNAL , tail , " Rational element of a Rational Term appears as the first Tail of a list " ) ;
2015-01-26 07:38:36 +00:00
}
# endif /* RATIONAL TERM SUPPORT FOR TRIES */
while ( STACK_NOT_EMPTY ( stack_aux , stack_terms ) ) {
head = STACK_POP_UP ( stack_aux ) ;
# ifdef TRIE_RATIONAL_TERMS
if ( IsRationalTerm ( head ) ) {
head = STACK_POP_UP ( stack_aux ) ; // thats the rational term
RationalTermTMP = STACK_POP_UP ( stack_aux ) ; // that is the variable to unify with
( void ) STACK_POP_UP ( stack_aux ) ; // eat the second rational mark
tail = MkPairTerm ( head , tail ) ;
Yap_unify ( RationalTermTMP , tail ) ;
} else
# endif /* RATIONAL TERM SUPPORT FOR TRIES */
tail = MkPairTerm ( head , tail ) ;
}
stack_terms = stack_terms_base - stack_terms_pair_offset ;
stack_terms_pair_offset = ( int ) STACK_POP_DOWN ( stack_terms ) ;
STACK_PUSH_UP ( tail , stack_terms ) ;
} else { /* CompactPairEndList / CompactPairEndTerm */
Term last ;
AUX_STACK_CHECK_EXPAND ( stack_terms , stack_terms_limit + 1 ) ;
last = STACK_POP_DOWN ( stack_terms ) ;
# ifdef TRIE_RATIONAL_TERMS
RationalTermTMP = TermNil ;
if ( IsRationalTerm ( last ) ) { // rather unlikely case the rational term is the last of a list
RationalTermTMP = STACK_POP_DOWN ( stack_terms ) ; // in this case we need to invert the term with the end of list
last = STACK_POP_DOWN ( stack_terms ) ; // variable to unify with
( void ) STACK_POP_DOWN ( stack_terms ) ; // eat the second rational mark
}
# endif /* RATIONAL TERM SUPPORT FOR TRIES */
STACK_PUSH_UP ( stack_terms_pair_offset , stack_terms ) ;
stack_terms_pair_offset = ( int ) ( stack_terms_base - stack_terms ) ;
if ( t = = CompactPairEndList )
STACK_PUSH_UP ( TermNil , stack_terms ) ;
# ifdef TRIE_RATIONAL_TERMS
if ( RationalTermTMP & & RationalTermTMP ! = TermNil ) {
/* most probably this never occurs */
STACK_PUSH_UP ( ( Term ) RationalMark , stack_terms ) ;
STACK_PUSH_UP ( last , stack_terms ) ;
STACK_PUSH_UP ( RationalTermTMP , stack_terms ) ;
STACK_PUSH_UP ( ( Term ) RationalMark , stack_terms ) ;
} else
# endif /* RATIONAL TERM SUPPORT FOR TRIES */
STACK_PUSH_UP ( last , stack_terms ) ;
}
# else /* ! TRIE_COMPACT_PAIRS */
Term head = STACK_POP_DOWN ( stack_terms ) ;
Term tail = STACK_POP_DOWN ( stack_terms ) ;
t = MkPairTerm ( head , tail ) ;
STACK_PUSH_UP ( t , stack_terms ) ;
# endif /* TRIE_COMPACT_PAIRS */
} else if ( IsApplTerm ( t ) ) {
Functor f = ( Functor ) RepAppl ( t ) ;
if ( f = = FunctorDouble ) {
union {
Term t_dbl [ sizeof ( Float ) / sizeof ( Term ) ] ;
Float dbl ;
} u ;
t = TrNode_entry ( current_node ) ;
current_node = TrNode_parent ( current_node ) ;
u . t_dbl [ 0 ] = t ;
# if SIZEOF_DOUBLE == 2 * SIZEOF_INT_P
t = TrNode_entry ( current_node ) ;
current_node = TrNode_parent ( current_node ) ;
u . t_dbl [ 1 ] = t ;
# endif /* SIZEOF_DOUBLE x SIZEOF_INT_P */
current_node = TrNode_parent ( current_node ) ;
t = MkFloatTerm ( u . dbl ) ;
} else if ( f = = FunctorLongInt ) {
Int li = TrNode_entry ( current_node ) ;
current_node = TrNode_parent ( current_node ) ;
current_node = TrNode_parent ( current_node ) ;
t = MkLongIntTerm ( li ) ;
} else if ( f = = FunctorBigInt | | f = = FunctorString ) {
CELL * ptr = ( CELL * ) TrNode_entry ( current_node ) ;
current_node = TrNode_parent ( current_node ) ;
current_node = TrNode_parent ( current_node ) ;
t = AbsAppl ( ptr ) ;
} else {
int f_arity = ArityOfFunctor ( f ) ;
t = Yap_MkApplTerm ( f , f_arity , stack_terms ) ;
stack_terms + = f_arity ;
}
AUX_STACK_CHECK_EXPAND ( stack_terms , stack_terms_limit ) ;
STACK_PUSH_UP ( t , stack_terms ) ;
}
# ifdef TRIE_RATIONAL_TERMS
if ( CyclicTerm ) {
RationalTermTMP = STACK_POP_DOWN ( stack_terms ) ;
if IsRationalTerm ( RationalTermTMP ) {
//printf("Special Case\n");
} else if ( IsPairTerm ( RationalTermTMP ) ) {
Yap_unify ( ( Term ) CyclicTerm , RationalTermTMP ) ;
} else if ( IsApplTerm ( RationalTermTMP ) ) {
Yap_unify ( ( Term ) CyclicTerm , RationalTermTMP ) ;
}
STACK_PUSH_UP ( RationalTermTMP , stack_terms ) ;
}
RationalTermTMP = TermNil ;
CyclicTerm = NULL ;
# endif /* RATIONAL TERM SUPPORT FOR TRIES */
t = TrNode_entry ( current_node ) ;
current_node = TrNode_parent ( current_node ) ;
} while ( current_node ) ;
# ifdef TRIE_RATIONAL_TERMS
term_array_free ( & Ts ) ;
# endif /* RATIONAL TERM SUPPORT FOR TRIES */
# ifdef MODE_GLOBAL_TRIE_LOOP
* vars_arity_ptr = vars_arity ;
# endif /* MODE_GLOBAL_TRIE_LOOP */
return stack_terms ;
# undef stack_terms_limit
# ifdef TRIE_COMPACT_PAIRS
# undef stack_terms_base
# 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