TABLING NEW: better support for incomplete tabling

git-svn-id: https://yap.svn.sf.net/svnroot/yap/trunk@1351 b08c6af1-5177-4d33-ba66-4b1c6b8b522a
This commit is contained in:
ricroc 2005-08-01 15:40:39 +00:00
parent edafbcc7c3
commit b36b836820
17 changed files with 394 additions and 224 deletions

View File

@ -10,8 +10,11 @@
* *
* File: absmi.c *
* comments: Portable abstract machine interpreter *
* Last rev: $Date: 2005-07-06 19:33:51 $,$Author: ricroc $ *
* Last rev: $Date: 2005-08-01 15:40:36 $,$Author: ricroc $ *
* $Log: not supported by cvs2svn $
* Revision 1.170 2005/07/06 19:33:51 ricroc
* TABLING: answers for completed calls can now be obtained by loading (new option) or executing (default) them from the trie data structure.
*
* Revision 1.169 2005/07/06 15:10:01 vsc
* improvements to compiler: merged instructions and fixes for ->
*
@ -1408,20 +1411,19 @@ Yap_absmi(int inp)
go_on = FALSE;
switch (opnum) {
#ifdef TABLING
case _table_load_answer:
low_level_trace(retry_table_loader, LOAD_CP(B)->cp_pred_entry, NULL);
break;
case _table_try_answer:
case _table_retry_me:
case _table_trust_me:
case _table_retry:
case _table_trust:
low_level_trace(retry_table_generator, TabEnt_pe(GEN_CP(B)->cp_tab_ent), (CELL *)(GEN_CP(B)+ 1));
break;
case _table_completion:
low_level_trace(retry_table_generator, TabEnt_pe(GEN_CP(B)->cp_tab_ent), (CELL *)(GEN_CP(B)+1));
low_level_trace(retry_table_generator, GEN_CP(B)->cp_pred_entry, (CELL *)(GEN_CP(B) + 1));
break;
case _table_answer_resolution:
low_level_trace(retry_table_consumer, TabEnt_pe(CONS_CP(B)->cp_tab_ent), NULL);
break;
case _table_load_answer:
low_level_trace(retry_table_loader, TabEnt_pe(LOAD_CP(B)->cp_tab_ent), NULL);
low_level_trace(retry_table_consumer, CONS_CP(B)->cp_pred_entry, NULL);
break;
case _trie_retry_null:
case _trie_trust_null:

View File

@ -11,8 +11,11 @@
* File: cdmgr.c *
* comments: Code manager *
* *
* Last rev: $Date: 2005-07-06 19:33:52 $,$Author: ricroc $ *
* Last rev: $Date: 2005-08-01 15:40:37 $,$Author: ricroc $ *
* $Log: not supported by cvs2svn $
* Revision 1.165 2005/07/06 19:33:52 ricroc
* TABLING: answers for completed calls can now be obtained by loading (new option) or executing (default) them from the trie data structure.
*
* Revision 1.164 2005/07/06 15:10:03 vsc
* improvements to compiler: merged instructions and fixes for ->
*
@ -311,12 +314,13 @@ PredForChoicePt(yamop *p_code) {
case _trie_retry_long:
case _trie_trust_long:
return NULL;
case _table_load_answer:
case _table_try_answer:
case _table_answer_resolution:
case _table_completion:
case _table_load_answer:
return NULL; /* ricroc: is this OK? */
/* compile error --> return ENV_ToP(gc_B->cp_cp); */
#endif
#endif /* TABLING */
case _or_else:
if (p_code == p_code->u.sla.sla_u.l) {
/* repeat */
@ -331,7 +335,7 @@ PredForChoicePt(yamop *p_code) {
return p_code->u.sla.p0;
#else
return p_code->u.p.p;
#endif
#endif /* YAPOR */
break;
case _trust_logical_pred:
case _count_retry_me:
@ -444,7 +448,7 @@ Yap_BuildMegaClause(PredEntry *ap)
if (ap->PredFlags & (DynamicPredFlag|LogUpdatePredFlag|MegaClausePredFlag
#ifdef TABLING
|TabledPredFlag
#endif
#endif /* TABLING */
) ||
ap->cs.p_code.FirstClause == NULL ||
ap->cs.p_code.NOfClauses < 16) {
@ -663,7 +667,7 @@ RemoveMainIndex(PredEntry *ap)
} else if (ap->cs.p_code.NOfClauses > 1
#ifdef TABLING
||ap->PredFlags & TabledPredFlag
#endif
#endif /* TABLING */
) {
ap->OpcodeOfPred = INDEX_OPCODE;
ap->CodeOfPred = ap->cs.p_code.TrueCodeOfPred = (yamop *)(&(ap->OpcodeOfPred));

View File

@ -1828,6 +1828,19 @@ mark_choicepoints(register choiceptr gc_B, tr_fr_ptr saved_TR, int very_verbose)
nargs = 0;
break;
#ifdef TABLING
case _table_load_answer:
{
CELL *vars_ptr, vars;
vars_ptr = (CELL *) (LOAD_CP(gc_B) + 1);
vars = *vars_ptr++;
while (vars--) {
mark_external_reference(vars_ptr);
vars_ptr++;
}
}
nargs = 0;
break;
case _table_try_answer:
case _table_retry_me:
case _table_trust_me:
case _table_retry:
@ -1877,18 +1890,6 @@ mark_choicepoints(register choiceptr gc_B, tr_fr_ptr saved_TR, int very_verbose)
}
nargs = 0;
break;
case _table_load_answer:
{
CELL *vars_ptr, vars;
vars_ptr = (CELL *) (LOAD_CP(gc_B) + 1);
vars = *vars_ptr++;
while (vars--) {
mark_external_reference(vars_ptr);
vars_ptr++;
}
}
nargs = 0;
break;
case _trie_retry_null:
case _trie_trust_null:
case _trie_retry_var:
@ -2548,6 +2549,25 @@ sweep_choicepoints(choiceptr gc_B)
opnum = Yap_op_from_opcode(op);
goto restart_cp;
#ifdef TABLING
case _table_load_answer:
{
CELL *vars_ptr, vars;
sweep_environments(gc_B->cp_env, EnvSize((CELL_PTR) (gc_B->cp_cp)), EnvBMap((CELL_PTR) (gc_B->cp_cp)));
vars_ptr = (CELL *) (LOAD_CP(gc_B) + 1);
vars = *vars_ptr++;
while (vars--) {
CELL cp_cell = *vars_ptr;
if (MARKED_PTR(vars_ptr)) {
UNMARK(vars_ptr);
if (HEAP_PTR(cp_cell)) {
into_relocation_chain(vars_ptr, GET_NEXT(cp_cell));
}
}
vars_ptr++;
}
}
break;
case _table_try_answer:
case _table_retry_me:
case _table_trust_me:
case _table_retry:
@ -2629,24 +2649,6 @@ sweep_choicepoints(choiceptr gc_B)
}
}
break;
case _table_load_answer:
{
CELL *vars_ptr, vars;
sweep_environments(gc_B->cp_env, EnvSize((CELL_PTR) (gc_B->cp_cp)), EnvBMap((CELL_PTR) (gc_B->cp_cp)));
vars_ptr = (CELL *) (LOAD_CP(gc_B) + 1);
vars = *vars_ptr++;
while (vars--) {
CELL cp_cell = *vars_ptr;
if (MARKED_PTR(vars_ptr)) {
UNMARK(vars_ptr);
if (HEAP_PTR(cp_cell)) {
into_relocation_chain(vars_ptr, GET_NEXT(cp_cell));
}
}
vars_ptr++;
}
}
break;
case _trie_retry_null:
case _trie_trust_null:
case _trie_retry_var:

View File

@ -11,8 +11,11 @@
* File: index.c *
* comments: Indexing a Prolog predicate *
* *
* Last rev: $Date: 2005-07-19 16:54:20 $,$Author: rslopes $ *
* Last rev: $Date: 2005-08-01 15:40:37 $,$Author: ricroc $ *
* $Log: not supported by cvs2svn $
* Revision 1.141 2005/07/19 16:54:20 rslopes
* fix for older compilers...
*
* Revision 1.140 2005/07/18 17:41:16 vsc
* Yap should respect single argument indexing.
*
@ -709,13 +712,14 @@ has_cut(yamop *pc)
case _sync:
#endif /* YAPOR */
#ifdef TABLING
case _table_load_answer:
case _table_try_answer:
case _table_try_me_single:
case _table_try_me:
case _table_retry_me:
case _table_trust_me:
case _table_answer_resolution:
case _table_completion:
case _table_load_answer:
#endif /* TABLING */
pc = NEXTOP(pc,ld);
break;
@ -2129,6 +2133,8 @@ add_info(ClauseDef *clause, UInt regno)
case _table_try_single:
cl = NEXTOP(cl,ld);
break;
case _table_load_answer:
case _table_try_answer:
case _table_try_me:
case _table_retry_me:
case _table_trust_me:
@ -2137,7 +2143,6 @@ add_info(ClauseDef *clause, UInt regno)
case _table_trust:
case _table_answer_resolution:
case _table_completion:
case _table_load_answer:
#endif /* TABLING */
case _enter_profiling:
case _count_call:

View File

@ -783,13 +783,15 @@ InitCodes(void)
Yap_heap_regs->getwork_first_time_code.opc = Yap_opcode(_getwork_first_time);
#endif /* YAPOR */
#ifdef TABLING
Yap_heap_regs->table_load_answer_code.opc = Yap_opcode(_table_load_answer);
Yap_heap_regs->table_try_answer_code.opc = Yap_opcode(_table_try_answer);
Yap_heap_regs->table_completion_code.opc = Yap_opcode(_table_completion);
Yap_heap_regs->table_answer_resolution_code.opc = Yap_opcode(_table_answer_resolution);
Yap_heap_regs->table_load_answer_code.opc = Yap_opcode(_table_load_answer);
#ifdef YAPOR
INIT_YAMOP_LTT(&(Yap_heap_regs->table_load_answer_code), 0);
INIT_YAMOP_LTT(&(Yap_heap_regs->table_try_answer_code), 0);
INIT_YAMOP_LTT(&(Yap_heap_regs->table_completion_code), 0);
INIT_YAMOP_LTT(&(Yap_heap_regs->table_answer_resolution_code), 0);
INIT_YAMOP_LTT(&(Yap_heap_regs->table_load_answer_code), 0);
#endif /* YAPOR */
#endif /* TABLING */
Yap_heap_regs->expand_op_code = Yap_opcode(_expand_index);

View File

@ -10,7 +10,7 @@
* File: Heap.h *
* mods: *
* comments: Heap Init Structure *
* version: $Id: Heap.h,v 1.81 2005-07-06 19:34:11 ricroc Exp $ *
* version: $Id: Heap.h,v 1.82 2005-08-01 15:40:38 ricroc Exp $ *
*************************************************************************/
/* information that can be stored in Code Space */
@ -141,9 +141,10 @@ typedef struct various_codes {
yamop getwork_first_time_code;
#endif /* YAPOR */
#ifdef TABLING
yamop table_load_answer_code;
yamop table_try_answer_code;
yamop table_answer_resolution_code;
yamop table_completion_code;
yamop table_load_answer_code;
#endif /* TABLING */
OPCODE expand_op_code;
yamop *expand_clauses_first, *expand_clauses_last;
@ -469,9 +470,10 @@ struct various_codes *Yap_heap_regs;
#define GETWORK_FIRST_TIME (&(Yap_heap_regs->getwork_first_time_code))
#endif /* YAPOR */
#ifdef TABLING
#define LOAD_ANSWER ((yamop *)&(Yap_heap_regs->table_load_answer_code))
#define TRY_ANSWER ((yamop *)&(Yap_heap_regs->table_try_answer_code))
#define ANSWER_RESOLUTION ((yamop *)&(Yap_heap_regs->table_answer_resolution_code))
#define COMPLETION ((yamop *)&(Yap_heap_regs->table_completion_code))
#define LOAD_ANSWER ((yamop *)&(Yap_heap_regs->table_load_answer_code))
#endif /* TABLING */
#define EXPAND_OP_CODE Yap_heap_regs->expand_op_code
#define ExpandClausesFirst Yap_heap_regs->expand_clauses_first

View File

@ -11,8 +11,11 @@
* File: YapOpcodes.h *
* comments: Central Table with all YAP opcodes *
* *
* Last rev: $Date: 2005-07-06 19:34:11 $ *
* Last rev: $Date: 2005-08-01 15:40:38 $ *
* $Log: not supported by cvs2svn $
* Revision 1.32 2005/07/06 19:34:11 ricroc
* TABLING: answers for completed calls can now be obtained by loading (new option) or executing (default) them from the trie data structure.
*
* Revision 1.31 2005/07/06 15:10:15 vsc
* improvements to compiler: merged instructions and fixes for ->
*
@ -76,6 +79,8 @@
OPCODE(clause_with_cut ,e),
#endif /* TABLING_INNER_CUTS */
#ifdef TABLING
OPCODE(table_load_answer ,ld),
OPCODE(table_try_answer ,ld),
OPCODE(table_try_single ,ld),
OPCODE(table_try_me ,ld),
OPCODE(table_try ,ld),
@ -86,7 +91,6 @@
OPCODE(table_new_answer ,s),
OPCODE(table_answer_resolution ,ld),
OPCODE(table_completion ,ld),
OPCODE(table_load_answer ,ld),
OPCODE(trie_do_null ,e),
OPCODE(trie_trust_null ,e),

View File

@ -12,8 +12,11 @@
* File: rclause.h *
* comments: walk through a clause *
* *
* Last rev: $Date: 2005-07-06 19:34:11 $,$Author: ricroc $ *
* Last rev: $Date: 2005-08-01 15:40:38 $,$Author: ricroc $ *
* $Log: not supported by cvs2svn $
* Revision 1.9 2005/07/06 19:34:11 ricroc
* TABLING: answers for completed calls can now be obtained by loading (new option) or executing (default) them from the trie data structure.
*
* Revision 1.8 2005/07/06 15:10:15 vsc
* improvements to compiler: merged instructions and fixes for ->
*
@ -124,6 +127,8 @@ restore_opcodes(yamop *pc)
case _sync:
#endif
#ifdef TABLING
case _table_load_answer:
case _table_try_answer:
case _table_try_single:
case _table_try_me:
case _table_retry_me:
@ -133,7 +138,6 @@ restore_opcodes(yamop *pc)
case _table_trust:
case _table_answer_resolution:
case _table_completion:
case _table_load_answer:
#endif /* TABLING */
pc->u.ld.p = PtoPredAdjust(pc->u.ld.p);
pc->u.ld.d = PtoOpAdjust(pc->u.ld.d);

View File

@ -11,8 +11,11 @@
* File: rheap.h *
* comments: walk through heap code *
* *
* Last rev: $Date: 2005-07-06 19:34:11 $,$Author: ricroc $ *
* Last rev: $Date: 2005-08-01 15:40:38 $,$Author: ricroc $ *
* $Log: not supported by cvs2svn $
* Revision 1.52 2005/07/06 19:34:11 ricroc
* TABLING: answers for completed calls can now be obtained by loading (new option) or executing (default) them from the trie data structure.
*
* Revision 1.51 2005/07/06 15:10:15 vsc
* improvements to compiler: merged instructions and fixes for ->
*
@ -114,13 +117,15 @@ restore_codes(void)
Yap_heap_regs->getwork_first_time_code.opc = Yap_opcode(_getwork_first_time);
#endif /* YAPOR */
#ifdef TABLING
Yap_heap_regs->table_load_answer_code.opc = Yap_opcode(_table_load_answer);
Yap_heap_regs->table_try_answer_code.opc = Yap_opcode(_table_try_answer);
Yap_heap_regs->table_answer_resolution_code.opc = Yap_opcode(_table_answer_resolution);
Yap_heap_regs->table_completion_code.opc = Yap_opcode(_table_completion);
Yap_heap_regs->table_load_answer_code.opc = Yap_opcode(_table_load_answer);
#ifdef YAPOR
INIT_YAMOP_LTT(&(Yap_heap_regs->table_load_answer_code), 0);
INIT_YAMOP_LTT(&(Yap_heap_regs->table_try_answer_code), 0);
INIT_YAMOP_LTT(&(Yap_heap_regs->table_completion_code), 0);
INIT_YAMOP_LTT(&(Yap_heap_regs->table_answer_resolution_code), 0);
INIT_YAMOP_LTT(&(Yap_heap_regs->table_load_answer_code), 0);
#endif /* YAPOR */
#endif /* TABLING */
Yap_heap_regs->expand_op_code = Yap_opcode(_expand_index);

View File

@ -5,7 +5,7 @@
Copyright: R. Rocha and NCC - University of Porto, Portugal
File: opt.config.h
version: $Id: opt.config.h,v 1.7 2005-07-11 19:17:24 ricroc Exp $
version: $Id: opt.config.h,v 1.8 2005-08-01 15:40:38 ricroc Exp $
**********************************************************************/
@ -63,6 +63,11 @@
/* #define TABLE_LOCK_AT_NODE_LEVEL 1 */
/* #define ALLOC_BEFORE_CHECK 1 */
/* ----------------------------------------------- **
** support incomplete tabling? (optional) **
** ----------------------------------------------- */
/* #define INCOMPLETE_TABLING 1 */
/* --------------------------------------- **
** support inner cuts? (optional) **
** --------------------------------------- */
@ -155,9 +160,12 @@
#ifndef YAPOR
#undef YAPOR_ERRORS
#endif /* !YAPOR */
#ifndef TABLING
#undef INCOMPLETE_TABLING
#undef TABLING_ERRORS
#endif /* !TABLING */
#if defined(YAPOR_ERRORS) && defined(TABLING_ERRORS)
#define OPTYAP_ERRORS
#endif /* YAPOR_ERRORS && TABLING_ERRORS */

View File

@ -5,7 +5,7 @@
Copyright: R. Rocha and NCC - University of Porto, Portugal
File: opt.macros.h
version: $Id: opt.macros.h,v 1.7 2005-07-11 19:17:27 ricroc Exp $
version: $Id: opt.macros.h,v 1.8 2005-08-01 15:40:38 ricroc Exp $
**********************************************************************/
@ -51,11 +51,6 @@ extern int Yap_page_size;
#define UPDATE_STATS(STAT, VALUE) STAT += VALUE
#ifdef MALLOC_MEMORY_ALLOC_SCHEME /* --------------------------------------------- */
#define ALLOC_BLOCK(BLOCK, SIZE) \
if ((BLOCK = malloc(SIZE)) == NULL) \
Yap_Error(FATAL_ERROR, TermNil, "malloc error (ALLOC_BLOCK)")
#define FREE_BLOCK(BLOCK) \
free(BLOCK)
#define ALLOC_STRUCT(STR, STR_PAGES, STR_TYPE) \
UPDATE_STATS(Pg_str_in_use(STR_PAGES), 1); \
if ((STR = (STR_TYPE *)malloc(sizeof(STR_TYPE))) == NULL) \
@ -66,11 +61,6 @@ extern int Yap_page_size;
UPDATE_STATS(Pg_str_in_use(STR_PAGES), -1); \
free(STR)
#elif YAP_MEMORY_ALLOC_SCHEME /* ----------------------------------------------- */
#define ALLOC_BLOCK(BLOCK, SIZE) \
if ((BLOCK = (void *) Yap_AllocCodeSpace(SIZE)) == NULL) \
Yap_Error(FATAL_ERROR, TermNil, "Yap_AllocCodeSpace error (ALLOC_BLOCK)")
#define FREE_BLOCK(BLOCK) \
Yap_FreeCodeSpace((char *) (BLOCK))
#define ALLOC_STRUCT(STR, STR_PAGES, STR_TYPE) \
UPDATE_STATS(Pg_str_in_use(STR_PAGES), 1); \
if ((STR = (STR_TYPE *) Yap_AllocCodeSpace(sizeof(STR_TYPE))) == NULL) \
@ -81,12 +71,6 @@ extern int Yap_page_size;
UPDATE_STATS(Pg_str_in_use(STR_PAGES), -1); \
Yap_FreeCodeSpace((char *) (STR))
#elif SHM_MEMORY_ALLOC_SCHEME /* ------------------------------------------------ */
#define ALLOC_BLOCK(BLOCK, SIZE) \
if ((BLOCK = (void *) Yap_AllocCodeSpace(SIZE)) == NULL) \
Yap_Error(FATAL_ERROR, TermNil, "Yap_AllocCodeSpace error (ALLOC_BLOCK)")
#define FREE_BLOCK(BLOCK) \
Yap_FreeCodeSpace((char *) (BLOCK))
#define ALLOC_PAGE(PG_HD) \
LOCK(Pg_lock(GLOBAL_PAGES_void)); \
UPDATE_STATS(Pg_str_in_use(GLOBAL_PAGES_void), 1); \
@ -216,6 +200,22 @@ extern int Yap_page_size;
}
#endif /* ------------------------- MEMORY_ALLOC_SCHEME -------------------------- */
#ifdef YAPOR
#define ALLOC_BLOCK(BLOCK, SIZE) \
if ((BLOCK = (void *) Yap_AllocCodeSpace(SIZE)) == NULL) \
Yap_Error(FATAL_ERROR, TermNil, "Yap_AllocCodeSpace error (ALLOC_BLOCK)")
#define FREE_BLOCK(BLOCK) \
Yap_FreeCodeSpace((char *) (BLOCK))
#else /* TABLING */
#define ALLOC_BLOCK(BLOCK, SIZE) \
if ((BLOCK = malloc(SIZE)) == NULL) \
Yap_Error(FATAL_ERROR, TermNil, "malloc error (ALLOC_BLOCK)")
#define FREE_BLOCK(BLOCK) \
free(BLOCK)
#endif /* YAPOR - TABLING */
#define ALLOC_HASH_BUCKETS(BUCKET_PTR, NUM_BUCKETS) \
{ int i; void **ptr; \
ALLOC_BLOCK(ptr, NUM_BUCKETS * sizeof(void *)); \
@ -225,6 +225,8 @@ extern int Yap_page_size;
}
#define FREE_HASH_BUCKETS(BUCKET_PTR) FREE_BLOCK(BUCKET_PTR)
#define ALLOC_OR_FRAME(STR) ALLOC_STRUCT(STR, GLOBAL_PAGES_or_fr, struct or_frame)
#define FREE_OR_FRAME(STR) FREE_STRUCT(STR, GLOBAL_PAGES_or_fr, struct or_frame)

View File

@ -5,7 +5,7 @@
Copyright: R. Rocha and NCC - University of Porto, Portugal
File: opt.preds.c
version: $Id: opt.preds.c,v 1.21 2005-07-28 16:29:50 ricroc Exp $
version: $Id: opt.preds.c,v 1.22 2005-08-01 15:40:38 ricroc Exp $
**********************************************************************/
@ -678,7 +678,8 @@ int p_show_table(void) {
tab_ent = RepPredProp(PredPropByFunc(FunctorOfTerm(t), mod))->TableOfPred;
} else
return (FALSE);
traverse_trie(tab_ent, at, TRUE);
fprintf(Yap_stderr, "Table structure for predicate '%s/%d'\n", AtomName(at), TabEnt_arity(tab_ent));
traverse_table(tab_ent, at, TRUE);
return (TRUE);
}
@ -699,7 +700,9 @@ int p_table_statistics(void) {
tab_ent = RepPredProp(PredPropByFunc(FunctorOfTerm(t), mod))->TableOfPred;
} else
return (FALSE);
traverse_trie(tab_ent, at, FALSE);
fprintf(Yap_stderr, "Table statistics for predicate '%s/%d'", AtomName(at), TabEnt_arity(tab_ent));
if (traverse_table(tab_ent, at, FALSE))
table_stats();
return (TRUE);
}

