2010-04-03 05:58:14 +01: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 * *
* * * *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/************************************************************************
* * Tabling instructions : auxiliary macros * *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2001-04-09 20:54:03 +01:00
2005-07-06 20:34:12 +01:00
# ifdef LOW_LEVEL_TRACER
2010-04-18 04:59:11 +01:00
# define store_low_level_trace_info(CP, TAB_ENT) \
CP - > cp_pred_entry = TabEnt_pe ( TAB_ENT )
2005-07-06 20:34:12 +01:00
# else
# define store_low_level_trace_info(CP, TAB_ENT)
# endif /* LOW_LEVEL_TRACER */
2015-11-12 14:59:07 +00:00
# define TABLING_ERROR_CHECKING_STACK \
2011-12-22 16:50:20 +00:00
TABLING_ERROR_CHECKING ( store_node , Unsigned ( H ) + 1024 > Unsigned ( B ) ) ; \
2010-04-18 04:59:11 +01:00
TABLING_ERROR_CHECKING ( store_node , Unsigned ( H_FZ ) + 1024 > Unsigned ( B ) )
2005-07-06 20:34:12 +01:00
2011-12-22 16:50:20 +00:00
# define store_generator_node(TAB_ENT, SG_FR, ARITY, AP) \
{ register CELL * pt_args ; \
register choiceptr gcp ; \
/* store args */ \
pt_args = XREGS + ( ARITY ) ; \
while ( pt_args > XREGS ) { \
register CELL aux_arg = pt_args [ 0 ] ; \
- - YENV ; \
- - pt_args ; \
* YENV = aux_arg ; \
} \
/* initialize gcp and adjust subgoal frame field */ \
YENV = ( CELL * ) ( GEN_CP ( YENV ) - 1 ) ; \
gcp = NORM_CP ( YENV ) ; \
SgFr_gen_cp ( SG_FR ) = gcp ; \
/* store generator choice point */ \
2014-01-19 21:15:05 +00:00
HBREG = HR ; \
2011-12-22 16:50:20 +00:00
store_yaam_reg_cpdepth ( gcp ) ; \
gcp - > cp_tr = TR ; \
gcp - > cp_ap = ( yamop * ) ( AP ) ; \
2014-01-19 21:15:05 +00:00
gcp - > cp_h = HR ; \
2011-12-22 16:50:20 +00:00
gcp - > cp_b = B ; \
gcp - > cp_env = ENV ; \
gcp - > cp_cp = CPREG ; \
if ( IsMode_Local ( TabEnt_mode ( TAB_ENT ) ) ) { \
/* go local */ \
register dep_fr_ptr new_dep_fr ; \
/* adjust freeze registers */ \
2014-01-19 21:15:05 +00:00
H_FZ = HR ; \
2011-12-22 16:50:20 +00:00
B_FZ = gcp ; \
TR_FZ = TR ; \
/* store dependency frame */ \
new_dependency_frame ( new_dep_fr , TRUE , LOCAL_top_or_fr , gcp , \
gcp , SG_FR , FALSE , LOCAL_top_dep_fr ) ; \
LOCAL_top_dep_fr = new_dep_fr ; \
GEN_CP ( gcp ) - > cp_dep_fr = LOCAL_top_dep_fr ; \
} else { \
/* go batched */ \
GEN_CP ( gcp ) - > cp_dep_fr = NULL ; \
} \
GEN_CP ( gcp ) - > cp_sg_fr = SG_FR ; \
store_low_level_trace_info ( GEN_CP ( gcp ) , TAB_ENT ) ; \
set_cut ( ( CELL * ) gcp , B ) ; \
B = gcp ; \
YAPOR_SET_LOAD ( B ) ; \
SET_BB ( B ) ; \
TABLING_ERROR_CHECKING_STACK ; \
2001-04-09 20:54:03 +01:00
}
2009-07-03 00:54:39 +01:00
# ifdef DETERMINISTIC_TABLING
# define store_deterministic_generator_node(TAB_ENT, SG_FR) \
{ register choiceptr gcp ; \
/* initialize gcp and adjust subgoal frame field */ \
YENV = ( CELL * ) ( DET_GEN_CP ( YENV ) - 1 ) ; \
gcp = NORM_CP ( YENV ) ; \
SgFr_gen_cp ( SG_FR ) = gcp ; \
/* store deterministic generator choice point */ \
2014-01-19 21:15:05 +00:00
HBREG = HR ; \
2009-07-03 00:54:39 +01:00
store_yaam_reg_cpdepth ( gcp ) ; \
gcp - > cp_ap = COMPLETION ; \
gcp - > cp_b = B ; \
2009-08-09 03:38:07 +01:00
gcp - > cp_tr = TR ; \
2014-01-19 21:15:05 +00:00
gcp - > cp_h = HR ; \
2009-07-03 00:54:39 +01:00
DET_GEN_CP ( gcp ) - > cp_sg_fr = SG_FR ; \
store_low_level_trace_info ( DET_GEN_CP ( gcp ) , TAB_ENT ) ; \
set_cut ( ( CELL * ) gcp , B ) ; \
B = gcp ; \
YAPOR_SET_LOAD ( B ) ; \
SET_BB ( B ) ; \
2010-04-18 04:59:11 +01:00
TABLING_ERROR_CHECKING_STACK ; \
2009-07-03 00:54:39 +01:00
}
# endif /* DETERMINISTIC_TABLING */
2011-12-22 16:50:20 +00:00
# ifdef THREADS_CONSUMER_SHARING
# define store_generator_consumer_node(TAB_ENT, SG_FR, DEP_ON_STACK,ARITY) \
{ register CELL * pt_args ; \
register choiceptr gccp ; \
register dep_fr_ptr new_dep_fr ; \
/* store args */ \
pt_args = XREGS + ( ARITY ) ; \
while ( pt_args > XREGS ) { \
register CELL aux_arg = pt_args [ 0 ] ; \
- - YENV ; \
- - pt_args ; \
* YENV = aux_arg ; \
} \
/* initialize gcp and adjust subgoal frame field */ \
YENV = ( CELL * ) ( GEN_CP ( YENV ) - 1 ) ; \
gccp = NORM_CP ( YENV ) ; \
SgFr_gen_cp ( SG_FR ) = gccp ; \
/* store generator choice point */ \
2014-01-19 21:15:05 +00:00
HBREG = HR ; \
2011-12-22 16:50:20 +00:00
store_yaam_reg_cpdepth ( gccp ) ; \
gccp - > cp_tr = TR ; \
gccp - > cp_ap = ANSWER_RESOLUTION_COMPLETION ; \
2014-01-19 21:15:05 +00:00
gccp - > cp_h = HR ; \
2011-12-22 16:50:20 +00:00
gccp - > cp_b = B ; \
gccp - > cp_env = ENV ; \
gccp - > cp_cp = CPREG ; \
/* store dependency frame */ \
new_dependency_frame ( new_dep_fr , DEP_ON_STACK , LOCAL_top_or_fr , \
gccp , gccp , SG_FR , TRUE , LOCAL_top_dep_fr ) ; \
LOCAL_top_dep_fr = new_dep_fr ; \
GEN_CP ( gccp ) - > cp_dep_fr = LOCAL_top_dep_fr ; \
GEN_CP ( gccp ) - > cp_sg_fr = SG_FR ; \
/* adjust freeze registers */ \
2014-01-19 21:15:05 +00:00
H_FZ = HR ; \
2011-12-22 16:50:20 +00:00
B_FZ = gccp ; \
TR_FZ = TR ; \
store_low_level_trace_info ( GEN_CP ( gccp ) , TAB_ENT ) ; \
set_cut ( ( CELL * ) gccp , B ) ; \
B = gccp ; \
YAPOR_SET_LOAD ( B ) ; \
SET_BB ( B ) ; \
TABLING_ERROR_CHECKING_STACK ; \
}
# endif /* THREADS_CONSUMER_SHARING */
2005-03-04 20:30:14 +00:00
# define restore_generator_node(ARITY, AP) \
2001-04-09 20:54:03 +01:00
{ register CELL * pt_args , * x_args ; \
2005-04-07 18:56:58 +01:00
register choiceptr gcp = B ; \
2001-04-09 20:54:03 +01:00
/* restore generator choice point */ \
2014-01-19 21:15:05 +00:00
HR = HBREG = PROTECT_FROZEN_H ( gcp ) ; \
2005-04-07 18:56:58 +01:00
restore_yaam_reg_cpdepth ( gcp ) ; \
CPREG = gcp - > cp_cp ; \
ENV = gcp - > cp_env ; \
2001-04-09 20:54:03 +01:00
YAPOR_update_alternative ( PREG , ( yamop * ) AP ) \
2005-04-07 18:56:58 +01:00
gcp - > cp_ap = ( yamop * ) AP ; \
2001-04-09 20:54:03 +01:00
/* restore args */ \
2005-04-07 18:56:58 +01:00
pt_args = ( CELL * ) ( GEN_CP ( gcp ) + 1 ) + ARITY ; \
2001-04-09 20:54:03 +01:00
x_args = XREGS + 1 + ARITY ; \
while ( x_args > XREGS + 1 ) { \
register CELL x = pt_args [ - 1 ] ; \
- - x_args ; \
- - pt_args ; \
* x_args = x ; \
} \
}
2005-03-04 20:30:14 +00:00
# define pop_generator_node(ARITY) \
{ register CELL * pt_args , * x_args ; \
2005-04-07 18:56:58 +01:00
register choiceptr gcp = B ; \
2005-03-04 20:30:14 +00:00
/* pop generator choice point */ \
2014-01-19 21:15:05 +00:00
HR = PROTECT_FROZEN_H ( gcp ) ; \
2005-04-07 18:56:58 +01:00
pop_yaam_reg_cpdepth ( gcp ) ; \
CPREG = gcp - > cp_cp ; \
ENV = gcp - > cp_env ; \
TR = gcp - > cp_tr ; \
B = gcp - > cp_b ; \
2005-03-04 20:30:14 +00:00
HBREG = PROTECT_FROZEN_H ( B ) ; \
/* pop args */ \
x_args = XREGS + 1 ; \
2005-04-07 18:56:58 +01:00
pt_args = ( CELL * ) ( GEN_CP ( gcp ) + 1 ) ; \
2005-03-04 20:30:14 +00:00
while ( x_args < XREGS + 1 + ARITY ) { \
register CELL x = pt_args [ 0 ] ; \
pt_args + + ; \
x_args + + ; \
x_args [ - 1 ] = x ; \
} \
YENV = pt_args ; \
SET_BB ( PROTECT_FROZEN_B ( B ) ) ; \
2001-04-09 20:54:03 +01:00
}
2011-12-22 16:50:20 +00:00
# define store_consumer_node(TAB_ENT, SG_FR, LEADER_CP, DEP_ON_STACK) \
{ register choiceptr ccp ; \
register dep_fr_ptr new_dep_fr ; \
/* initialize ccp */ \
YENV = ( CELL * ) ( CONS_CP ( YENV ) - 1 ) ; \
ccp = NORM_CP ( YENV ) ; \
/* adjust freeze registers */ \
2014-01-19 21:15:05 +00:00
H_FZ = HR ; \
2011-12-22 16:50:20 +00:00
B_FZ = ccp ; \
TR_FZ = TR ; \
/* store dependency frame */ \
new_dependency_frame ( new_dep_fr , DEP_ON_STACK , LOCAL_top_or_fr , \
LEADER_CP , ccp , SG_FR , FALSE , LOCAL_top_dep_fr ) ; \
LOCAL_top_dep_fr = new_dep_fr ; \
/* store consumer choice point */ \
2014-01-19 21:15:05 +00:00
HBREG = HR ; \
2011-12-22 16:50:20 +00:00
store_yaam_reg_cpdepth ( ccp ) ; \
ccp - > cp_tr = TR ; \
ccp - > cp_ap = ANSWER_RESOLUTION ; \
2014-01-19 21:15:05 +00:00
ccp - > cp_h = HR ; \
2011-12-22 16:50:20 +00:00
ccp - > cp_b = B ; \
ccp - > cp_env = ENV ; \
ccp - > cp_cp = CPREG ; \
CONS_CP ( ccp ) - > cp_dep_fr = LOCAL_top_dep_fr ; \
store_low_level_trace_info ( CONS_CP ( ccp ) , TAB_ENT ) ; \
/* set_cut((CELL *)ccp, B); --> no effect */ \
B = ccp ; \
YAPOR_SET_LOAD ( B ) ; \
SET_BB ( B ) ; \
TABLING_ERROR_CHECKING_STACK ; \
2001-04-09 20:54:03 +01:00
}
2005-07-06 20:34:12 +01:00
2011-12-22 16:50:20 +00:00
# ifdef THREADS_CONSUMER_SHARING
# define consume_answer_and_procceed(DEP_FR, ANSWER) \
{ CELL * subs_ptr ; \
/* restore consumer choice point */ \
2014-01-19 21:15:05 +00:00
HR = HBREG = PROTECT_FROZEN_H ( B ) ; \
2011-12-22 16:50:20 +00:00
restore_yaam_reg_cpdepth ( B ) ; \
CPREG = B - > cp_cp ; \
ENV = B - > cp_env ; \
/* set_cut(YENV, B->cp_b); --> no effect */ \
PREG = ( yamop * ) CPREG ; \
PREFETCH_OP ( PREG ) ; \
/* load answer from table to global stack */ \
if ( B = = DepFr_leader_cp ( DEP_FR ) | | DepFr_external ( DEP_FR ) ) { \
/* B is a generator-consumer node */ \
TABLING_ERROR_CHECKING ( generator_consumer , IS_BATCHED_GEN_CP ( B ) ) ; \
subs_ptr = ( CELL * ) ( GEN_CP ( B ) + 1 ) ; \
subs_ptr + = SgFr_arity ( GEN_CP ( B ) - > cp_sg_fr ) ; \
} else { \
subs_ptr = ( CELL * ) ( CONS_CP ( B ) + 1 ) ; \
} \
load_answer ( ANSWER , subs_ptr ) ; \
/* procceed */ \
YENV = ENV ; \
GONext ( ) ; \
}
# else
2010-04-18 04:59:11 +01:00
# define consume_answer_and_procceed(DEP_FR, ANSWER) \
{ CELL * subs_ptr ; \
/* restore consumer choice point */ \
2014-01-19 21:15:05 +00:00
HR = HBREG = PROTECT_FROZEN_H ( B ) ; \
2010-04-18 04:59:11 +01:00
restore_yaam_reg_cpdepth ( B ) ; \
CPREG = B - > cp_cp ; \
ENV = B - > cp_env ; \
/* set_cut(YENV, B->cp_b); --> no effect */ \
PREG = ( yamop * ) CPREG ; \
PREFETCH_OP ( PREG ) ; \
/* load answer from table to global stack */ \
if ( B = = DepFr_leader_cp ( DEP_FR ) ) { \
/* B is a generator-consumer node */ \
/* never here if batched scheduling */ \
TABLING_ERROR_CHECKING ( generator_consumer , IS_BATCHED_GEN_CP ( B ) ) ; \
subs_ptr = ( CELL * ) ( GEN_CP ( B ) + 1 ) ; \
subs_ptr + = SgFr_arity ( GEN_CP ( B ) - > cp_sg_fr ) ; \
} else { \
subs_ptr = ( CELL * ) ( CONS_CP ( B ) + 1 ) ; \
} \
load_answer ( ANSWER , subs_ptr ) ; \
/* procceed */ \
YENV = ENV ; \
GONext ( ) ; \
2001-04-09 20:54:03 +01:00
}
2011-12-22 16:50:20 +00:00
# endif /* THREADS_CONSUMER_SHARING */
2001-04-09 20:54:03 +01:00
2005-07-06 20:34:12 +01:00
# define store_loader_node(TAB_ENT, ANSWER) \
{ register choiceptr lcp ; \
/* initialize lcp */ \
lcp = NORM_CP ( LOAD_CP ( YENV ) - 1 ) ; \
/* store loader choice point */ \
2014-01-19 21:15:05 +00:00
HBREG = HR ; \
2005-07-06 20:34:12 +01:00
store_yaam_reg_cpdepth ( lcp ) ; \
lcp - > cp_tr = TR ; \
lcp - > cp_ap = LOAD_ANSWER ; \
2014-01-19 21:15:05 +00:00
lcp - > cp_h = HR ; \
2005-07-06 20:34:12 +01:00
lcp - > cp_b = B ; \
lcp - > cp_env = ENV ; \
lcp - > cp_cp = CPREG ; \
LOAD_CP ( lcp ) - > cp_last_answer = ANSWER ; \
store_low_level_trace_info ( LOAD_CP ( lcp ) , TAB_ENT ) ; \
/* set_cut((CELL *)lcp, B); --> no effect */ \
B = lcp ; \
YAPOR_SET_LOAD ( B ) ; \
SET_BB ( B ) ; \
2010-04-18 04:59:11 +01:00
TABLING_ERROR_CHECKING_STACK ; \
2005-07-06 20:34:12 +01:00
}
# define restore_loader_node(ANSWER) \
2014-01-19 21:15:05 +00:00
HR = HBREG = PROTECT_FROZEN_H ( B ) ; \
2005-07-06 20:34:12 +01:00
restore_yaam_reg_cpdepth ( B ) ; \
CPREG = B - > cp_cp ; \
ENV = B - > cp_env ; \
LOAD_CP ( B ) - > cp_last_answer = ANSWER ; \
SET_BB ( PROTECT_FROZEN_B ( B ) )
# define pop_loader_node() \
2014-01-19 21:15:05 +00:00
HR = PROTECT_FROZEN_H ( B ) ; \
2005-07-06 20:34:12 +01:00
pop_yaam_reg_cpdepth ( B ) ; \
CPREG = B - > cp_cp ; \
TABLING_close_alt ( B ) ; \
ENV = B - > cp_env ; \
B = B - > cp_b ; \
HBREG = PROTECT_FROZEN_H ( B ) ; \
SET_BB ( PROTECT_FROZEN_B ( B ) )
2001-11-16 20:27:06 +00:00
# ifdef DEPTH_LIMIT
2005-05-31 01:49:49 +01:00
# define allocate_environment() \
YENV [ E_CP ] = ( CELL ) CPREG ; \
YENV [ E_E ] = ( CELL ) ENV ; \
YENV [ E_B ] = ( CELL ) B ; \
YENV [ E_DEPTH ] = ( CELL ) DEPTH ; \
ENV = YENV
2001-11-16 20:27:06 +00:00
# else
2005-05-31 01:49:49 +01:00
# define allocate_environment() \
YENV [ E_CP ] = ( CELL ) CPREG ; \
YENV [ E_E ] = ( CELL ) ENV ; \
YENV [ E_B ] = ( CELL ) B ; \
ENV = YENV
# endif /* DEPTH_LIMIT */
2001-04-09 20:54:03 +01:00
2010-04-03 05:58:14 +01:00
/************************************************************************
* * clause_with_cut * *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2001-04-09 20:54:03 +01:00
# ifdef TABLING_INNER_CUTS
Op ( clause_with_cut , e )
if ( LOCAL_pruning_scope ) {
if ( YOUNGER_CP ( LOCAL_pruning_scope , B ) )
LOCAL_pruning_scope = B ;
} else {
LOCAL_pruning_scope = B ;
PUT_IN_PRUNING ( worker_id ) ;
}
PREG = NEXTOP ( PREG , e ) ;
GONext ( ) ;
ENDOp ( ) ;
# endif /* TABLING_INNER_CUTS */
2010-04-03 05:58:14 +01:00
/************************************************************************
* * table_load_answer * *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2008-09-05 05:22:19 +01:00
PBOp ( table_load_answer , Otapl )
2005-08-01 16:40:39 +01:00
CELL * subs_ptr ;
ans_node_ptr ans_node ;
# ifdef YAPOR
if ( SCH_top_shared_cp ( B ) ) {
2010-01-14 17:38:39 +00:00
#if 0
2005-08-01 16:40:39 +01:00
PROBLEM : cp_last_answer field is local to the cp !
- > we need a shared data structure to avoid redundant computations !
UNLOCK_OR_FRAME ( LOCAL_top_or_fr ) ;
2010-01-14 17:38:39 +00:00
# else
2015-11-12 14:59:07 +00:00
fprintf ( stderr , " PROBLEM: cp_last_answer field is local to the cp! \n " ) ;
2010-01-14 17:38:39 +00:00
exit ( 1 ) ;
# endif
2005-08-01 16:40:39 +01:00
}
# endif /* YAPOR */
subs_ptr = ( CELL * ) ( LOAD_CP ( B ) + 1 ) ;
ans_node = TrNode_child ( LOAD_CP ( B ) - > cp_last_answer ) ;
if ( TrNode_child ( ans_node ) ! = NULL ) {
restore_loader_node ( ans_node ) ;
} else {
pop_loader_node ( ) ;
}
PREG = ( yamop * ) CPREG ;
PREFETCH_OP ( PREG ) ;
2009-09-27 02:31:31 +01:00
load_answer ( ans_node , subs_ptr ) ;
2005-08-01 16:40:39 +01:00
YENV = ENV ;
GONext ( ) ;
ENDPBOp ( ) ;
2010-04-03 05:58:14 +01:00
/************************************************************************
* * table_try_answer * *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2008-09-05 05:22:19 +01:00
PBOp ( table_try_answer , Otapl )
2005-08-01 16:40:39 +01:00
# ifdef INCOMPLETE_TABLING
sg_fr_ptr sg_fr ;
ans_node_ptr ans_node ;
sg_fr = GEN_CP ( B ) - > cp_sg_fr ;
ans_node = TrNode_child ( SgFr_try_answer ( sg_fr ) ) ;
if ( ans_node ) {
CELL * subs_ptr = ( CELL * ) ( GEN_CP ( B ) + 1 ) + SgFr_arity ( sg_fr ) ;
2014-01-19 21:15:05 +00:00
HR = HBREG = PROTECT_FROZEN_H ( B ) ;
2005-08-01 16:40:39 +01:00
restore_yaam_reg_cpdepth ( B ) ;
CPREG = B - > cp_cp ;
ENV = B - > cp_env ;
SgFr_try_answer ( sg_fr ) = ans_node ;
# ifdef YAPOR
if ( SCH_top_shared_cp ( B ) )
UNLOCK_OR_FRAME ( LOCAL_top_or_fr ) ;
# endif /* YAPOR */
SET_BB ( PROTECT_FROZEN_B ( B ) ) ;
PREG = ( yamop * ) CPREG ;
PREFETCH_OP ( PREG ) ;
2009-09-27 02:31:31 +01:00
load_answer ( ans_node , subs_ptr ) ;
2005-08-01 16:40:39 +01:00
YENV = ENV ;
GONext ( ) ;
} else {
yamop * code_ap ;
PREG = SgFr_code ( sg_fr ) ;
2005-08-01 19:26:28 +01:00
if ( PREG - > opc = = Yap_opcode ( _table_try ) ) {
2005-08-01 16:40:39 +01:00
/* table_try */
2008-09-05 05:22:19 +01:00
code_ap = NEXTOP ( PREG , Otapl ) ;
2014-05-30 01:06:09 +01:00
PREG = PREG - > y_u . Otapl . d ;
2005-08-01 19:26:28 +01:00
} else if ( PREG - > opc = = Yap_opcode ( _table_try_single ) ) {
2005-08-01 16:40:39 +01:00
/* table_try_single */
code_ap = COMPLETION ;
2014-05-30 01:06:09 +01:00
PREG = PREG - > y_u . Otapl . d ;
2005-08-01 19:26:28 +01:00
} else {
/* table_try_me */
2014-05-30 01:06:09 +01:00
code_ap = PREG - > y_u . Otapl . d ;
2008-09-05 05:22:19 +01:00
PREG = NEXTOP ( PREG , Otapl ) ;
2005-08-01 16:40:39 +01:00
}
2006-01-17 14:10:42 +00:00
PREFETCH_OP ( PREG ) ;
2005-08-01 16:40:39 +01:00
restore_generator_node ( SgFr_arity ( sg_fr ) , code_ap ) ;
YENV = ( CELL * ) PROTECT_FROZEN_B ( B ) ;
set_cut ( YENV , B - > cp_b ) ;
SET_BB ( NORM_CP ( YENV ) ) ;
allocate_environment ( ) ;
GONext ( ) ;
}
2006-01-17 14:10:42 +00:00
# else
2014-05-30 01:06:09 +01:00
PREG = PREG - > y_u . Otapl . d ;
2007-04-26 15:13:21 +01:00
PREFETCH_OP ( PREG ) ;
GONext ( ) ;
2005-08-01 16:40:39 +01:00
# endif /* INCOMPLETE_TABLING */
ENDPBOp ( ) ;
2010-04-03 05:58:14 +01:00
/************************************************************************
* * table_try_single * *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2008-09-05 05:22:19 +01:00
PBOp ( table_try_single , Otapl )
2001-04-09 20:54:03 +01:00
tab_ent_ptr tab_ent ;
sg_fr_ptr sg_fr ;
2005-08-05 15:55:03 +01:00
check_trail ( TR ) ;
2014-05-30 01:06:09 +01:00
tab_ent = PREG - > y_u . Otapl . te ;
2006-01-17 14:10:42 +00:00
YENV2MEM ;
2015-08-07 22:57:53 +01:00
saveregs ( ) ;
sg_fr = subgoal_search ( PREG , YENV_ADDRESS ) ;
setregs ( ) ;
2006-01-17 14:10:42 +00:00
MEM2YENV ;
2011-12-22 16:50:20 +00:00
# if defined(THREADS_FULL_SHARING) || defined(THREADS_CONSUMER_SHARING)
if ( SgFr_state ( sg_fr ) < = ready ) {
LOCK_SG_FR ( sg_fr ) ;
if ( SgFr_sg_ent_state ( sg_fr ) > = complete )
SgFr_state ( sg_fr ) = SgFr_sg_ent_state ( sg_fr ) ;
else
SgFr_active_workers ( sg_fr ) + + ;
UNLOCK_SG_FR ( sg_fr ) ;
}
# endif /* THREADS_FULL_SHARING || THREADS_CONSUMER_SHARING */
2011-12-05 16:54:22 +00:00
LOCK_SG_FR ( sg_fr ) ;
2011-12-22 16:50:20 +00:00
# ifdef THREADS_CONSUMER_SHARING
if ( SgFr_state ( sg_fr ) = = ready_external ) {
init_subgoal_frame ( sg_fr ) ;
2014-05-30 01:06:09 +01:00
store_generator_consumer_node ( tab_ent , sg_fr , TRUE , PREG - > y_u . Otapl . s ) ;
2011-12-22 16:50:20 +00:00
PREFETCH_OP ( PREG ) ;
allocate_environment ( ) ;
check_for_deadlock ( sg_fr ) ;
goto answer_resolution_completion ;
} else
# endif /* THREADS_CONSUMER_SHARING */
2005-08-04 16:45:56 +01:00
if ( SgFr_state ( sg_fr ) = = ready ) {
2005-08-01 16:40:39 +01:00
/* subgoal new */
2005-04-07 18:56:58 +01:00
init_subgoal_frame ( sg_fr ) ;
2011-12-05 16:54:22 +00:00
UNLOCK_SG_FR ( sg_fr ) ;
2009-07-03 00:54:39 +01:00
# ifdef DETERMINISTIC_TABLING
if ( IsMode_Batched ( TabEnt_mode ( tab_ent ) ) ) {
store_deterministic_generator_node ( tab_ent , sg_fr ) ;
} else
# endif /* DETERMINISTIC_TABLING */
{
2014-05-30 01:06:09 +01:00
store_generator_node ( tab_ent , sg_fr , PREG - > y_u . Otapl . s , COMPLETION ) ;
2009-07-03 00:54:39 +01:00
}
2014-05-30 01:06:09 +01:00
PREG = PREG - > y_u . Otapl . d ; /* should work also with PREG = NEXTOP(PREG,Otapl); */
2001-04-09 20:54:03 +01:00
PREFETCH_OP ( PREG ) ;
2005-05-31 01:49:49 +01:00
allocate_environment ( ) ;
2001-04-09 20:54:03 +01:00
GONext ( ) ;
2005-08-04 16:45:56 +01:00
# ifdef INCOMPLETE_TABLING
} else if ( SgFr_state ( sg_fr ) = = incomplete ) {
2013-12-20 14:56:13 +00:00
if ( IsMode_CoInductive ( TabEnt_flags ( tab_ent ) ) ) {
2013-12-19 17:08:55 +00:00
printf ( " Currently Unsupported \n " ) ;
} else {
2013-12-19 16:56:55 +00:00
/* subgoal incomplete --> start by loading the answers already found */
ans_node_ptr ans_node = SgFr_first_answer ( sg_fr ) ;
CELL * subs_ptr = YENV ;
init_subgoal_frame ( sg_fr ) ;
UNLOCK_SG_FR ( sg_fr ) ;
SgFr_try_answer ( sg_fr ) = ans_node ;
2014-05-30 01:06:09 +01:00
store_generator_node ( tab_ent , sg_fr , PREG - > y_u . Otapl . s , TRY_ANSWER ) ;
2013-12-19 16:56:55 +00:00
PREG = ( yamop * ) CPREG ;
PREFETCH_OP ( PREG ) ;
load_answer ( ans_node , subs_ptr ) ;
YENV = ENV ;
GONext ( ) ;
2013-12-19 17:08:55 +00:00
}
2005-08-04 16:45:56 +01:00
# endif /* INCOMPLETE_TABLING */
2005-04-07 18:56:58 +01:00
} else if ( SgFr_state ( sg_fr ) = = evaluating ) {
2013-12-20 14:56:13 +00:00
if ( IsMode_CoInductive ( TabEnt_flags ( tab_ent ) ) ) {
2013-12-19 17:08:55 +00:00
/* Used for coinductive tabling strategy */
CELL * subs_ptr ;
subs_ptr = ( CELL * ) ( GEN_CP ( SgFr_gen_cp ( sg_fr ) ) + 1 ) ;
subs_ptr + = SgFr_arity ( sg_fr ) ; // Points at the Parent goal Variables
int i ;
for ( i = 0 ; i < subs_ptr [ 0 ] ; i + + )
Yap_unify ( subs_ptr [ i + 1 ] , YENV [ i + 1 ] ) ;
/* yes answer --> procceed */
UNLOCK_SG_FR ( sg_fr ) ;
PREG = ( yamop * ) CPREG ;
PREFETCH_OP ( PREG ) ;
YENV = ENV ; // Consume the variables
GONext ( ) ; // Succeed the goal :-D
} else {
2013-12-19 16:56:55 +00:00
/* subgoal in evaluation */
2013-12-19 17:08:55 +00:00
choiceptr leader_cp ;
2014-03-20 12:32:51 +00:00
# ifdef YAPOR
2013-12-19 16:56:55 +00:00
int leader_dep_on_stack ;
2014-03-20 12:32:51 +00:00
# endif
2013-12-19 16:56:55 +00:00
find_dependency_node ( sg_fr , leader_cp , leader_dep_on_stack ) ;
UNLOCK_SG_FR ( sg_fr ) ;
find_leader_node ( leader_cp , leader_dep_on_stack ) ;
store_consumer_node ( tab_ent , sg_fr , leader_cp , leader_dep_on_stack ) ;
2013-12-19 17:08:55 +00:00
}
2010-04-18 04:59:11 +01:00
# ifdef DEBUG_OPTYAP
2011-06-21 15:19:07 +01:00
if ( GLOBAL_parallel_mode = = PARALLEL_MODE_RUNNING ) {
2005-04-07 18:56:58 +01:00
choiceptr aux_cp ;
aux_cp = B ;
2010-01-14 15:58:19 +00:00
while ( YOUNGER_CP ( aux_cp , Get_LOCAL_top_cp_on_stack ( ) ) )
2005-04-07 18:56:58 +01:00
aux_cp = aux_cp - > cp_b ;
2010-04-18 04:59:11 +01:00
OPTYAP_ERROR_CHECKING ( table_try_single , aux_cp - > cp_or_fr ! = DepFr_top_or_fr ( LOCAL_top_dep_fr ) ) ;
2005-04-07 18:56:58 +01:00
aux_cp = B ;
while ( YOUNGER_CP ( aux_cp , DepFr_leader_cp ( LOCAL_top_dep_fr ) ) )
aux_cp = aux_cp - > cp_b ;
2010-04-18 04:59:11 +01:00
OPTYAP_ERROR_CHECKING ( table_try_single , aux_cp ! = DepFr_leader_cp ( LOCAL_top_dep_fr ) ) ;
2005-04-07 18:56:58 +01:00
}
2010-04-18 04:59:11 +01:00
# endif /* DEBUG_OPTYAP */
2005-04-07 18:56:58 +01:00
goto answer_resolution ;
} else {
/* subgoal completed */
2005-07-06 20:34:12 +01:00
ans_node_ptr ans_node = SgFr_first_answer ( sg_fr ) ;
if ( ans_node = = NULL ) {
2005-04-07 18:56:58 +01:00
/* no answers --> fail */
2011-12-05 16:54:22 +00:00
UNLOCK_SG_FR ( sg_fr ) ;
2005-04-07 18:56:58 +01:00
goto fail ;
2005-07-06 20:34:12 +01:00
} else if ( ans_node = = SgFr_answer_trie ( sg_fr ) ) {
2005-04-07 18:56:58 +01:00
/* yes answer --> procceed */
2011-12-05 16:54:22 +00:00
UNLOCK_SG_FR ( sg_fr ) ;
2005-04-07 18:56:58 +01:00
PREG = ( yamop * ) CPREG ;
PREFETCH_OP ( PREG ) ;
YENV = ENV ;
GONext ( ) ;
} else {
2005-07-06 20:34:12 +01:00
/* answers -> get first answer */
2005-08-04 16:45:56 +01:00
# ifdef LIMIT_TABLING
if ( SgFr_state ( sg_fr ) = = complete | | SgFr_state ( sg_fr ) = = compiled ) {
SgFr_state ( sg_fr ) + + ; /* complete --> complete_in_use : compiled --> compiled_in_use */
remove_from_global_sg_fr_list ( sg_fr ) ;
TRAIL_FRAME ( sg_fr ) ;
}
# endif /* LIMIT_TABLING */
2011-12-22 16:50:20 +00:00
# if defined(THREADS_FULL_SHARING) || defined(THREADS_CONSUMER_SHARING)
if ( IsMode_LoadAnswers ( TabEnt_mode ( tab_ent ) ) | | SgFr_active_workers ( sg_fr ) > 0 ) {
# else
if ( IsMode_LoadAnswers ( TabEnt_mode ( tab_ent ) ) ) {
# endif /* THREADS_FULL_SHARING || THREADS_CONSUMER_SHARING */
2005-07-06 20:34:12 +01:00
/* load answers from the trie */
2011-12-05 16:54:22 +00:00
UNLOCK_SG_FR ( sg_fr ) ;
2005-07-06 20:34:12 +01:00
if ( TrNode_child ( ans_node ) ! = NULL ) {
store_loader_node ( tab_ent , ans_node ) ;
}
PREG = ( yamop * ) CPREG ;
PREFETCH_OP ( PREG ) ;
2009-09-27 02:31:31 +01:00
load_answer ( ans_node , YENV ) ;
2005-07-06 20:34:12 +01:00
YENV = ENV ;
GONext ( ) ;
} else {
/* execute compiled code from the trie */
2011-12-22 16:50:20 +00:00
# if defined(THREADS_FULL_SHARING) || defined(THREADS_CONSUMER_SHARING)
if ( SgFr_sg_ent_state ( sg_fr ) < compiled )
# else
2005-08-04 16:45:56 +01:00
if ( SgFr_state ( sg_fr ) < compiled )
2011-12-22 16:50:20 +00:00
# endif /* THREADS_FULL_SHARING || THREADS_CONSUMER_SHARING */
2005-07-06 20:34:12 +01:00
update_answer_trie ( sg_fr ) ;
2011-12-05 16:54:22 +00:00
UNLOCK_SG_FR ( sg_fr ) ;
2005-07-06 20:34:12 +01:00
PREG = ( yamop * ) TrNode_child ( SgFr_answer_trie ( sg_fr ) ) ;
PREFETCH_OP ( PREG ) ;
* - - YENV = 0 ; /* vars_arity */
* - - YENV = 0 ; /* heap_arity */
GONext ( ) ;
}
2001-04-09 20:54:03 +01:00
}
}
ENDPBOp ( ) ;
2010-04-03 05:58:14 +01:00
/************************************************************************
* * table_try_me * *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2008-09-05 05:22:19 +01:00
PBOp ( table_try_me , Otapl )
2001-04-09 20:54:03 +01:00
tab_ent_ptr tab_ent ;
sg_fr_ptr sg_fr ;
2005-08-05 15:55:03 +01:00
check_trail ( TR ) ;
2014-05-30 01:06:09 +01:00
tab_ent = PREG - > y_u . Otapl . te ;
2006-01-17 14:10:42 +00:00
YENV2MEM ;
2015-08-07 22:57:53 +01:00
saveregs ( ) ;
2006-01-17 14:10:42 +00:00
sg_fr = subgoal_search ( PREG , YENV_ADDRESS ) ;
2015-08-07 22:57:53 +01:00
setregs ( ) ;
2006-01-17 14:10:42 +00:00
MEM2YENV ;
2011-12-22 16:50:20 +00:00
# if defined(THREADS_FULL_SHARING) || defined(THREADS_CONSUMER_SHARING)
if ( SgFr_state ( sg_fr ) < = ready ) {
LOCK_SG_FR ( sg_fr ) ;
if ( SgFr_sg_ent_state ( sg_fr ) > = complete )
SgFr_state ( sg_fr ) = SgFr_sg_ent_state ( sg_fr ) ;
else
SgFr_active_workers ( sg_fr ) + + ;
UNLOCK_SG_FR ( sg_fr ) ;
}
# endif /* THREADS_FULL_SHARING || THREADS_CONSUMER_SHARING */
2011-12-05 16:54:22 +00:00
LOCK_SG_FR ( sg_fr ) ;
2011-12-22 16:50:20 +00:00
# ifdef THREADS_CONSUMER_SHARING
if ( SgFr_state ( sg_fr ) = = ready_external ) {
init_subgoal_frame ( sg_fr ) ;
UNLOCK_SG_FR ( sg_fr ) ;
2014-05-30 01:06:09 +01:00
store_generator_consumer_node ( tab_ent , sg_fr , TRUE , PREG - > y_u . Otapl . s ) ;
2011-12-22 16:50:20 +00:00
PREFETCH_OP ( PREG ) ;
allocate_environment ( ) ;
check_for_deadlock ( sg_fr ) ;
goto answer_resolution_completion ;
} else
# endif /* THREADS_CONSUMER_SHARING */
2005-08-04 16:45:56 +01:00
if ( SgFr_state ( sg_fr ) = = ready ) {
2005-08-01 16:40:39 +01:00
/* subgoal new */
2005-04-07 18:56:58 +01:00
init_subgoal_frame ( sg_fr ) ;
2011-12-05 16:54:22 +00:00
UNLOCK_SG_FR ( sg_fr ) ;
2014-05-30 01:06:09 +01:00
store_generator_node ( tab_ent , sg_fr , PREG - > y_u . Otapl . s , PREG - > y_u . Otapl . d ) ;
2008-09-05 05:22:19 +01:00
PREG = NEXTOP ( PREG , Otapl ) ;
2001-04-09 20:54:03 +01:00
PREFETCH_OP ( PREG ) ;
2005-05-31 01:49:49 +01:00
allocate_environment ( ) ;
2001-04-09 20:54:03 +01:00
GONext ( ) ;
2005-08-04 16:45:56 +01:00
# ifdef INCOMPLETE_TABLING
} else if ( SgFr_state ( sg_fr ) = = incomplete ) {
2013-12-20 14:56:13 +00:00
if ( IsMode_CoInductive ( TabEnt_flags ( tab_ent ) ) ) {
2013-12-19 17:08:55 +00:00
printf ( " Currently Unsupported \n " ) ;
} else {
2013-12-19 16:56:55 +00:00
/* subgoal incomplete --> start by loading the answers already found */
ans_node_ptr ans_node = SgFr_first_answer ( sg_fr ) ;
CELL * subs_ptr = YENV ;
init_subgoal_frame ( sg_fr ) ;
UNLOCK_SG_FR ( sg_fr ) ;
SgFr_try_answer ( sg_fr ) = ans_node ;
2014-05-30 01:06:09 +01:00
store_generator_node ( tab_ent , sg_fr , PREG - > y_u . Otapl . s , TRY_ANSWER ) ;
2013-12-19 16:56:55 +00:00
PREG = ( yamop * ) CPREG ;
PREFETCH_OP ( PREG ) ;
load_answer ( ans_node , subs_ptr ) ;
YENV = ENV ;
GONext ( ) ;
2013-12-19 17:08:55 +00:00
}
2005-08-04 16:45:56 +01:00
# endif /* INCOMPLETE_TABLING */
2005-04-07 18:56:58 +01:00
} else if ( SgFr_state ( sg_fr ) = = evaluating ) {
2013-12-20 14:56:13 +00:00
if ( IsMode_CoInductive ( TabEnt_flags ( tab_ent ) ) ) {
2013-12-19 17:08:55 +00:00
printf ( " Currently Unsupported \n " ) ;
} else {
2013-12-19 16:56:55 +00:00
/* subgoal in evaluation */
choiceptr leader_cp ;
2014-03-20 12:32:51 +00:00
# ifdef YAPOR
2013-12-19 16:56:55 +00:00
int leader_dep_on_stack ;
2014-03-20 12:32:51 +00:00
# endif
2013-12-19 16:56:55 +00:00
find_dependency_node ( sg_fr , leader_cp , leader_dep_on_stack ) ;
UNLOCK_SG_FR ( sg_fr ) ;
find_leader_node ( leader_cp , leader_dep_on_stack ) ;
store_consumer_node ( tab_ent , sg_fr , leader_cp , leader_dep_on_stack ) ;
2013-12-19 17:08:55 +00:00
}
2010-04-18 04:59:11 +01:00
# ifdef DEBUG_OPTYAP
2011-06-21 15:19:07 +01:00
if ( GLOBAL_parallel_mode = = PARALLEL_MODE_RUNNING ) {
2005-04-07 18:56:58 +01:00
choiceptr aux_cp ;
aux_cp = B ;
2010-01-14 15:58:19 +00:00
while ( YOUNGER_CP ( aux_cp , Get_LOCAL_top_cp_on_stack ( ) ) )
2005-04-07 18:56:58 +01:00
aux_cp = aux_cp - > cp_b ;
2010-04-18 04:59:11 +01:00
OPTYAP_ERROR_CHECKING ( table_try_me , aux_cp - > cp_or_fr ! = DepFr_top_or_fr ( LOCAL_top_dep_fr ) ) ;
2005-04-07 18:56:58 +01:00
aux_cp = B ;
while ( YOUNGER_CP ( aux_cp , DepFr_leader_cp ( LOCAL_top_dep_fr ) ) )
aux_cp = aux_cp - > cp_b ;
2010-04-18 04:59:11 +01:00
OPTYAP_ERROR_CHECKING ( table_try_me , aux_cp ! = DepFr_leader_cp ( LOCAL_top_dep_fr ) ) ;
2005-04-07 18:56:58 +01:00
}
2010-04-18 04:59:11 +01:00
# endif /* DEBUG_OPTYAP */
2005-04-07 18:56:58 +01:00
goto answer_resolution ;
} else {
/* subgoal completed */
2005-07-06 20:34:12 +01:00
ans_node_ptr ans_node = SgFr_first_answer ( sg_fr ) ;
if ( ans_node = = NULL ) {
2005-04-07 18:56:58 +01:00
/* no answers --> fail */
2011-12-05 16:54:22 +00:00
UNLOCK_SG_FR ( sg_fr ) ;
2005-04-07 18:56:58 +01:00
goto fail ;
2006-05-02 09:01:27 +01:00
} else if ( ans_node = = SgFr_answer_trie ( sg_fr ) ) {
2005-04-07 18:56:58 +01:00
/* yes answer --> procceed */
2011-12-05 16:54:22 +00:00
UNLOCK_SG_FR ( sg_fr ) ;
2005-04-07 18:56:58 +01:00
PREG = ( yamop * ) CPREG ;
PREFETCH_OP ( PREG ) ;
YENV = ENV ;
GONext ( ) ;
} else {
2005-07-06 20:34:12 +01:00
/* answers -> get first answer */
2005-08-04 16:45:56 +01:00
# ifdef LIMIT_TABLING
if ( SgFr_state ( sg_fr ) = = complete | | SgFr_state ( sg_fr ) = = compiled ) {
SgFr_state ( sg_fr ) + + ; /* complete --> complete_in_use : compiled --> compiled_in_use */
remove_from_global_sg_fr_list ( sg_fr ) ;
TRAIL_FRAME ( sg_fr ) ;
}
# endif /* LIMIT_TABLING */
2011-12-22 16:50:20 +00:00
# if defined(THREADS_FULL_SHARING) || defined(THREADS_CONSUMER_SHARING)
if ( IsMode_LoadAnswers ( TabEnt_mode ( tab_ent ) ) | | SgFr_active_workers ( sg_fr ) > 0 ) {
# else
if ( IsMode_LoadAnswers ( TabEnt_mode ( tab_ent ) ) ) {
# endif /* THREADS_FULL_SHARING || THREADS_CONSUMER_SHARING */
2005-07-06 20:34:12 +01:00
/* load answers from the trie */
2011-12-05 16:54:22 +00:00
UNLOCK_SG_FR ( sg_fr ) ;
2005-07-06 20:34:12 +01:00
if ( TrNode_child ( ans_node ) ! = NULL ) {
store_loader_node ( tab_ent , ans_node ) ;
}
PREG = ( yamop * ) CPREG ;
PREFETCH_OP ( PREG ) ;
2009-09-27 02:31:31 +01:00
load_answer ( ans_node , YENV ) ;
2005-07-06 20:34:12 +01:00
YENV = ENV ;
GONext ( ) ;
} else {
/* execute compiled code from the trie */
2011-12-22 16:50:20 +00:00
# if defined(THREADS_FULL_SHARING) || defined(THREADS_CONSUMER_SHARING)
if ( SgFr_sg_ent_state ( sg_fr ) < compiled )
# else
2005-08-04 16:45:56 +01:00
if ( SgFr_state ( sg_fr ) < compiled )
2011-12-22 16:50:20 +00:00
# endif /*THREADS_FULL_SHARING || THREADS_CONSUMER_SHARING*/
2005-07-06 20:34:12 +01:00
update_answer_trie ( sg_fr ) ;
2011-12-05 16:54:22 +00:00
UNLOCK_SG_FR ( sg_fr ) ;
2005-07-06 20:34:12 +01:00
PREG = ( yamop * ) TrNode_child ( SgFr_answer_trie ( sg_fr ) ) ;
PREFETCH_OP ( PREG ) ;
* - - YENV = 0 ; /* vars_arity */
* - - YENV = 0 ; /* heap_arity */
GONext ( ) ;
}
2001-04-09 20:54:03 +01:00
}
}
ENDPBOp ( ) ;
2005-06-03 09:19:18 +01:00
2010-04-03 05:58:14 +01:00
/************************************************************************
* * table_try * *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2008-09-05 05:22:19 +01:00
PBOp ( table_try , Otapl )
2003-12-18 16:38:40 +00:00
tab_ent_ptr tab_ent ;
sg_fr_ptr sg_fr ;
2005-08-05 15:55:03 +01:00
check_trail ( TR ) ;
2014-05-30 01:06:09 +01:00
tab_ent = PREG - > y_u . Otapl . te ;
2006-01-17 14:10:42 +00:00
YENV2MEM ;
sg_fr = subgoal_search ( PREG , YENV_ADDRESS ) ;
MEM2YENV ;
2011-12-22 16:50:20 +00:00
# if defined(THREADS_FULL_SHARING) || defined(THREADS_CONSUMER_SHARING)
if ( SgFr_state ( sg_fr ) < = ready ) {
LOCK_SG_FR ( sg_fr ) ;
if ( SgFr_sg_ent_state ( sg_fr ) > = complete )
SgFr_state ( sg_fr ) = SgFr_sg_ent_state ( sg_fr ) ;
else
SgFr_active_workers ( sg_fr ) + + ;
UNLOCK_SG_FR ( sg_fr ) ;
}
# endif /* THREADS_FULL_SHARING || THREADS_CONSUMER_SHARING */
2011-12-05 16:54:22 +00:00
LOCK_SG_FR ( sg_fr ) ;
2011-12-22 16:50:20 +00:00
# ifdef THREADS_CONSUMER_SHARING
if ( SgFr_state ( sg_fr ) = = ready_external ) {
init_subgoal_frame ( sg_fr ) ;
UNLOCK_SG_FR ( sg_fr ) ;
2014-05-30 01:06:09 +01:00
store_generator_consumer_node ( tab_ent , sg_fr , TRUE , PREG - > y_u . Otapl . s ) ;
2011-12-22 16:50:20 +00:00
PREFETCH_OP ( PREG ) ;
allocate_environment ( ) ;
check_for_deadlock ( sg_fr ) ;
goto answer_resolution_completion ;
} else
# endif /* THREADS_CONSUMER_SHARING */
2005-08-04 16:45:56 +01:00
if ( SgFr_state ( sg_fr ) = = ready ) {
2005-08-01 16:40:39 +01:00
/* subgoal new */
2005-04-07 18:56:58 +01:00
init_subgoal_frame ( sg_fr ) ;
2011-12-05 16:54:22 +00:00
UNLOCK_SG_FR ( sg_fr ) ;
2014-05-30 01:06:09 +01:00
store_generator_node ( tab_ent , sg_fr , PREG - > y_u . Otapl . s , NEXTOP ( PREG , Otapl ) ) ;
PREG = PREG - > y_u . Otapl . d ;
2003-12-18 16:38:40 +00:00
PREFETCH_OP ( PREG ) ;
2005-05-31 01:49:49 +01:00
allocate_environment ( ) ;
2003-12-18 16:38:40 +00:00
GONext ( ) ;
2005-08-04 16:45:56 +01:00
# ifdef INCOMPLETE_TABLING
} else if ( SgFr_state ( sg_fr ) = = incomplete ) {
2013-12-20 14:56:13 +00:00
if ( IsMode_CoInductive ( TabEnt_flags ( tab_ent ) ) ) {
2013-12-19 17:08:55 +00:00
printf ( " Currently Unsupported \n " ) ;
} else {
/* subgoal incomplete --> start by loading the answers already found */
ans_node_ptr ans_node = SgFr_first_answer ( sg_fr ) ;
CELL * subs_ptr = YENV ;
init_subgoal_frame ( sg_fr ) ;
UNLOCK_SG_FR ( sg_fr ) ;
SgFr_try_answer ( sg_fr ) = ans_node ;
2014-05-30 01:06:09 +01:00
store_generator_node ( tab_ent , sg_fr , PREG - > y_u . Otapl . s , TRY_ANSWER ) ;
2013-12-19 17:08:55 +00:00
PREG = ( yamop * ) CPREG ;
PREFETCH_OP ( PREG ) ;
load_answer ( ans_node , subs_ptr ) ;
YENV = ENV ;
GONext ( ) ;
}
2005-08-04 16:45:56 +01:00
# endif /* INCOMPLETE_TABLING */
2005-04-07 18:56:58 +01:00
} else if ( SgFr_state ( sg_fr ) = = evaluating ) {
2013-12-20 14:56:13 +00:00
if ( IsMode_CoInductive ( TabEnt_flags ( tab_ent ) ) ) {
2013-12-19 17:08:55 +00:00
/* Used for coinductive tabling strategy */
CELL * subs_ptr ;
subs_ptr = ( CELL * ) ( GEN_CP ( SgFr_gen_cp ( sg_fr ) ) + 1 ) ;
subs_ptr + = SgFr_arity ( sg_fr ) ; // Points at the Parent goal Variables
int i ;
for ( i = 0 ; i < subs_ptr [ 0 ] ; i + + )
Yap_unify ( subs_ptr [ i + 1 ] , YENV [ i + 1 ] ) ;
/* yes answer --> procceed */
UNLOCK_SG_FR ( sg_fr ) ;
PREG = ( yamop * ) CPREG ;
PREFETCH_OP ( PREG ) ;
YENV = ENV ; // Consume the variables
GONext ( ) ; // Succeed the goal :-D
} else {
/* subgoal in evaluation */
choiceptr leader_cp ;
2014-03-20 12:32:51 +00:00
# ifdef YAPOR
2013-12-19 17:08:55 +00:00
int leader_dep_on_stack ;
2014-03-20 12:32:51 +00:00
# endif
2013-12-19 17:08:55 +00:00
find_dependency_node ( sg_fr , leader_cp , leader_dep_on_stack ) ;
UNLOCK_SG_FR ( sg_fr ) ;
find_leader_node ( leader_cp , leader_dep_on_stack ) ;
store_consumer_node ( tab_ent , sg_fr , leader_cp , leader_dep_on_stack ) ;
}
2010-04-18 04:59:11 +01:00
# ifdef DEBUG_OPTYAP
2011-06-21 15:19:07 +01:00
if ( GLOBAL_parallel_mode = = PARALLEL_MODE_RUNNING ) {
2005-04-07 18:56:58 +01:00
choiceptr aux_cp ;
aux_cp = B ;
2010-01-14 15:58:19 +00:00
while ( YOUNGER_CP ( aux_cp , Get_LOCAL_top_cp_on_stack ( ) ) )
2005-04-07 18:56:58 +01:00
aux_cp = aux_cp - > cp_b ;
2010-04-18 04:59:11 +01:00
OPTYAP_ERROR_CHECKING ( table_try , aux_cp - > cp_or_fr ! = DepFr_top_or_fr ( LOCAL_top_dep_fr ) ) ;
2005-04-07 18:56:58 +01:00
aux_cp = B ;
while ( YOUNGER_CP ( aux_cp , DepFr_leader_cp ( LOCAL_top_dep_fr ) ) )
aux_cp = aux_cp - > cp_b ;
2010-04-18 04:59:11 +01:00
OPTYAP_ERROR_CHECKING ( table_try , aux_cp ! = DepFr_leader_cp ( LOCAL_top_dep_fr ) ) ;
2005-04-07 18:56:58 +01:00
}
2010-04-18 04:59:11 +01:00
# endif /* DEBUG_OPTYAP */
2005-04-07 18:56:58 +01:00
goto answer_resolution ;
} else {
/* subgoal completed */
2005-07-06 20:34:12 +01:00
ans_node_ptr ans_node = SgFr_first_answer ( sg_fr ) ;
if ( ans_node = = NULL ) {
2005-04-07 18:56:58 +01:00
/* no answers --> fail */
2011-12-05 16:54:22 +00:00
UNLOCK_SG_FR ( sg_fr ) ;
2005-04-07 18:56:58 +01:00
goto fail ;
2006-05-02 09:01:27 +01:00
} else if ( ans_node = = SgFr_answer_trie ( sg_fr ) ) {
2005-04-07 18:56:58 +01:00
/* yes answer --> procceed */
2011-12-05 16:54:22 +00:00
UNLOCK_SG_FR ( sg_fr ) ;
2005-04-07 18:56:58 +01:00
PREG = ( yamop * ) CPREG ;
PREFETCH_OP ( PREG ) ;
YENV = ENV ;
GONext ( ) ;
} else {
2005-07-06 20:34:12 +01:00
/* answers -> get first answer */
2005-08-04 16:45:56 +01:00
# ifdef LIMIT_TABLING
if ( SgFr_state ( sg_fr ) = = complete | | SgFr_state ( sg_fr ) = = compiled ) {
SgFr_state ( sg_fr ) + + ; /* complete --> complete_in_use : compiled --> compiled_in_use */
remove_from_global_sg_fr_list ( sg_fr ) ;
TRAIL_FRAME ( sg_fr ) ;
}
# endif /* LIMIT_TABLING */
2011-12-22 16:50:20 +00:00
# if defined(THREADS_FULL_SHARING) || defined(THREADS_CONSUMER_SHARING)
if ( IsMode_LoadAnswers ( TabEnt_mode ( tab_ent ) ) | | SgFr_active_workers ( sg_fr ) > 0 ) {
# else
if ( IsMode_LoadAnswers ( TabEnt_mode ( tab_ent ) ) ) {
# endif /* THREADS_FULL_SHARING || THREADS_CONSUMER_SHARING */
2005-07-06 20:34:12 +01:00
/* load answers from the trie */
2011-12-05 16:54:22 +00:00
UNLOCK_SG_FR ( sg_fr ) ;
2005-07-06 20:34:12 +01:00
if ( TrNode_child ( ans_node ) ! = NULL ) {
store_loader_node ( tab_ent , ans_node ) ;
}
PREG = ( yamop * ) CPREG ;
PREFETCH_OP ( PREG ) ;
2009-09-27 02:31:31 +01:00
load_answer ( ans_node , YENV ) ;
2005-07-06 20:34:12 +01:00
YENV = ENV ;
GONext ( ) ;
} else {
/* execute compiled code from the trie */
2011-12-22 16:50:20 +00:00
# if defined(THREADS_FULL_SHARING) || defined(THREADS_CONSUMER_SHARING)
if ( SgFr_sg_ent_state ( sg_fr ) < compiled )
# else
2005-08-04 16:45:56 +01:00
if ( SgFr_state ( sg_fr ) < compiled )
2011-12-22 16:50:20 +00:00
# endif /*THREADS_FULL_SHARING || THREADS_CONSUMER_SHARING */
2005-07-06 20:34:12 +01:00
update_answer_trie ( sg_fr ) ;
2011-12-05 16:54:22 +00:00
UNLOCK_SG_FR ( sg_fr ) ;
2005-07-06 20:34:12 +01:00
PREG = ( yamop * ) TrNode_child ( SgFr_answer_trie ( sg_fr ) ) ;
PREFETCH_OP ( PREG ) ;
* - - YENV = 0 ; /* vars_arity */
* - - YENV = 0 ; /* heap_arity */
GONext ( ) ;
}
2003-12-18 16:38:40 +00:00
}
}
ENDPBOp ( ) ;
2010-04-03 05:58:14 +01:00
/************************************************************************
* * table_retry_me * *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2008-09-05 05:22:19 +01:00
Op ( table_retry_me , Otapl )
2014-05-30 01:06:09 +01:00
restore_generator_node ( PREG - > y_u . Otapl . s , PREG - > y_u . Otapl . d ) ;
2003-12-18 16:38:40 +00:00
YENV = ( CELL * ) PROTECT_FROZEN_B ( B ) ;
set_cut ( YENV , B - > cp_b ) ;
SET_BB ( NORM_CP ( YENV ) ) ;
2005-05-31 01:49:49 +01:00
allocate_environment ( ) ;
2008-09-05 05:22:19 +01:00
PREG = NEXTOP ( PREG , Otapl ) ;
2003-12-18 16:38:40 +00:00
GONext ( ) ;
ENDOp ( ) ;
2001-04-09 20:54:03 +01:00
2005-06-03 09:19:18 +01:00
2010-04-03 05:58:14 +01:00
/************************************************************************
* * table_retry * *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2008-09-05 05:22:19 +01:00
Op ( table_retry , Otapl )
2014-05-30 01:06:09 +01:00
restore_generator_node ( PREG - > y_u . Otapl . s , NEXTOP ( PREG , Otapl ) ) ;
2002-11-26 22:19:48 +00:00
YENV = ( CELL * ) PROTECT_FROZEN_B ( B ) ;
set_cut ( YENV , B - > cp_b ) ;
SET_BB ( NORM_CP ( YENV ) ) ;
2005-05-31 01:49:49 +01:00
allocate_environment ( ) ;
2014-05-30 01:06:09 +01:00
PREG = PREG - > y_u . Otapl . d ;
2001-04-09 20:54:03 +01:00
GONext ( ) ;
ENDOp ( ) ;
2010-04-03 05:58:14 +01:00
/************************************************************************
* * table_trust_me * *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2008-09-05 05:22:19 +01:00
Op ( table_trust_me , Otapl )
2014-05-30 01:06:09 +01:00
restore_generator_node ( PREG - > y_u . Otapl . s , COMPLETION ) ;
2009-07-03 00:54:39 +01:00
# ifdef DETERMINISTIC_TABLING
if ( B_FZ > B & & IS_BATCHED_NORM_GEN_CP ( B ) ) {
2014-05-30 01:06:09 +01:00
CELL * subs_ptr = ( CELL * ) ( GEN_CP ( B ) + 1 ) + PREG - > y_u . Otapl . s ;
2009-07-03 00:54:39 +01:00
choiceptr gcp = NORM_CP ( DET_GEN_CP ( subs_ptr ) - 1 ) ;
sg_fr_ptr sg_fr = GEN_CP ( B ) - > cp_sg_fr ;
DET_GEN_CP ( gcp ) - > cp_sg_fr = sg_fr ;
2009-08-09 03:38:07 +01:00
gcp - > cp_h = B - > cp_h ;
2009-07-03 00:54:39 +01:00
# ifdef DEPTH_LIMIT
gcp - > cp_depth = B - > cp_depth ;
# endif /* DEPTH_LIMIT */
gcp - > cp_tr = B - > cp_tr ;
gcp - > cp_b = B - > cp_b ;
gcp - > cp_ap = B - > cp_ap ;
SgFr_gen_cp ( sg_fr ) = B = gcp ;
}
# endif /* DETERMINISTIC_TABLING */
2002-11-26 22:19:48 +00:00
YENV = ( CELL * ) PROTECT_FROZEN_B ( B ) ;
set_cut ( YENV , B - > cp_b ) ;
SET_BB ( NORM_CP ( YENV ) ) ;
2005-05-31 01:49:49 +01:00
allocate_environment ( ) ;
2008-09-05 05:22:19 +01:00
PREG = NEXTOP ( PREG , Otapl ) ;
2001-04-09 20:54:03 +01:00
GONext ( ) ;
ENDOp ( ) ;
2005-06-03 09:19:18 +01:00
2010-04-03 05:58:14 +01:00
/************************************************************************
* * table_trust * *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2008-09-05 05:22:19 +01:00
Op ( table_trust , Otapl )
2014-05-30 01:06:09 +01:00
restore_generator_node ( PREG - > y_u . Otapl . s , COMPLETION ) ;
2009-07-03 00:54:39 +01:00
# ifdef DETERMINISTIC_TABLING
if ( B_FZ > B & & IS_BATCHED_NORM_GEN_CP ( B ) ) {
2014-05-30 01:06:09 +01:00
CELL * subs_ptr = ( CELL * ) ( GEN_CP ( B ) + 1 ) + PREG - > y_u . Otapl . s ;
2009-07-03 00:54:39 +01:00
choiceptr gcp = NORM_CP ( DET_GEN_CP ( subs_ptr ) - 1 ) ;
sg_fr_ptr sg_fr = GEN_CP ( B ) - > cp_sg_fr ;
DET_GEN_CP ( gcp ) - > cp_sg_fr = sg_fr ;
2009-08-09 03:38:07 +01:00
gcp - > cp_h = B - > cp_h ;
2009-07-03 00:54:39 +01:00
# ifdef DEPTH_LIMIT
gcp - > cp_depth = B - > cp_depth ;
# endif /* DEPTH_LIMIT */
gcp - > cp_tr = B - > cp_tr ;
gcp - > cp_b = B - > cp_b ;
gcp - > cp_ap = B - > cp_ap ;
SgFr_gen_cp ( sg_fr ) = B = gcp ;
}
# endif /* DETERMINISTIC_TABLING */
2003-12-18 16:38:40 +00:00
YENV = ( CELL * ) PROTECT_FROZEN_B ( B ) ;
set_cut ( YENV , B - > cp_b ) ;
SET_BB ( NORM_CP ( YENV ) ) ;
2005-05-31 01:49:49 +01:00
allocate_environment ( ) ;
2014-05-30 01:06:09 +01:00
PREG = PREG - > y_u . Otapl . d ;
2003-12-18 16:38:40 +00:00
GONext ( ) ;
ENDOp ( ) ;
2001-04-09 20:54:03 +01:00
2005-06-03 09:19:18 +01:00
2010-04-03 05:58:14 +01:00
/************************************************************************
* * table_new_answer * *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2001-04-09 20:54:03 +01:00
PBOp ( table_new_answer , s )
CELL * subs_ptr ;
2005-04-07 18:56:58 +01:00
choiceptr gcp ;
2001-04-09 20:54:03 +01:00
sg_fr_ptr sg_fr ;
ans_node_ptr ans_node ;
2005-04-07 18:56:58 +01:00
gcp = NORM_CP ( YENV [ E_B ] ) ;
2009-07-03 00:54:39 +01:00
# ifdef DETERMINISTIC_TABLING
if ( IS_DET_GEN_CP ( gcp ) ) {
sg_fr = DET_GEN_CP ( gcp ) - > cp_sg_fr ;
subs_ptr = ( CELL * ) ( DET_GEN_CP ( gcp ) + 1 ) ;
} else
# endif /* DETERMINISTIC_TABLING */
{
sg_fr = GEN_CP ( gcp ) - > cp_sg_fr ;
2014-05-30 01:06:09 +01:00
subs_ptr = ( CELL * ) ( GEN_CP ( gcp ) + 1 ) + PREG - > y_u . s . s ;
2009-07-03 00:54:39 +01:00
}
2010-04-18 04:59:11 +01:00
# if defined(DEBUG_TABLING) && !defined(DETERMINISTIC_TABLING)
2001-04-09 20:54:03 +01:00
{
int i , j , arity_args , arity_subs ;
CELL * aux_args ;
CELL * aux_subs ;
2014-05-30 01:06:09 +01:00
arity_args = PREG - > y_u . s . s ;
2001-04-09 20:54:03 +01:00
arity_subs = * subs_ptr ;
2005-04-07 18:56:58 +01:00
aux_args = ( CELL * ) ( GEN_CP ( gcp ) + 1 ) ;
2001-04-09 20:54:03 +01:00
aux_subs = subs_ptr ;
for ( i = 1 ; i < = arity_subs ; i + + ) {
Term term_subs = Deref ( * ( aux_subs + i ) ) ;
for ( j = 0 ; j < arity_args ; j + + ) {
Term term_arg = Deref ( * ( aux_args + j ) ) ;
if ( term_subs = = term_arg ) break ;
}
2010-04-18 04:59:11 +01:00
TABLING_ERROR_CHECKING ( table_new_answer , j = = arity_args ) ;
2001-04-09 20:54:03 +01:00
}
}
2010-04-18 04:59:11 +01:00
# endif /* DEBUG_TABLING && !DETERMINISTIC_TABLING */
2011-11-15 16:57:51 +00:00
LOCK_ANSWER_TRIE ( sg_fr ) ;
2011-10-22 16:49:13 +01:00
# ifdef MODE_DIRECTED_TABLING
2011-11-15 16:57:51 +00:00
if ( SgFr_mode_directed ( sg_fr ) ) {
ans_node = mode_directed_answer_search ( sg_fr , subs_ptr ) ;
if ( ans_node = = NULL ) {
/* no answer inserted */
UNLOCK_ANSWER_TRIE ( sg_fr ) ;
goto fail ;
}
} else
2011-11-09 11:00:31 +00:00
# endif /* MODE_DIRECTED_TABLING */
2011-11-15 16:57:51 +00:00
ans_node = answer_search ( sg_fr , subs_ptr ) ;
LOCK_ANSWER_NODE ( ans_node ) ;
2001-04-09 20:54:03 +01:00
if ( ! IS_ANSWER_LEAF_NODE ( ans_node ) ) {
/* new answer */
# ifdef TABLING_INNER_CUTS
/* check for potencial prunings */
2011-05-10 11:47:18 +01:00
if ( ! BITMAP_empty ( GLOBAL_bm_pruning_workers ) ) {
2001-04-09 20:54:03 +01:00
int until_depth , depth ;
until_depth = OrFr_depth ( SgFr_gen_top_or_fr ( sg_fr ) ) ;
depth = OrFr_depth ( LOCAL_top_or_fr ) ;
if ( depth > until_depth ) {
int i , ltt ;
bitmap prune_members , members ;
or_fr_ptr leftmost_or_fr , or_fr , nearest_or_fr ;
2011-05-10 11:47:18 +01:00
BITMAP_copy ( prune_members , GLOBAL_bm_pruning_workers ) ;
2001-04-09 20:54:03 +01:00
BITMAP_delete ( prune_members , worker_id ) ;
ltt = BRANCH_LTT ( worker_id , depth ) ;
BITMAP_intersection ( members , prune_members , OrFr_members ( LOCAL_top_or_fr ) ) ;
if ( members ) {
2011-05-10 11:47:18 +01:00
for ( i = 0 ; i < GLOBAL_number_workers ; i + + ) {
2001-04-09 20:54:03 +01:00
if ( BITMAP_member ( members , i ) & &
BRANCH_LTT ( i , depth ) > ltt & &
2010-01-14 15:58:19 +00:00
EQUAL_OR_YOUNGER_CP ( Get_LOCAL_top_cp ( ) , REMOTE_pruning_scope ( i ) ) ) {
2001-04-09 20:54:03 +01:00
leftmost_or_fr = LOCAL_top_or_fr ;
pending_table_new_answer :
2011-11-15 16:57:51 +00:00
UNLOCK_ANSWER_NODE ( ans_node ) ;
UNLOCK_ANSWER_TRIE ( sg_fr ) ;
2001-04-09 20:54:03 +01:00
LOCK_OR_FRAME ( leftmost_or_fr ) ;
2010-01-27 11:01:28 +00:00
if ( Get_LOCAL_prune_request ( ) ) {
2001-04-09 20:54:03 +01:00
UNLOCK_OR_FRAME ( leftmost_or_fr ) ;
SCHEDULER_GET_WORK ( ) ;
} else {
2005-04-07 18:56:58 +01:00
CUT_store_tg_answer ( leftmost_or_fr , ans_node , gcp , ltt ) ;
2001-04-09 20:54:03 +01:00
UNLOCK_OR_FRAME ( leftmost_or_fr ) ;
}
2005-04-07 18:56:58 +01:00
if ( IS_BATCHED_GEN_CP ( gcp ) ) {
/* deallocate and procceed */
PREG = ( yamop * ) YENV [ E_CP ] ;
PREFETCH_OP ( PREG ) ;
CPREG = PREG ;
SREG = YENV ;
ENV = YENV = ( CELL * ) YENV [ E_E ] ;
2005-05-31 01:49:49 +01:00
# ifdef DEPTH_LIMIT
DEPTH = YENV [ E_DEPTH ] ;
# endif /* DEPTH_LIMIT */
2005-04-07 18:56:58 +01:00
GONext ( ) ;
} else {
/* fail */
goto fail ;
}
2001-04-09 20:54:03 +01:00
}
}
BITMAP_minus ( prune_members , members ) ;
}
leftmost_or_fr = OrFr_nearest_leftnode ( LOCAL_top_or_fr ) ;
depth = OrFr_depth ( leftmost_or_fr ) ;
if ( depth > until_depth ) {
ltt = BRANCH_LTT ( worker_id , depth ) ;
BITMAP_intersection ( members , prune_members , OrFr_members ( leftmost_or_fr ) ) ;
if ( members ) {
2011-05-10 11:47:18 +01:00
for ( i = 0 ; i < GLOBAL_number_workers ; i + + ) {
2001-04-09 20:54:03 +01:00
if ( BITMAP_member ( members , i ) & &
BRANCH_LTT ( i , depth ) > ltt & &
2010-01-14 17:38:39 +00:00
EQUAL_OR_YOUNGER_CP ( GetOrFr_node ( leftmost_or_fr ) , REMOTE_pruning_scope ( i ) ) )
2001-04-09 20:54:03 +01:00
goto pending_table_new_answer ;
}
BITMAP_minus ( prune_members , members ) ;
}
/* reaching that point we should update the nearest leftnode data */
leftmost_or_fr = OrFr_nearest_leftnode ( leftmost_or_fr ) ;
depth = OrFr_depth ( leftmost_or_fr ) ;
while ( depth > until_depth ) {
ltt = BRANCH_LTT ( worker_id , depth ) ;
BITMAP_intersection ( members , prune_members , OrFr_members ( leftmost_or_fr ) ) ;
if ( members ) {
2011-05-10 11:47:18 +01:00
for ( i = 0 ; i < GLOBAL_number_workers ; i + + ) {
2001-04-09 20:54:03 +01:00
if ( BITMAP_member ( members , i ) & &
BRANCH_LTT ( i , depth ) > ltt & &
2010-01-14 17:38:39 +00:00
EQUAL_OR_YOUNGER_CP ( GetOrFr_node ( leftmost_or_fr ) , REMOTE_pruning_scope ( i ) ) ) {
2001-04-09 20:54:03 +01:00
/* update nearest leftnode data */
or_fr = LOCAL_top_or_fr ;
nearest_or_fr = OrFr_nearest_leftnode ( or_fr ) ;
while ( OrFr_depth ( nearest_or_fr ) > depth ) {
LOCK_OR_FRAME ( or_fr ) ;
OrFr_nearest_leftnode ( or_fr ) = leftmost_or_fr ;
UNLOCK_OR_FRAME ( or_fr ) ;
or_fr = nearest_or_fr ;
nearest_or_fr = OrFr_nearest_leftnode ( or_fr ) ;
}
goto pending_table_new_answer ;
}
}
BITMAP_minus ( prune_members , members ) ;
}
leftmost_or_fr = OrFr_nearest_leftnode ( leftmost_or_fr ) ;
depth = OrFr_depth ( leftmost_or_fr ) ;
}
/* update nearest leftnode data */
or_fr = LOCAL_top_or_fr ;
nearest_or_fr = OrFr_nearest_leftnode ( or_fr ) ;
while ( OrFr_depth ( nearest_or_fr ) > depth ) {
LOCK_OR_FRAME ( or_fr ) ;
OrFr_nearest_leftnode ( or_fr ) = leftmost_or_fr ;
UNLOCK_OR_FRAME ( or_fr ) ;
or_fr = nearest_or_fr ;
nearest_or_fr = OrFr_nearest_leftnode ( or_fr ) ;
}
}
}
}
/* check for prune requests */
2010-01-27 11:01:28 +00:00
if ( Get_LOCAL_prune_request ( ) ) {
2011-11-15 16:57:51 +00:00
UNLOCK_ANSWER_NODE ( ans_node ) ;
UNLOCK_ANSWER_TRIE ( sg_fr ) ;
2001-04-09 20:54:03 +01:00
SCHEDULER_GET_WORK ( ) ;
}
# endif /* TABLING_INNER_CUTS */
TAG_AS_ANSWER_LEAF_NODE ( ans_node ) ;
2011-12-22 16:50:20 +00:00
# ifdef THREADS_FULL_SHARING
INFO_THREADS ( " new answer (1) sgfr=%p ans_node=%p " , SgFr_sg_ent ( sg_fr ) , ans_node ) ;
if ( IsMode_Batched ( TabEnt_mode ( SgFr_tab_ent ( sg_fr ) ) ) ) {
ANSWER_LEAF_NODE_INSTR_RELATIVE ( ans_node ) ;
if ( worker_id < ANSWER_LEAF_NODE_MAX_THREADS )
ANSWER_LEAF_NODE_SET_WID ( ans_node , worker_id ) ;
}
# endif /* THREADS_FULL_SHARING */
2011-11-15 16:57:51 +00:00
UNLOCK_ANSWER_NODE ( ans_node ) ;
# ifndef ANSWER_TRIE_LOCK_AT_ENTRY_LEVEL
2011-12-05 16:54:22 +00:00
LOCK_SG_FR ( sg_fr ) ;
2011-11-15 16:57:51 +00:00
# endif /* ! ANSWER_TRIE_LOCK_AT_ENTRY_LEVEL */
2005-05-31 01:49:49 +01:00
if ( SgFr_first_answer ( sg_fr ) = = NULL )
SgFr_first_answer ( sg_fr ) = ans_node ;
else
2001-04-09 20:54:03 +01:00
TrNode_child ( SgFr_last_answer ( sg_fr ) ) = ans_node ;
SgFr_last_answer ( sg_fr ) = ans_node ;
2010-04-18 04:59:11 +01:00
# ifdef DEBUG_TABLING
2001-04-09 20:54:03 +01:00
{
ans_node_ptr aux_ans_node = SgFr_first_answer ( sg_fr ) ;
while ( aux_ans_node ! = SgFr_last_answer ( sg_fr ) ) {
2010-04-18 04:59:11 +01:00
TABLING_ERROR_CHECKING ( table_new_answer , ! IS_ANSWER_LEAF_NODE ( aux_ans_node ) ) ;
2001-04-09 20:54:03 +01:00
aux_ans_node = TrNode_child ( aux_ans_node ) ;
}
}
2010-04-18 04:59:11 +01:00
# endif /* DEBUG_TABLING */
2011-12-05 16:54:22 +00:00
UNLOCK_SG_FR ( sg_fr ) ;
2005-04-07 18:56:58 +01:00
if ( IS_BATCHED_GEN_CP ( gcp ) ) {
2011-12-22 16:50:20 +00:00
# ifdef THREADS_FULL_SHARING
if ( worker_id > = ANSWER_LEAF_NODE_MAX_THREADS )
SgFr_batched_cached_answers_check_insert ( sg_fr , ans_node ) ; //add to buffer all answers except the ans_node
# endif /* THREADS_FULL_SHARING */
2009-08-06 02:27:59 +01:00
# ifdef TABLING_EARLY_COMPLETION
2009-08-08 03:53:51 +01:00
if ( gcp = = PROTECT_FROZEN_B ( B ) & & ( * subs_ptr = = 0 | | gcp - > cp_ap = = COMPLETION ) ) {
/* if the current generator choice point is the topmost choice point and the current */
/* call is deterministic (i.e., the number of substitution variables is zero or */
/* there are no more alternatives) then the current answer is deterministic and we */
/* can perform an early completion and remove the current generator choice point */
2009-07-03 00:54:39 +01:00
private_completion ( sg_fr ) ;
B = B - > cp_b ;
SET_BB ( PROTECT_FROZEN_B ( B ) ) ;
2009-08-08 03:53:51 +01:00
} else if ( * subs_ptr = = 0 ) {
/* if the number of substitution variables is zero, an answer is sufficient to perform */
/* an early completion, but the current generator choice point cannot be removed */
mark_as_completed ( sg_fr ) ;
2009-08-06 02:27:59 +01:00
if ( gcp - > cp_ap ! = NULL )
gcp - > cp_ap = COMPLETION ;
2008-05-20 19:25:37 +01:00
}
2009-08-06 02:27:59 +01:00
# endif /* TABLING_EARLY_COMPLETION */
2005-04-07 18:56:58 +01:00
/* deallocate and procceed */
PREG = ( yamop * ) YENV [ E_CP ] ;
PREFETCH_OP ( PREG ) ;
CPREG = PREG ;
SREG = YENV ;
ENV = YENV = ( CELL * ) YENV [ E_E ] ;
2005-05-31 01:49:49 +01:00
# ifdef DEPTH_LIMIT
DEPTH = YENV [ E_DEPTH ] ;
# endif /* DEPTH_LIMIT */
2005-04-07 18:56:58 +01:00
GONext ( ) ;
} else {
2009-08-06 02:27:59 +01:00
# ifdef TABLING_EARLY_COMPLETION
if ( * subs_ptr = = 0 ) {
2009-08-08 03:53:51 +01:00
/* if the number of substitution variables is zero, an answer is sufficient to perform */
/* an early completion, but the current generator choice point cannot be removed */
mark_as_completed ( sg_fr ) ;
2009-08-06 02:27:59 +01:00
if ( gcp - > cp_ap ! = ANSWER_RESOLUTION )
gcp - > cp_ap = COMPLETION ;
2008-05-20 19:25:37 +01:00
}
2009-08-06 02:27:59 +01:00
# endif /* TABLING_EARLY_COMPLETION */
2005-04-07 18:56:58 +01:00
/* fail */
goto fail ;
}
2001-04-09 20:54:03 +01:00
} else {
/* repeated answer */
2011-12-22 16:50:20 +00:00
# ifdef THREADS_FULL_SHARING
if ( IsMode_Batched ( TabEnt_mode ( SgFr_tab_ent ( sg_fr ) ) ) ) {
if ( worker_id > = ANSWER_LEAF_NODE_MAX_THREADS ) {
UNLOCK_ANSWER_NODE ( ans_node ) ;
UNLOCK_ANSWER_TRIE ( sg_fr ) ;
SgFr_batched_cached_answers_check_insert ( sg_fr , NULL ) ;
INFO_THREADS ( " new answer (2) sgfr=%p ans_node=%p " , SgFr_sg_ent ( sg_fr ) , ans_node ) ;
if ( SgFr_batched_cached_answers_check_remove ( sg_fr , ans_node ) = = 1 ) {
INFO_THREADS ( " ans_node=%p not found " , ans_node ) ;
goto fail ;
}
/* deallocate and procceed */
PREG = ( yamop * ) YENV [ E_CP ] ;
PREFETCH_OP ( PREG ) ;
CPREG = PREG ;
SREG = YENV ;
ENV = YENV = ( CELL * ) YENV [ E_E ] ;
# ifdef DEPTH_LIMIT
DEPTH = YENV [ E_DEPTH ] ;
# endif /*DEPTH_LIMIT */
GONext ( ) ;
} else {
if ( ! ANSWER_LEAF_NODE_CHECK_WID ( ans_node , worker_id ) ) {
ANSWER_LEAF_NODE_SET_WID ( ans_node , worker_id ) ;
UNLOCK_ANSWER_NODE ( ans_node ) ;
UNLOCK_ANSWER_TRIE ( sg_fr ) ;
/* deallocate and procceed */
INFO_THREADS ( " new answer (2) sgfr=%p ans_node=%p " , SgFr_sg_ent ( sg_fr ) , ans_node ) ;
PREG = ( yamop * ) YENV [ E_CP ] ;
PREFETCH_OP ( PREG ) ;
CPREG = PREG ;
SREG = YENV ;
ENV = YENV = ( CELL * ) YENV [ E_E ] ;
# ifdef DEPTH_LIMIT
DEPTH = YENV [ E_DEPTH ] ;
# endif /*DEPTH_LIMIT */
GONext ( ) ;
}
}
}
# else
2011-11-15 16:57:51 +00:00
UNLOCK_ANSWER_NODE ( ans_node ) ;
UNLOCK_ANSWER_TRIE ( sg_fr ) ;
2011-12-22 16:50:20 +00:00
# endif /* THREADS_FULL_SHARING */
# if defined(THREADS_FULL_SHARING) || defined(THREADS_CONSUMER_SHARING)
INFO_THREADS ( " new answer(rep) sgfr=%p ans_node=%p " , SgFr_sg_ent ( sg_fr ) , ans_node ) ;
# else
INFO_THREADS ( " new answer(rep) sgfr=%p ans_node=%p " , sg_fr , ans_node ) ;
# endif /* THREADS_FULL_SHARING || THREADS_CONSUMER_SHARING */
2001-04-09 20:54:03 +01:00
goto fail ;
}
ENDPBOp ( ) ;
2010-04-03 05:58:14 +01:00
/************************************************************************
* * table_answer_resolution * *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2008-09-05 05:22:19 +01:00
BOp ( table_answer_resolution , Otapl )
2001-04-09 20:54:03 +01:00
# ifdef YAPOR
if ( SCH_top_shared_cp ( B ) ) {
UNLOCK_OR_FRAME ( LOCAL_top_or_fr ) ;
}
# endif /* YAPOR */
2006-05-02 09:01:27 +01:00
2001-04-09 20:54:03 +01:00
answer_resolution :
2017-04-13 21:42:34 +01:00
INIT_PREFETCH ( )
dep_fr_ptr dep_fr ;
ans_node_ptr ans_node ;
OPTYAP_ERROR_CHECKING ( answer_resolution , SCH_top_shared_cp ( B ) & & B - > cp_or_fr - > alternative ! = ANSWER_RESOLUTION ) ;
OPTYAP_ERROR_CHECKING ( answer_resolution , ! SCH_top_shared_cp ( B ) & & B - > cp_ap ! = ANSWER_RESOLUTION ) ;
dep_fr = CONS_CP ( B ) - > cp_dep_fr ;
LOCK_DEP_FR ( dep_fr ) ;
ans_node = DepFr_last_answer ( dep_fr ) ;
if ( TrNode_child ( ans_node ) ) {
/* unconsumed answers */
2011-10-22 16:49:13 +01:00
# ifdef MODE_DIRECTED_TABLING
2017-04-13 21:42:34 +01:00
if ( IS_ANSWER_INVALID_NODE ( TrNode_child ( ans_node ) ) ) {
ans_node_ptr old_ans_node ;
old_ans_node = ans_node ;
2011-11-09 11:00:31 +00:00
ans_node = TrNode_child ( ans_node ) ;
2017-04-13 21:42:34 +01:00
do {
ans_node = TrNode_child ( ans_node ) ;
} while ( IS_ANSWER_INVALID_NODE ( ans_node ) ) ;
TrNode_child ( old_ans_node ) = ans_node ;
} else
2011-11-09 11:00:31 +00:00
# endif /* MODE_DIRECTED_TABLING */
2017-04-13 21:42:34 +01:00
ans_node = TrNode_child ( ans_node ) ;
DepFr_last_answer ( dep_fr ) = ans_node ;
UNLOCK_DEP_FR ( dep_fr ) ;
consume_answer_and_procceed ( dep_fr , ans_node ) ;
}
2011-12-05 16:54:22 +00:00
UNLOCK_DEP_FR ( dep_fr ) ;
2001-04-09 20:54:03 +01:00
2005-04-07 18:56:58 +01:00
# ifdef YAPOR
2017-04-13 21:42:34 +01:00
if ( B = = DepFr_leader_cp ( LOCAL_top_dep_fr ) ) {
/* B is a generator-consumer node **
* * never here if batched scheduling */
TABLING_ERROR_CHECKING ( answer_resolution , IS_BATCHED_GEN_CP ( B ) ) ;
goto completion ;
}
2005-04-07 18:56:58 +01:00
# endif /* YAPOR */
2001-04-09 20:54:03 +01:00
/* no unconsumed answers */
if ( DepFr_backchain_cp ( dep_fr ) = = NULL ) {
/* normal backtrack */
# ifdef YAPOR
if ( SCH_top_shared_cp ( B ) ) {
SCHEDULER_GET_WORK ( ) ;
}
# endif /* YAPOR */
B = B - > cp_b ;
goto fail ;
} else {
/* chain backtrack */
choiceptr top_chain_cp , chain_cp ;
# ifdef YAPOR
or_fr_ptr start_or_fr , end_or_fr ;
# endif /* YAPOR */
/* find chain choice point to backtrack */
top_chain_cp = DepFr_backchain_cp ( dep_fr ) ;
chain_cp = DepFr_leader_cp ( LOCAL_top_dep_fr ) ;
if ( YOUNGER_CP ( top_chain_cp , chain_cp ) )
chain_cp = top_chain_cp ;
2010-04-18 04:59:11 +01:00
TABLING_ERROR_CHECKING ( answer_resolution , EQUAL_OR_YOUNGER_CP ( top_chain_cp , B ) ) ;
TABLING_ERROR_CHECKING ( answer_resolution , EQUAL_OR_YOUNGER_CP ( chain_cp , B ) ) ;
2001-04-09 20:54:03 +01:00
/* check for dependency frames with unconsumed answers */
dep_fr = DepFr_next ( dep_fr ) ;
while ( YOUNGER_CP ( DepFr_cons_cp ( dep_fr ) , chain_cp ) ) {
2011-12-05 16:54:22 +00:00
LOCK_DEP_FR ( dep_fr ) ;
2005-04-07 18:56:58 +01:00
ans_node = DepFr_last_answer ( dep_fr ) ;
2011-11-09 11:00:31 +00:00
if ( TrNode_child ( ans_node ) ) {
/* dependency frame with unconsumed answers */
2011-10-22 16:49:13 +01:00
# ifdef MODE_DIRECTED_TABLING
2011-12-22 16:50:20 +00:00
if ( IS_ANSWER_INVALID_NODE ( TrNode_child ( ans_node ) ) ) {
2011-11-16 12:47:43 +00:00
ans_node_ptr old_ans_node ;
old_ans_node = ans_node ;
2011-11-09 11:00:31 +00:00
ans_node = TrNode_child ( ans_node ) ;
2011-11-11 19:17:55 +00:00
do {
ans_node = TrNode_child ( ans_node ) ;
2011-12-22 16:50:20 +00:00
} while ( IS_ANSWER_INVALID_NODE ( ans_node ) ) ;
2011-11-16 12:47:43 +00:00
TrNode_child ( old_ans_node ) = ans_node ;
2011-11-11 19:17:55 +00:00
} else
2011-11-09 11:00:31 +00:00
# endif /* MODE_DIRECTED_TABLING */
2011-11-11 19:17:55 +00:00
ans_node = TrNode_child ( ans_node ) ;
2011-11-09 11:00:31 +00:00
DepFr_last_answer ( dep_fr ) = ans_node ;
2001-04-09 20:54:03 +01:00
# ifdef YAPOR
if ( YOUNGER_CP ( DepFr_backchain_cp ( dep_fr ) , top_chain_cp ) )
# endif /* YAPOR */
DepFr_backchain_cp ( dep_fr ) = top_chain_cp ;
2011-12-05 16:54:22 +00:00
UNLOCK_DEP_FR ( dep_fr ) ;
2001-04-09 20:54:03 +01:00
chain_cp = DepFr_cons_cp ( dep_fr ) ;
# ifdef YAPOR
/* update shared nodes */
start_or_fr = LOCAL_top_or_fr ;
end_or_fr = DepFr_top_or_fr ( dep_fr ) ;
if ( start_or_fr ! = end_or_fr ) {
LOCAL_top_or_fr = end_or_fr ;
2010-01-14 17:38:39 +00:00
Set_LOCAL_top_cp ( GetOrFr_node ( end_or_fr ) ) ;
2001-04-09 20:54:03 +01:00
do {
2010-01-14 17:38:39 +00:00
while ( YOUNGER_CP ( GetOrFr_node ( start_or_fr ) , GetOrFr_node ( end_or_fr ) ) ) {
2001-04-09 20:54:03 +01:00
LOCK_OR_FRAME ( start_or_fr ) ;
BITMAP_delete ( OrFr_members ( start_or_fr ) , worker_id ) ;
if ( BITMAP_empty ( OrFr_members ( start_or_fr ) ) ) {
if ( frame_with_suspensions_not_collected ( start_or_fr ) ) {
collect_suspension_frames ( start_or_fr ) ;
}
# ifdef TABLING_INNER_CUTS
if ( OrFr_tg_solutions ( start_or_fr ) ) {
tg_sol_fr_ptr tg_solutions ;
or_fr_ptr leftmost_until ;
tg_solutions = OrFr_tg_solutions ( start_or_fr ) ;
leftmost_until = CUT_leftmost_until ( start_or_fr , OrFr_depth ( TgSolFr_gen_cp ( tg_solutions ) - > cp_or_fr ) ) ;
OrFr_tg_solutions ( start_or_fr ) = NULL ;
UNLOCK_OR_FRAME ( start_or_fr ) ;
if ( leftmost_until ) {
LOCK_OR_FRAME ( leftmost_until ) ;
tg_solutions = CUT_store_tg_answers ( leftmost_until , tg_solutions ,
BRANCH_LTT ( worker_id , OrFr_depth ( leftmost_until ) ) ) ;
UNLOCK_OR_FRAME ( leftmost_until ) ;
}
CUT_validate_tg_answers ( tg_solutions ) ;
goto continue_update_loop1 ;
}
# endif /* TABLING_INNER_CUTS */
}
UNLOCK_OR_FRAME ( start_or_fr ) ;
# ifdef TABLING_INNER_CUTS
continue_update_loop1 :
# endif /* TABLING_INNER_CUTS */
start_or_fr = OrFr_next ( start_or_fr ) ;
}
2010-01-14 17:38:39 +00:00
while ( YOUNGER_CP ( GetOrFr_node ( end_or_fr ) , GetOrFr_node ( start_or_fr ) ) ) {
2001-04-09 20:54:03 +01:00
LOCK_OR_FRAME ( end_or_fr ) ;
BITMAP_insert ( OrFr_members ( end_or_fr ) , worker_id ) ;
BRANCH ( worker_id , OrFr_depth ( end_or_fr ) ) = 1 ;
UNLOCK_OR_FRAME ( end_or_fr ) ;
end_or_fr = OrFr_next ( end_or_fr ) ;
}
} while ( start_or_fr ! = end_or_fr ) ;
2010-01-27 11:01:28 +00:00
if ( Get_LOCAL_prune_request ( ) )
2001-04-09 20:54:03 +01:00
pruning_over_tabling_data_structures ( ) ;
}
# endif /* YAPOR */
2010-04-18 04:59:11 +01:00
# ifdef DEBUG_OPTYAP
2011-06-21 15:19:07 +01:00
if ( GLOBAL_parallel_mode = = PARALLEL_MODE_RUNNING ) {
2010-04-18 04:59:11 +01:00
choiceptr aux_cp ;
OPTYAP_ERROR_CHECKING ( completion , YOUNGER_CP ( Get_LOCAL_top_cp ( ) , Get_LOCAL_top_cp_on_stack ( ) ) ) ;
aux_cp = chain_cp ;
while ( aux_cp ! = Get_LOCAL_top_cp ( ) ) {
OPTYAP_ERROR_CHECKING ( completion , YOUNGER_CP ( Get_LOCAL_top_cp ( ) , aux_cp ) ) ;
OPTYAP_ERROR_CHECKING ( completion , EQUAL_OR_YOUNGER_CP ( Get_LOCAL_top_cp_on_stack ( ) , aux_cp ) ) ;
aux_cp = aux_cp - > cp_b ;
}
2001-04-09 20:54:03 +01:00
}
2010-04-18 04:59:11 +01:00
# endif /* DEBUG_OPTYAP */
2001-04-09 20:54:03 +01:00
/* restore bindings, update registers, consume answer and procceed */
restore_bindings ( B - > cp_tr , chain_cp - > cp_tr ) ;
2010-04-18 04:59:11 +01:00
TABLING_ERROR_CHECKING ( answer_resolution , TR ! = B - > cp_tr & & ! IsPairTerm ( ( CELL ) TrailTerm ( TR - 1 ) ) ) ;
TABLING_ERROR_CHECKING ( answer_resolution , TR ! = B - > cp_tr & & ( tr_fr_ptr ) RepPair ( ( CELL ) TrailTerm ( TR - 1 ) ) ! = B - > cp_tr ) ;
2001-04-09 20:54:03 +01:00
B = chain_cp ;
TR = TR_FZ ;
2001-06-08 21:21:59 +01:00
TRAIL_LINK ( B - > cp_tr ) ;
2001-04-09 20:54:03 +01:00
consume_answer_and_procceed ( dep_fr , ans_node ) ;
}
2011-12-05 16:54:22 +00:00
UNLOCK_DEP_FR ( dep_fr ) ;
2001-04-09 20:54:03 +01:00
dep_fr = DepFr_next ( dep_fr ) ;
}
/* no dependency frames with unconsumed answers found */
# ifdef YAPOR
/* update shared nodes */
2010-01-14 15:58:19 +00:00
if ( EQUAL_OR_YOUNGER_CP ( Get_LOCAL_top_cp_on_stack ( ) , chain_cp ) ) {
2001-04-09 20:54:03 +01:00
end_or_fr = chain_cp - > cp_or_fr ;
start_or_fr = LOCAL_top_or_fr ;
if ( start_or_fr ! = end_or_fr ) {
LOCAL_top_or_fr = end_or_fr ;
2010-01-14 17:38:39 +00:00
Set_LOCAL_top_cp ( GetOrFr_node ( end_or_fr ) ) ;
2001-04-09 20:54:03 +01:00
while ( start_or_fr ! = end_or_fr ) {
LOCK_OR_FRAME ( start_or_fr ) ;
BITMAP_delete ( OrFr_members ( start_or_fr ) , worker_id ) ;
if ( BITMAP_empty ( OrFr_members ( start_or_fr ) ) ) {
if ( frame_with_suspensions_not_collected ( start_or_fr ) ) {
collect_suspension_frames ( start_or_fr ) ;
}
# ifdef TABLING_INNER_CUTS
if ( OrFr_tg_solutions ( start_or_fr ) ) {
tg_sol_fr_ptr tg_solutions ;
or_fr_ptr leftmost_until ;
tg_solutions = OrFr_tg_solutions ( start_or_fr ) ;
leftmost_until = CUT_leftmost_until ( start_or_fr , OrFr_depth ( TgSolFr_gen_cp ( tg_solutions ) - > cp_or_fr ) ) ;
OrFr_tg_solutions ( start_or_fr ) = NULL ;
UNLOCK_OR_FRAME ( start_or_fr ) ;
if ( leftmost_until ) {
LOCK_OR_FRAME ( leftmost_until ) ;
tg_solutions = CUT_store_tg_answers ( leftmost_until , tg_solutions ,
BRANCH_LTT ( worker_id , OrFr_depth ( leftmost_until ) ) ) ;
UNLOCK_OR_FRAME ( leftmost_until ) ;
}
CUT_validate_tg_answers ( tg_solutions ) ;
goto continue_update_loop2 ;
}
# endif /* TABLING_INNER_CUTS */
}
UNLOCK_OR_FRAME ( start_or_fr ) ;
# ifdef TABLING_INNER_CUTS
continue_update_loop2 :
# endif /* TABLING_INNER_CUTS */
start_or_fr = OrFr_next ( start_or_fr ) ;
}
2010-01-27 11:01:28 +00:00
if ( Get_LOCAL_prune_request ( ) )
2001-04-09 20:54:03 +01:00
pruning_over_tabling_data_structures ( ) ;
}
}
# endif /* YAPOR */
2010-04-18 04:59:11 +01:00
# ifdef DEBUG_OPTYAP
2011-06-21 15:19:07 +01:00
if ( GLOBAL_parallel_mode = = PARALLEL_MODE_RUNNING ) {
2010-04-18 04:59:11 +01:00
choiceptr aux_cp ;
OPTYAP_ERROR_CHECKING ( completion , YOUNGER_CP ( Get_LOCAL_top_cp ( ) , Get_LOCAL_top_cp_on_stack ( ) ) ) ;
aux_cp = chain_cp ;
while ( aux_cp ! = Get_LOCAL_top_cp ( ) ) {
OPTYAP_ERROR_CHECKING ( completion , YOUNGER_CP ( Get_LOCAL_top_cp ( ) , aux_cp ) ) ;
OPTYAP_ERROR_CHECKING ( completion , EQUAL_OR_YOUNGER_CP ( Get_LOCAL_top_cp_on_stack ( ) , aux_cp ) ) ;
aux_cp = aux_cp - > cp_b ;
2001-04-09 20:54:03 +01:00
}
}
2010-04-18 04:59:11 +01:00
# endif /* DEBUG_OPTYAP */
2001-04-09 20:54:03 +01:00
/* unbind variables */
unbind_variables ( B - > cp_tr , chain_cp - > cp_tr ) ;
2010-04-18 04:59:11 +01:00
TABLING_ERROR_CHECKING ( answer_resolution , TR ! = B - > cp_tr & & ! IsPairTerm ( ( CELL ) TrailTerm ( TR - 1 ) ) ) ;
TABLING_ERROR_CHECKING ( answer_resolution , TR ! = B - > cp_tr & & ( tr_fr_ptr ) RepPair ( ( CELL ) TrailTerm ( TR - 1 ) ) ! = B - > cp_tr ) ;
2005-04-07 18:56:58 +01:00
if ( DepFr_leader_cp ( LOCAL_top_dep_fr ) = = chain_cp & & (
/* chain_cp is a leader node AND ... */
2001-04-09 20:54:03 +01:00
# ifdef YAPOR
2005-04-07 18:56:58 +01:00
/* the leader dependency is not on stack OR ... */
DepFr_leader_dep_is_on_stack ( LOCAL_top_dep_fr ) = = FALSE | |
/* the leader dependency is on stack (this means that chain_cp is a generator node) and */
2001-04-09 20:54:03 +01:00
# endif /* YAPOR */
2005-04-07 18:56:58 +01:00
/* there are no unexploited alternatives **
* * ( NULL if batched scheduling OR ANSWER_RESOLUTION if local scheduling ) */
chain_cp - > cp_ap = = NULL | | chain_cp - > cp_ap = = ANSWER_RESOLUTION ) ) {
B = chain_cp ;
TR = TR_FZ ;
TRAIL_LINK ( B - > cp_tr ) ;
goto completion ;
2001-04-09 20:54:03 +01:00
}
/* backtrack to chain choice point */
PREG = chain_cp - > cp_ap ;
PREFETCH_OP ( PREG ) ;
B = chain_cp ;
TR = TR_FZ ;
2001-06-08 21:21:59 +01:00
TRAIL_LINK ( B - > cp_tr ) ;
2001-04-09 20:54:03 +01:00
GONext ( ) ;
}
END_PREFETCH ( )
ENDBOp ( ) ;
2010-04-03 05:58:14 +01:00
/************************************************************************
* * table_completion * *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2008-09-05 05:22:19 +01:00
BOp ( table_completion , Otapl )
2001-04-09 20:54:03 +01:00
# ifdef YAPOR
if ( SCH_top_shared_cp ( B ) ) {
2005-04-07 18:56:58 +01:00
if ( IS_BATCHED_GEN_CP ( B ) ) {
SCH_new_alternative ( PREG , NULL ) ;
if ( B ! = DepFr_leader_cp ( LOCAL_top_dep_fr ) & & EQUAL_OR_YOUNGER_CP ( B_FZ , B ) ) {
/* not leader on that node */
SCHEDULER_GET_WORK ( ) ;
}
} else {
SCH_new_alternative ( PREG , ANSWER_RESOLUTION ) ;
if ( B ! = DepFr_leader_cp ( LOCAL_top_dep_fr ) ) {
/* not leader on that node */
SCHEDULER_GET_WORK ( ) ;
}
}
2001-04-09 20:54:03 +01:00
} else
# endif /* YAPOR */
2005-04-07 18:56:58 +01:00
{
2011-12-22 16:50:20 +00:00
# ifdef THREADS_CONSUMER_SHARING
goto answer_resolution_completion ;
# endif /* THREADS_CONSUMER_SHARING */
2005-04-07 18:56:58 +01:00
if ( IS_BATCHED_GEN_CP ( B ) ) {
B - > cp_ap = NULL ;
if ( EQUAL_OR_YOUNGER_CP ( B_FZ , B ) & & B ! = DepFr_leader_cp ( LOCAL_top_dep_fr ) ) {
/* not leader on that node */
B = B - > cp_b ;
goto fail ;
}
} else {
B - > cp_ap = ANSWER_RESOLUTION ;
if ( B ! = DepFr_leader_cp ( LOCAL_top_dep_fr ) ) {
/* not leader on that node */
B = B - > cp_b ;
goto fail ;
}
2001-04-09 20:54:03 +01:00
}
}
/* leader on that node */
completion :
2011-12-22 16:50:20 +00:00
# ifdef THREADS_CONSUMER_SHARING
goto answer_resolution_completion ;
# endif /* THREADS_CONSUMER_SHARING */
2017-04-13 21:42:34 +01:00
INIT_PREFETCH ( )
dep_fr_ptr dep_fr ;
ans_node_ptr ans_node ;
2001-04-09 20:54:03 +01:00
# ifdef YAPOR
# ifdef TIMESTAMP_CHECK
long timestamp = 0 ;
# endif /* TIMESTAMP_CHECK */
int entry_owners = 0 ;
if ( SCH_top_shared_cp ( B ) ) {
# ifdef TIMESTAMP_CHECK
2011-05-10 11:47:18 +01:00
timestamp = + + GLOBAL_timestamp ;
2001-04-09 20:54:03 +01:00
# endif /* TIMESTAMP_CHECK */
entry_owners = OrFr_owners ( LOCAL_top_or_fr ) ;
}
# endif /* YAPOR */
/* check for dependency frames with unconsumed answers */
dep_fr = LOCAL_top_dep_fr ;
while ( YOUNGER_CP ( DepFr_cons_cp ( dep_fr ) , B ) ) {
2011-12-05 16:54:22 +00:00
LOCK_DEP_FR ( dep_fr ) ;
2005-04-07 18:56:58 +01:00
ans_node = DepFr_last_answer ( dep_fr ) ;
2011-11-09 11:00:31 +00:00
if ( TrNode_child ( ans_node ) ) {
/* dependency frame with unconsumed answers */
2011-10-22 16:49:13 +01:00
# ifdef MODE_DIRECTED_TABLING
2011-12-22 16:50:20 +00:00
if ( IS_ANSWER_INVALID_NODE ( TrNode_child ( ans_node ) ) ) {
2011-11-16 12:47:43 +00:00
ans_node_ptr old_ans_node ;
old_ans_node = ans_node ;
2011-11-09 11:00:31 +00:00
ans_node = TrNode_child ( ans_node ) ;
2011-11-11 19:17:55 +00:00
do {
ans_node = TrNode_child ( ans_node ) ;
2011-12-22 16:50:20 +00:00
} while ( IS_ANSWER_INVALID_NODE ( ans_node ) ) ;
2011-11-16 12:47:43 +00:00
TrNode_child ( old_ans_node ) = ans_node ;
2011-11-11 19:17:55 +00:00
} else
2011-11-09 11:00:31 +00:00
# endif /* MODE_DIRECTED_TABLING */
2011-11-11 19:17:55 +00:00
ans_node = TrNode_child ( ans_node ) ;
2011-11-09 11:00:31 +00:00
DepFr_last_answer ( dep_fr ) = ans_node ;
2001-04-09 20:54:03 +01:00
if ( B - > cp_ap ) {
# ifdef YAPOR
if ( YOUNGER_CP ( DepFr_backchain_cp ( dep_fr ) , B ) )
# endif /* YAPOR */
DepFr_backchain_cp ( dep_fr ) = B ;
} else {
# ifdef YAPOR
if ( YOUNGER_CP ( DepFr_backchain_cp ( dep_fr ) , B - > cp_b ) )
# endif /* YAPOR */
DepFr_backchain_cp ( dep_fr ) = B - > cp_b ;
}
2011-12-05 16:54:22 +00:00
UNLOCK_DEP_FR ( dep_fr ) ;
2001-04-09 20:54:03 +01:00
2010-04-18 04:59:11 +01:00
# ifdef DEBUG_OPTYAP
2011-06-21 15:19:07 +01:00
if ( GLOBAL_parallel_mode = = PARALLEL_MODE_RUNNING ) {
2010-04-18 04:59:11 +01:00
choiceptr aux_cp ;
OPTYAP_ERROR_CHECKING ( completion , Get_LOCAL_top_cp ( ) , Get_LOCAL_top_cp_on_stack ( ) ) ;
aux_cp = DepFr_cons_cp ( dep_fr ) ;
while ( YOUNGER_CP ( aux_cp , Get_LOCAL_top_cp_on_stack ( ) ) )
aux_cp = aux_cp - > cp_b ;
OPTYAP_ERROR_CHECKING ( completion , aux_cp - > cp_or_fr ! = DepFr_top_or_fr ( dep_fr ) ) ;
2001-04-09 20:54:03 +01:00
}
2010-04-18 04:59:11 +01:00
# endif /* DEBUG_OPTYAP */
2001-04-09 20:54:03 +01:00
# ifdef YAPOR
/* update shared nodes */
2010-01-14 15:58:19 +00:00
if ( YOUNGER_CP ( Get_LOCAL_top_cp_on_stack ( ) , Get_LOCAL_top_cp ( ) ) ) {
2001-04-09 20:54:03 +01:00
or_fr_ptr or_frame = DepFr_top_or_fr ( dep_fr ) ;
while ( or_frame ! = LOCAL_top_or_fr ) {
LOCK_OR_FRAME ( or_frame ) ;
BITMAP_insert ( OrFr_members ( or_frame ) , worker_id ) ;
BRANCH ( worker_id , OrFr_depth ( or_frame ) ) = 1 ;
UNLOCK_OR_FRAME ( or_frame ) ;
or_frame = OrFr_next ( or_frame ) ;
}
LOCAL_top_or_fr = DepFr_top_or_fr ( dep_fr ) ;
2010-01-14 17:38:39 +00:00
Set_LOCAL_top_cp ( GetOrFr_node ( LOCAL_top_or_fr ) ) ;
2001-04-09 20:54:03 +01:00
}
# endif /* YAPOR */
2010-04-18 04:59:11 +01:00
# ifdef DEBUG_OPTYAP
2011-06-21 15:19:07 +01:00
if ( GLOBAL_parallel_mode = = PARALLEL_MODE_RUNNING ) {
2010-04-18 04:59:11 +01:00
choiceptr aux_cp ;
OPTYAP_ERROR_CHECKING ( completion , YOUNGER_CP ( Get_LOCAL_top_cp ( ) , Get_LOCAL_top_cp_on_stack ( ) ) ) ;
aux_cp = DepFr_cons_cp ( dep_fr ) ;
while ( aux_cp ! = Get_LOCAL_top_cp ( ) ) {
OPTYAP_ERROR_CHECKING ( completion , YOUNGER_CP ( Get_LOCAL_top_cp ( ) , aux_cp ) ) ;
OPTYAP_ERROR_CHECKING ( completion , EQUAL_OR_YOUNGER_CP ( Get_LOCAL_top_cp_on_stack ( ) , aux_cp ) ) ;
aux_cp = aux_cp - > cp_b ;
}
2001-04-09 20:54:03 +01:00
}
2010-04-18 04:59:11 +01:00
# endif /* DEBUG_OPTYAP */
2001-04-09 20:54:03 +01:00
/* rebind variables, update registers, consume answer and procceed */
2010-04-18 04:59:11 +01:00
TABLING_ERROR_CHECKING ( completion , EQUAL_OR_YOUNGER_CP ( B , DepFr_cons_cp ( dep_fr ) ) ) ;
TABLING_ERROR_CHECKING ( completion , B - > cp_tr > DepFr_cons_cp ( dep_fr ) - > cp_tr ) ;
2001-04-09 20:54:03 +01:00
rebind_variables ( DepFr_cons_cp ( dep_fr ) - > cp_tr , B - > cp_tr ) ;
2010-04-18 04:59:11 +01:00
TABLING_ERROR_CHECKING ( completion , TR ! = B - > cp_tr & & ! IsPairTerm ( ( CELL ) TrailTerm ( TR - 1 ) ) ) ;
TABLING_ERROR_CHECKING ( completion , TR ! = B - > cp_tr & & ( tr_fr_ptr ) RepPair ( ( CELL ) TrailTerm ( TR - 1 ) ) ! = B - > cp_tr ) ;
2001-04-09 20:54:03 +01:00
B = DepFr_cons_cp ( dep_fr ) ;
TR = TR_FZ ;
if ( TR ! = B - > cp_tr )
2001-06-08 21:21:59 +01:00
TRAIL_LINK ( B - > cp_tr ) ;
2001-04-09 20:54:03 +01:00
consume_answer_and_procceed ( dep_fr , ans_node ) ;
}
2011-12-05 16:54:22 +00:00
UNLOCK_DEP_FR ( dep_fr ) ;
2001-04-09 20:54:03 +01:00
# ifdef TIMESTAMP_CHECK
DepFr_timestamp ( dep_fr ) = timestamp ;
# endif /* TIMESTAMP_CHECK */
dep_fr = DepFr_next ( dep_fr ) ;
}
/* no dependency frames with unconsumed answers found */
# ifdef YAPOR
if ( SCH_top_shared_cp ( B ) ) {
if ( entry_owners > 1 ) {
/* more owners when we start looking for dependency frames with unconsumed answers */
if ( YOUNGER_CP ( B_FZ , B ) ) {
suspend_branch ( ) ;
/* check for suspension frames to be resumed */
2010-01-14 17:38:39 +00:00
while ( YOUNGER_CP ( GetOrFr_node ( LOCAL_top_susp_or_fr ) , Get_LOCAL_top_cp ( ) ) ) {
2001-04-09 20:54:03 +01:00
or_fr_ptr susp_or_fr ;
susp_fr_ptr resume_fr ;
susp_or_fr = LOCAL_top_susp_or_fr ;
LOCK_OR_FRAME ( susp_or_fr ) ;
# ifdef TIMESTAMP_CHECK
resume_fr = suspension_frame_to_resume ( susp_or_fr , timestamp ) ;
# else
resume_fr = suspension_frame_to_resume ( susp_or_fr ) ;
# endif /* TIMESTAMP_CHECK */
if ( resume_fr ) {
if ( OrFr_suspensions ( susp_or_fr ) = = NULL ) {
LOCAL_top_susp_or_fr = OrFr_nearest_suspnode ( susp_or_fr ) ;
OrFr_nearest_suspnode ( susp_or_fr ) = susp_or_fr ;
}
UNLOCK_OR_FRAME ( susp_or_fr ) ;
2010-01-14 17:38:39 +00:00
rebind_variables ( GetOrFr_node ( susp_or_fr ) - > cp_tr , B - > cp_tr ) ;
2001-04-09 20:54:03 +01:00
resume_suspension_frame ( resume_fr , susp_or_fr ) ;
2010-01-14 15:58:19 +00:00
B = Get_LOCAL_top_cp ( ) ;
2001-04-09 20:54:03 +01:00
SET_BB ( B_FZ ) ;
TR = TR_FZ ;
2001-06-08 21:21:59 +01:00
TRAIL_LINK ( B - > cp_tr ) ;
2001-04-09 20:54:03 +01:00
goto completion ;
}
LOCAL_top_susp_or_fr = OrFr_nearest_suspnode ( susp_or_fr ) ;
OrFr_nearest_suspnode ( susp_or_fr ) = NULL ;
UNLOCK_OR_FRAME ( susp_or_fr ) ;
}
}
} else {
/* unique owner */
if ( frame_with_suspensions_not_collected ( LOCAL_top_or_fr ) )
collect_suspension_frames ( LOCAL_top_or_fr ) ;
/* check for suspension frames to be resumed */
2010-01-14 17:38:39 +00:00
while ( EQUAL_OR_YOUNGER_CP ( GetOrFr_node ( LOCAL_top_susp_or_fr ) , Get_LOCAL_top_cp ( ) ) ) {
2001-04-09 20:54:03 +01:00
or_fr_ptr susp_or_fr ;
susp_fr_ptr resume_fr ;
susp_or_fr = LOCAL_top_susp_or_fr ;
# ifdef TIMESTAMP_CHECK
resume_fr = suspension_frame_to_resume ( susp_or_fr , timestamp ) ;
# else
resume_fr = suspension_frame_to_resume ( susp_or_fr ) ;
# endif /* TIMESTAMP_CHECK */
if ( resume_fr ) {
if ( OrFr_suspensions ( susp_or_fr ) = = NULL ) {
LOCAL_top_susp_or_fr = OrFr_nearest_suspnode ( susp_or_fr ) ;
OrFr_nearest_suspnode ( susp_or_fr ) = susp_or_fr ;
}
if ( YOUNGER_CP ( B_FZ , B ) ) {
suspend_branch ( ) ;
}
2010-01-14 17:38:39 +00:00
rebind_variables ( GetOrFr_node ( susp_or_fr ) - > cp_tr , B - > cp_tr ) ;
2001-04-09 20:54:03 +01:00
resume_suspension_frame ( resume_fr , susp_or_fr ) ;
2010-01-14 15:58:19 +00:00
B = Get_LOCAL_top_cp ( ) ;
2001-04-09 20:54:03 +01:00
SET_BB ( B_FZ ) ;
TR = TR_FZ ;
2001-06-08 21:21:59 +01:00
TRAIL_LINK ( B - > cp_tr ) ;
2001-04-09 20:54:03 +01:00
goto completion ;
}
LOCAL_top_susp_or_fr = OrFr_nearest_suspnode ( susp_or_fr ) ;
OrFr_nearest_suspnode ( susp_or_fr ) = NULL ;
}
/* complete all */
public_completion ( ) ;
}
2010-04-18 04:59:11 +01:00
TABLING_ERROR_CHECKING ( completion , TR ! = B - > cp_tr & & ! IsPairTerm ( ( CELL ) TrailTerm ( TR - 1 ) ) ) ;
TABLING_ERROR_CHECKING ( completion , TR ! = B - > cp_tr & & ( tr_fr_ptr ) RepPair ( ( CELL ) TrailTerm ( TR - 1 ) ) ! = B - > cp_tr ) ;
2005-04-07 18:56:58 +01:00
if ( B = = DepFr_leader_cp ( LOCAL_top_dep_fr ) ) {
/* B is a generator-consumer node */
/* never here if batched scheduling */
2001-04-09 20:54:03 +01:00
ans_node_ptr ans_node ;
2010-04-18 04:59:11 +01:00
TABLING_ERROR_CHECKING ( completion , IS_BATCHED_GEN_CP ( B ) ) ;
2001-04-09 20:54:03 +01:00
TR = B - > cp_tr ;
SET_BB ( B ) ;
LOCK_OR_FRAME ( LOCAL_top_or_fr ) ;
2011-12-05 16:54:22 +00:00
LOCK_DEP_FR ( LOCAL_top_dep_fr ) ;
2005-04-07 18:56:58 +01:00
ans_node = DepFr_last_answer ( LOCAL_top_dep_fr ) ;
if ( TrNode_child ( ans_node ) ) {
2011-11-09 11:00:31 +00:00
/* unconsumed answers */
2005-04-07 18:56:58 +01:00
UNLOCK_OR_FRAME ( LOCAL_top_or_fr ) ;
2011-11-09 11:00:31 +00:00
# ifdef MODE_DIRECTED_TABLING
2011-12-22 16:50:20 +00:00
if ( IS_ANSWER_INVALID_NODE ( TrNode_child ( ans_node ) ) ) {
2011-11-16 12:47:43 +00:00
ans_node_ptr old_ans_node ;
old_ans_node = ans_node ;
2011-11-09 11:00:31 +00:00
ans_node = TrNode_child ( ans_node ) ;
2011-11-11 19:17:55 +00:00
do {
ans_node = TrNode_child ( ans_node ) ;
2011-12-22 16:50:20 +00:00
} while ( IS_ANSWER_INVALID_NODE ( ans_node ) ) ;
2011-11-16 12:47:43 +00:00
TrNode_child ( old_ans_node ) = ans_node ;
2011-11-11 19:17:55 +00:00
} else
2011-11-09 11:00:31 +00:00
# endif /* MODE_DIRECTED_TABLING */
2011-11-11 19:17:55 +00:00
ans_node = TrNode_child ( ans_node ) ;
2011-11-09 11:00:31 +00:00
DepFr_last_answer ( LOCAL_top_dep_fr ) = ans_node ;
2011-12-05 16:54:22 +00:00
UNLOCK_DEP_FR ( LOCAL_top_dep_fr ) ;
2001-04-09 20:54:03 +01:00
consume_answer_and_procceed ( LOCAL_top_dep_fr , ans_node ) ;
}
/* no unconsumed answers */
2011-12-05 16:54:22 +00:00
UNLOCK_DEP_FR ( LOCAL_top_dep_fr ) ;
2001-04-09 20:54:03 +01:00
if ( OrFr_owners ( LOCAL_top_or_fr ) > 1 ) {
/* more owners -> move up one node */
2011-12-22 16:50:20 +00:00
Set_LOCAL_top_cp_on_stack ( GetOrFr_node ( OrFr_next_on_stack ( LOCAL_top_or_fr ) ) ) ;
2001-04-09 20:54:03 +01:00
BITMAP_delete ( OrFr_members ( LOCAL_top_or_fr ) , worker_id ) ;
OrFr_owners ( LOCAL_top_or_fr ) - - ;
LOCAL_top_dep_fr = DepFr_next ( LOCAL_top_dep_fr ) ;
UNLOCK_OR_FRAME ( LOCAL_top_or_fr ) ;
2010-01-14 15:58:19 +00:00
if ( LOCAL_top_sg_fr & & Get_LOCAL_top_cp ( ) = = SgFr_gen_cp ( LOCAL_top_sg_fr ) ) {
2001-04-09 20:54:03 +01:00
LOCAL_top_sg_fr = SgFr_next ( LOCAL_top_sg_fr ) ;
}
SCH_update_local_or_tops ( ) ;
CUT_reset_prune_request ( ) ;
adjust_freeze_registers ( ) ;
goto shared_fail ;
} else {
/* free top dependency frame --> get work */
OrFr_alternative ( LOCAL_top_or_fr ) = NULL ;
UNLOCK_OR_FRAME ( LOCAL_top_or_fr ) ;
dep_fr = DepFr_next ( LOCAL_top_dep_fr ) ;
FREE_DEPENDENCY_FRAME ( LOCAL_top_dep_fr ) ;
LOCAL_top_dep_fr = dep_fr ;
adjust_freeze_registers ( ) ;
SCHEDULER_GET_WORK ( ) ;
}
}
/* goto getwork */
PREG = B - > cp_ap ;
PREFETCH_OP ( PREG ) ;
TR = B - > cp_tr ;
SET_BB ( B ) ;
GONext ( ) ;
} else
# endif /* YAPOR */
2011-12-22 16:50:20 +00:00
# ifdef THREADS_CONSUMER_SHARING
complete_all :
# endif /* THREADS_CONSUMER_SHARING */
2001-04-09 20:54:03 +01:00
{
/* complete all */
sg_fr_ptr sg_fr ;
2009-07-03 00:54:39 +01:00
# ifdef DETERMINISTIC_TABLING
if ( IS_DET_GEN_CP ( B ) )
sg_fr = DET_GEN_CP ( B ) - > cp_sg_fr ;
else
# endif /* DETERMINISTIC_TABLING */
sg_fr = GEN_CP ( B ) - > cp_sg_fr ;
2001-04-09 20:54:03 +01:00
private_completion ( sg_fr ) ;
2011-12-22 16:50:20 +00:00
# ifdef THREADS_CONSUMER_SHARING
if ( IS_BATCHED_GEN_CP ( B ) | | SgFr_gen_worker ( sg_fr ) ! = worker_id ) { /* if it is an gen_cons node then all the answers were already consumed */
# else
2005-04-07 18:56:58 +01:00
if ( IS_BATCHED_GEN_CP ( B ) ) {
2011-12-22 16:50:20 +00:00
# endif /*THREADS_CONSUMER_SHARING */
2005-04-07 18:56:58 +01:00
/* backtrack */
2001-04-09 20:54:03 +01:00
B = B - > cp_b ;
SET_BB ( PROTECT_FROZEN_B ( B ) ) ;
goto fail ;
2005-04-07 18:56:58 +01:00
} else {
/* subgoal completed */
2005-07-06 20:34:12 +01:00
ans_node = SgFr_first_answer ( sg_fr ) ;
if ( ans_node = = NULL ) {
2005-04-07 18:56:58 +01:00
/* no answers --> fail */
B = B - > cp_b ;
SET_BB ( PROTECT_FROZEN_B ( B ) ) ;
goto fail ;
}
2010-04-18 04:59:11 +01:00
TABLING_ERROR_CHECKING ( completion , TR ! = B - > cp_tr & & ! IsPairTerm ( ( CELL ) TrailTerm ( TR - 1 ) ) ) ;
TABLING_ERROR_CHECKING ( completion , TR ! = B - > cp_tr & & ( tr_fr_ptr ) RepPair ( ( CELL ) TrailTerm ( TR - 1 ) ) ! = B - > cp_tr ) ;
2005-04-07 18:56:58 +01:00
pop_generator_node ( SgFr_arity ( sg_fr ) ) ;
2005-07-06 20:34:12 +01:00
if ( ans_node = = SgFr_answer_trie ( sg_fr ) ) {
2005-04-07 18:56:58 +01:00
/* yes answer --> procceed */
PREG = ( yamop * ) CPREG ;
PREFETCH_OP ( PREG ) ;
YENV = ENV ;
GONext ( ) ;
} else {
2005-07-06 20:34:12 +01:00
/* answers -> get first answer */
tab_ent_ptr tab_ent = SgFr_tab_ent ( sg_fr ) ;
2005-08-04 16:45:56 +01:00
# ifdef LIMIT_TABLING
SgFr_state ( sg_fr ) + + ; /* complete --> complete_in_use */
remove_from_global_sg_fr_list ( sg_fr ) ;
TRAIL_FRAME ( sg_fr ) ;
# endif /* LIMIT_TABLING */
2005-07-06 20:34:12 +01:00
if ( IsMode_LoadAnswers ( TabEnt_mode ( tab_ent ) ) ) {
/* load answers from the trie */
if ( TrNode_child ( ans_node ) ! = NULL ) {
store_loader_node ( tab_ent , ans_node ) ;
}
PREG = ( yamop * ) CPREG ;
PREFETCH_OP ( PREG ) ;
2009-09-27 02:31:31 +01:00
load_answer ( ans_node , YENV ) ;
2005-07-06 20:34:12 +01:00
YENV = ENV ;
GONext ( ) ;
} else {
2011-12-22 16:50:20 +00:00
# if defined(THREADS_FULL_SHARING) || defined(THREADS_CONSUMER_SHARING)
LOCK_SG_FR ( sg_fr ) ;
if ( SgFr_active_workers ( sg_fr ) > 0 ) {
/* load answers from the trie */
UNLOCK_SG_FR ( sg_fr ) ;
if ( TrNode_child ( ans_node ) ! = NULL ) {
store_loader_node ( tab_ent , ans_node ) ;
}
PREG = ( yamop * ) CPREG ;
PREFETCH_OP ( PREG ) ;
load_answer ( ans_node , YENV ) ;
YENV = ENV ;
GONext ( ) ;
}
# endif /* THREADS_FULL_SHARING || THREADS_CONSUMER_SHARING */
2005-07-06 20:34:12 +01:00
/* execute compiled code from the trie */
2011-12-22 16:50:20 +00:00
# if defined(THREADS_FULL_SHARING) || defined(THREADS_CONSUMER_SHARING)
if ( SgFr_sg_ent_state ( sg_fr ) < compiled )
# else
2011-12-05 16:54:22 +00:00
LOCK_SG_FR ( sg_fr ) ;
2005-08-04 16:45:56 +01:00
if ( SgFr_state ( sg_fr ) < compiled )
2011-12-22 16:50:20 +00:00
# endif /* THREADS_FULL_SHARING || THREADS_CONSUMER_SHARING */
2005-07-06 20:34:12 +01:00
update_answer_trie ( sg_fr ) ;
2011-12-05 16:54:22 +00:00
UNLOCK_SG_FR ( sg_fr ) ;
2005-07-06 20:34:12 +01:00
PREG = ( yamop * ) TrNode_child ( SgFr_answer_trie ( sg_fr ) ) ;
PREFETCH_OP ( PREG ) ;
* - - YENV = 0 ; /* vars_arity */
2010-04-15 01:09:59 +01:00
* - - YENV = 0 ; /* heap_arity */
2005-07-06 20:34:12 +01:00
GONext ( ) ;
}
}
2001-04-09 20:54:03 +01:00
}
}
END_PREFETCH ( )
ENDBOp ( ) ;
2011-12-22 16:50:20 +00:00
/************************************************************************
* * table_answer_resolution_completion * *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
# ifdef THREADS_CONSUMER_SHARING
BOp ( table_answer_resolution_completion , Otapl )
answer_resolution_completion :
{
INIT_PREFETCH ( )
int do_not_complete_tables ;
int wid = worker_id ;
do {
dep_fr_ptr dep_fr ;
ans_node_ptr ans_node ;
do_not_complete_tables = 0 ; /* 0 - complete all the tables 1 - do not complete all the tables */
if ( B - > cp_ap = = ANSWER_RESOLUTION_COMPLETION ) {
/* generator consumer node (external node) */
if ( ( IS_BATCHED_GEN_CP ( B ) & & ( EQUAL_OR_YOUNGER_CP ( B_FZ , B ) & & B ! = DepFr_leader_cp ( LOCAL_top_dep_fr ) ) ) | |
( B ! = DepFr_leader_cp ( LOCAL_top_dep_fr ) ) ) {
/* not leader on that node */
INFO_THREADS ( " ans_reso_com (1) : not leader on that node dep_fr = %p leader_node =%p " , LOCAL_top_dep_fr , GEN_CP ( DepFr_leader_cp ( LOCAL_top_dep_fr ) ) - > cp_dep_fr ) ;
ThDepFr_state ( GLOBAL_th_dep_fr ( wid ) ) = working ;
B - > cp_ap = ANSWER_RESOLUTION ;
goto answer_resolution ;
}
/* leader on that node */
dep_fr = GEN_CP ( B ) - > cp_dep_fr ;
ans_node = DepFr_last_answer ( dep_fr ) ;
if ( TrNode_child ( ans_node ) ) {
/* unconsumed answer */
ThDepFr_state ( GLOBAL_th_dep_fr ( wid ) ) = working ;
ans_node = DepFr_last_answer ( dep_fr ) = TrNode_child ( ans_node ) ;
INFO_THREADS ( " ans_reso_com (2) : consume_answer =%p dep_fr = %p leader_node =%p " , ans_node , dep_fr , GEN_CP ( DepFr_leader_cp ( dep_fr ) ) - > cp_dep_fr ) ;
consume_answer_and_procceed ( dep_fr , ans_node ) ;
}
sg_fr_ptr sg_fr = GEN_CP ( B ) - > cp_sg_fr ;
if ( SgFr_sg_ent_state ( sg_fr ) < complete | | ( SgFr_sg_ent_state ( sg_fr ) > = complete & & TrNode_child ( ans_node ) ! = NULL ) )
do_not_complete_tables = 1 ;
} else { /* using the B->cp_ap == ANSWER_RESOLUTION_COMPLETION to distinguish gen_cons nodes from gen */
/* generator node */
if ( IS_BATCHED_GEN_CP ( B ) ) {
if ( EQUAL_OR_YOUNGER_CP ( B_FZ , B ) & & B ! = DepFr_leader_cp ( LOCAL_top_dep_fr ) ) {
/* not leader on that node */
ThDepFr_state ( GLOBAL_th_dep_fr ( wid ) ) = working ;
B - > cp_ap = NULL ;
B = B - > cp_b ;
goto fail ;
}
} else {
if ( B ! = DepFr_leader_cp ( LOCAL_top_dep_fr ) ) {
/* not leader on that node */
ThDepFr_state ( GLOBAL_th_dep_fr ( wid ) ) = working ;
B - > cp_ap = ANSWER_RESOLUTION ;
B = B - > cp_b ;
INFO_THREADS ( " ans_reso_com (3) : not leader on that node dep_fr = %p leader_node =%p " , LOCAL_top_dep_fr , GEN_CP ( DepFr_leader_cp ( LOCAL_top_dep_fr ) ) - > cp_dep_fr ) ;
goto fail ;
}
}
}
/* leader on that node */
/* no unconsumed answers */
dep_fr = LOCAL_top_dep_fr ;
/* check for dependency frames with unconsumed answers */
while ( YOUNGER_CP ( DepFr_cons_cp ( dep_fr ) , B ) ) {
ans_node = DepFr_last_answer ( dep_fr ) ;
if ( TrNode_child ( ans_node ) ) {
ThDepFr_state ( GLOBAL_th_dep_fr ( wid ) ) = working ;
/*dependency frame with unconsumed answers */
ans_node = DepFr_last_answer ( dep_fr ) = TrNode_child ( ans_node ) ;
if ( IS_BATCHED_GEN_CP ( B ) )
DepFr_backchain_cp ( dep_fr ) = B - > cp_b ;
else
DepFr_backchain_cp ( dep_fr ) = B ;
/*rebind variables, update registers, consume answer and procceed */
TABLING_ERROR_CHECKING ( answer_resolution_completion , EQUAL_OR_YOUNGER_CP ( B , DepFr_cons_cp ( dep_fr ) ) ) ;
TABLING_ERROR_CHECKING ( answer_resolution_completion , B - > cp_tr > DepFr_cons_cp ( dep_fr ) - > cp_tr ) ;
rebind_variables ( DepFr_cons_cp ( dep_fr ) - > cp_tr , B - > cp_tr ) ; //don't know if it is the same unbind_variables(DepFr_cons_cp(dep_fr)->cp_tr, B->cp_tr);
TABLING_ERROR_CHECKING ( answer_resolution_completion , TR ! = B - > cp_tr & & ! IsPairTerm ( ( CELL ) TrailTerm ( TR - 1 ) ) ) ;
TABLING_ERROR_CHECKING ( answer_resolution_completion , TR ! = B - > cp_tr & & ( tr_fr_ptr ) RepPair ( ( CELL ) TrailTerm ( TR - 1 ) ) ! = B - > cp_tr ) ;
B = DepFr_cons_cp ( dep_fr ) ;
TR = TR_FZ ;
if ( TR ! = B - > cp_tr )
TRAIL_LINK ( B - > cp_tr ) ;
INFO_THREADS ( " ans_reso_com (4) : consume_answer =%p dep_fr = %p leader_node =%p " , ans_node , dep_fr , GEN_CP ( DepFr_leader_cp ( dep_fr ) ) - > cp_dep_fr ) ;
consume_answer_and_procceed ( dep_fr , ans_node ) ;
}
if ( DepFr_external ( dep_fr ) = = TRUE ) {
sg_fr_ptr sg_fr = GEN_CP ( DepFr_cons_cp ( dep_fr ) ) - > cp_sg_fr ;
if ( SgFr_sg_ent_state ( sg_fr ) < complete | | ( SgFr_sg_ent_state ( sg_fr ) > = complete & & TrNode_child ( ans_node ) ! = NULL ) )
do_not_complete_tables = 1 ;
}
dep_fr = DepFr_next ( dep_fr ) ;
}
/******************************** a terminaçao das threads *************************************/
if ( do_not_complete_tables = = 1 ) {
/*all the dependency frames have consumed all answers and we have external tables */
if ( ThDepFr_next ( GLOBAL_th_dep_fr ( wid ) ) = = wid )
/* worker_id is not inside an SCC */
continue ;
if ( ThDepFr_state ( GLOBAL_th_dep_fr ( wid ) ) = = working ) {
int c_wid = ThDepFr_next ( GLOBAL_th_dep_fr ( wid ) ) ;
do {
ThDepFr_terminator ( GLOBAL_th_dep_fr ( c_wid ) ) = 1 ;
c_wid = ThDepFr_next ( GLOBAL_th_dep_fr ( c_wid ) ) ;
} while ( c_wid ! = wid ) ;
ThDepFr_terminator ( GLOBAL_th_dep_fr ( wid ) ) = 1 ;
ThDepFr_state ( GLOBAL_th_dep_fr ( wid ) ) = idle ;
} else if ( ThDepFr_state ( GLOBAL_th_dep_fr ( wid ) ) = = idle ) {
int l_wid = wid ; /* leader wid */
int c_wid = ThDepFr_next ( GLOBAL_th_dep_fr ( wid ) ) ;
int jump_state = TRUE ;
do {
if ( ThDepFr_state ( GLOBAL_th_dep_fr ( c_wid ) ) ! = idle ) {
jump_state = FALSE ;
break ;
} else
if ( l_wid > c_wid )
l_wid = c_wid ;
c_wid = ThDepFr_next ( GLOBAL_th_dep_fr ( c_wid ) ) ;
} while ( c_wid ! = wid ) ;
if ( jump_state & & l_wid = = wid ) {
/* wid is the current leader thread */
ThDepFr_terminator ( GLOBAL_th_dep_fr ( wid ) ) = 0 ;
c_wid = ThDepFr_next ( GLOBAL_th_dep_fr ( wid ) ) ;
do {
dep_fr_ptr remote_dep_fr = REMOTE_top_dep_fr ( c_wid ) ;
while ( YOUNGER_CP ( DepFr_cons_cp ( remote_dep_fr ) , DepFr_leader_cp ( REMOTE_top_dep_fr ( c_wid ) ) ) ) {
if ( TrNode_child ( DepFr_last_answer ( remote_dep_fr ) ) ) {
/* dependency frame with unconsumed answers */
jump_state = FALSE ;
break ;
}
remote_dep_fr = DepFr_next ( remote_dep_fr ) ;
}
if ( ThDepFr_state ( GLOBAL_th_dep_fr ( c_wid ) ) ! = idle ) {
jump_state = FALSE ;
break ;
}
c_wid = ThDepFr_next ( GLOBAL_th_dep_fr ( c_wid ) ) ;
} while ( c_wid ! = wid ) ;
}
if ( jump_state & & ThDepFr_terminator ( GLOBAL_th_dep_fr ( wid ) ) = = 0 ) {
c_wid = ThDepFr_next ( GLOBAL_th_dep_fr ( wid ) ) ;
do {
ThDepFr_state ( GLOBAL_th_dep_fr ( c_wid ) ) = completing ;
c_wid = ThDepFr_next ( GLOBAL_th_dep_fr ( c_wid ) ) ;
} while ( c_wid ! = wid ) ;
ThDepFr_state ( GLOBAL_th_dep_fr ( wid ) ) = completing ;
}
} else if ( ThDepFr_state ( GLOBAL_th_dep_fr ( wid ) ) = = completing ) {
INFO_THREADS ( " ans_reso_com (5) : completing thread_state =%d " , ThDepFr_state ( GLOBAL_th_dep_fr ( wid ) ) ) ;
break ; /*do_not_complete_tables = 0; -- same as "break;" */
}
}
} while ( do_not_complete_tables ) ;
END_PREFETCH ( )
INFO_THREADS ( " ans_reso_com (6) : completing thread_state =%d " , ThDepFr_state ( GLOBAL_th_dep_fr ( worker_id ) ) ) ;
goto complete_all ;
}
ENDBOp ( ) ;
# endif /* THREADS_CONSUMER_SHARING */