Adding tabling support for mixed strategy evaluation (batched and local scheduling)

UPDATE: compilation flags -DTABLING_BATCHED_SCHEDULING and -DTABLING_LOCAL_SCHEDULING removed. To support tabling use -DTABLING in the Makefile or --enable-tabling in configure.
  NEW: yap_flag(tabling_mode,MODE) changes the tabling execution mode of all tabled predicates to MODE (batched, local or default).
  NEW: tabling_mode(PRED,MODE) changes the default tabling execution mode of predicate PRED to MODE (batched or local).


git-svn-id: https://yap.svn.sf.net/svnroot/yap/trunk@1268 b08c6af1-5177-4d33-ba66-4b1c6b8b522a
This commit is contained in:
ricroc 2005-04-07 17:56:58 +00:00
parent b089ae2575
commit de17f5cca4
31 changed files with 1082 additions and 930 deletions

195
C/absmi.c
View File

@ -10,8 +10,13 @@
* *
* File: absmi.c *
* comments: Portable abstract machine interpreter *
* Last rev: $Date: 2005-03-13 06:26:09 $,$Author: vsc $ *
* Last rev: $Date: 2005-04-07 17:48:53 $,$Author: ricroc $ *
* $Log: not supported by cvs2svn $
* Revision 1.161 2005/03/13 06:26:09 vsc
* fix excessive pruning in meta-calls
* fix Term->int breakage in compiler
* improve JPL (at least it does something now for amd64).
*
* Revision 1.160 2005/03/07 17:49:14 vsc
* small fixes
*
@ -1698,13 +1703,15 @@ Yap_absmi(int inp)
/* trust_fail */
BOp(trust_fail, e);
#ifdef YAPOR
CUT_prune_to((choiceptr) d0);
{
choiceptr cut_pt;
cut_pt = B->cp_b;
CUT_prune_to(cut_pt);
B = cut_pt;
}
#else
B = B->cp_b;
#endif /* YAPOR */
#ifdef TABLING
abolish_incomplete_subgoals(B);
#endif /* TABLING */
goto fail;
ENDBOp();
@ -1763,7 +1770,7 @@ Yap_absmi(int inp)
if ((caller_op != _call && caller_op != _fcall) || pe == NULL) {
low_level_trace(retry_table_producer, NULL, NULL);
} else {
low_level_trace(retry_table_producer, pe, (CELL *)(((gen_cp_ptr)B)+1));
low_level_trace(retry_table_producer, pe, (CELL *)(GEN_CP(B)+1));
}
}
break;
@ -1781,7 +1788,7 @@ Yap_absmi(int inp)
break;
case _table_retry_me:
case _table_trust_me:
low_level_trace(retry_pred, ipc->u.lds.p, (CELL *)(((gen_cp_ptr)B)+1));
low_level_trace(retry_pred, ipc->u.lds.p, (CELL *)(GEN_CP(B)+ 1));
break;
#endif /* TABLING */
case _or_else:
@ -1987,10 +1994,11 @@ Yap_absmi(int inp)
/* so the next cell is the old value */
#if FROZEN_STACKS
pt[0] = TrailVal(pt0-1);
pt0 -= 1;
#else
pt[0] = TrailTerm(pt0-1);
#endif /* FROZEN_STACKS */
pt0 -= 2;
#endif /* FROZEN_STACKS */
goto failloop;
}
#endif
@ -2011,17 +2019,80 @@ Yap_absmi(int inp)
BEGD(d0);
/* assume cut is always in stack */
d0 = YREG[E_CB];
#ifdef YAPOR
CUT_prune_to((choiceptr) d0);
#endif /* YAPOR */
if (SHOULD_CUT_UP_TO(B,(choiceptr) d0)) {
/* cut ! */
#ifdef YAPOR
CUT_prune_to((choiceptr) d0);
#else
while (B->cp_b < (choiceptr)d0) {
B = B->cp_b;
}
#ifdef TABLING
abolish_incomplete_subgoals(B);
#endif /* TABLING */
trim_trail:
HBREG = PROTECT_FROZEN_H(B->cp_b);
#if 1
#if TABLING
{
tr_fr_ptr pt0, pt1, pbase;
pbase = B->cp_tr;
pt0 = pt1 = TR - 1;
while (pt1 >= pbase) {
BEGD(d1);
d1 = TrailTerm(pt1);
if (IsVarTerm(d1)) {
if (d1 < (CELL)HBREG || d1 > Unsigned(B->cp_b)) {
TrailTerm(pt0) = d1;
TrailVal(pt0) = TrailVal(pt1);
pt0--;
}
pt1--;
} else if (IsApplTerm(d1)) {
TrailTerm(pt0) = TrailTerm(pt0-2) = d1;
TrailTerm(pt0-1) = TrailTerm(pt1-1);
pt0 -= 3;
pt1 -= 3;
} else if (IsPairTerm(d1)) {
CELL *pt = RepPair(d1);
if ((ADDR) pt >= Yap_TrailBase) {
pt1 = (tr_fr_ptr)pt;
} else if ((*pt & (LogUpdMask|IndexMask)) == (LogUpdMask|IndexMask)) {
LogUpdIndex *cl = ClauseFlagsToLogUpdIndex(pt);
int erase;
LOCK(cl->ClLock);
DEC_CLREF_COUNT(cl);
cl->ClFlags &= ~InUseMask;
erase = (cl->ClFlags & ErasedMask) && !(cl->ClRefCount);
UNLOCK(cl->ClLock);
if (erase) {
/* at this point, we are the only ones accessing the clause,
hence we don't need to have a lock it */
saveregs();
Yap_ErLogUpdIndex(cl, NULL);
setregs();
}
} else {
TrailTerm(pt0) = d1;
pt0--;
}
pt1--;
} else {
TrailTerm(pt0) = d1;
pt0--;
pt1--;
}
ENDD(d1);
}
if (pt0 != pt1) {
int size;
pt0++;
size = TR - pt0;
memcpy(pbase, pt0, size * sizeof(struct trail_frame));
TR = pbase + size;
}
}
#else
{
tr_fr_ptr pt1, pt0;
pt1 = pt0 = B->cp_tr;
@ -2032,7 +2103,7 @@ Yap_absmi(int inp)
if (d1 < (CELL)HBREG || d1 > Unsigned(B->cp_b)) {
TrailTerm(pt0) = d1;
pt0++;
}
}
pt1++;
} else if (IsApplTerm(d1)) {
TrailTerm(pt0+1) = TrailTerm(pt1+1);
@ -2051,8 +2122,7 @@ Yap_absmi(int inp)
erase = (cl->ClFlags & ErasedMask) && !(cl->ClRefCount);
UNLOCK(cl->ClLock);
if (erase) {
/* at this point,
we are the only ones accessing the clause,
/* at this point, we are the only ones accessing the clause,
hence we don't need to have a lock it */
saveregs();
Yap_ErLogUpdIndex(cl, NULL);
@ -2072,12 +2142,8 @@ Yap_absmi(int inp)
}
TR = pt0;
}
#endif /* X */
B = B->cp_b;
#endif /* YAPOR */
#ifdef TABLING
abolish_incomplete_subgoals(B);
#endif /* TABLING */
B = B->cp_b;
SET_BB(PROTECT_FROZEN_B(B));
}
ENDD(d0);
@ -2091,16 +2157,17 @@ Yap_absmi(int inp)
BEGD(d0);
/* assume cut is always in stack */
d0 = YREG[E_CB];
#ifdef YAPOR
CUT_prune_to((choiceptr) d0);
#endif /* YAPOR */
if (SHOULD_CUT_UP_TO(B,(choiceptr) d0)) {
/* cut ! */
#ifdef YAPOR
CUT_prune_to((choiceptr) d0);
#else
while (B->cp_b < (choiceptr)d0) {
B = B->cp_b;
}
#endif /* YAPOR */
#ifdef TABLING
abolish_incomplete_subgoals(B);
#endif /* TABLING */
#ifdef FROZEN_STACKS
{
choiceptr top_b = PROTECT_FROZEN_B(B->cp_b);
@ -2118,8 +2185,8 @@ Yap_absmi(int inp)
else {
YREG = (CELL *) ((CELL) ENV + ENV_Size(CPREG));
}
YREG[E_CB] = d0;
#endif /* FROZEN_STACKS */
YREG[E_CB] = d0;
goto trim_trail;
}
ENDD(d0);
@ -2132,15 +2199,17 @@ Yap_absmi(int inp)
BEGD(d0);
/* we assume dealloc leaves in S the previous env */
d0 = SREG[E_CB];
#ifdef YAPOR
CUT_prune_to((choiceptr) d0);
#endif /* YAPOR */
if (SHOULD_CUT_UP_TO(B,(choiceptr)d0)) {
/* cut ! */
#ifdef YAPOR
CUT_prune_to((choiceptr) d0);
#else
while (B->cp_b < (choiceptr)d0) {
B = B->cp_b;
}
#endif /* YAPOR */
#ifdef TABLING
abolish_incomplete_subgoals(B);
#endif /* TABLING */
goto trim_trail;
}
ENDD(d0);
@ -2191,14 +2260,16 @@ Yap_absmi(int inp)
#else
pt0 = (choiceptr)(LCL0-IntOfTerm(d0));
#endif
if (SHOULD_CUT_UP_TO(B,pt0)) {
#ifdef YAPOR
CUT_prune_to(pt0);
#else
CUT_prune_to(pt0);
#endif /* YAPOR */
if (SHOULD_CUT_UP_TO(B,pt0)) {
while (B->cp_b < pt0) {
B = B->cp_b;
}
#endif /* YAPOR */
#ifdef TABLING
abolish_incomplete_subgoals(B);
#endif /* TABLING */
goto trim_trail;
}
}
@ -2224,14 +2295,16 @@ Yap_absmi(int inp)
#else
pt0 = (choiceptr)(LCL0-IntOfTerm(d0));
#endif
if (SHOULD_CUT_UP_TO(B,pt0)) {
#ifdef YAPOR
CUT_prune_to(pt0);
#else
CUT_prune_to(pt0);
#endif /* YAPOR */
if (SHOULD_CUT_UP_TO(B,pt0)) {
while (B->cp_b < pt0) {
B = B->cp_b;
}
#endif /* YAPOR */
#ifdef TABLING
abolish_incomplete_subgoals(B);
#endif /* TABLING */
goto trim_trail;
}
}
@ -8524,16 +8597,18 @@ Yap_absmi(int inp)
#else
pt0 = (choiceptr)(LCL0-IntOfTerm(d0));
#endif
#ifdef YAPOR
CUT_prune_to(pt0);
#endif /* YAPOR */
/* find where to cut to */
if (SHOULD_CUT_UP_TO(B,pt0)) {
/* Wow, we're gonna cut!!! */
#ifdef YAPOR
CUT_prune_to(pt0);
#else
while (B->cp_b < pt0) {
B = B->cp_b;
}
#endif /* YAPOR */
#ifdef TABLING
abolish_incomplete_subgoals(B);
#endif /* TABLING */
goto trim_trail;
}
PREG = NEXTOP(PREG, xF);
@ -8570,15 +8645,17 @@ Yap_absmi(int inp)
#else
pt1 = (choiceptr)(LCL0-IntOfTerm(d0));
#endif
#ifdef YAPOR
CUT_prune_to(pt1);
#endif /* YAPOR */
if (SHOULD_CUT_UP_TO(B,pt1)) {
/* Wow, we're gonna cut!!! */
#ifdef YAPOR
CUT_prune_to(pt1);
#else
while (B->cp_b < pt1) {
B = B->cp_b;
}
#endif /* YAPOR */
#ifdef TABLING
abolish_incomplete_subgoals(B);
#endif /* TABLING */
goto trim_trail;
}
PREG = NEXTOP(PREG, yF);
@ -12509,18 +12586,19 @@ Yap_absmi(int inp)
arity = 0;
if (at == AtomCut) {
choiceptr cut_pt = (choiceptr)pt0[E_CB];
#ifdef YAPOR
CUT_prune_to(cut_pt);
#endif /* YAPOR */
/* find where to cut to */
if (SHOULD_CUT_UP_TO(B,cut_pt)) {
#ifdef YAPOR
/* Wow, we're gonna cut!!! */
CUT_prune_to(cut_pt);
#else
/* Wow, we're gonna cut!!! */
B = cut_pt;
#endif /* YAPOR */
#ifdef TABLING
while (B->cp_b < cut_pt) {
B = B->cp_b;
}
abolish_incomplete_subgoals(B);
#endif /* TABLING */
B = cut_pt;
HB = PROTECT_FROZEN_H(B);
}
}
@ -12599,18 +12677,19 @@ Yap_absmi(int inp)
CACHE_A1();
} else if ((Atom)(pen->FunctorOfPred) == AtomCut) {
choiceptr cut_pt = (choiceptr)pt0[E_CB];
#ifdef YAPOR
CUT_prune_to(cut_pt);
#endif /* YAPOR */
/* find where to cut to */
if (SHOULD_CUT_UP_TO(B,cut_pt)) {
#ifdef YAPOR
/* Wow, we're gonna cut!!! */
CUT_prune_to(cut_pt);
#else
/* Wow, we're gonna cut!!! */
B = cut_pt;
#endif /* YAPOR */
#ifdef TABLING
while (B->cp_b < cut_pt) {
B = B->cp_b;
}
abolish_incomplete_subgoals(B);
#endif /* TABLING */
B = cut_pt;
HB = PROTECT_FROZEN_H(B);
}
}