View File

@ -5,7 +5,7 @@
Copyright: R. Rocha and NCC - University of Porto, Portugal
File: opt.proto.h
version: $Id: opt.proto.h,v 1.9 2005-07-11 19:17:27 ricroc Exp $
version: $Id: opt.proto.h,v 1.10 2005-08-01 15:40:38 ricroc Exp $
**********************************************************************/
@ -63,14 +63,15 @@ void finish_yapor(void);
** ------------- */
#ifdef TABLING
sg_fr_ptr subgoal_search(tab_ent_ptr tab_ent, OPREG arity, CELL **Yaddr);
sg_fr_ptr subgoal_search(yamop *preg, 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_branch(ans_node_ptr node);
void update_answer_trie(sg_fr_ptr sg_fr);
void traverse_trie(tab_ent_ptr tab_ent, Atom pred_atom, int show_trie);
int traverse_table(tab_ent_ptr tab_ent, Atom pred_atom, int show_table);
void table_stats(void);
#endif /* TABLING */

View File

@ -5,7 +5,7 @@
Copyright: R. Rocha and NCC - University of Porto, Portugal
File: tab.insts.i
version: $Id: tab.insts.i,v 1.16 2005-07-06 19:34:10 ricroc Exp $
version: $Id: tab.insts.i,v 1.17 2005-08-01 15:40:38 ricroc Exp $
**********************************************************************/
@ -14,7 +14,7 @@
** ------------------------------------------------ */
#ifdef LOW_LEVEL_TRACER
#define store_low_level_trace_info(CP, TAB_ENT) CP->cp_tab_ent = TAB_ENT
#define store_low_level_trace_info(CP, TAB_ENT) CP->cp_pred_entry = TabEnt_pe(TAB_ENT)
#else
#define store_low_level_trace_info(CP, TAB_ENT)
#endif /* LOW_LEVEL_TRACER */
@ -273,16 +273,115 @@
PBOp(table_load_answer, ld)
CELL *subs_ptr;
ans_node_ptr ans_node;
#ifdef YAPOR
if (SCH_top_shared_cp(B)) {
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);
}
#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);
load_answer_trie(ans_node, subs_ptr);
YENV = ENV;
GONext();
ENDPBOp();
PBOp(table_try_answer, ld)
#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);
H = HBREG = PROTECT_FROZEN_H(B);
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);
load_answer_trie(ans_node, subs_ptr);
YENV = ENV;
GONext();
} else {
yamop *code_ap;
OPCODE code = Yap_opcode(_table_try_me);
PREG = SgFr_code(sg_fr);
if (PREG->opc > code) {
/* table_try */
code_ap = NEXTOP(PREG,ld);
PREG = PREG->u.ld.d;
} else if (PREG->opc == code) {
/* table_try_me */
code_ap = PREG->u.ld.d;
PREG = NEXTOP(PREG,ld);
} else {
/* table_try_single */
code_ap = COMPLETION;
PREG = PREG->u.ld.d;
}
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();
}
#endif /* INCOMPLETE_TABLING */
ENDPBOp();
PBOp(table_try_single, ld)
tab_ent_ptr tab_ent;
sg_fr_ptr sg_fr;
check_trail();
tab_ent = PREG->u.ld.te;
sg_fr = subgoal_search(tab_ent, PREG->u.ld.s, &YENV);
sg_fr = subgoal_search(PREG, &YENV);
LOCK(SgFr_lock(sg_fr));
if (SgFr_state(sg_fr) == start) {
/* subgoal new or abolished */
/* subgoal new or not complete (abolished) */
#ifdef INCOMPLETE_TABLING
ans_node_ptr ans_node = SgFr_first_answer(sg_fr);
if (ans_node) {
/* subgoal not complete --> start by loading the answers already found */
CELL *subs_ptr = YENV;
init_subgoal_frame(sg_fr);
UNLOCK(SgFr_lock(sg_fr));
SgFr_try_answer(sg_fr) = ans_node;
store_generator_node(tab_ent, sg_fr, PREG->u.ld.s, TRY_ANSWER);
PREG = (yamop *) CPREG;
PREFETCH_OP(PREG);
load_answer_trie(ans_node, subs_ptr);
YENV = ENV;
GONext();
}
#endif /* INCOMPLETE_TABLING */
/* subgoal new */
init_subgoal_frame(sg_fr);
UNLOCK(SgFr_lock(sg_fr));
store_generator_node(tab_ent, sg_fr, PREG->u.ld.s, COMPLETION);
@ -364,10 +463,27 @@
check_trail();
tab_ent = PREG->u.ld.te;
sg_fr = subgoal_search(tab_ent, PREG->u.ld.s, &YENV);
sg_fr = subgoal_search(PREG, &YENV);
LOCK(SgFr_lock(sg_fr));
if (SgFr_state(sg_fr) == start) {
/* subgoal new or abolished */
/* subgoal new or not complete (abolished) */
#ifdef INCOMPLETE_TABLING
ans_node_ptr ans_node = SgFr_first_answer(sg_fr);
if (ans_node) {
/* subgoal not complete --> start by loading the answers already found */
CELL *subs_ptr = YENV;
init_subgoal_frame(sg_fr);
UNLOCK(SgFr_lock(sg_fr));
SgFr_try_answer(sg_fr) = ans_node;
store_generator_node(tab_ent, sg_fr, PREG->u.ld.s, TRY_ANSWER);
PREG = (yamop *) CPREG;
PREFETCH_OP(PREG);
load_answer_trie(ans_node, subs_ptr);
YENV = ENV;
GONext();
}
#endif /* INCOMPLETE_TABLING */
/* subgoal new */
init_subgoal_frame(sg_fr);
UNLOCK(SgFr_lock(sg_fr));
store_generator_node(tab_ent, sg_fr, PREG->u.ld.s, PREG->u.ld.d);
@ -449,10 +565,27 @@
check_trail();
tab_ent = PREG->u.ld.te;
sg_fr = subgoal_search(tab_ent, PREG->u.ld.s, &YENV);
sg_fr = subgoal_search(PREG, &YENV);
LOCK(SgFr_lock(sg_fr));
if (SgFr_state(sg_fr) == start) {
/* subgoal new or abolished */
/* subgoal new or not complete (abolished) */
#ifdef INCOMPLETE_TABLING
ans_node_ptr ans_node = SgFr_first_answer(sg_fr);
if (ans_node) {
/* subgoal not complete --> start by loading the answers already found */
CELL *subs_ptr = YENV;
init_subgoal_frame(sg_fr);
UNLOCK(SgFr_lock(sg_fr));
SgFr_try_answer(sg_fr) = ans_node;
store_generator_node(tab_ent, sg_fr, PREG->u.ld.s, TRY_ANSWER);
PREG = (yamop *) CPREG;
PREFETCH_OP(PREG);
load_answer_trie(ans_node, subs_ptr);
YENV = ENV;
GONext();
}
#endif /* INCOMPLETE_TABLING */
/* subgoal new */
init_subgoal_frame(sg_fr);
UNLOCK(SgFr_lock(sg_fr));
store_generator_node(tab_ent, sg_fr, PREG->u.ld.s, NEXTOP(PREG,ld));
@ -1092,7 +1225,7 @@
BOp(table_completion, ld);
BOp(table_completion, ld)
#ifdef YAPOR
if (SCH_top_shared_cp(B)) {
if (IS_BATCHED_GEN_CP(B)) {
@ -1449,29 +1582,3 @@
}
END_PREFETCH()
ENDBOp();
BOp(table_load_answer, ld);
CELL *subs_ptr;
ans_node_ptr ans_node;
#ifdef YAPOR
if (SCH_top_shared_cp(B)) {
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);
}
#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);
load_answer_trie(ans_node, subs_ptr);
YENV = ENV;
GONext();
ENDBOp();

View File

@ -5,7 +5,7 @@
Copyright: R. Rocha and NCC - University of Porto, Portugal
File: tab.macros.h
version: $Id: tab.macros.h,v 1.16 2005-07-26 16:28:28 ricroc Exp $
version: $Id: tab.macros.h,v 1.17 2005-08-01 15:40:38 ricroc Exp $
**********************************************************************/
@ -227,23 +227,22 @@ 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, TAB_ENT, ARITY) \
#define new_subgoal_frame(SG_FR, CODE) \
{ register ans_node_ptr ans_node; \
ALLOC_SUBGOAL_FRAME(SG_FR); \
INIT_LOCK(SgFr_lock(SG_FR)); \
SgFr_tab_ent(SG_FR) = TAB_ENT; \
SgFr_arity(SG_FR) = ARITY; \
new_answer_trie_node(ans_node, 0, 0, NULL, NULL, NULL); \
SgFr_answer_trie(SG_FR) = ans_node; \
SgFr_hash_chain(SG_FR) = NULL; \
SgFr_code(SG_FR) = CODE; \
SgFr_state(SG_FR) = start; \
new_answer_trie_node(ans_node, 0, 0, NULL, NULL, NULL); \
SgFr_hash_chain(SG_FR) = NULL; \
SgFr_answer_trie(SG_FR) = ans_node; \
SgFr_first_answer(SG_FR) = NULL; \
SgFr_last_answer(SG_FR) = NULL; \
}
#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_state(SG_FR) = evaluating; \
SgFr_next(SG_FR) = LOCAL_top_sg_fr; \
LOCAL_top_sg_fr = sg_fr; \
@ -518,9 +517,14 @@ void abolish_incomplete_subgoals(choiceptr prune_cp) {
LOCAL_top_sg_fr = SgFr_next(sg_fr);
LOCK(SgFr_lock(sg_fr));
if (SgFr_first_answer(sg_fr) == SgFr_answer_trie(sg_fr)) {
/* yes answer --> complete */
SgFr_state(sg_fr) = complete;
UNLOCK(SgFr_lock(sg_fr));
} else {
#ifdef INCOMPLETE_TABLING
SgFr_state(sg_fr) = start;
UNLOCK(SgFr_lock(sg_fr));
#else
ans_node_ptr node;
SgFr_state(sg_fr) = start;
free_answer_hash_chain(SgFr_hash_chain(sg_fr));
@ -532,6 +536,7 @@ void abolish_incomplete_subgoals(choiceptr prune_cp) {
UNLOCK(SgFr_lock(sg_fr));
if (node)
free_answer_trie_branch(node);
#endif /* INCOMPLETE_TABLING */
}
}

View File

@ -5,7 +5,7 @@
Copyright: R. Rocha and NCC - University of Porto, Portugal
File: tab.structs.h
version: $Id: tab.structs.h,v 1.8 2005-07-11 19:17:29 ricroc Exp $
version: $Id: tab.structs.h,v 1.9 2005-08-01 15:40:39 ricroc Exp $
**********************************************************************/
@ -154,51 +154,59 @@ typedef struct subgoal_frame {
int generator_worker;
struct or_frame *top_or_frame_on_generator_branch;
#endif /* YAPOR */
struct table_entry *tab_ent;
int subgoal_arity;
choiceptr generator_choice_point;
struct answer_trie_node *answer_trie;
struct answer_trie_node *first_answer;
struct answer_trie_node *last_answer;
struct answer_hash *hash_chain;
yamop *code_of_subgoal;
enum {
start = 0,
evaluating = 1,
complete = 2,
compiled = 3
} state_flag;
choiceptr generator_choice_point;
struct answer_hash *hash_chain;
struct answer_trie_node *answer_trie;
struct answer_trie_node *first_answer;
struct answer_trie_node *last_answer;
#ifdef INCOMPLETE_TABLING
struct answer_trie_node *try_answer;
#endif /* INCOMPLETE_TABLING */
struct subgoal_frame *next;
} *sg_fr_ptr;
#define SgFr_lock(X) ((X)->lock)
#define SgFr_gen_worker(X) ((X)->generator_worker)
#define SgFr_gen_top_or_fr(X) ((X)->top_or_frame_on_generator_branch)
#define SgFr_tab_ent(X) ((X)->tab_ent)
#define SgFr_arity(X) ((X)->subgoal_arity)
#define SgFr_code(X) ((X)->code_of_subgoal)
#define SgFr_tab_ent(X) (((X)->code_of_subgoal)->u.ld.te)
#define SgFr_arity(X) (((X)->code_of_subgoal)->u.ld.s)
#define SgFr_state(X) ((X)->state_flag)
#define SgFr_gen_cp(X) ((X)->generator_choice_point)
#define SgFr_hash_chain(X) ((X)->hash_chain)
#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_try_answer(X) ((X)->try_answer)
#define SgFr_next(X) ((X)->next)
/* ------------------------------------------------------------------------------------------- **
SgFr_lock: lock variable to modify the frame fields.
SgFr_lock: spin-lock to modify the frame fields.
SgFr_gen_worker: the id of the worker that had allocated the frame.
SgFr_gen_top_or_fr: a pointer to the top or-frame in the generator choice point branch.
When the generator choice point is shared the pointer is updated
to its or-frame. It is used to find the direct dependency node for
consumer nodes in other workers branches.
SgFr_code initial instruction of the subgoal's compiled code.
SgFr_tab_ent a pointer to the correspondent table entry.
SgFr_arity the arity of the subgoal.
SgFr_state: a flag that indicates the subgoal state.
SgFr_gen_cp: a pointer to the correspondent generator choice point.
SgFr_hash_chain: a pointer to the first answer_hash struct for the subgoal in hand.
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_try_answer: a pointer to the bottom answer trie node of the last tried answer.
It is used when a subgoal was not completed during the previous evaluation.
Not completed subgoals start by trying the answers already found.
SgFr_next: a pointer to chain between subgoal frames.
** ------------------------------------------------------------------------------------------- */
@ -298,7 +306,7 @@ struct generator_choicept {
struct dependency_frame *cp_dep_fr; /* NULL if batched scheduling */
struct subgoal_frame *cp_sg_fr;
#ifdef LOW_LEVEL_TRACER
struct table_entry* cp_tab_ent;
struct pred_entry *cp_pred_entry;
#endif /* LOW_LEVEL_TRACER */
};
@ -306,7 +314,7 @@ struct consumer_choicept {
struct choicept cp;
struct dependency_frame *cp_dep_fr;
#ifdef LOW_LEVEL_TRACER
struct table_entry* cp_tab_ent;
struct pred_entry *cp_pred_entry;
#endif /* LOW_LEVEL_TRACER */
};
@ -314,6 +322,6 @@ struct loader_choicept {
struct choicept cp;
struct answer_trie_node *cp_last_answer;
#ifdef LOW_LEVEL_TRACER
struct table_entry* cp_tab_ent;
struct pred_entry *cp_pred_entry;
#endif /* LOW_LEVEL_TRACER */
};

View File

@ -5,7 +5,7 @@
Copyright: R. Rocha and NCC - University of Porto, Portugal
File: tab.tries.C
version: $Id: tab.tries.c,v 1.14 2005-07-11 19:17:29 ricroc Exp $
version: $Id: tab.tries.c,v 1.15 2005-08-01 15:40:39 ricroc Exp $
**********************************************************************/
@ -675,12 +675,15 @@ ans_node_ptr answer_trie_node_check_insert(sg_fr_ptr sg_fr, ans_node_ptr parent_
** Global functions **
** -------------------------- */
sg_fr_ptr subgoal_search(tab_ent_ptr tab_ent, OPREG arity, CELL **Yaddr) {
int i, j, count_vars;
sg_fr_ptr subgoal_search(yamop *preg, CELL **Yaddr) {
int i, j, count_vars, arity;
CELL *stack_vars, *stack_terms_limit, *stack_terms_base, *stack_terms;
sg_node_ptr current_sg_node;
tab_ent_ptr tab_ent;
sg_fr_ptr sg_fr;
arity = preg->u.ld.s;
tab_ent = preg->u.ld.te;
count_vars = 0;
stack_vars = *Yaddr;
stack_terms_limit = (CELL *)TR;
@ -747,7 +750,7 @@ sg_fr_ptr subgoal_search(tab_ent_ptr tab_ent, OPREG arity, CELL **Yaddr) {
#endif /* TABLE_LOCK_LEVEL */
if (TrNode_sg_fr(current_sg_node) == NULL) {
/* new tabled subgoal */
new_subgoal_frame(sg_fr, tab_ent, arity);
new_subgoal_frame(sg_fr, preg);
TrNode_sg_fr(current_sg_node) = (sg_node_ptr) sg_fr;
} else {
sg_fr = (sg_fr_ptr) TrNode_sg_fr(current_sg_node);
@ -1031,6 +1034,7 @@ void update_answer_trie(sg_fr_ptr sg_fr) {
return;
}
static struct trie_statistics{
int show;
long subgoals;
@ -1048,38 +1052,34 @@ static struct trie_statistics{
int answer_trie_max_depth;
int answer_trie_min_depth;
} trie_stats;
#define TrStat_show trie_stats.show
#define TrStat_subgoals trie_stats.subgoals
#define TrStat_sg_not_complete trie_stats.subgoals_not_complete
#define TrStat_sg_nodes trie_stats.subgoal_trie_nodes
#define TrStat_sg_linear_nodes trie_stats.subgoal_linear_nodes
#define TrStat_sg_max_depth trie_stats.subgoal_trie_max_depth
#define TrStat_sg_min_depth trie_stats.subgoal_trie_min_depth
#define TrStat_answers trie_stats.answers
#define TrStat_answers_yes trie_stats.answers_yes
#define TrStat_answers_no trie_stats.answers_no
#define TrStat_ans_pruned trie_stats.answers_pruned
#define TrStat_ans_nodes trie_stats.answer_trie_nodes
#define TrStat_ans_linear_nodes trie_stats.answer_linear_nodes
#define TrStat_ans_max_depth trie_stats.answer_trie_max_depth
#define TrStat_ans_min_depth trie_stats.answer_trie_min_depth
#define TrStat_show trie_stats.show
#define TrStat_subgoals trie_stats.subgoals
#define TrStat_sg_not_complete trie_stats.subgoals_not_complete
#define TrStat_sg_nodes trie_stats.subgoal_trie_nodes
#define TrStat_sg_linear_nodes trie_stats.subgoal_linear_nodes
#define TrStat_sg_max_depth trie_stats.subgoal_trie_max_depth
#define TrStat_sg_min_depth trie_stats.subgoal_trie_min_depth
#define TrStat_answers trie_stats.answers
#define TrStat_answers_yes trie_stats.answers_yes
#define TrStat_answers_no trie_stats.answers_no
#define TrStat_ans_pruned trie_stats.answers_pruned
#define TrStat_ans_nodes trie_stats.answer_trie_nodes
#define TrStat_ans_linear_nodes trie_stats.answer_linear_nodes
#define TrStat_ans_max_depth trie_stats.answer_trie_max_depth
#define TrStat_ans_min_depth trie_stats.answer_trie_min_depth
#define STR_ARRAY_SIZE 1000
#define ARITY_ARRAY_SIZE 100
#define SHOW_INFO(MESG, ARGS...) fprintf(Yap_stderr, MESG, ##ARGS)
#define SHOW_TRIE(MESG, ARGS...) if (TrStat_show) fprintf(Yap_stderr, MESG, ##ARGS)
#define SHOW_TABLE(MESG, ARGS...) if (TrStat_show) fprintf(Yap_stderr, MESG, ##ARGS)
void traverse_trie(tab_ent_ptr tab_ent, Atom pred_atom, int show_trie) {
char str[STR_ARRAY_SIZE];
int arity[ARITY_ARRAY_SIZE];
int str_index;
int pred_arity = TabEnt_arity(tab_ent);
int traverse_table(tab_ent_ptr tab_ent, Atom pred_atom, int show_table) {
sg_node_ptr sg_node = TrNode_child(TabEnt_subgoal_trie(tab_ent));
TrStat_show = show_trie;
TrStat_show = show_table;
TrStat_subgoals = 0;
TrStat_sg_not_complete = 0;
TrStat_sg_nodes = 0;
TrStat_sg_nodes = 1;
TrStat_sg_linear_nodes = 0;
TrStat_sg_max_depth = -1;
TrStat_sg_min_depth = -1;
@ -1091,43 +1091,49 @@ void traverse_trie(tab_ent_ptr tab_ent, Atom pred_atom, int show_trie) {
TrStat_ans_linear_nodes = 0;
TrStat_ans_max_depth = -1;
TrStat_ans_min_depth = -1;
str_index = sprintf(str, " ?- %s(", AtomName(pred_atom));
arity[0] = 1;
arity[1] = pred_arity;
SHOW_TRIE("\ntable structure for predicate '%s/%d'\n", AtomName(pred_atom), pred_arity);
TrStat_sg_nodes++;
if (sg_node && ! traverse_subgoal_trie(sg_node, str, str_index, arity, 1, TRAVERSE_NORMAL))
return;
SHOW_INFO("\ntable statistics for predicate '%s/%d'", AtomName(pred_atom), pred_arity);
SHOW_INFO("\n subgoal trie structure");
SHOW_INFO("\n subgoals: %ld", TrStat_subgoals);
SHOW_INFO("\n subgoals not complete: %ld", TrStat_sg_not_complete);
SHOW_INFO("\n nodes: %ld (%ld%c saving)",
TrStat_sg_nodes,
TrStat_sg_linear_nodes == 0 ? 0 : (TrStat_sg_linear_nodes - TrStat_sg_nodes + 1) * 100 / TrStat_sg_linear_nodes,
if (sg_node) {
char str[STR_ARRAY_SIZE];
int str_index = sprintf(str, " ?- %s(", AtomName(pred_atom));
int arity[ARITY_ARRAY_SIZE];
arity[0] = 1;
arity[1] = TabEnt_arity(tab_ent);
return traverse_subgoal_trie(sg_node, str, str_index, arity, 1, TRAVERSE_NORMAL);
}
SHOW_TABLE(" empty\n");
return TRUE;
}
void table_stats(void) {
fprintf(Yap_stderr, "\n Subgoal trie structure");
fprintf(Yap_stderr, "\n subgoals: %ld", TrStat_subgoals);
fprintf(Yap_stderr, "\n subgoals not complete: %ld", TrStat_sg_not_complete);
fprintf(Yap_stderr, "\n nodes: %ld (%ld%c saving)",
TrStat_sg_nodes,
TrStat_sg_linear_nodes == 0 ? 0 : (TrStat_sg_linear_nodes - TrStat_sg_nodes + 1) * 100 / TrStat_sg_linear_nodes,
'%');
fprintf(Yap_stderr, "\n average depth: %.2f (%d min - %d max)",
TrStat_subgoals == 0 ? 0 : (float)TrStat_sg_linear_nodes / (float)TrStat_subgoals,
TrStat_sg_min_depth < 0 ? 0 : TrStat_sg_min_depth,
TrStat_sg_max_depth < 0 ? 0 : TrStat_sg_max_depth);
fprintf(Yap_stderr, "\n Answer trie structure");
fprintf(Yap_stderr, "\n answers: %ld", TrStat_answers);
fprintf(Yap_stderr, "\n yes answers: %ld", TrStat_answers_yes);
fprintf(Yap_stderr, "\n no answers: %ld", TrStat_answers_no);
fprintf(Yap_stderr, "\n pruned answers: %ld", TrStat_ans_pruned);
fprintf(Yap_stderr, "\n nodes: %ld (%ld%c saving)",
TrStat_ans_nodes,
TrStat_ans_linear_nodes == 0 ? 0 : (TrStat_ans_linear_nodes - TrStat_ans_nodes + TrStat_subgoals) * 100 / TrStat_ans_linear_nodes,
'%');
SHOW_INFO("\n average depth: %.2f (%d min - %d max)",
TrStat_subgoals == 0 ? 0 : (float)TrStat_sg_linear_nodes / (float)TrStat_subgoals,
TrStat_sg_min_depth < 0 ? 0 : TrStat_sg_min_depth,
TrStat_sg_max_depth < 0 ? 0 : TrStat_sg_max_depth);
SHOW_INFO("\n answer trie structure");
SHOW_INFO("\n answers: %ld", TrStat_answers);
SHOW_INFO("\n yes answers: %ld", TrStat_answers_yes);
SHOW_INFO("\n no answers: %ld", TrStat_answers_no);
SHOW_INFO("\n pruned answers: %ld", TrStat_ans_pruned);
SHOW_INFO("\n nodes: %ld (%ld%c saving)",
TrStat_ans_nodes,
TrStat_ans_linear_nodes == 0 ? 0 : (TrStat_ans_linear_nodes - TrStat_ans_nodes + TrStat_subgoals) * 100 / TrStat_ans_linear_nodes,
'%');
SHOW_INFO("\n average depth: %.2f (%d min - %d max)",
TrStat_answers == 0 ? 0 : (float)TrStat_ans_linear_nodes / (float)TrStat_answers,
TrStat_ans_min_depth < 0 ? 0 : TrStat_ans_min_depth,
TrStat_ans_max_depth < 0 ? 0 : TrStat_ans_max_depth);
SHOW_INFO("\n total memory in use\n %ld bytes\n\n",
sizeof(struct table_entry) +
TrStat_sg_nodes * sizeof(struct subgoal_trie_node) +
TrStat_ans_nodes * sizeof(struct answer_trie_node) +
TrStat_subgoals * sizeof(struct subgoal_frame));
fprintf(Yap_stderr, "\n average depth: %.2f (%d min - %d max)",
TrStat_answers == 0 ? 0 : (float)TrStat_ans_linear_nodes / (float)TrStat_answers,
TrStat_ans_min_depth < 0 ? 0 : TrStat_ans_min_depth,
TrStat_ans_max_depth < 0 ? 0 : TrStat_ans_max_depth);
fprintf(Yap_stderr, "\n Total memory in use\n %ld bytes\n",
sizeof(struct table_entry) +
TrStat_sg_nodes * sizeof(struct subgoal_trie_node) +
TrStat_ans_nodes * sizeof(struct answer_trie_node) +
TrStat_subgoals * sizeof(struct subgoal_frame));
return;
}
@ -1278,7 +1284,7 @@ int traverse_subgoal_trie(sg_node_ptr sg_node, char *str, int str_index, int *ar
arity[arity[0]]++;
if (arity[arity[0]] == 0) {
str[str_index] = 0;
SHOW_INFO("%s --> TRIE ERROR: pair without end atom '[]' !!!\n", str);
fprintf(Yap_stderr, "%s --> TRIE ERROR: pair without end atom '[]' !!!\n", str);
return FALSE;
}
str_index += sprintf(& str[str_index], "|");
@ -1303,7 +1309,7 @@ int traverse_subgoal_trie(sg_node_ptr sg_node, char *str, int str_index, int *ar
arity[arity[0]]++;
if (arity[arity[0]] == 0) {
str[str_index] = 0;
SHOW_INFO("%s --> TRIE ERROR: pair without end atom '[]' !!!\n", str);
fprintf(Yap_stderr, "%s --> TRIE ERROR: pair without end atom '[]' !!!\n", str);
return FALSE;
}
str_index += sprintf(& str[str_index], "|");
@ -1350,7 +1356,7 @@ int traverse_subgoal_trie(sg_node_ptr sg_node, char *str, int str_index, int *ar
arity[arity[0]]++;
if (arity[arity[0]] == 0) {
str[str_index] = 0;
SHOW_INFO("%s --> TRIE ERROR: pair without end atom '[]' !!!\n", str);
fprintf(Yap_stderr, "%s --> TRIE ERROR: pair without end atom '[]' !!!\n", str);
return FALSE;
}
str_index += sprintf(& str[str_index], "|");
@ -1361,7 +1367,7 @@ int traverse_subgoal_trie(sg_node_ptr sg_node, char *str, int str_index, int *ar
if (arity[arity[0]] == -1) {
if (strcmp("[]", AtomName(AtomOfTerm(t)))) {
str[str_index] = 0;
SHOW_INFO("%s --> TRIE ERROR: pair without end atom '[]' !!!\n", str);
fprintf(Yap_stderr, "%s --> TRIE ERROR: pair without end atom '[]' !!!\n", str);
return FALSE;
}
str[str_index - 1] = ']';
@ -1383,7 +1389,7 @@ int traverse_subgoal_trie(sg_node_ptr sg_node, char *str, int str_index, int *ar
arity[arity[0]]++;
if (arity[arity[0]] == 0) {
str[str_index] = 0;
SHOW_INFO("%s --> TRIE ERROR: pair without end atom '[]' !!!\n", str);
fprintf(Yap_stderr, "%s --> TRIE ERROR: pair without end atom '[]' !!!\n", str);
return FALSE;
}
str_index += sprintf(& str[str_index], "|");
@ -1430,9 +1436,9 @@ int traverse_subgoal_trie(sg_node_ptr sg_node, char *str, int str_index, int *ar
}
if (SgFr_state(sg_fr) == start || SgFr_state(sg_fr) == evaluating) {
TrStat_sg_not_complete++;
SHOW_TRIE("%s. ---> NOT COMPLETE\n", str);
SHOW_TABLE("%s. ---> NOT COMPLETE\n", str);
} else {
SHOW_TRIE("%s.\n", str);
SHOW_TABLE("%s.\n", str);
}
TrStat_ans_nodes++;
if (SgFr_first_answer(sg_fr) == NULL) {
@ -1440,14 +1446,14 @@ int traverse_subgoal_trie(sg_node_ptr sg_node, char *str, int str_index, int *ar
TrStat_ans_max_depth = 0;
TrStat_ans_min_depth = 0;
TrStat_answers_no++;
SHOW_TRIE(" NO ANSWERS\n");
SHOW_TABLE(" NO ANSWERS\n");
} else if (SgFr_first_answer(sg_fr) == SgFr_answer_trie(sg_fr)) {
if (TrStat_ans_max_depth < 0)
TrStat_ans_max_depth = 0;
TrStat_ans_min_depth = 0;
TrStat_answers_yes++;
TrStat_answers++;
SHOW_TRIE(" TRUE\n");
SHOW_TABLE(" TRUE\n");
} else {
char answer_str[STR_ARRAY_SIZE];
int answer_arity[ARITY_ARRAY_SIZE];
@ -1536,7 +1542,7 @@ int traverse_answer_trie(ans_node_ptr ans_node, char *str, int str_index, int *a
arity[arity[0]]++;
if (arity[arity[0]] == 0) {
str[str_index] = 0;
SHOW_INFO("%s --> TRIE ERROR: pair without end atom '[]' !!!\n", str);
fprintf(Yap_stderr, "%s --> TRIE ERROR: pair without end atom '[]' !!!\n", str);
return FALSE;
}
str_index += sprintf(& str[str_index], "|");
@ -1563,7 +1569,7 @@ int traverse_answer_trie(ans_node_ptr ans_node, char *str, int str_index, int *a
arity[arity[0]]++;
if (arity[arity[0]] == 0) {
str[str_index] = 0;
SHOW_INFO("%s --> TRIE ERROR: pair without end atom '[]' !!!\n", str);
fprintf(Yap_stderr, "%s --> TRIE ERROR: pair without end atom '[]' !!!\n", str);
return FALSE;
}
str_index += sprintf(& str[str_index], "|");
@ -1612,7 +1618,7 @@ int traverse_answer_trie(ans_node_ptr ans_node, char *str, int str_index, int *a
arity[arity[0]]++;
if (arity[arity[0]] == 0) {
str[str_index] = 0;
SHOW_INFO("%s --> TRIE ERROR: pair without end atom '[]' !!!\n", str);
fprintf(Yap_stderr, "%s --> TRIE ERROR: pair without end atom '[]' !!!\n", str);
return FALSE;
}
str_index += sprintf(& str[str_index], "|");
@ -1623,7 +1629,7 @@ int traverse_answer_trie(ans_node_ptr ans_node, char *str, int str_index, int *a
if (arity[arity[0]] == -1) {
if (strcmp("[]", AtomName(AtomOfTerm(t)))) {
str[str_index] = 0;
SHOW_INFO("%s --> TRIE ERROR: pair without end atom '[]' !!!\n", str);
fprintf(Yap_stderr, "%s --> TRIE ERROR: pair without end atom '[]' !!!\n", str);
return FALSE;
}
str[str_index - 1] = ']';
@ -1645,7 +1651,7 @@ int traverse_answer_trie(ans_node_ptr ans_node, char *str, int str_index, int *a
arity[arity[0]]++;
if (arity[arity[0]] == 0) {
str[str_index] = 0;
SHOW_INFO("%s --> TRIE ERROR: pair without end atom '[]' !!!\n", str);
fprintf(Yap_stderr, "%s --> TRIE ERROR: pair without end atom '[]' !!!\n", str);
return FALSE;
}
str_index += sprintf(& str[str_index], "|");
@ -1680,7 +1686,7 @@ int traverse_answer_trie(ans_node_ptr ans_node, char *str, int str_index, int *a
/* show answer .... */
if (IS_ANSWER_LEAF_NODE(ans_node)) {
str[str_index] = 0;
SHOW_TRIE("%s\n", str);
SHOW_TABLE("%s\n", str);
TrStat_answers++;
TrStat_ans_linear_nodes+= depth;
if (TrStat_ans_max_depth < 0)