View File

@ -1167,18 +1167,23 @@ Yap_execute_goal(Term t, int nargs, Term mod)
}
if (out == 1) {
choiceptr old_B;
choiceptr cut_B, old_B;
/* we succeeded, let's prune */
/* restore the old environment */
/* get to previous environment */
cut_B = (choiceptr)ENV[E_CB];
#ifdef YAPOR
CUT_prune_to((choiceptr)(ENV[E_CB]));
#else
B = (choiceptr)(ENV[E_CB]);
CUT_prune_to(cut_B);
#endif /* YAPOR */
#ifdef TABLING
abolish_incomplete_subgoals(B);
if (B != cut_B) {
while (B->cp_b < cut_B) {
B = B->cp_b;
}
abolish_incomplete_subgoals(B);
}
#endif /* TABLING */
B = cut_B;
/* find out where we have the old arguments */
old_B = ((choiceptr)(ENV-(EnvSizeInCells+nargs+1)))-1;
CP = saved_cp;
@ -1355,17 +1360,19 @@ p_restore_regs2(void)
#else
pt0 = (choiceptr)(LCL0-IntOfTerm(d0));
#endif
#ifdef YAPOR
CUT_prune_to(pt0);
#endif /* YAPOR */
/* find where to cut to */
if (pt0 > B) {
/* Wow, we're gonna cut!!! */
#ifdef YAPOR
CUT_prune_to(pt0);
#else
B = pt0;
#endif /* YAPOR */
#ifdef TABLING
while (B->cp_b < pt0) {
B = B->cp_b;
}
abolish_incomplete_subgoals(B);
#endif /* TABLING */
B = pt0;
HB = B->cp_h;
/* trim_trail();*/
}
@ -1448,7 +1455,12 @@ JumpToEnv(Term t) {
B = first_func;
}
#ifdef TABLING
abolish_incomplete_subgoals(B);
if (B != B0) {
while (B0->cp_b < B) {
B0 = B0->cp_b;
}
abolish_incomplete_subgoals(B0);
}
#endif /* TABLING */
return FALSE;
}

View File

@ -1656,16 +1656,16 @@ mark_trail(tr_fr_ptr trail_ptr, tr_fr_ptr trail_base, CELL *gc_H, choiceptr gc_B
*/
#ifdef TABLING
#ifdef TABLING_BATCHED_SCHEDULING
#define init_substitution_pointer(GCB, SUBS_PTR, DEP_FR) \
SUBS_PTR = (CELL *) (CONS_CP(GCB) + 1)
#else /* TABLING_LOCAL_SCHEDULING */
#define init_substitution_pointer(GCB, SUBS_PTR, DEP_FR) \
SUBS_PTR = (CELL *) (CONS_CP(GCB) + 1); \
if (DepFr_leader_cp(DEP_FR) == GCB) \
SUBS_PTR += SgFr_arity(GEN_CP_SG_FR(GCB))
#endif /* TABLING_SCHEDULING */
#endif
if (DepFr_leader_cp(DEP_FR) == GCB) { \
/* GCB is a generator-consumer node */ \
/* never here if batched scheduling */ \
SUBS_PTR = (CELL *) (GEN_CP(GCB) + 1); \
SUBS_PTR += SgFr_arity(GEN_CP(GCB)->cp_sg_fr); \
} else { \
SUBS_PTR = (CELL *) (CONS_CP(GCB) + 1); \
}
#endif /* TABLING */
static void
@ -1829,7 +1829,7 @@ mark_choicepoints(register choiceptr gc_B, tr_fr_ptr saved_TR, int very_verbose)
CELL vars;
/* fetch the solution */
init_substitution_pointer(gc_B, answ_fr, CONS_CP(gc_B)->ccp_dep_fr);
init_substitution_pointer(gc_B, answ_fr, CONS_CP(gc_B)->cp_dep_fr);
vars = *answ_fr++;
while (vars--) {
mark_external_reference(answ_fr);
@ -1840,15 +1840,8 @@ mark_choicepoints(register choiceptr gc_B, tr_fr_ptr saved_TR, int very_verbose)
break;
case _table_completion:
{
register gen_cp_ptr gcp = GEN_CP(gc_B);
int nargs;
#ifdef TABLING_BATCHED_SCHEDULING
nargs = gcp->gcp_sg_fr->subgoal_arity;
#else
nargs = gcp->gcp_dep_fr->subgoal_frame->subgoal_arity;
#endif
saved_reg = (CELL *)(gcp+1)+nargs;
int nargs = SgFr_arity(GEN_CP(gc_B)->cp_sg_fr);
saved_reg = (CELL *)(GEN_CP(gc_B) + 1) + nargs;
nargs = *saved_reg++;
while (nargs--) {
mark_external_reference(saved_reg);
@ -1862,13 +1855,12 @@ mark_choicepoints(register choiceptr gc_B, tr_fr_ptr saved_TR, int very_verbose)
case _table_retry:
case _table_trust:
{
register gen_cp_ptr gcp = GEN_CP(gc_B);
int nargs = rtp->u.ld.s;
/* for each saved register */
for (saved_reg = (CELL *)(gcp+1);
for (saved_reg = (CELL *)(GEN_CP(gc_B) + 1);
/* assumes we can count registers in CP this
way */
saved_reg < (CELL *)(gcp+1) + nargs;
saved_reg < (CELL *)(GEN_CP(gc_B) + 1) + nargs;
saved_reg++) {
mark_external_reference(saved_reg);
}
@ -2552,7 +2544,7 @@ sweep_choicepoints(choiceptr gc_B)
EnvBMap((CELL_PTR) (gc_B->cp_cp)));
/* fetch the solution */
init_substitution_pointer(gc_B, answ_fr, CONS_CP(gc_B)->ccp_dep_fr);
init_substitution_pointer(gc_B, answ_fr, CONS_CP(gc_B)->cp_dep_fr);
vars = *answ_fr++;
while (vars--) {
CELL cp_cell = *answ_fr;
@ -2568,16 +2560,10 @@ sweep_choicepoints(choiceptr gc_B)
break;
case _table_completion:
{
register gen_cp_ptr gcp = GEN_CP(gc_B);
#ifdef TABLING_BATCHED_SCHEDULING
int nargs = gcp->gcp_sg_fr->subgoal_arity;
#else
int nargs = gcp->gcp_dep_fr->subgoal_frame->subgoal_arity;
#endif
int nargs = SgFr_arity(GEN_CP(gc_B)->cp_sg_fr);
CELL *saved_reg;
saved_reg = (CELL *)(gcp+1)+nargs;
saved_reg = (CELL *)(GEN_CP(gc_B) + 1) + nargs;
nargs = *saved_reg++;
while (nargs--) {
CELL cp_cell = *saved_reg;
@ -2596,7 +2582,6 @@ sweep_choicepoints(choiceptr gc_B)
case _table_retry:
case _table_trust:
{
register gen_cp_ptr gcp = GEN_CP(gc_B);
int nargs;
CELL *saved_reg;
@ -2606,10 +2591,10 @@ sweep_choicepoints(choiceptr gc_B)
nargs = rtp->u.ld.s;
/* for each saved register */
for (saved_reg = (CELL *)(gcp+1);
for (saved_reg = (CELL *)(GEN_CP(gc_B) + 1);
/* assumes we can count registers in CP this
way */
saved_reg < (CELL *)(gcp+1) + nargs;
saved_reg < (CELL *)(GEN_CP(gc_B) + 1) + nargs;
saved_reg++) {
CELL cp_cell = *saved_reg;
if (MARKED_PTR(saved_reg)) {
@ -2619,7 +2604,7 @@ sweep_choicepoints(choiceptr gc_B)
}
}
}
saved_reg = (CELL *)(gcp+1) + nargs;
saved_reg = (CELL *)(GEN_CP(gc_B) + 1) + nargs;
nargs = *saved_reg++;
while (nargs--) {
CELL cp_cell = *saved_reg;

View File

@ -11,8 +11,12 @@
* File: index.c *
* comments: Indexing a Prolog predicate *
* *
* Last rev: $Date: 2005-03-15 18:29:23 $,$Author: vsc $ *
* Last rev: $Date: 2005-04-07 17:48:54 $,$Author: ricroc $ *
* $Log: not supported by cvs2svn $
* Revision 1.120 2005/03/15 18:29:23 vsc
* fix GPL
* fix idb: stuff in coroutines.
*
* Revision 1.119 2005/03/04 20:30:12 ricroc
* bug fixes for YapTab support
*
@ -647,7 +651,7 @@ has_cut(yamop *pc)
case _getwork:
case _getwork_seq:
case _sync:
#endif
#endif /* YAPOR */
#ifdef TABLING
case _table_try_me_single:
case _table_try_me:
@ -655,7 +659,7 @@ has_cut(yamop *pc)
case _table_trust_me:
case _table_answer_resolution:
case _table_completion:
#endif
#endif /* TABLING */
pc = NEXTOP(pc,ld);
break;
/* instructions type Ill */
@ -702,7 +706,7 @@ has_cut(yamop *pc)
case _write_l_list:
#if !defined(YAPOR)
case _or_last:
#endif
#endif /* !YAPOR */
case _pop:
case _index_pred:
#if THREADS
@ -722,7 +726,7 @@ has_cut(yamop *pc)
case _index_blob:
#ifdef YAPOR
case _getwork_first_time:
#endif
#endif /* YAPOR */
#ifdef TABLING
case _trie_do_var:
case _trie_trust_var:
@ -744,7 +748,7 @@ has_cut(yamop *pc)
case _trie_trust_struct:
case _trie_try_struct:
case _trie_retry_struct:
#endif
#endif /* TABLING */
pc = NEXTOP(pc,e);
break;
case _expand_clauses:
@ -800,7 +804,7 @@ has_cut(yamop *pc)
case _call:
#ifdef YAPOR
case _or_last:
#endif
#endif /* YAPOR */
pc = NEXTOP(pc,sla);
break;
/* instructions type sla, but for disjunctions */
@ -963,7 +967,7 @@ has_cut(yamop *pc)
case _pop_n:
#ifdef TABLING
case _table_new_answer:
#endif
#endif /* TABLING */
pc = NEXTOP(pc,s);
break;
/* instructions type ps */
@ -1347,7 +1351,7 @@ add_info(ClauseDef *clause, UInt regno)
case _call:
#ifdef YAPOR
case _or_last:
#endif
#endif /* YAPOR */
case _either:
case _or_else:
case _call_cpred:
@ -1960,7 +1964,7 @@ add_info(ClauseDef *clause, UInt regno)
case _getwork:
case _getwork_seq:
case _sync:
#endif
#endif /* YAPOR */
#ifdef TABLING
case _table_try_single:
case _table_try_me:
@ -1971,7 +1975,7 @@ add_info(ClauseDef *clause, UInt regno)
case _table_trust:
case _table_answer_resolution:
case _table_completion:
#endif
#endif /* TABLING */
case _enter_profiling:
case _count_call:
case _retry_profiled:
@ -2003,7 +2007,7 @@ add_info(ClauseDef *clause, UInt regno)
case _procceed:
#if !defined(YAPOR)
case _or_last:
#endif
#endif /* !YAPOR */
case _pop:
case _index_pred:
#if THREADS
@ -2022,7 +2026,7 @@ add_info(ClauseDef *clause, UInt regno)
case _index_blob:
#ifdef YAPOR
case _getwork_first_time:
#endif
#endif /* YAPOR */
#ifdef TABLING
case _table_new_answer:
case _trie_do_var:
@ -2045,7 +2049,7 @@ add_info(ClauseDef *clause, UInt regno)
case _trie_trust_struct:
case _trie_try_struct:
case _trie_retry_struct:
#endif
#endif /* TABLING */
clause->Tag = (CELL)NULL;
return;
}
@ -2957,7 +2961,7 @@ emit_optry(int var_group, int first, int clauses, int clleft, PredEntry *ap)
/* we never actually get to remove the last choice-point in this case */
return retry_op;
} else
#endif
#endif /* TABLING */
{
/* last group */
return try_op;
@ -3286,7 +3290,7 @@ emit_single_switch_case(ClauseDef *min, struct intermediates *cint, int first, i
return lbl;
}
}
#endif
#endif /* TABLING */
return (UInt)(min->CurrentCode);
}
@ -3566,7 +3570,7 @@ emit_protection_choicepoint(int first, int clleft, UInt nxtlbl, struct intermedi
but should work.
*/
Yap_emit(retryme_op, (CELL)TRUSTFAILCODE, 0, cint);
#endif
#endif /* TABLING */
} else {
Yap_emit(trustme_op, 0, 0, cint);
}
@ -4571,12 +4575,19 @@ expand_index(struct intermediates *cint) {
case _retry_me2:
case _retry_me3:
case _retry_me4:
#ifdef TABLING
case _table_retry_me:
#endif /* TABLING */
isfirstcl = FALSE;
case _try_me:
case _try_me1:
case _try_me2:
case _try_me3:
case _try_me4:
#ifdef TABLING
case _table_try_single:
case _table_try_me:
#endif /* TABLING */
/* ok, we found the start for an indexing block,
but we don't if we are going to operate here or not */
/* if we are to commit here, alt will tell us where */
@ -4593,6 +4604,9 @@ expand_index(struct intermediates *cint) {
case _trust_me2:
case _trust_me3:
case _trust_me4:
#ifdef TABLING
case _table_trust_me:
#endif /* TABLING */
/* we will commit to this group for sure */
ipc = NEXTOP(ipc,ld);
alt = NULL;
@ -4880,8 +4894,11 @@ expand_index(struct intermediates *cint) {
}
} else {
op_numbers op = Yap_op_from_opcode(alt->opc);
if (op == _retry ||
op == _trust) {
if (op == _retry || op == _trust
#ifdef TABLING
|| op == _table_retry || op == _table_trust
#endif /* TABLING */
) {
last = alt->u.ld.d;
} else if (op >= _retry2 && op <= _retry4) {
last = alt->u.l.l;
@ -7608,13 +7625,15 @@ Yap_FollowIndexingCode(PredEntry *ap, yamop *ipc, Term Terms[3], yamop *ap_pc, y
break;
case _trust:
#ifdef YAPOR
CUT_prune_to(B->cp_b);
{
choiceptr cut_pt;
cut_pt = B->cp_b;
CUT_prune_to(cut_pt);
B = cut_pt;
}
#else
B = B->cp_b;
#endif /* YAPOR */
#ifdef TABLING
abolish_incomplete_subgoals(B);
#endif /* TABLING */
b0 = B;
if (lu_pred)
return lu_clause(ipc->u.ld.d);
@ -7628,13 +7647,15 @@ Yap_FollowIndexingCode(PredEntry *ap, yamop *ipc, Term Terms[3], yamop *ap_pc, y
case _trust_me3:
case _trust_me4:
#ifdef YAPOR
CUT_prune_to(B->cp_b);
{
choiceptr cut_pt;
cut_pt = B->cp_b;
CUT_prune_to(cut_pt);
B = cut_pt;
}
#else
B = B->cp_b;
#endif /* YAPOR */
#ifdef TABLING
abolish_incomplete_subgoals(B);
#endif /* TABLING */
ipc = NEXTOP(ipc,ld);
break;
case _trust_logical_pred:
@ -7942,13 +7963,15 @@ Yap_FollowIndexingCode(PredEntry *ap, yamop *ipc, Term Terms[3], yamop *ap_pc, y
default:
if (b0) {
#ifdef YAPOR
CUT_prune_to(B->cp_b);
{
choiceptr cut_pt;
cut_pt = B->cp_b;
CUT_prune_to(cut_pt);
B = cut_pt;
}
#else
B = B->cp_b;
#endif /* YAPOR */
#ifdef TABLING
abolish_incomplete_subgoals(B);
#endif /* TABLING */
/* I did a trust */
}
if (lu_pred)
@ -7960,13 +7983,15 @@ Yap_FollowIndexingCode(PredEntry *ap, yamop *ipc, Term Terms[3], yamop *ap_pc, y
if (b0) {
/* I did a trust */
#ifdef YAPOR
CUT_prune_to(B->cp_b);
{
choiceptr cut_pt;
cut_pt = B->cp_b;
CUT_prune_to(cut_pt);
B = cut_pt;
}
#else
B = B->cp_b;
#endif /* YAPOR */
#ifdef TABLING
abolish_incomplete_subgoals(B);
#endif /* TABLING */
}
return NULL;
}

View File

@ -746,6 +746,11 @@ InitFlags(void)
#endif
/* current default */
yap_flags[INDEXING_MODE_FLAG] = INDEX_MODE_MULTI;
#ifdef TABLING
yap_flags[TABLING_MODE_FLAG] = TABLING_MODE_DEFAULT;
#else
yap_flags[TABLING_MODE_FLAG] = TABLING_MODE_OFF;
#endif /* TABLING */
}
static void
@ -1155,14 +1160,6 @@ Yap_InitWorkspace(int Heap,
/* also init memory page size, required by later functions */
Yap_InitSysbits ();
#ifdef TABLING
#ifdef TABLING_BATCHED_SCHEDULING
INFORMATION_MESSAGE("YapTab: batched scheduling");
#else /* TABLING_LOCAL_SCHEDULING */
INFORMATION_MESSAGE("YapTab: local scheduling");
#endif /* BATCHED - LOCAL */
#endif /* TABLING */
#ifdef YAPOR
worker_id = 0;
if (aux_number_workers > MAX_WORKERS)

View File

@ -751,17 +751,19 @@ p_cut_by( void)
#else
pt0 = (choiceptr)(LCL0-IntOfTerm(d0));
#endif
#ifdef YAPOR
CUT_prune_to(pt0);
#endif /* YAPOR */
/* find where to cut to */
if (pt0 > B) {
/* Wow, we're gonna cut!!! */
#ifdef YAPOR
CUT_prune_to(pt0);
#else
B = pt0;
#endif /* YAPOR */
#ifdef TABLING
while (B->cp_b < pt0) {
B = B->cp_b;
}
abolish_incomplete_subgoals(B);
#endif /* TABLING */
B = pt0;
HB = B->cp_h;
/* trim_trail();*/
}

View File

@ -11,8 +11,13 @@
* File: stdpreds.c *
* comments: General-purpose C implemented system predicates *
* *
* Last rev: $Date: 2005-03-13 06:26:11 $,$Author: vsc $ *
* Last rev: $Date: 2005-04-07 17:48:55 $,$Author: ricroc $ *
* $Log: not supported by cvs2svn $
* Revision 1.86 2005/03/13 06:26:11 vsc
* fix excessive pruning in meta-calls
* fix Term->int breakage in compiler
* improve JPL (at least it does something now for amd64).
*
* Revision 1.85 2005/03/02 19:48:02 vsc
* Fix some possible errors in name/2 and friends, and cleanup code a bit
* YAP_Error changed.
@ -2852,6 +2857,15 @@ p_set_yap_flags(void)
return(FALSE);
yap_flags[INDEXING_MODE_FLAG] = value;
break;
case TABLING_MODE_FLAG:
#ifdef TABLING
if (value != TABLING_MODE_DEFAULT && value != TABLING_MODE_BATCHED && value != TABLING_MODE_LOCAL)
return(FALSE);
yap_flags[TABLING_MODE_FLAG] = value;
#else
return(FALSE);
#endif /* TABLING */
break;
default:
return(FALSE);
}

View File

@ -390,10 +390,11 @@ reset_trail(tr_fr_ptr TR0) {
/* so the next cell is the old value */
#if FROZEN_STACKS
pt[0] = TrailVal(TR-1);
TR -= 1;
#else
pt[0] = TrailTerm(TR-1);
#endif /* FROZEN_STACKS */
TR -= 2;
#endif /* FROZEN_STACKS */
}
#endif
}

View File

@ -40,9 +40,7 @@ INFODIR=$(SHAREDIR)/info
# -DENV_COPY: or-parallelism with environment copying, in Muse style.
# -DSBA: or-parallelism with sparse binding arrays.
# -DACOW: or-parallelism with copy-on-write.
# -DTABLING_BATCHED_SCHEDULING: support for tabulation with
# batched scheduling
# -DTABLING_LOCAL_SCHEDULING: support for tabulation with local scheduling
# -DTABLING: support for tabling
#
#
# check also optimisation options in INSTALL file.

View File

@ -37,9 +37,9 @@ struct worker WORKER;
void abort_yaptab(const char *msg, ...) {
va_list args;
va_start(args, msg);
fprintf(stderr, "[ Fatal YapTab Error: ");
fprintf(stderr, "%% YAPTAB FATAL ERROR: ");
vfprintf(stderr, msg, args);
fprintf(stderr, " ]\n");
fprintf(stderr, "\n");
exit (1);
}
#endif /* TABLING */
@ -49,9 +49,9 @@ void abort_yaptab(const char *msg, ...) {
void abort_yapor(const char *msg, ...) {
va_list args;
va_start(args, msg);
fprintf(stderr, "[ Fatal YapOr Error: ");
fprintf(stderr, "%% YAPOR FATAL ERROR: ");
vfprintf(stderr, msg, args);
fprintf(stderr, " (worker %d exiting...) ]\n", worker_id);
fprintf(stderr, " (worker %d exiting...)\n", worker_id);
unmap_memory();
exit (1);
}

View File

@ -8,13 +8,13 @@
#include "Yatom.h"
#include "Heap.h"
#include "yapio.h"
#if HAVE_STRING_H
#include <string.h>
#endif
#ifdef YAPOR
#if HAVE_SYS_TIME_H
#include <sys/time.h>
#endif
#if HAVE_STRING_H
#include <string.h>
#endif
#include "or.macros.h"
#endif /* YAPOR */
#ifdef TABLING
@ -37,8 +37,8 @@ static qg_ans_fr_ptr actual_answer;
#ifdef YAPOR
static realtime current_time(void);
static int yapor_on(void);
static int start_yapor(void);
static int p_yapor_on(void);
static int p_start_yapor(void);
static int p_sequential(void);
static int p_default_sequential(void);
static int p_execution_mode(void);
@ -50,10 +50,11 @@ static void show_answers(void);
static void answer_to_stdout(char *answer);
#endif /* YAPOR */
#ifdef TABLING
static int p_table(void);
static int p_abolish_trie(void);
static int p_show_trie(void);
static int p_show_trie_stats(void);
static int p_do_table(void);
static int p_do_tabling_mode(void);
static int p_do_abolish_trie(void);
static int p_do_show_trie(void);
static int p_do_show_trie_stats(void);
#endif /* TABLING */
#ifdef STATISTICS
static int p_show_frames_stats(void);
@ -70,8 +71,8 @@ static int p_debug_prolog(void);
void Yap_init_optyap_preds(void) {
#ifdef YAPOR
Yap_InitCPred("$yapor_on", 0, yapor_on, SafePredFlag|SyncPredFlag|HiddenPredFlag);
Yap_InitCPred("$start_yapor", 0, start_yapor, SafePredFlag|SyncPredFlag|HiddenPredFlag);
Yap_InitCPred("$yapor_on", 0, p_yapor_on, SafePredFlag|SyncPredFlag|HiddenPredFlag);
Yap_InitCPred("$start_yapor", 0, p_start_yapor, SafePredFlag|SyncPredFlag|HiddenPredFlag);
Yap_InitCPred("$sequential", 1, p_sequential, SafePredFlag|SyncPredFlag|HiddenPredFlag);
Yap_InitCPred("$default_sequential", 1, p_default_sequential, SafePredFlag|SyncPredFlag|HiddenPredFlag);
Yap_InitCPred("execution_mode", 1, p_execution_mode, SafePredFlag|SyncPredFlag);
@ -80,10 +81,11 @@ void Yap_init_optyap_preds(void) {
Yap_InitCPred("$parallel_yes_answer", 0, p_parallel_yes_answer, SafePredFlag|SyncPredFlag|HiddenPredFlag);
#endif /* YAPOR */
#ifdef TABLING
Yap_InitCPred("$do_table", 2, p_table, SafePredFlag|SyncPredFlag|HiddenPredFlag);
Yap_InitCPred("$do_abolish_trie", 2, p_abolish_trie, SafePredFlag|SyncPredFlag|HiddenPredFlag);
Yap_InitCPred("$do_show_trie", 2, p_show_trie, SafePredFlag|SyncPredFlag|HiddenPredFlag);
Yap_InitCPred("$do_show_trie_stats", 2, p_show_trie_stats, SafePredFlag|SyncPredFlag|HiddenPredFlag);
Yap_InitCPred("$do_table", 2, p_do_table, SafePredFlag|SyncPredFlag|HiddenPredFlag);
Yap_InitCPred("$do_tabling_mode", 3, p_do_tabling_mode, SafePredFlag|SyncPredFlag|HiddenPredFlag);
Yap_InitCPred("$do_abolish_trie", 2, p_do_abolish_trie, SafePredFlag|SyncPredFlag|HiddenPredFlag);
Yap_InitCPred("$do_show_trie", 2, p_do_show_trie, SafePredFlag|SyncPredFlag|HiddenPredFlag);
Yap_InitCPred("$do_show_trie_stats", 2, p_do_show_trie_stats, SafePredFlag|SyncPredFlag|HiddenPredFlag);
#endif /* TABLING */
#ifdef STATISTICS
Yap_InitCPred("show_frames_stats", 0, p_show_frames_stats, SafePredFlag|SyncPredFlag);
@ -124,13 +126,13 @@ realtime current_time(void) {
static
int yapor_on(void) {
int p_yapor_on(void) {
return (PARALLEL_EXECUTION_MODE);
}
static
int start_yapor(void) {
int p_start_yapor(void) {
#ifdef TIMESTAMP_CHECK
GLOBAL_timestamp = 0;
#endif /* TIMESTAMP_CHECK */
@ -443,7 +445,7 @@ void answer_to_stdout(char *answer) {
#ifdef TABLING
static
int p_table(void) {
int p_do_table(void) {
Term t, mod;
PredEntry *pe;
tab_ent_ptr te;
@ -463,6 +465,9 @@ int p_table(void) {
} else {
return (FALSE);
}
if (pe->PredFlags & TabledPredFlag) {
return (TRUE);
}
pe->PredFlags |= TabledPredFlag;
new_subgoal_trie_node(sg_node, 0, NULL, NULL, NULL);
new_table_entry(te, sg_node);
@ -472,7 +477,53 @@ int p_table(void) {
static
int p_abolish_trie(void) {
int p_do_tabling_mode(void) {
Term t, mod, s;
PredEntry *pe;
mod = Deref(ARG2);
if (IsVarTerm(mod) || !IsAtomTerm(mod)) {
return (FALSE);
}
t = Deref(ARG1);
if (IsAtomTerm(t)) {
Atom at = AtomOfTerm(t);
pe = RepPredProp(PredPropByAtom(at, mod));
} else if (IsApplTerm(t)) {
Functor func = FunctorOfTerm(t);
pe = RepPredProp(PredPropByFunc(func, mod));
} else {
return (FALSE);
}
s = Deref(ARG3);
if (IsVarTerm(s)) {
Term sa;
if (pe->PredFlags & LocalSchedPredFlag) {
sa = MkAtomTerm(Yap_LookupAtom("local"));
} else {
sa = MkAtomTerm(Yap_LookupAtom("batched"));
}
Bind((CELL *)s, sa);
return(TRUE);
}
if (IsAtomTerm(s)) {
char *sa;
sa = RepAtom(AtomOfTerm(s))->StrOfAE;
if (strcmp(sa, "local") == 0) {
pe->PredFlags |= LocalSchedPredFlag;
return(TRUE);
}
if (strcmp(sa,"batched") == 0) {
pe->PredFlags &= ~LocalSchedPredFlag;
return(TRUE);
}
}
return (FALSE);
}
static
int p_do_abolish_trie(void) {
Term t, mod;
tab_ent_ptr tab_ent;
sg_hash_ptr hash;
@ -508,7 +559,7 @@ int p_abolish_trie(void) {
static
int p_show_trie(void) {
int p_do_show_trie(void) {
Term t1, mod;
PredEntry *pe;
Atom at;
@ -537,7 +588,7 @@ int p_show_trie(void) {
static
int p_show_trie_stats(void) {
int p_do_show_trie_stats(void) {
Term t, mod;
PredEntry *pe;
Atom at;

View File

@ -68,12 +68,12 @@ void finish_yapor(void);
#ifdef TABLING
#include <stdio.h>
sg_node_ptr subgoal_search(tab_ent_ptr tab_ent, OPREG arity, CELL **Yaddr);
sg_fr_ptr subgoal_search(tab_ent_ptr tab_ent, OPREG arity, CELL **Yaddr);
ans_node_ptr answer_search(sg_fr_ptr sg_fr, CELL *subs_ptr);
void load_answer_trie(ans_node_ptr ans_node, CELL *subs_ptr);
void private_completion(sg_fr_ptr sg_fr);
void free_subgoal_trie_branch(sg_node_ptr node, int missing_nodes);
void free_answer_trie(sg_fr_ptr sg_fr);
void free_answer_trie_branch(ans_node_ptr node);
void update_answer_trie(sg_fr_ptr sg_fr);
void traverse_trie(FILE *stream, sg_node_ptr sg_node, int pred_arity, Atom pred_atom, int show);
#endif /* TABLING */

View File

@ -657,7 +657,7 @@ void share_private_nodes(int worker_q) {
/* update subgoal frames in the recently shared branches */
while (sg_frame && YOUNGER_CP(SgFr_gen_cp(sg_frame), LOCAL_top_cp_on_stack)) {
SgFr_gen_worker(sg_frame) = MAX_WORKERS;
SgFr_gen_top_or_fr(sg_frame) = GEN_CP(SgFr_gen_cp(sg_frame))->gcp_or_fr;
SgFr_gen_top_or_fr(sg_frame) = SgFr_gen_cp(sg_frame)->cp_or_fr;
sg_frame = SgFr_next(sg_frame);
}
@ -676,7 +676,7 @@ void share_private_nodes(int worker_q) {
REMOTE_top_dep_fr(worker_q) = dep_frame;
/* update dependency frames in the recently shared branches */
while (YOUNGER_CP(DepFr_cons_cp(dep_frame), LOCAL_top_cp_on_stack)) {
DepFr_top_or_fr(dep_frame) = CONS_CP(DepFr_cons_cp(dep_frame))->ccp_or_fr;
DepFr_top_or_fr(dep_frame) = DepFr_cons_cp(dep_frame)->cp_or_fr;
dep_frame = DepFr_next(dep_frame);
}
#endif /* TABLING */

View File

@ -38,18 +38,31 @@
/* the frozen branch depends on the current top node **
** this means that the current top node is a generator node */
LOCK_OR_FRAME(LOCAL_top_or_fr);
#ifdef TABLING_BATCHED_SCHEDULING
if (OrFr_alternative(LOCAL_top_or_fr) != GEN_CP_NULL_ALT) {
#else /* TABLING_LOCAL_SCHEDULING */
if (OrFr_alternative(LOCAL_top_or_fr) != GEN_CP_NULL_ALT || B_FZ == LOCAL_top_cp) {
#endif /* TABLING_SCHEDULING */
/* the current top node has unexploited alternatives ---> we should **
** exploit all the available alternatives before execute completion */
if (OrFr_alternative(LOCAL_top_or_fr) == NULL ||
(OrFr_alternative(LOCAL_top_or_fr) == ANSWER_RESOLUTION && B_FZ != LOCAL_top_cp)) {
/* there are no unexploited alternatives **
** (NULL if batched scheduling OR ANSWER_RESOLUTION if local scheduling) */
UNLOCK_OR_FRAME(LOCAL_top_or_fr);
goto completion;
} else {
/* there are unexploited alternatives **
** we should exploit all the available alternatives before execute completion */
PREG = OrFr_alternative(LOCAL_top_or_fr);
PREFETCH_OP(PREG);
GONext();
}
/* ricroc - obsolete
#ifdef batched scheduling
if (OrFr_alternative(LOCAL_top_or_fr) != NULL) {
#else local scheduling
if (OrFr_alternative(LOCAL_top_or_fr) != ANSWER_RESOLUTION || B_FZ == LOCAL_top_cp) {
#endif
PREG = OrFr_alternative(LOCAL_top_or_fr);
PREFETCH_OP(PREG);
GONext();
}
UNLOCK_OR_FRAME(LOCAL_top_or_fr);
*/
}
goto completion;
}

View File

@ -20,7 +20,6 @@ STD_PROTO(static inline void SCH_refuse_share_request_if_any, (void));
STD_PROTO(static inline void SCH_set_load, (choiceptr));
STD_PROTO(static inline void SCH_new_alternative, (yamop *,yamop *));
STD_PROTO(static inline void CUT_prune_to, (choiceptr));
STD_PROTO(static inline void CUT_send_prune_request, (int, choiceptr));
STD_PROTO(static inline void CUT_reset_prune_request, (void));
@ -152,6 +151,13 @@ STD_PROTO(static inline qg_sol_fr_ptr CUT_prune_solution_frames, (qg_sol_fr_ptr,
** Cut Macros **
** -------------------- */
#define CUT_prune_to(PRUNE_CP) \
if (YOUNGER_CP(LOCAL_top_cp, PRUNE_CP)) { \
if (! LOCAL_prune_request) \
prune_shared_branch(PRUNE_CP); \
PRUNE_CP = LOCAL_top_cp; \
}
#define CUT_wait_leftmost() \
if (PARALLEL_EXECUTION_MODE) { \
/* parallel execution mode --> wait until leftmost */ \
@ -318,19 +324,6 @@ void SCH_new_alternative(yamop *curpc, yamop *new) {
** Cut Stuff: Pruning **
** ---------------------------- */
static inline
void CUT_prune_to(choiceptr prune_cp) {
if (EQUAL_OR_YOUNGER_CP(prune_cp, LOCAL_top_cp)) {
B = prune_cp;
} else {
if (! LOCAL_prune_request)
prune_shared_branch(prune_cp);
B = LOCAL_top_cp;
}
return;
}
static inline
void CUT_send_prune_request(int worker, choiceptr prune_cp) {
LOCK_WORKER(worker);

View File

@ -117,7 +117,7 @@ void move_up_to_prune_request(void) {
CUT_reset_prune_request();
#ifdef TABLING
LOCAL_top_cp_on_stack = LOCAL_top_cp;
abolish_incomplete_subgoals(LOCAL_top_cp);
abolish_incomplete_subgoals(LOCAL_top_cp - 1); /* do not include LOCAL_top_cp */
#endif /* TABLIG */
return;
@ -277,13 +277,18 @@ int move_up_one_node(or_fr_ptr nearest_livenode) {
if (OrFr_pend_prune_cp(LOCAL_top_or_fr)
&& ! LOCAL_prune_request
&& CUT_last_worker_left_pending_prune(LOCAL_top_or_fr)) {
#ifdef TABLING
choiceptr aux_cp = LOCAL_top_cp;
#endif /* TABLIG */
choiceptr prune_cp = OrFr_pend_prune_cp(LOCAL_top_or_fr);
OrFr_pend_prune_cp(LOCAL_top_or_fr) = NULL;
BRANCH(worker_id, OrFr_depth(LOCAL_top_or_fr)) = OrFr_pend_prune_ltt(LOCAL_top_or_fr);
UNLOCK_OR_FRAME(LOCAL_top_or_fr);
prune_shared_branch(prune_cp);
#ifdef TABLING
abolish_incomplete_subgoals(LOCAL_top_cp);
while (YOUNGER_CP(aux_cp->cp_b, LOCAL_top_cp))
aux_cp = aux_cp->cp_b;
abolish_incomplete_subgoals(aux_cp);
#endif /* TABLIG */
return FALSE;
}

File diff suppressed because it is too large Load Diff

View File

@ -1,8 +1,8 @@
#include <stdlib.h>
#include "opt.mavar.h"
/* -------------------- **
** Prototypes **
** -------------------- */
@ -63,9 +63,11 @@ STD_PROTO(static inline tg_sol_fr_ptr CUT_prune_tg_solution_frames, (tg_sol_fr_p
#endif /* TAGS_FAST_OPS */
#define NORM_CP(CP) ((choiceptr)(CP))
#define GEN_CP(CP) ((gen_cp_ptr)(CP))
#define CONS_CP(CP) ((cons_cp_ptr)(CP))
#define NORM_CP(CP) ((choiceptr)(CP))
#define CONS_CP(CP) ((struct consumer_choicept *)(CP))
#define GEN_CP(CP) ((struct generator_choicept *)(CP))
#define IS_BATCHED_GEN_CP(CP) (GEN_CP(CP)->cp_dep_fr == NULL)
#define TAG_AS_ANSWER_LEAF_NODE(NODE) TrNode_parent(NODE) = (ans_node_ptr)((unsigned int)TrNode_parent(NODE) | 0x1)
#define UNTAG_ANSWER_LEAF_NODE(NODE) ((ans_node_ptr)((unsigned int)NODE & 0xfffffffe))
@ -159,15 +161,6 @@ STD_PROTO(static inline tg_sol_fr_ptr CUT_prune_tg_solution_frames, (tg_sol_fr_p
#endif /* YAPOR */
#ifdef TABLING_BATCHED_SCHEDULING
#define GEN_CP_NULL_ALT NULL
#define GEN_CP_SG_FR(GCP) GEN_CP(GCP)->gcp_sg_fr
#else /* TABLING_LOCAL_SCHEDULING */
#define GEN_CP_NULL_ALT ANSWER_RESOLUTION
#define GEN_CP_SG_FR(GCP) DepFr_sg_fr(GEN_CP(GCP)->gcp_dep_fr)
#endif /* TABLING_SCHEDULING */
#ifdef YAPOR
#ifdef TIMESTAMP
#define DepFr_init_timestamp_field(DEP_FR) DepFr_timestamp(DEP_FR) = 0
@ -237,32 +230,39 @@ STD_PROTO(static inline tg_sol_fr_ptr CUT_prune_tg_solution_frames, (tg_sol_fr_p
memcpy(SuspFr_trail_start(SUSP_FR), SuspFr_trail_reg(SUSP_FR), TR_SIZE)
#define new_subgoal_frame(SG_FR, BOTTOM_SG_NODE, ARITY, NEXT) \
#define new_subgoal_frame(SG_FR, ARITY) \
{ register ans_node_ptr ans_node; \
ALLOC_SUBGOAL_FRAME(SG_FR); \
INIT_LOCK(SgFr_lock(SG_FR)); \
SgFr_init_yapor_fields(SG_FR); \
SgFr_subgoal_trie(SG_FR) = BOTTOM_SG_NODE; \
new_answer_trie_node(ans_node, 0, 0, NULL, NULL, NULL); \
SgFr_answer_trie(SG_FR) = ans_node; \
SgFr_first_answer(SG_FR) = NULL; \
SgFr_last_answer(SG_FR) = NULL; \
SgFr_hash_chain(SG_FR) = NULL; \
SgFr_state(SG_FR) = resolving; \
SgFr_state(SG_FR) = ready; \
SgFr_abolished(SG_FR) = 0; \
SgFr_arity(SG_FR) = ARITY; \
SgFr_next(SG_FR) = NEXT; \
}
#define new_dependency_frame(DEP_FR, DEP_ON_STACK, TOP_OR_FR, LEADER_CP, CONS_CP, SG_FR, NEXT) \
ALLOC_DEPENDENCY_FRAME(DEP_FR); \
INIT_LOCK(DepFr_lock(DEP_FR)); \
DepFr_init_yapor_fields(DEP_FR, DEP_ON_STACK, TOP_OR_FR); \
DepFr_backchain_cp(DEP_FR) = NULL; \
DepFr_leader_cp(DEP_FR) = NORM_CP(LEADER_CP); \
DepFr_cons_cp(DEP_FR) = NORM_CP(CONS_CP); \
DepFr_sg_fr(DEP_FR) = SG_FR; \
DepFr_last_ans(DEP_FR) = NULL; \
#define init_subgoal_frame(SG_FR) \
{ SgFr_init_yapor_fields(SG_FR); \
SgFr_first_answer(SG_FR) = NULL; \
SgFr_last_answer(SG_FR) = NULL; \
SgFr_hash_chain(SG_FR) = NULL; \
SgFr_state(SG_FR) = evaluating; \
SgFr_next(SG_FR) = LOCAL_top_sg_fr; \
LOCAL_top_sg_fr = sg_fr; \
}
#define new_dependency_frame(DEP_FR, DEP_ON_STACK, TOP_OR_FR, LEADER_CP, CONS_CP, SG_FR, NEXT) \
ALLOC_DEPENDENCY_FRAME(DEP_FR); \
INIT_LOCK(DepFr_lock(DEP_FR)); \
DepFr_init_yapor_fields(DEP_FR, DEP_ON_STACK, TOP_OR_FR); \
DepFr_backchain_cp(DEP_FR) = NULL; \
DepFr_leader_cp(DEP_FR) = NORM_CP(LEADER_CP); \
DepFr_cons_cp(DEP_FR) = NORM_CP(CONS_CP); \
/* start with TrNode_child(DepFr_last_answer(DEP_FR)) pointing to SgFr_first_answer(SG_FR) */ \
DepFr_last_answer(DEP_FR) = (ans_node_ptr)((int)(SG_FR) + \
(int)(&SgFr_first_answer((sg_fr_ptr)DEP_FR)) - (int)(&TrNode_child((ans_node_ptr)DEP_FR))); \
DepFr_next(DEP_FR) = NEXT
@ -501,11 +501,11 @@ void pruning_over_tabling_data_structures(void) {
static inline
void abolish_incomplete_subgoals(choiceptr prune_cp) {
#ifdef YAPOR
if (YOUNGER_CP(OrFr_node(LOCAL_top_susp_or_fr), prune_cp))
if (EQUAL_OR_YOUNGER_CP(OrFr_node(LOCAL_top_susp_or_fr), prune_cp))
pruning_over_tabling_data_structures();
#endif /* YAPOR */
if (YOUNGER_CP(DepFr_cons_cp(LOCAL_top_dep_fr), prune_cp)) {
if (EQUAL_OR_YOUNGER_CP(DepFr_cons_cp(LOCAL_top_dep_fr), prune_cp)) {
#ifdef YAPOR
if (PARALLEL_EXECUTION_MODE)
pruning_over_tabling_data_structures();
@ -514,22 +514,31 @@ void abolish_incomplete_subgoals(choiceptr prune_cp) {
dep_fr_ptr dep_fr = LOCAL_top_dep_fr;
LOCAL_top_dep_fr = DepFr_next(dep_fr);
FREE_DEPENDENCY_FRAME(dep_fr);
} while (YOUNGER_CP(DepFr_cons_cp(LOCAL_top_dep_fr), prune_cp));
} while (EQUAL_OR_YOUNGER_CP(DepFr_cons_cp(LOCAL_top_dep_fr), prune_cp));
adjust_freeze_registers();
}
while (LOCAL_top_sg_fr && YOUNGER_CP(SgFr_gen_cp(LOCAL_top_sg_fr), prune_cp)) {
while (LOCAL_top_sg_fr && EQUAL_OR_YOUNGER_CP(SgFr_gen_cp(LOCAL_top_sg_fr), prune_cp)) {
sg_fr_ptr sg_fr;
ans_hash_ptr hash;
ans_node_ptr node;
#ifdef YAPOR
if (PARALLEL_EXECUTION_MODE)
pruning_over_tabling_data_structures();
#endif /* YAPOR */
sg_fr = LOCAL_top_sg_fr;
LOCAL_top_sg_fr = SgFr_next(sg_fr);
TrNode_sg_fr(SgFr_subgoal_trie(sg_fr)) = NULL;
free_answer_hash_chain(SgFr_hash_chain(sg_fr));
free_answer_trie(sg_fr);
FREE_SUBGOAL_FRAME(sg_fr);
LOCK(SgFr_lock(sg_fr));
hash = SgFr_hash_chain(sg_fr);
node = TrNode_child(SgFr_answer_trie(sg_fr));
TrNode_child(SgFr_answer_trie(sg_fr)) = NULL;
TrNode_parent(SgFr_answer_trie(sg_fr)) = NULL;
SgFr_state(sg_fr) = ready;
SgFr_abolished(sg_fr)++;
UNLOCK(SgFr_lock(sg_fr));
free_answer_hash_chain(hash);
if (node)
free_answer_trie_branch(node);
}
return;
@ -634,7 +643,10 @@ susp_fr_ptr suspension_frame_to_resume(or_fr_ptr susp_or_fr) {
while (susp_fr) {
dep_fr = SuspFr_top_dep_fr(susp_fr);
do {
if (DepFr_last_ans(dep_fr) != SgFr_last_answer(DepFr_sg_fr(dep_fr))) {
if (TrNode_child(DepFr_last_answer(dep_fr))) {
/* ricroc - obsolete
if (DepFr_last_answer(dep_fr) != SgFr_last_answer(DepFr_sg_fr(dep_fr))) {
*/
/* unconsumed answers in susp_fr */
*susp_ptr = SuspFr_next(susp_fr);
return susp_fr;
@ -775,7 +787,7 @@ void CUT_validate_tg_answers(tg_sol_fr_ptr valid_solutions) {
while (valid_solutions) {
first_answer = last_answer = NULL;
sg_fr = GEN_CP_SG_FR(TgSolFr_gen_cp(valid_solutions));
sg_fr = GEN_CP(TgSolFr_gen_cp(valid_solutions))->cp_sg_fr;
ltt_valid_solutions = valid_solutions;
valid_solutions = TgSolFr_next(valid_solutions);
do {

View File

@ -27,8 +27,8 @@ typedef struct subgoal_trie_node {
#ifdef TABLE_LOCK_AT_NODE_LEVEL
lockvar lock;
#endif /* TABLE_LOCK_AT_NODE_LEVEL */
struct subgoal_trie_node *child;
struct subgoal_trie_node *parent;
struct subgoal_trie_node *child;
struct subgoal_trie_node *next;
} *sg_node_ptr;
@ -41,8 +41,8 @@ typedef struct answer_trie_node {
#ifdef TABLE_LOCK_AT_NODE_LEVEL
lockvar lock;
#endif /* TABLE_LOCK_AT_NODE_LEVEL */
struct answer_trie_node *child;
struct answer_trie_node *parent;
struct answer_trie_node *child;
struct answer_trie_node *next;
} *ans_node_ptr;
@ -50,9 +50,9 @@ typedef struct answer_trie_node {
#define TrNode_or_arg(X) ((X)->or_arg)
#define TrNode_entry(X) ((X)->entry)
#define TrNode_lock(X) ((X)->lock)
#define TrNode_sg_fr(X) ((X)->child)
#define TrNode_child(X) ((X)->child)
#define TrNode_parent(X) ((X)->parent)
#define TrNode_child(X) ((X)->child)
#define TrNode_sg_fr(X) ((X)->child)
#define TrNode_next(X) ((X)->next)
@ -102,16 +102,17 @@ typedef struct subgoal_frame {
struct or_frame *top_or_frame_on_generator_branch;
#endif /* YAPOR */
choiceptr generator_choice_point;
struct subgoal_trie_node *subgoal_trie;
struct answer_trie_node *answer_trie;
struct answer_trie_node *first_answer;
struct answer_trie_node *last_answer;
struct answer_hash *hash_chain;
enum {
resolving = 0,
complete = 1,
executable = 2
ready = 0,
evaluating = 1,
complete = 2,
executable = 3
} state_flag;
int abolished_operations;
int subgoal_arity;
struct subgoal_frame *next;
} *sg_fr_ptr;
@ -120,12 +121,12 @@ typedef struct subgoal_frame {
#define SgFr_gen_worker(X) ((X)->generator_worker)
#define SgFr_gen_top_or_fr(X) ((X)->top_or_frame_on_generator_branch)
#define SgFr_gen_cp(X) ((X)->generator_choice_point)
#define SgFr_subgoal_trie(X) ((X)->subgoal_trie)
#define SgFr_answer_trie(X) ((X)->answer_trie)
#define SgFr_first_answer(X) ((X)->first_answer)
#define SgFr_last_answer(X) ((X)->last_answer)
#define SgFr_hash_chain(X) ((X)->hash_chain)
#define SgFr_state(X) ((X)->state_flag)
#define SgFr_abolished(X) ((X)->abolished_operations)
#define SgFr_arity(X) ((X)->subgoal_arity)
#define SgFr_next(X) ((X)->next)
@ -137,14 +138,14 @@ typedef struct subgoal_frame {
to its or-frame. It is used to find the direct dependency node for
consumer nodes in other workers branches.
SgFr_gen_cp: a pointer to the correspondent generator choice point.
SgFr_subgoal_trie: a pointer to the bottom subgoal trie node.
It is used to abolish incomplete subgoals.
SgFr_answer_trie: a pointer to the top answer trie node.
It is used to check for/insert new answers.
SgFr_first_answer: a pointer to the bottom answer trie node of the first available answer.
SgFr_last_answer: a pointer to the bottom answer trie node of the last available answer.
SgFr_hash_chain: a pointer to the first answer_hash struct for the subgoal in hand.
SgFr_state: a flag that indicates the subgoal state
SgFr_state: a flag that indicates the subgoal state.
SgFr_abolished the number of times the subgoal was abolished.
SgFr_arity the arity of the subgoal.
SgFr_next: a pointer to chain between subgoal frames.
** ------------------------------------------------------------------------------------------- */
@ -166,7 +167,6 @@ typedef struct dependency_frame {
choiceptr backchain_choice_point;
choiceptr leader_choice_point;
choiceptr consumer_choice_point;
struct subgoal_frame *subgoal_frame;
struct answer_trie_node *last_consumed_answer;
struct dependency_frame *next;
} *dep_fr_ptr;
@ -178,8 +178,7 @@ typedef struct dependency_frame {
#define DepFr_backchain_cp(X) ((X)->backchain_choice_point)
#define DepFr_leader_cp(X) ((X)->leader_choice_point)
#define DepFr_cons_cp(X) ((X)->consumer_choice_point)
#define DepFr_sg_fr(X) ((X)->subgoal_frame)
#define DepFr_last_ans(X) ((X)->last_consumed_answer)
#define DepFr_last_answer(X) ((X)->last_consumed_answer)
#define DepFr_next(X) ((X)->next)
/* ---------------------------------------------------------------------------------------------------- **
@ -197,8 +196,7 @@ typedef struct dependency_frame {
we perform the last backtracking through answers operation.
DepFr_leader_cp: a pointer to the leader choice point.
DepFr_cons_cp: a pointer to the correspondent consumer choice point.
DepFr_sg_fr: a pointer to the correspondent subgoal frame.
DepFr_last_ans: a pointer to the last consumed answer.
DepFr_last_answer: a pointer to the last consumed answer.
DepFr_next: a pointer to chain between dependency frames.
** ---------------------------------------------------------------------------------------------------- */
@ -238,54 +236,17 @@ typedef struct suspension_frame {
/* ----------------------------- **
** Struct generator_cp **
** ----------------------------- */
/* ---------------------------------------------------------- **
** Structs generator_choicept and consumer_choicept **
** ---------------------------------------------------------- */
typedef struct generator_choice_point {
/* common choicepoints fields */
tr_fr_ptr gcp_tr;
CELL *gcp_h;
struct choicept *gcp_b;
#ifdef DEPTH_LIMIT
CELL gcp_depth;
#endif /* DEPTH_LIMIT */
yamop *gcp_cp;
#ifdef YAPOR
struct or_frame *gcp_or_fr;
#endif /* YAPOR */
yamop *gcp_ap;
CELL *gcp_env;
struct generator_choicept {
struct choicept cp;
struct dependency_frame *cp_dep_fr; /* NULL if batched scheduling */
struct subgoal_frame *cp_sg_fr;
};
/* specific generator choicepoint fields */
#ifdef TABLING_BATCHED_SCHEDULING
struct subgoal_frame *gcp_sg_fr;
#else /* TABLING_LOCAL_SCHEDULING */
struct dependency_frame *gcp_dep_fr;
#endif /* TABLING_SCHEDULING */
} *gen_cp_ptr;
/* ---------------------------- **
** Struct consumer_cp **
** ---------------------------- */
typedef struct consumer_choice_point {
/* common choicepoints fields */
tr_fr_ptr ccp_tr;
CELL *ccp_h;
struct choicept *ccp_b;
#ifdef DEPTH_LIMIT
CELL ccp_depth;
#endif /* DEPTH_LIMIT */
yamop *ccp_cp;
#ifdef YAPOR
struct or_frame *ccp_or_fr;
#endif /* YAPOR */
yamop *ccp_ap;
CELL *ccp_env;
/* specific consumer choicepoint fields */
struct dependency_frame *ccp_dep_fr;
} *cons_cp_ptr;
struct consumer_choicept {
struct choicept cp;
struct dependency_frame *cp_dep_fr;
};

View File

@ -35,7 +35,7 @@ void public_completion(void) {
sg_fr_ptr top_sg_fr;
/* complete subgoals */
top_sg_fr = SgFr_next(GEN_CP_SG_FR(LOCAL_top_cp));
top_sg_fr = SgFr_next(GEN_CP(LOCAL_top_cp)->cp_sg_fr);
do {
mark_as_completed(LOCAL_top_sg_fr);
LOCAL_top_sg_fr = SgFr_next(LOCAL_top_sg_fr);
@ -293,9 +293,9 @@ void resume_suspension_frame(susp_fr_ptr resume_fr, or_fr_ptr top_or_fr) {
SuspFr_trail_size(resume_fr));
#ifdef OPTYAP_ERRORS
if (CONS_CP(DepFr_cons_cp(SuspFr_top_dep_fr(resume_fr)))->ccp_h != SuspFr_global_reg(resume_fr) + SuspFr_global_size(resume_fr))
if (DepFr_cons_cp(SuspFr_top_dep_fr(resume_fr))->cp_h != SuspFr_global_reg(resume_fr) + SuspFr_global_size(resume_fr))
OPTYAP_ERROR_MESSAGE("DepFr_cons_cp(SuspFr_top_dep_fr)->cp_h != SuspFr_global_reg + SuspFr_global_size (resume_suspension_frame)");
if (CONS_CP(DepFr_cons_cp(SuspFr_top_dep_fr(resume_fr)))->ccp_tr != SuspFr_trail_reg(resume_fr) + SuspFr_trail_size(resume_fr))
if (DepFr_cons_cp(SuspFr_top_dep_fr(resume_fr))->cp_tr != SuspFr_trail_reg(resume_fr) + SuspFr_trail_size(resume_fr))
OPTYAP_ERROR_MESSAGE("DepFr_cons_cp(SuspFr_top_dep_fr)->cp_tr != SuspFr_trail_reg + SuspFr_trail_size (resume_suspension_frame)");
if (DepFr_cons_cp(SuspFr_top_dep_fr(resume_fr)) != SuspFr_local_reg(resume_fr))
OPTYAP_ERROR_MESSAGE("DepFr_cons_cp(SuspFr_top_dep_fr) != SuspFr_local_reg (resume_suspension_frame)");
@ -358,14 +358,14 @@ void complete_suspension_branch(susp_fr_ptr susp_fr, choiceptr top_cp, or_fr_ptr
aux_sg_fr = SuspFr_top_sg_fr(susp_fr);
if (DepFr_leader_dep_is_on_stack(aux_dep_fr)) {
while (aux_sg_fr &&
! SgFr_state(aux_sg_fr) &&
SgFr_state(aux_sg_fr) == evaluating &&
EQUAL_OR_YOUNGER_CP(SgFr_gen_cp(aux_sg_fr), top_cp)) {
mark_as_completed(aux_sg_fr);
aux_sg_fr = SgFr_next(aux_sg_fr);
}
} else {
while (aux_sg_fr &&
! SgFr_state(aux_sg_fr) &&
SgFr_state(aux_sg_fr) == evaluating &&
YOUNGER_CP(SgFr_gen_cp(aux_sg_fr), top_cp)) {
mark_as_completed(aux_sg_fr);
aux_sg_fr = SgFr_next(aux_sg_fr);

View File

@ -20,7 +20,6 @@
static int traverse_subgoal_trie(FILE *stream, sg_node_ptr sg_node, char *str, int str_index, int *arity, int depth);
static int traverse_answer_trie(FILE *stream, ans_node_ptr ans_node, char *str, int str_index, int *arity, int var_index, int depth);
static void free_answer_trie_branch(ans_node_ptr node);
#ifdef YAPOR
#ifdef TABLING_INNER_CUTS
static int update_answer_trie_branch(ans_node_ptr previous_node, ans_node_ptr node);
@ -652,10 +651,11 @@ ans_node_ptr answer_trie_node_check_insert(sg_fr_ptr sg_fr, ans_node_ptr parent_
** Global functions **
** -------------------------- */
sg_node_ptr subgoal_search(tab_ent_ptr tab_ent, OPREG arity, CELL **Yaddr) {
sg_fr_ptr subgoal_search(tab_ent_ptr tab_ent, OPREG arity, CELL **Yaddr) {
int i, j, count_vars;
CELL *stack_vars, *stack_terms_top, *stack_terms_base, *stack_terms;
sg_node_ptr current_sg_node;
sg_fr_ptr sg_fr;
count_vars = 0;
stack_vars = *Yaddr;
@ -717,7 +717,25 @@ sg_node_ptr subgoal_search(tab_ent_ptr tab_ent, OPREG arity, CELL **Yaddr) {
RESET_VARIABLE(t);
}
return current_sg_node;
#if defined(TABLE_LOCK_AT_NODE_LEVEL)
LOCK(TrNode_lock(current_sg_node));
#elif defined(TABLE_LOCK_AT_WRITE_LEVEL)
LOCK_TABLE(current_sg_node);
#endif /* TABLE_LOCK_LEVEL */
if (TrNode_sg_fr(current_sg_node) == NULL) {
/* new tabled subgoal */
new_subgoal_frame(sg_fr, arity);
TrNode_sg_fr(current_sg_node) = (sg_node_ptr) sg_fr;
} else {
sg_fr = (sg_fr_ptr) TrNode_sg_fr(current_sg_node);
}
#if defined(TABLE_LOCK_AT_NODE_LEVEL)
UNLOCK(TrNode_lock(current_sg_node));
#elif defined(TABLE_LOCK_AT_WRITE_LEVEL)
UNLOCK_TABLE(current_sg_node);
#endif /* TABLE_LOCK_LEVEL */
return sg_fr;
}
@ -936,11 +954,7 @@ void private_completion(sg_fr_ptr sg_fr) {
LOCAL_top_sg_fr = SgFr_next(LOCAL_top_sg_fr);
/* release dependency frames */
#ifdef TABLING_BATCHED_SCHEDULING
while (YOUNGER_CP(DepFr_cons_cp(LOCAL_top_dep_fr), B)) {
#else /* TABLING_LOCAL_SCHEDULING */
while (EQUAL_OR_YOUNGER_CP(DepFr_cons_cp(LOCAL_top_dep_fr), B)) {
#endif /* TABLING_SCHEDULING */
while (EQUAL_OR_YOUNGER_CP(DepFr_cons_cp(LOCAL_top_dep_fr), B)) { /* never equal if batched scheduling */
dep_fr_ptr dep_fr = DepFr_next(LOCAL_top_dep_fr);
FREE_DEPENDENCY_FRAME(LOCAL_top_dep_fr);
LOCAL_top_dep_fr = dep_fr;
@ -981,12 +995,14 @@ void free_subgoal_trie_branch(sg_node_ptr node, int missing_nodes) {
free_subgoal_trie_branch(TrNode_child(node), missing_nodes);
} else {
sg_fr_ptr sg_fr;
ans_node_ptr ans_node;
sg_fr = (sg_fr_ptr) TrNode_sg_fr(node);
if (sg_fr) {
free_answer_hash_chain(SgFr_hash_chain(sg_fr));
free_answer_trie(sg_fr);
FREE_SUBGOAL_FRAME(sg_fr);
}
free_answer_hash_chain(SgFr_hash_chain(sg_fr));
ans_node = SgFr_answer_trie(sg_fr);
if (TrNode_child(ans_node))
free_answer_trie_branch(TrNode_child(ans_node));
FREE_ANSWER_TRIE_NODE(ans_node);
FREE_SUBGOAL_FRAME(sg_fr);
}
FREE_SUBGOAL_TRIE_NODE(node);
@ -994,11 +1010,15 @@ void free_subgoal_trie_branch(sg_node_ptr node, int missing_nodes) {
}
void free_answer_trie(sg_fr_ptr sg_fr) {
ans_node_ptr node;
node = SgFr_answer_trie(sg_fr);
if (TrNode_child(node))
void free_answer_trie_branch(ans_node_ptr node) {
#ifdef TABLING_INNER_CUTS
if (TrNode_child(node) && ! IS_ANSWER_LEAF_NODE(node))
#else
if (! IS_ANSWER_LEAF_NODE(node))
#endif /* TABLING_INNER_CUTS */
free_answer_trie_branch(TrNode_child(node));
if (TrNode_next(node))
free_answer_trie_branch(TrNode_next(node));
FREE_ANSWER_TRIE_NODE(node);
return;
}
@ -1123,12 +1143,12 @@ int traverse_subgoal_trie(FILE *stream, sg_node_ptr sg_node, char *str, int str_
} else if (depth > TrStat_sg_max_depth) {
TrStat_sg_max_depth = depth;
}
if (sg_node == NULL) {
if (SgFr_state((sg_fr_ptr)sg_node) == ready) {
TrStat_subgoals_abolished++;
SHOW_TRIE("%s.\n ABOLISHED\n", str);
return TRUE;
}
if (! SgFr_state((sg_fr_ptr)sg_node)) {
if (SgFr_state((sg_fr_ptr)sg_node) == evaluating) {
SHOW_INFO("%s. --> TRIE ERROR: subgoal not completed !!!\n", str);
return FALSE;
}
@ -1438,21 +1458,6 @@ int traverse_answer_trie(FILE *stream, ans_node_ptr ans_node, char *str, int str
}
static
void free_answer_trie_branch(ans_node_ptr node) {
#ifdef TABLING_INNER_CUTS
if (TrNode_child(node) && ! IS_ANSWER_LEAF_NODE(node))
#else
if (! IS_ANSWER_LEAF_NODE(node))
#endif /* TABLING_INNER_CUTS */
free_answer_trie_branch(TrNode_child(node));
if (TrNode_next(node))
free_answer_trie_branch(TrNode_next(node));
FREE_ANSWER_TRIE_NODE(node);
return;
}
#ifdef YAPOR
#ifdef TABLING_INNER_CUTS
static
@ -1512,7 +1517,7 @@ int update_answer_trie_branch(ans_node_ptr node) {
ltt = 1;
}
TrNode_or_arg(node) = ltt;
TrNode_instr(node) = Yap__opcode(TrNode_instr(node));
TrNode_instr(node) = Yap_opcode(TrNode_instr(node));
return ltt;
}
#endif /* TABLING_INNER_CUTS */

View File

@ -65,6 +65,7 @@
YENV = (CELL *) (NORM_CP(YENV) - 1); \
cp = NORM_CP(YENV); \
HBREG = H; \
store_yaam_reg_cpdepth(cp); \
cp->cp_tr = TR; \
cp->cp_h = H; \
cp->cp_b = B; \
@ -79,6 +80,7 @@
#define restore_trie_choice_point(AP) \
H = HBREG = PROTECT_FROZEN_H(B); \
restore_yaam_reg_cpdepth(B); \
CPREG = B->cp_cp; \
ENV = B->cp_env; \
YAPOR_update_alternative(PREG, (yamop *) AP) \
@ -90,6 +92,7 @@
#define pop_trie_choice_point() \
YENV = (CELL *) PROTECT_FROZEN_B((B+1)); \
H = PROTECT_FROZEN_H(B); \
pop_yaam_reg_cpdepth(B); \
CPREG = B->cp_cp; \
TABLING_close_alt(B); \
ENV = B->cp_env; \

3
README
View File

@ -155,8 +155,7 @@ useful for normal users.
o --enable-parallelism={env-copy,sba,a-cow} allows or-parallelism
supported by one of these three forms. This is still highly experimental.
o --enable-tabling={local,batched} allows one of the two forms of
tabling. This is still experimental.
o --enable-tabling=yes allows tabling support. This is still experimental.
2.3 Porting Yap

14
configure vendored
View File

@ -850,7 +850,7 @@ Optional Features:
--enable-depth-limit support depth-bound computation
--enable-or-parallelism support or-parallelism as: env-copy,sba,a-cow
--enable-low-level-tracer support support for procedure-call tracing
--enable-tabling support tabling as: batched,local
--enable-tabling support tabling
--enable-threads support system threads
--pthread-locking use pthread locking primitives for internal locking (requires threads)
--enable-max-performance try using the best flags for specific architecture
@ -5890,14 +5890,10 @@ case "$orparallelism" in
;;
esac
case "$tabling" in
local)
YAP_EXTRAS="$YAP_EXTRAS -DTABLING_LOCAL_SCHEDULING=1"
;;
yes|batched)
YAP_EXTRAS="$YAP_EXTRAS -DTABLING_BATCHED_SCHEDULING=1"
;;
esac
if test "$tabling" = "yes"
then
YAP_EXTRAS="$YAP_EXTRAS -DTABLING=1"
fi
echo "$as_me:$LINENO: checking for ANSI C header files" >&5
echo $ECHO_N "checking for ANSI C header files... $ECHO_C" >&6

View File

@ -34,7 +34,7 @@ AC_ARG_ENABLE(low-level-tracer,
[ --enable-low-level-tracer support support for procedure-call tracing ],
lowleveltracer="$enableval", lowleveltracer=no)
AC_ARG_ENABLE(tabling,
[ --enable-tabling support tabling as: batched,local ],
[ --enable-tabling support tabling ],
tabling="$enableval", tabling=no)
AC_ARG_ENABLE(threads,
[ --enable-threads support system threads ],
@ -721,14 +721,10 @@ case "$orparallelism" in
;;
esac
case "$tabling" in
local)
YAP_EXTRAS="$YAP_EXTRAS -DTABLING_LOCAL_SCHEDULING=1"
;;
yes|batched)
YAP_EXTRAS="$YAP_EXTRAS -DTABLING_BATCHED_SCHEDULING=1"
;;
esac
if test "$tabling" = "yes"
then
YAP_EXTRAS="$YAP_EXTRAS -DTABLING=1"
fi
dnl Checks for header files.
AC_HEADER_STDC

View File

@ -565,8 +565,8 @@ useful for normal users.
support High Throughput Computing (HTC) on large collections of
distributively owned computing resources.
@item @code{--enable-tabling=@{local,batched@}} allows one of the two
forms of tabling. This option is still experimental.
@item @code{--enable-tabling=yes} allows tabling support. This option
is still experimental.
@item @code{--enable-parallelism=@{env-copy,sba,a-cow@}} allows
or-parallelism supported by one of these three forms. This option is

View File

@ -10,7 +10,7 @@
* File: Yap.h.m4 *
* mods: *
* comments: main header file for YAP *
* version: $Id: Yap.h.m4,v 1.81 2005-03-14 17:02:40 vsc Exp $ *
* version: $Id: Yap.h.m4,v 1.82 2005-04-07 17:56:00 ricroc Exp $ *
*************************************************************************/
#include "config.h"
@ -29,18 +29,6 @@
#define MULTI_ASSIGNMENT_VARIABLES 1
#if defined(TABLING)
#error Do not explicitly define TABLING
#endif /* TABLING */
#if defined(TABLING_BATCHED_SCHEDULING) && defined(TABLING_LOCAL_SCHEDULING)
#error Do not define multiple tabling scheduling strategies
#endif /* TABLING_BATCHED_SCHEDULING || TABLING_LOCAL_SCHEDULING */
#if defined(TABLING_BATCHED_SCHEDULING) || defined(TABLING_LOCAL_SCHEDULING)
#define TABLING 1
#endif /* TABLING_BATCHED_SCHEDULING || TABLING_LOCAL_SCHEDULING */
#if defined(YAPOR)
#error Do not explicitly define YAPOR
#endif /* YAPOR */
@ -533,7 +521,8 @@ typedef enum {
HALT_AFTER_CONSULT_FLAG = 15,
FAST_BOOT_FLAG = 16,
STACK_DUMP_ON_ERROR_FLAG = 17,
INDEXING_MODE_FLAG = 18
INDEXING_MODE_FLAG = 18,
TABLING_MODE_FLAG = 19
} yap_flags;
#define STRING_AS_CHARS 0
@ -554,6 +543,13 @@ typedef enum {
INDEX_MODE_MAX = 4
} index_mode_options;
typedef enum {
TABLING_MODE_OFF = 0,
TABLING_MODE_BATCHED = 1,
TABLING_MODE_LOCAL = 2,
TABLING_MODE_DEFAULT = 3
} tabling_mode_options;
typedef enum {
YAP_CREEP_SIGNAL = 0x1, /* received a creep */
YAP_WAKEUP_SIGNAL = 0x2, /* goals to wake up */
@ -574,7 +570,7 @@ typedef enum {
YAP_DELAY_CREEP_SIGNAL= 0x10000 /* received a creep but should not do it */
} yap_signals;
#define NUMBER_OF_YAP_FLAGS INDEXING_MODE_FLAG+1
#define NUMBER_OF_YAP_FLAGS TABLING_MODE_FLAG + 1
/************************ prototypes **********************************/

View File

@ -162,34 +162,35 @@ Inline(IsValProperty, PropFlags, int, flags, (flags == ValProperty) )
CodeOfPred holds the address of the correspondent C-function.
*/
typedef enum {
MegaClausePredFlag=0x80000000L, /* predicate is implemented as a mega-clause */
ThreadLocalPredFlag=0x40000000L, /* local to a thread */
MultiFileFlag = 0x20000000L, /* is multi-file */
UserCPredFlag = 0x10000000L, /* CPred defined by the user */
LogUpdatePredFlag= 0x08000000L, /* dynamic predicate with log. upd. sem.*/
InUsePredFlag = 0x04000000L, /* count calls to pred */
CountPredFlag = 0x02000000L, /* count calls to pred */
HiddenPredFlag = 0x01000000L, /* invisible predicate */
CArgsPredFlag = 0x00800000L, /* SWI-like C-interface pred. */
SourcePredFlag = 0x00400000L, /* static predicate with source declaration */
MetaPredFlag = 0x00200000L, /* predicate subject to a meta declaration */
SyncPredFlag = 0x00100000L, /* has to synch before it can execute*/
NumberDBPredFlag = 0x00080000L, /* entry for a number key */
AtomDBPredFlag = 0x00040000L, /* entry for an atom key */
GoalExPredFlag = 0x00020000L, /* predicate that is called by goal_expand */
TestPredFlag = 0x00010000L, /* is a test (optim. comit) */
AsmPredFlag = 0x00008000L, /* inline */
StandardPredFlag= 0x00004000L, /* system predicate */
DynamicPredFlag= 0x00002000L, /* dynamic predicate */
CPredFlag = 0x00001000L, /* written in C */
SafePredFlag = 0x00000800L, /* does not alter arguments */
CompiledPredFlag= 0x00000400L, /* is static */
IndexedPredFlag= 0x00000200L, /* has indexing code */
SpiedPredFlag = 0x00000100L, /* is a spy point */
BinaryTestPredFlag=0x00000080L, /* test predicate. */
TabledPredFlag = 0x00000040L, /* is tabled */
SequentialPredFlag=0x00000020L, /* may not create par. choice points!*/
ProfiledPredFlag = 0x00000010L /* pred is being profiled */
MegaClausePredFlag = 0x80000000L, /* predicate is implemented as a mega-clause */
ThreadLocalPredFlag = 0x40000000L, /* local to a thread */
MultiFileFlag = 0x20000000L, /* is multi-file */
UserCPredFlag = 0x10000000L, /* CPred defined by the user */
LogUpdatePredFlag= 0x08000000L, /* dynamic predicate with log. upd. sem. */
InUsePredFlag = 0x04000000L, /* count calls to pred */
CountPredFlag = 0x02000000L, /* count calls to pred */
HiddenPredFlag = 0x01000000L, /* invisible predicate */
CArgsPredFlag = 0x00800000L, /* SWI-like C-interface pred. */
SourcePredFlag = 0x00400000L, /* static predicate with source declaration */
MetaPredFlag = 0x00200000L, /* predicate subject to a meta declaration */
SyncPredFlag = 0x00100000L, /* has to synch before it can execute*/
NumberDBPredFlag = 0x00080000L, /* entry for a number key */
AtomDBPredFlag = 0x00040000L, /* entry for an atom key */
GoalExPredFlag = 0x00020000L, /* predicate that is called by goal_expand */
TestPredFlag = 0x00010000L, /* is a test (optim. comit) */
AsmPredFlag = 0x00008000L, /* inline */
StandardPredFlag = 0x00004000L, /* system predicate */
DynamicPredFlag = 0x00002000L, /* dynamic predicate */
CPredFlag = 0x00001000L, /* written in C */
SafePredFlag = 0x00000800L, /* does not alter arguments */
CompiledPredFlag = 0x00000400L, /* is static */
IndexedPredFlag = 0x00000200L, /* has indexing code */
SpiedPredFlag = 0x00000100L, /* is a spy point */
BinaryTestPredFlag = 0x00000080L, /* test predicate */
TabledPredFlag = 0x00000040L, /* is tabled */
SequentialPredFlag = 0x00000020L, /* may not create parallel choice points! */
ProfiledPredFlag = 0x00000010L, /* pred is being profiled */
LocalSchedPredFlag = 0x00000008L /* use local scheduling as default for tabling */
} pred_flag;
/* profile data */

View File

@ -228,6 +228,25 @@ yap_flag(home,X) :-
'$transl_to_index_mode'(3, on). % default is multi argument indexing
'$transl_to_index_mode'(4, max).
% tabling schedulinhg mode
yap_flag(tabling_mode,X) :- var(X),
'$access_yap_flags'(19, X1),
'$transl_to_tabling_mode'(X1,X), !.
yap_flag(tabling_mode,X) :-
'$access_yap_flags'(19, X1),
'$transl_to_tabling_mode'(X1,off), !,
'$do_error'(permission_error(modify,flag,tabling_mode),yap_flag(tabling_mode,X)).
yap_flag(tabling_mode,X) :- X \= off,
'$transl_to_tabling_mode'(X1,X), !,
'$set_yap_flags'(19,X1).
yap_flag(tabling_mode,X) :-
'$do_error'(domain_error(flag_value,tabling_mode+X),yap_flag(tabling_mode,X)).
% should match definitions in Yap.h.m4
'$transl_to_tabling_mode'(0,off).
'$transl_to_tabling_mode'(1,batched).
'$transl_to_tabling_mode'(2,local).
'$transl_to_tabling_mode'(3,default).
yap_flag(informational_messages,X) :- var(X), !,
get_value('$verbose',X).
@ -591,6 +610,7 @@ yap_flag(host_type,X) :-
V = home ;
V = host_type ;
V = index ;
V = tabling ;
V = informational_messages ;
V = integer_rounding_function ;
V = language ;

View File

@ -11,8 +11,12 @@
* File: errors.yap *
* comments: error messages for YAP *
* *
* Last rev: $Date: 2005-02-21 16:50:21 $,$Author: vsc $ *
* Last rev: $Date: 2005-04-07 17:55:05 $,$Author: ricroc $ *
* $Log: not supported by cvs2svn $
* Revision 1.61 2005/02/21 16:50:21 vsc
* amd64 fixes
* library fixes
*
* Revision 1.60 2005/01/28 23:14:41 vsc
* move to Yap-4.5.7
* Fix clause size
@ -481,6 +485,9 @@ print_message(Level, Mss) :-
'$output_error_message'(domain_error(write_option,N), Where) :-
format(user_error,'% DOMAIN ERROR- ~w: ~w invalid option to write~n',
[Where,N]).
'$output_error_message'(domain_error(table,P), Where) :-
format(user_error,'% DOMAIN ERROR- ~w: non-tabled procedure ~w~n',
[Where,P]).
'$output_error_message'(existence_error(array,F), W) :-
format(user_error,'% EXISTENCE ERROR- ~w could not open array ~w~n',
[W,F]).
@ -592,6 +599,9 @@ print_message(Level, Mss) :-
'$output_error_message'(permission_error(modify,static_procedure_in_use,_), Where) :-
format(user_error,'% PERMISSION ERROR- ~w: modifying a static procedure in use~n',
[Where]).
'$output_error_message'(permission_error(modify,table,P), _) :-
format(user_error,'% PERMISSION ERROR- cannot table procedure ~w~n',
[P]).
'$output_error_message'(permission_error(module,redefined,Mod), Who) :-
format(user_error,'% PERMISSION ERROR ~w- redefining module ~a in a different file~n',
[Who,Mod]).

View File

@ -17,69 +17,82 @@
:- meta_predicate table(:), abolish_trie(:), show_trie(:), show_trie_stats(:).
table(M:P) :- !, '$table'(P,M).
table(P) :- '$current_module'(M), '$table'(P,M).
'$table'(P,M) :- var(P), !, '$do_error'(instantiation_error,table).
table(P) :- '$current_module'(M), '$table'(P,M).
'$table'(P,M) :- var(P), !, '$do_error'(instantiation_error,table(M:P)).
'$table'(M:P,_) :- !, '$table'(P,M).
'$table'([],_) :- !.
'$table'([H|T],M) :- !, '$table'(H,M), '$table'(T,M).
'$table'((P1,P2),M) :- !, '$table'(P1,M), '$table'(P2,M).
'$table'(P/N,M) :- integer(N), atom(P), !,
functor(T,P,N), '$declare_tabled'(T,M).
'$table'(P,M) :- '$do_error'(type_error(callable,P),table).
'$table'(A/N,M) :- integer(N), atom(A), !, functor(T,A,N), '$declare_tabled'(T,M).
'$table'(P,M) :- '$do_error'(type_error(callable,P),table(M:P)).
'$declare_tabled'(T,M) :- '$undefined'(T,M), !, '$do_table'(T,M).
'$declare_tabled'(T,M) :- '$flags'(T,M,F,F),
X is F /\ 0x1991F880, X =:= 0, !, '$do_table'(T,M).
'$declare_tabled'(T,M) :- functor(T,A,N),
'$do_error'(permission_error(modify,static_procedure,A/N),tabled(M:A/N)).
'$declare_tabled'(T,M) :- '$flags'(T,M,F,F), F /\ 0x1991F880 =:= 0, !, '$do_table'(T,M).
'$declare_tabled'(T,M) :- functor(T,A,N), '$do_error'(permission_error(modify,table,M:A/N),table(M:A/N)).
tabling_mode(P,S) :- '$current_module'(M), '$tabling_mode'(P,M,S).
'$tabling_mode'(P,M,S) :- var(P), !, '$do_error'(instantiation_error,tabling_mode(M:P,S)).
'$tabling_mode'(M:P,_,S) :- !, '$tabling_mode'(P,M,S).
'$tabling_mode'([],_,_) :- !.
'$tabling_mode'([H|T],M,S) :- !, '$tabling_mode'(H,M,S), '$tabling_mode'(T,M,S).
'$tabling_mode'((P1,P2),M,S) :- !, '$tabling_mode'(P1,M,S), '$tabling_mode'(P2,M,S).
'$tabling_mode'(A/N,M,S) :- integer(N), atom(A), !, functor(T,A,N), '$flags'(T,M,F,F),
(F /\ 0x000040 =\= 0, !, '$set_tabling_mode'(T,M,S)
;
'$do_error'(domain_error(table,M:A/N),tabling_mode(M:A/N,S))).
'$tabling_mode'(P,M,S) :- '$do_error'(type_error(callable,P),tabling_mode(M:P,S)).
'$set_tabling_mode'(T,M,S) :- var(S), !, '$do_tabling_mode'(T,M,S).
'$set_tabling_mode'(T,M,S) :- (S = local ; S = batched), !, '$do_tabling_mode'(T,M,S).
'$set_tabling_mode'(T,M,S) :- functor(T,A,N), '$do_error'(domain_error(flag_value,tabling_mode+S),tabling_mode(M:A/N,S)).
abolish_trie(M:P) :- !, '$abolish_trie'(P,M).
abolish_trie(P) :- '$current_module'(M), '$abolish_trie'(P,M).
'$abolish_trie'(P,M) :- var(P), !, '$do_error'(instantiation_error,abolish_trie).
'$abolish_trie'(P,M) :- var(P), !, '$do_error'(instantiation_error,abolish_trie(M:P)).
'$abolish_trie'(M:P,_) :- !, '$abolish_trie'(P,M).
'$abolish_trie'([],_) :- !.
'$abolish_trie'([H|T],M) :- !, '$abolish_trie'(H,M), '$abolish_trie'(T,M).
'$abolish_trie'((P1,P2),M) :- !, '$abolish_trie'(P1,M), '$abolish_trie'(P2,M).
'$abolish_trie'(P/N,M) :- integer(N), atom(P), !,
functor(T,P,N), '$flags'(T,M,F,F),
(
X is F /\ 0x000040, X =\= 0, !, '$do_abolish_trie'(T,M)
;
write(user_error, '[ PERMISSION ERROR- '),
write(user_error, M:P/N),
write(user_error, ' is not tabled ]'),
nl(user_error), fail
).
'$abolish_trie'(P,_) :- '$do_error'(type_error(callable,P),abolish_trie).
'$abolish_trie'(A/N,M) :- integer(N), atom(A), !, functor(T,A,N), '$flags'(T,M,F,F),
(F /\ 0x000040 =\= 0, !, '$do_abolish_trie'(T,M)
;
'$do_error'(domain_error(table,M:A/N),abolish_trie(M:A/N))).
'$abolish_trie'(P,M) :- '$do_error'(type_error(callable,P),abolish_trie(M:P)).
show_trie(M:P) :- !, '$show_trie'(P,M).
show_trie(P) :- '$current_module'(M), '$show_trie'(P,M).
'$show_trie'(P,M) :- var(P), !, '$do_error'(instantiation_error,show_trie).
'$show_trie'(P,M) :- var(P), !, '$do_error'(instantiation_error,show_trie(M:P)).
'$show_trie'(M:P,_) :- !, '$show_trie'(P,M).
'$show_trie'([],_) :- !.
'$show_trie'([H|T],M) :- !, '$show_trie'(H,M), '$show_trie'(T,M).
'$show_trie'((P1,P2),M) :- !, '$show_trie'(P1,M), '$show_trie'(P2,M).
'$show_trie'(P/N, M) :- integer(N), atom(P), !,
functor(T,P,N), '$flags'(T,M,F,F),
(
X is F /\ 0x000040, X =\= 0, !, '$do_show_trie'(T,M)
;
write(user_error, '[ PERMISSION ERROR- '),
write(user_error, M:P/N),
write(user_error, ' is not tabled ]'),
nl(user_error), fail
).
'$show_trie'(P,_) :- '$do_error'(type_error(callable,P),show_trie).
'$show_trie'(A/N,M) :- integer(N), atom(A), !, functor(T,A,N), '$flags'(T,M,F,F),
(F /\ 0x000040 =\= 0, !, '$do_show_trie'(T,M)
;
'$do_error'(domain_error(table,M:A/N),show_trie(M:A/N))).
'$show_trie'(P,M) :- '$do_error'(type_error(callable,P),show_trie(M:P)).
show_trie_stats(M:P) :- !,'$show_trie_stats'(P,M).
show_trie_stats(P) :- '$current_module'(M), '$show_trie_stats'(P,M).
'$show_trie_stats'(P,M) :- var(P), !, '$do_error'(instantiation_error,show_trie_stats).
show_trie_stats(P) :- '$current_module'(M), '$show_trie_stats'(P,M).
'$show_trie_stats'(P,M) :- var(P), !, '$do_error'(instantiation_error,show_trie_stats(M:P)).
'$show_trie_stats'(M:P,_) :- !, '$show_trie_stats'(P,M).
'$show_trie_stats'([],_) :- !.
'$show_trie_stats'([H|T],M) :- !, '$show_trie_stats'(H,M), '$show_trie_stats'(T,M).
'$show_trie_stats'((P1,P2),M) :- !, '$show_trie_stats'(P1,M), '$show_trie_stats'(P2,M).
'$show_trie_stats'(P/N,M) :- atom(P), integer(N), !,
functor(T,P,N), '$flags'(T,M,F,F),
(
X is F /\ 0x000040, X =\= 0, !, '$do_show_trie_stats'(T,M)
;
write(user_error, '[ PERMISSION ERROR- '),
write(user_error, M:P/N),
write(user_error, ' is not tabled ]'),
nl(user_error), fail
).
'$show_trie_stats'(P,_) :- '$do_error'(type_error(callable,P),show_trie_stats).
'$show_trie_stats'(A/N,M) :- atom(A), integer(N), !, functor(T,A,N), '$flags'(T,M,F,F),
(F /\ 0x000040 =\= 0, !, '$do_show_trie_stats'(T,M)
;
'$do_error'(domain_error(table,M:A/N),show_trie_stats(M:A/N))).
'$show_trie_stats'(P,M) :- '$do_error'(type_error(callable,P),show_trie_stats(M:P)).