fix recursive functions that manipulate tries

This commit is contained in:
Ricardo Rocha 2009-08-05 05:48:00 +01:00
parent f68cc92bce
commit cf5d68edda
5 changed files with 461 additions and 399 deletions

View File

@ -52,335 +52,335 @@ extern int Yap_page_size;
#define UPDATE_STATS(STAT, VALUE) STAT += VALUE #define UPDATE_STATS(STAT, VALUE) STAT += VALUE
#ifdef MALLOC_MEMORY_ALLOC_SCHEME /* ------------------------------------------------ */ #ifdef MALLOC_MEMORY_ALLOC_SCHEME /* ---------------------------------------------------------------- */
#define ALLOC_STRUCT(STR, STR_PAGES, STR_TYPE) \ #define ALLOC_STRUCT(STR, STR_PAGES, STR_TYPE) \
UPDATE_STATS(Pg_str_in_use(STR_PAGES), 1); \ UPDATE_STATS(Pg_str_in_use(STR_PAGES), 1); \
if ((STR = (STR_TYPE *)malloc(sizeof(STR_TYPE))) == NULL) \ if ((STR = (STR_TYPE *)malloc(sizeof(STR_TYPE))) == NULL) \
Yap_Error(FATAL_ERROR, TermNil, "malloc error (ALLOC_STRUCT)") Yap_Error(FATAL_ERROR, TermNil, "malloc error (ALLOC_STRUCT)")
#define ALLOC_NEXT_FREE_STRUCT(STR, STR_PAGES, STR_TYPE) \ #define ALLOC_NEXT_FREE_STRUCT(STR, STR_PAGES, STR_TYPE) \
ALLOC_STRUCT(STR, STR_PAGES, STR_TYPE) ALLOC_STRUCT(STR, STR_PAGES, STR_TYPE)
#define FREE_STRUCT(STR, STR_PAGES, STR_TYPE) \ #define FREE_STRUCT(STR, STR_PAGES, STR_TYPE) \
UPDATE_STATS(Pg_str_in_use(STR_PAGES), -1); \ UPDATE_STATS(Pg_str_in_use(STR_PAGES), -1); \
free(STR) free(STR)
#elif YAP_MEMORY_ALLOC_SCHEME /* ---------------------------------------------------- */ #elif YAP_MEMORY_ALLOC_SCHEME /* -------------------------------------------------------------------- */
#define ALLOC_STRUCT(STR, STR_PAGES, STR_TYPE) \ #define ALLOC_STRUCT(STR, STR_PAGES, STR_TYPE) \
{ char *ptr = Yap_AllocCodeSpace(sizeof(STR_TYPE) + sizeof(CELL)); \ { char *ptr = Yap_AllocCodeSpace(sizeof(STR_TYPE) + sizeof(CELL)); \
if (ptr) { \ if (ptr) { \
*ptr = 'y'; \ *ptr = 'y'; \
ptr += sizeof(CELL); \ ptr += sizeof(CELL); \
STR = (STR_TYPE *)ptr; \ STR = (STR_TYPE *)ptr; \
} else { \ } else { \
ptr = (char *)malloc(sizeof(STR_TYPE) + sizeof(CELL)); \ ptr = (char *)malloc(sizeof(STR_TYPE) + sizeof(CELL)); \
if (ptr) { \ if (ptr) { \
*ptr = 'm'; \ *ptr = 'm'; \
ptr += sizeof(CELL); \ ptr += sizeof(CELL); \
STR = (STR_TYPE *)ptr; \ STR = (STR_TYPE *)ptr; \
} else { \ } else { \
Yap_Error(FATAL_ERROR, TermNil, "malloc error (ALLOC_STRUCT)"); \ Yap_Error(FATAL_ERROR, TermNil, "malloc error (ALLOC_STRUCT)"); \
STR = NULL; \ STR = NULL; \
} \ } \
} \ } \
UPDATE_STATS(Pg_str_in_use(STR_PAGES), 1); \ UPDATE_STATS(Pg_str_in_use(STR_PAGES), 1); \
} }
#define ALLOC_NEXT_FREE_STRUCT(STR, STR_PAGES, STR_TYPE) \ #define ALLOC_NEXT_FREE_STRUCT(STR, STR_PAGES, STR_TYPE) \
ALLOC_STRUCT(STR, STR_PAGES, STR_TYPE) ALLOC_STRUCT(STR, STR_PAGES, STR_TYPE)
#define FREE_STRUCT(STR, STR_PAGES, STR_TYPE) \ #define FREE_STRUCT(STR, STR_PAGES, STR_TYPE) \
{ char *ptr = (char *)(STR) - sizeof(CELL); \ { char *ptr = (char *)(STR) - sizeof(CELL); \
if (ptr[0] == 'y') { \ if (ptr[0] == 'y') { \
Yap_FreeCodeSpace(ptr); \ Yap_FreeCodeSpace(ptr); \
} else \ } else \
free(ptr); \ free(ptr); \
UPDATE_STATS(Pg_str_in_use(STR_PAGES), -1); \ UPDATE_STATS(Pg_str_in_use(STR_PAGES), -1); \
} }
#elif SHM_MEMORY_ALLOC_SCHEME /* ---------------------------------------------------- */ #elif SHM_MEMORY_ALLOC_SCHEME /* -------------------------------------------------------------------- */
#ifdef LIMIT_TABLING #ifdef LIMIT_TABLING
#define INIT_PAGE(PG_HD, STR_PAGES, STR_TYPE) \ #define INIT_PAGE(PG_HD, STR_PAGES, STR_TYPE) \
{ int i; \ { int i; \
STR_TYPE *aux_str; \ STR_TYPE *aux_str; \
PgHd_str_in_use(PG_HD) = 0; \ PgHd_str_in_use(PG_HD) = 0; \
PgHd_previous(PG_HD) = NULL; \ PgHd_previous(PG_HD) = NULL; \
aux_str = (STR_TYPE *) (PG_HD + 1); \ aux_str = (STR_TYPE *) (PG_HD + 1); \
PgHd_free_str(PG_HD) = (void *) aux_str; \ PgHd_free_str(PG_HD) = (void *) aux_str; \
for (i = 1; i < Pg_str_per_pg(STR_PAGES); i++) { \ for (i = 1; i < Pg_str_per_pg(STR_PAGES); i++) { \
STRUCT_NEXT(aux_str) = aux_str + 1; \ STRUCT_NEXT(aux_str) = aux_str + 1; \
aux_str++; \ aux_str++; \
} \ } \
STRUCT_NEXT(aux_str) = NULL; \ STRUCT_NEXT(aux_str) = NULL; \
LOCK(Pg_lock(STR_PAGES)); \ LOCK(Pg_lock(STR_PAGES)); \
if ((PgHd_next(PG_HD) = Pg_free_pg(STR_PAGES)) != NULL) \ if ((PgHd_next(PG_HD) = Pg_free_pg(STR_PAGES)) != NULL) \
PgHd_previous(PgHd_next(PG_HD)) = PG_HD; \ PgHd_previous(PgHd_next(PG_HD)) = PG_HD; \
Pg_free_pg(STR_PAGES) = PG_HD; \ Pg_free_pg(STR_PAGES) = PG_HD; \
UPDATE_STATS(Pg_pg_alloc(STR_PAGES), 1); \ UPDATE_STATS(Pg_pg_alloc(STR_PAGES), 1); \
} }
#define ALLOC_PAGE(PG_HD) \ #define ALLOC_PAGE(PG_HD) \
{ int i, shmid; \ { int i, shmid; \
pg_hd_ptr aux_pg_hd; \ pg_hd_ptr aux_pg_hd; \
if ((shmid = shmget(IPC_PRIVATE, SHMMAX, SHM_R|SHM_W)) == -1) \ if ((shmid = shmget(IPC_PRIVATE, SHMMAX, SHM_R|SHM_W)) == -1) \
Yap_Error(FATAL_ERROR, TermNil, "shmget error (ALLOC_PAGE)"); \ Yap_Error(FATAL_ERROR, TermNil, "shmget error (ALLOC_PAGE)"); \
if ((PG_HD = (pg_hd_ptr) shmat(shmid, NULL, 0)) == (void *) -1) \ if ((PG_HD = (pg_hd_ptr) shmat(shmid, NULL, 0)) == (void *) -1) \
Yap_Error(FATAL_ERROR, TermNil, "shmat error (ALLOC_PAGE)"); \ Yap_Error(FATAL_ERROR, TermNil, "shmat error (ALLOC_PAGE)"); \
if (shmctl(shmid, IPC_RMID, 0) != 0) \ if (shmctl(shmid, IPC_RMID, 0) != 0) \
Yap_Error(FATAL_ERROR, TermNil, "shmctl error (ALLOC_PAGE)"); \ Yap_Error(FATAL_ERROR, TermNil, "shmctl error (ALLOC_PAGE)"); \
aux_pg_hd = (pg_hd_ptr)(((void *)PG_HD) + Yap_page_size); \ aux_pg_hd = (pg_hd_ptr)(((void *)PG_HD) + Yap_page_size); \
Pg_free_pg(GLOBAL_PAGES_void) = aux_pg_hd; \ Pg_free_pg(GLOBAL_PAGES_void) = aux_pg_hd; \
for (i = 2; i < SHMMAX / Yap_page_size; i++) { \ for (i = 2; i < SHMMAX / Yap_page_size; i++) { \
PgHd_next(aux_pg_hd) = (pg_hd_ptr)(((void *)aux_pg_hd) + Yap_page_size); \ PgHd_next(aux_pg_hd) = (pg_hd_ptr)(((void *)aux_pg_hd) + Yap_page_size); \
aux_pg_hd = PgHd_next(aux_pg_hd); \ aux_pg_hd = PgHd_next(aux_pg_hd); \
} \ } \
PgHd_next(aux_pg_hd) = NULL; \ PgHd_next(aux_pg_hd) = NULL; \
UPDATE_STATS(Pg_pg_alloc(GLOBAL_PAGES_void), SHMMAX / Yap_page_size); \ UPDATE_STATS(Pg_pg_alloc(GLOBAL_PAGES_void), SHMMAX / Yap_page_size); \
} }
#define RECOVER_UNUSED_SPACE(STR_PAGES) \ #define RECOVER_UNUSED_SPACE(STR_PAGES) \
{ sg_fr_ptr sg_fr = GLOBAL_check_sg_fr; \ { sg_fr_ptr sg_fr = GLOBAL_check_sg_fr; \
do { \ do { \
if (sg_fr) \ if (sg_fr) \
sg_fr = SgFr_next(sg_fr); \ sg_fr = SgFr_next(sg_fr); \
else \ else \
sg_fr = GLOBAL_first_sg_fr; \ sg_fr = GLOBAL_first_sg_fr; \
if (sg_fr == NULL) \ if (sg_fr == NULL) \
Yap_Error(FATAL_ERROR, TermNil, "no space left (RECOVER_UNUSED_SPACE)"); \ Yap_Error(FATAL_ERROR, TermNil, "no space left (RECOVER_UNUSED_SPACE)"); \
/* see function 'InteractSIGINT' in file 'sysbits.c' */ \ /* see function 'InteractSIGINT' in file 'sysbits.c' */ \
/* Yap_Error(PURE_ABORT, TermNil, ""); */ \ /* Yap_Error(PURE_ABORT, TermNil, ""); */ \
/* restore_absmi_regs(&Yap_standard_regs); */ \ /* restore_absmi_regs(&Yap_standard_regs); */ \
/* siglongjmp (Yap_RestartEnv, 1); */ \ /* siglongjmp (Yap_RestartEnv, 1); */ \
if (SgFr_first_answer(sg_fr) && \ if (SgFr_first_answer(sg_fr) && \
SgFr_first_answer(sg_fr) != SgFr_answer_trie(sg_fr)) { \ SgFr_first_answer(sg_fr) != SgFr_answer_trie(sg_fr)) { \
SgFr_state(sg_fr) = ready; \ SgFr_state(sg_fr) = ready; \
free_answer_hash_chain(SgFr_hash_chain(sg_fr)); \ free_answer_hash_chain(SgFr_hash_chain(sg_fr)); \
SgFr_hash_chain(sg_fr) = NULL; \ SgFr_hash_chain(sg_fr) = NULL; \
SgFr_first_answer(sg_fr) = NULL; \ SgFr_first_answer(sg_fr) = NULL; \
SgFr_last_answer(sg_fr) = NULL; \ SgFr_last_answer(sg_fr) = NULL; \
free_answer_trie_branch(TrNode_child(SgFr_answer_trie(sg_fr))); \ free_answer_trie_branch(TrNode_child(SgFr_answer_trie(sg_fr)), TRAVERSE_POSITION_FIRST); \
TrNode_child(SgFr_answer_trie(sg_fr)) = NULL; \ TrNode_child(SgFr_answer_trie(sg_fr)) = NULL; \
} \ } \
} while (Pg_free_pg(GLOBAL_PAGES_void) == Pg_free_pg(STR_PAGES)); \ } while (Pg_free_pg(GLOBAL_PAGES_void) == Pg_free_pg(STR_PAGES)); \
GLOBAL_check_sg_fr = sg_fr; \ GLOBAL_check_sg_fr = sg_fr; \
} }
#define ALLOC_STRUCT(STR, STR_PAGES, STR_TYPE) \ #define ALLOC_STRUCT(STR, STR_PAGES, STR_TYPE) \
{ pg_hd_ptr pg_hd; \ { pg_hd_ptr pg_hd; \
LOCK(Pg_lock(STR_PAGES)); \ LOCK(Pg_lock(STR_PAGES)); \
pg_hd = Pg_free_pg(STR_PAGES); \ pg_hd = Pg_free_pg(STR_PAGES); \
while (pg_hd == NULL) { \ while (pg_hd == NULL) { \
UNLOCK(Pg_lock(STR_PAGES)); \ UNLOCK(Pg_lock(STR_PAGES)); \
LOCK(Pg_lock(GLOBAL_PAGES_void)); \ LOCK(Pg_lock(GLOBAL_PAGES_void)); \
if (Pg_free_pg(GLOBAL_PAGES_void)) { \ if (Pg_free_pg(GLOBAL_PAGES_void)) { \
pg_hd = Pg_free_pg(GLOBAL_PAGES_void); \ pg_hd = Pg_free_pg(GLOBAL_PAGES_void); \
Pg_free_pg(GLOBAL_PAGES_void) = PgHd_next(pg_hd); \ Pg_free_pg(GLOBAL_PAGES_void) = PgHd_next(pg_hd); \
UPDATE_STATS(Pg_str_in_use(GLOBAL_PAGES_void), 1); \ UPDATE_STATS(Pg_str_in_use(GLOBAL_PAGES_void), 1); \
UNLOCK(Pg_lock(GLOBAL_PAGES_void)); \ UNLOCK(Pg_lock(GLOBAL_PAGES_void)); \
INIT_PAGE(pg_hd, STR_PAGES, STR_TYPE); \ INIT_PAGE(pg_hd, STR_PAGES, STR_TYPE); \
} else if (GLOBAL_MAX_PAGES != Pg_pg_alloc(GLOBAL_PAGES_void)) { \ } else if (GLOBAL_MAX_PAGES != Pg_pg_alloc(GLOBAL_PAGES_void)) { \
ALLOC_PAGE(pg_hd); \ ALLOC_PAGE(pg_hd); \
UPDATE_STATS(Pg_str_in_use(GLOBAL_PAGES_void), 1); \ UPDATE_STATS(Pg_str_in_use(GLOBAL_PAGES_void), 1); \
UNLOCK(Pg_lock(GLOBAL_PAGES_void)); \ UNLOCK(Pg_lock(GLOBAL_PAGES_void)); \
INIT_PAGE(pg_hd, STR_PAGES, STR_TYPE); \ INIT_PAGE(pg_hd, STR_PAGES, STR_TYPE); \
} else { \ } else { \
UNLOCK(Pg_lock(GLOBAL_PAGES_void)); \ UNLOCK(Pg_lock(GLOBAL_PAGES_void)); \
RECOVER_UNUSED_SPACE(STR_PAGES); \ RECOVER_UNUSED_SPACE(STR_PAGES); \
LOCK(Pg_lock(STR_PAGES)); \ LOCK(Pg_lock(STR_PAGES)); \
pg_hd = Pg_free_pg(STR_PAGES); \ pg_hd = Pg_free_pg(STR_PAGES); \
} \ } \
} \ } \
PgHd_str_in_use(pg_hd)++; \ PgHd_str_in_use(pg_hd)++; \
STR = (STR_TYPE *) PgHd_free_str(pg_hd); \ STR = (STR_TYPE *) PgHd_free_str(pg_hd); \
if ((PgHd_free_str(pg_hd) = (void *) STRUCT_NEXT(STR)) == NULL) \ if ((PgHd_free_str(pg_hd) = (void *) STRUCT_NEXT(STR)) == NULL) \
if ((Pg_free_pg(STR_PAGES) = PgHd_next(pg_hd)) != NULL) \ if ((Pg_free_pg(STR_PAGES) = PgHd_next(pg_hd)) != NULL) \
PgHd_previous(PgHd_next(pg_hd)) = NULL; \ PgHd_previous(PgHd_next(pg_hd)) = NULL; \
UPDATE_STATS(Pg_str_in_use(STR_PAGES), 1); \ UPDATE_STATS(Pg_str_in_use(STR_PAGES), 1); \
UNLOCK(Pg_lock(STR_PAGES)); \ UNLOCK(Pg_lock(STR_PAGES)); \
} }
#define ALLOC_NEXT_FREE_STRUCT(STR, STR_PAGES, STR_TYPE) \ #define ALLOC_NEXT_FREE_STRUCT(STR, STR_PAGES, STR_TYPE) \
if ((STR = LOCAL_next_free_ans_node) == NULL) { \ if ((STR = LOCAL_next_free_ans_node) == NULL) { \
pg_hd_ptr pg_hd; \ pg_hd_ptr pg_hd; \
LOCK(Pg_lock(STR_PAGES)); \ LOCK(Pg_lock(STR_PAGES)); \
pg_hd = Pg_free_pg(STR_PAGES); \ pg_hd = Pg_free_pg(STR_PAGES); \
while (pg_hd == NULL) { \ while (pg_hd == NULL) { \
UNLOCK(Pg_lock(STR_PAGES)); \ UNLOCK(Pg_lock(STR_PAGES)); \
LOCK(Pg_lock(GLOBAL_PAGES_void)); \ LOCK(Pg_lock(GLOBAL_PAGES_void)); \
if (Pg_free_pg(GLOBAL_PAGES_void)) { \ if (Pg_free_pg(GLOBAL_PAGES_void)) { \
pg_hd = Pg_free_pg(GLOBAL_PAGES_void); \ pg_hd = Pg_free_pg(GLOBAL_PAGES_void); \
Pg_free_pg(GLOBAL_PAGES_void) = PgHd_next(pg_hd); \ Pg_free_pg(GLOBAL_PAGES_void) = PgHd_next(pg_hd); \
UPDATE_STATS(Pg_str_in_use(GLOBAL_PAGES_void), 1); \ UPDATE_STATS(Pg_str_in_use(GLOBAL_PAGES_void), 1); \
UNLOCK(Pg_lock(GLOBAL_PAGES_void)); \ UNLOCK(Pg_lock(GLOBAL_PAGES_void)); \
INIT_PAGE(pg_hd, STR_PAGES, STR_TYPE); \ INIT_PAGE(pg_hd, STR_PAGES, STR_TYPE); \
} else if (GLOBAL_MAX_PAGES != Pg_pg_alloc(GLOBAL_PAGES_void)) { \ } else if (GLOBAL_MAX_PAGES != Pg_pg_alloc(GLOBAL_PAGES_void)) { \
ALLOC_PAGE(pg_hd); \ ALLOC_PAGE(pg_hd); \
UPDATE_STATS(Pg_str_in_use(GLOBAL_PAGES_void), 1); \ UPDATE_STATS(Pg_str_in_use(GLOBAL_PAGES_void), 1); \
UNLOCK(Pg_lock(GLOBAL_PAGES_void)); \ UNLOCK(Pg_lock(GLOBAL_PAGES_void)); \
INIT_PAGE(pg_hd, STR_PAGES, STR_TYPE); \ INIT_PAGE(pg_hd, STR_PAGES, STR_TYPE); \
} else { \ } else { \
UNLOCK(Pg_lock(GLOBAL_PAGES_void)); \ UNLOCK(Pg_lock(GLOBAL_PAGES_void)); \
RECOVER_UNUSED_SPACE(STR_PAGES); \ RECOVER_UNUSED_SPACE(STR_PAGES); \
LOCK(Pg_lock(STR_PAGES)); \ LOCK(Pg_lock(STR_PAGES)); \
pg_hd = Pg_free_pg(STR_PAGES); \ pg_hd = Pg_free_pg(STR_PAGES); \
} \ } \
} \ } \
PgHd_str_in_use(pg_hd) = Pg_str_per_pg(STR_PAGES); \ PgHd_str_in_use(pg_hd) = Pg_str_per_pg(STR_PAGES); \
STR = (STR_TYPE *) PgHd_free_str(pg_hd); \ STR = (STR_TYPE *) PgHd_free_str(pg_hd); \
PgHd_free_str(pg_hd) = NULL; \ PgHd_free_str(pg_hd) = NULL; \
Pg_free_pg(STR_PAGES) = PgHd_next(pg_hd); \ Pg_free_pg(STR_PAGES) = PgHd_next(pg_hd); \
UPDATE_STATS(Pg_str_in_use(STR_PAGES), -PgHd_str_in_use(pg_hd)); \ UPDATE_STATS(Pg_str_in_use(STR_PAGES), -PgHd_str_in_use(pg_hd)); \
UPDATE_STATS(Pg_str_in_use(STR_PAGES), Pg_str_per_pg(STR_PAGES)); \ UPDATE_STATS(Pg_str_in_use(STR_PAGES), Pg_str_per_pg(STR_PAGES)); \
UNLOCK(Pg_lock(STR_PAGES)); \ UNLOCK(Pg_lock(STR_PAGES)); \
} \ } \
LOCAL_next_free_ans_node = STRUCT_NEXT(STR) LOCAL_next_free_ans_node = STRUCT_NEXT(STR)
#else #else
#define ALLOC_PAGE(PG_HD) \ #define ALLOC_PAGE(PG_HD) \
LOCK(Pg_lock(GLOBAL_PAGES_void)); \ LOCK(Pg_lock(GLOBAL_PAGES_void)); \
if (Pg_free_pg(GLOBAL_PAGES_void) == NULL) { \ if (Pg_free_pg(GLOBAL_PAGES_void) == NULL) { \
int i, shmid; \ int i, shmid; \
pg_hd_ptr pg_hd, aux_pg_hd; \ pg_hd_ptr pg_hd, aux_pg_hd; \
if ((shmid = shmget(IPC_PRIVATE, SHMMAX, SHM_R|SHM_W)) == -1) \ if ((shmid = shmget(IPC_PRIVATE, SHMMAX, SHM_R|SHM_W)) == -1) \
Yap_Error(FATAL_ERROR, TermNil, "shmget error (ALLOC_PAGE)"); \ Yap_Error(FATAL_ERROR, TermNil, "shmget error (ALLOC_PAGE)"); \
if ((pg_hd = (pg_hd_ptr) shmat(shmid, NULL, 0)) == (void *) -1) \ if ((pg_hd = (pg_hd_ptr) shmat(shmid, NULL, 0)) == (void *) -1) \
Yap_Error(FATAL_ERROR, TermNil, "shmat error (ALLOC_PAGE)"); \ Yap_Error(FATAL_ERROR, TermNil, "shmat error (ALLOC_PAGE)"); \
if (shmctl(shmid, IPC_RMID, 0) != 0) \ if (shmctl(shmid, IPC_RMID, 0) != 0) \
Yap_Error(FATAL_ERROR, TermNil, "shmctl error (ALLOC_PAGE)"); \ Yap_Error(FATAL_ERROR, TermNil, "shmctl error (ALLOC_PAGE)"); \
Pg_free_pg(GLOBAL_PAGES_void) = pg_hd; \ Pg_free_pg(GLOBAL_PAGES_void) = pg_hd; \
for (i = 1; i < SHMMAX / Yap_page_size; i++) { \ for (i = 1; i < SHMMAX / Yap_page_size; i++) { \
aux_pg_hd = (pg_hd_ptr)(((void *)pg_hd) + Yap_page_size); \ aux_pg_hd = (pg_hd_ptr)(((void *)pg_hd) + Yap_page_size); \
PgHd_next(pg_hd) = aux_pg_hd; \ PgHd_next(pg_hd) = aux_pg_hd; \
pg_hd = aux_pg_hd; \ pg_hd = aux_pg_hd; \
} \ } \
PgHd_next(pg_hd) = NULL; \ PgHd_next(pg_hd) = NULL; \
UPDATE_STATS(Pg_pg_alloc(GLOBAL_PAGES_void), SHMMAX / Yap_page_size); \ UPDATE_STATS(Pg_pg_alloc(GLOBAL_PAGES_void), SHMMAX / Yap_page_size); \
} \ } \
UPDATE_STATS(Pg_str_in_use(GLOBAL_PAGES_void), 1); \ UPDATE_STATS(Pg_str_in_use(GLOBAL_PAGES_void), 1); \
PG_HD = Pg_free_pg(GLOBAL_PAGES_void); \ PG_HD = Pg_free_pg(GLOBAL_PAGES_void); \
Pg_free_pg(GLOBAL_PAGES_void) = PgHd_next(PG_HD); \ Pg_free_pg(GLOBAL_PAGES_void) = PgHd_next(PG_HD); \
UNLOCK(Pg_lock(GLOBAL_PAGES_void)) UNLOCK(Pg_lock(GLOBAL_PAGES_void))
#define ALLOC_STRUCT(STR, STR_PAGES, STR_TYPE) \ #define ALLOC_STRUCT(STR, STR_PAGES, STR_TYPE) \
{ pg_hd_ptr pg_hd; \ { pg_hd_ptr pg_hd; \
LOCK(Pg_lock(STR_PAGES)); \ LOCK(Pg_lock(STR_PAGES)); \
UPDATE_STATS(Pg_str_in_use(STR_PAGES), 1); \ UPDATE_STATS(Pg_str_in_use(STR_PAGES), 1); \
if (Pg_free_pg(STR_PAGES)) { \ if (Pg_free_pg(STR_PAGES)) { \
pg_hd = Pg_free_pg(STR_PAGES); \ pg_hd = Pg_free_pg(STR_PAGES); \
PgHd_str_in_use(pg_hd)++; \ PgHd_str_in_use(pg_hd)++; \
STR = (STR_TYPE *) PgHd_free_str(pg_hd); \ STR = (STR_TYPE *) PgHd_free_str(pg_hd); \
if ((PgHd_free_str(pg_hd) = (void *) STRUCT_NEXT(STR)) == NULL) \ if ((PgHd_free_str(pg_hd) = (void *) STRUCT_NEXT(STR)) == NULL) \
if ((Pg_free_pg(STR_PAGES) = PgHd_next(pg_hd)) != NULL) \ if ((Pg_free_pg(STR_PAGES) = PgHd_next(pg_hd)) != NULL) \
PgHd_previous(PgHd_next(pg_hd)) = NULL; \ PgHd_previous(PgHd_next(pg_hd)) = NULL; \
UNLOCK(Pg_lock(STR_PAGES)); \ UNLOCK(Pg_lock(STR_PAGES)); \
} else { \ } else { \
int i; \ int i; \
UPDATE_STATS(Pg_pg_alloc(STR_PAGES), 1); \ UPDATE_STATS(Pg_pg_alloc(STR_PAGES), 1); \
UNLOCK(Pg_lock(STR_PAGES)); \ UNLOCK(Pg_lock(STR_PAGES)); \
ALLOC_PAGE(pg_hd); \ ALLOC_PAGE(pg_hd); \
PgHd_str_in_use(pg_hd) = 1; \ PgHd_str_in_use(pg_hd) = 1; \
PgHd_previous(pg_hd) = NULL; \ PgHd_previous(pg_hd) = NULL; \
STR = (STR_TYPE *) (pg_hd + 1); \ STR = (STR_TYPE *) (pg_hd + 1); \
PgHd_free_str(pg_hd) = (void *) ++STR; \ PgHd_free_str(pg_hd) = (void *) ++STR; \
for (i = Pg_str_per_pg(STR_PAGES); i != 2; i--) { \ for (i = Pg_str_per_pg(STR_PAGES); i != 2; i--) { \
STRUCT_NEXT(STR) = STR + 1; \ STRUCT_NEXT(STR) = STR + 1; \
STR++; \ STR++; \
} \ } \
STRUCT_NEXT(STR) = NULL; \ STRUCT_NEXT(STR) = NULL; \
STR = (STR_TYPE *) (pg_hd + 1); \ STR = (STR_TYPE *) (pg_hd + 1); \
LOCK(Pg_lock(STR_PAGES)); \ LOCK(Pg_lock(STR_PAGES)); \
if ((PgHd_next(pg_hd) = Pg_free_pg(STR_PAGES)) != NULL) \ if ((PgHd_next(pg_hd) = Pg_free_pg(STR_PAGES)) != NULL) \
PgHd_previous(PgHd_next(pg_hd)) = pg_hd; \ PgHd_previous(PgHd_next(pg_hd)) = pg_hd; \
Pg_free_pg(STR_PAGES) = pg_hd; \ Pg_free_pg(STR_PAGES) = pg_hd; \
UNLOCK(Pg_lock(STR_PAGES)); \ UNLOCK(Pg_lock(STR_PAGES)); \
} \ } \
} }
#define ALLOC_NEXT_FREE_STRUCT(STR, STR_PAGES, STR_TYPE) \ #define ALLOC_NEXT_FREE_STRUCT(STR, STR_PAGES, STR_TYPE) \
if ((STR = LOCAL_next_free_ans_node) == NULL) { \ if ((STR = LOCAL_next_free_ans_node) == NULL) { \
pg_hd_ptr pg_hd; \ pg_hd_ptr pg_hd; \
LOCK(Pg_lock(STR_PAGES)); \ LOCK(Pg_lock(STR_PAGES)); \
UPDATE_STATS(Pg_str_in_use(STR_PAGES), Pg_str_per_pg(STR_PAGES)); \ UPDATE_STATS(Pg_str_in_use(STR_PAGES), Pg_str_per_pg(STR_PAGES)); \
if (Pg_free_pg(STR_PAGES)) { \ if (Pg_free_pg(STR_PAGES)) { \
pg_hd = Pg_free_pg(STR_PAGES); \ pg_hd = Pg_free_pg(STR_PAGES); \
UPDATE_STATS(Pg_str_in_use(STR_PAGES), -PgHd_str_in_use(pg_hd)); \ UPDATE_STATS(Pg_str_in_use(STR_PAGES), -PgHd_str_in_use(pg_hd)); \
PgHd_str_in_use(pg_hd) = Pg_str_per_pg(STR_PAGES); \ PgHd_str_in_use(pg_hd) = Pg_str_per_pg(STR_PAGES); \
STR = (STR_TYPE *) PgHd_free_str(pg_hd); \ STR = (STR_TYPE *) PgHd_free_str(pg_hd); \
PgHd_free_str(pg_hd) = NULL; \ PgHd_free_str(pg_hd) = NULL; \
Pg_free_pg(STR_PAGES) = PgHd_next(pg_hd); \ Pg_free_pg(STR_PAGES) = PgHd_next(pg_hd); \
UNLOCK(Pg_lock(STR_PAGES)); \ UNLOCK(Pg_lock(STR_PAGES)); \
} else { \ } else { \
int i; \ int i; \
UPDATE_STATS(Pg_pg_alloc(STR_PAGES), 1); \ UPDATE_STATS(Pg_pg_alloc(STR_PAGES), 1); \
UNLOCK(Pg_lock(STR_PAGES)); \ UNLOCK(Pg_lock(STR_PAGES)); \
ALLOC_PAGE(pg_hd); \ ALLOC_PAGE(pg_hd); \
PgHd_str_in_use(pg_hd) = Pg_str_per_pg(STR_PAGES); \ PgHd_str_in_use(pg_hd) = Pg_str_per_pg(STR_PAGES); \
PgHd_free_str(pg_hd) = NULL; \ PgHd_free_str(pg_hd) = NULL; \
PgHd_previous(pg_hd) = NULL; \ PgHd_previous(pg_hd) = NULL; \
PgHd_next(pg_hd) = NULL; \ PgHd_next(pg_hd) = NULL; \
STR = (STR_TYPE *) (pg_hd + 1); \ STR = (STR_TYPE *) (pg_hd + 1); \
for (i = Pg_str_per_pg(STR_PAGES); i != 1; i--) { \ for (i = Pg_str_per_pg(STR_PAGES); i != 1; i--) { \
STRUCT_NEXT(STR) = STR + 1; \ STRUCT_NEXT(STR) = STR + 1; \
STR++; \ STR++; \
} \ } \
STRUCT_NEXT(STR) = NULL; \ STRUCT_NEXT(STR) = NULL; \
STR = (STR_TYPE *) (pg_hd + 1); \ STR = (STR_TYPE *) (pg_hd + 1); \
} \ } \
} \ } \
LOCAL_next_free_ans_node = STRUCT_NEXT(STR) LOCAL_next_free_ans_node = STRUCT_NEXT(STR)
#endif /* LIMIT_TABLING */ #endif /* LIMIT_TABLING */
#define FREE_PAGE(PG_HD) \ #define FREE_PAGE(PG_HD) \
LOCK(Pg_lock(GLOBAL_PAGES_void)); \ LOCK(Pg_lock(GLOBAL_PAGES_void)); \
UPDATE_STATS(Pg_str_in_use(GLOBAL_PAGES_void), -1); \ UPDATE_STATS(Pg_str_in_use(GLOBAL_PAGES_void), -1); \
PgHd_next(PG_HD) = Pg_free_pg(GLOBAL_PAGES_void); \ PgHd_next(PG_HD) = Pg_free_pg(GLOBAL_PAGES_void); \
Pg_free_pg(GLOBAL_PAGES_void) = PG_HD; \ Pg_free_pg(GLOBAL_PAGES_void) = PG_HD; \
UNLOCK(Pg_lock(GLOBAL_PAGES_void)) UNLOCK(Pg_lock(GLOBAL_PAGES_void))
#define FREE_STRUCT(STR, STR_PAGES, STR_TYPE) \ #define FREE_STRUCT(STR, STR_PAGES, STR_TYPE) \
{ pg_hd_ptr pg_hd; \ { pg_hd_ptr pg_hd; \
pg_hd = PAGE_HEADER(STR); \ pg_hd = PAGE_HEADER(STR); \
LOCK(Pg_lock(STR_PAGES)); \ LOCK(Pg_lock(STR_PAGES)); \
UPDATE_STATS(Pg_str_in_use(STR_PAGES), -1); \ UPDATE_STATS(Pg_str_in_use(STR_PAGES), -1); \
if (--PgHd_str_in_use(pg_hd) == 0) { \ if (--PgHd_str_in_use(pg_hd) == 0) { \
UPDATE_STATS(Pg_pg_alloc(STR_PAGES), -1); \ UPDATE_STATS(Pg_pg_alloc(STR_PAGES), -1); \
if (PgHd_previous(pg_hd)) { \ if (PgHd_previous(pg_hd)) { \
if ((PgHd_next(PgHd_previous(pg_hd)) = PgHd_next(pg_hd)) != NULL) \ if ((PgHd_next(PgHd_previous(pg_hd)) = PgHd_next(pg_hd)) != NULL) \
PgHd_previous(PgHd_next(pg_hd)) = PgHd_previous(pg_hd); \ PgHd_previous(PgHd_next(pg_hd)) = PgHd_previous(pg_hd); \
} else { \ } else { \
if ((Pg_free_pg(STR_PAGES) = PgHd_next(pg_hd)) != NULL) \ if ((Pg_free_pg(STR_PAGES) = PgHd_next(pg_hd)) != NULL) \
PgHd_previous(PgHd_next(pg_hd)) = NULL; \ PgHd_previous(PgHd_next(pg_hd)) = NULL; \
} \ } \
UNLOCK(Pg_lock(STR_PAGES)); \ UNLOCK(Pg_lock(STR_PAGES)); \
FREE_PAGE(pg_hd); \ FREE_PAGE(pg_hd); \
} else { \ } else { \
if ((STRUCT_NEXT(STR) = (STR_TYPE *) PgHd_free_str(pg_hd)) == NULL) { \ if ((STRUCT_NEXT(STR) = (STR_TYPE *) PgHd_free_str(pg_hd)) == NULL) { \
PgHd_previous(pg_hd) = NULL; \ PgHd_previous(pg_hd) = NULL; \
if ((PgHd_next(pg_hd) = Pg_free_pg(STR_PAGES)) != NULL) \ if ((PgHd_next(pg_hd) = Pg_free_pg(STR_PAGES)) != NULL) \
PgHd_previous(PgHd_next(pg_hd)) = pg_hd; \ PgHd_previous(PgHd_next(pg_hd)) = pg_hd; \
Pg_free_pg(STR_PAGES) = pg_hd; \ Pg_free_pg(STR_PAGES) = pg_hd; \
} \ } \
PgHd_free_str(pg_hd) = (void *) STR; \ PgHd_free_str(pg_hd) = (void *) STR; \
UNLOCK(Pg_lock(STR_PAGES)); \ UNLOCK(Pg_lock(STR_PAGES)); \
} \ } \
} }
#endif /* --------------------------- MEMORY_ALLOC_SCHEME ---------------------------- */ #endif /* --------------------------- MEMORY_ALLOC_SCHEME -------------------------------------------- */
#ifdef YAPOR #ifdef YAPOR
#define ALLOC_BLOCK(BLOCK, SIZE) \ #define ALLOC_BLOCK(BLOCK, SIZE) \
if ((BLOCK = (void *) Yap_AllocCodeSpace(SIZE)) == NULL) \ if ((BLOCK = (void *) Yap_AllocCodeSpace(SIZE)) == NULL) \
Yap_Error(FATAL_ERROR, TermNil, "Yap_AllocCodeSpace error (ALLOC_BLOCK)") Yap_Error(FATAL_ERROR, TermNil, "Yap_AllocCodeSpace error (ALLOC_BLOCK)")
#define FREE_BLOCK(BLOCK) \ #define FREE_BLOCK(BLOCK) \
Yap_FreeCodeSpace((char *) (BLOCK)) Yap_FreeCodeSpace((char *) (BLOCK))
#else /* TABLING */ #else /* TABLING */
#define ALLOC_BLOCK(BLOCK, SIZE) \ #define ALLOC_BLOCK(BLOCK, SIZE) \
if ((BLOCK = malloc(SIZE)) == NULL) \ if ((BLOCK = malloc(SIZE)) == NULL) \
Yap_Error(FATAL_ERROR, TermNil, "malloc error (ALLOC_BLOCK)") Yap_Error(FATAL_ERROR, TermNil, "malloc error (ALLOC_BLOCK)")
#define FREE_BLOCK(BLOCK) \ #define FREE_BLOCK(BLOCK) \
free(BLOCK) free(BLOCK)
#endif /* YAPOR - TABLING */ #endif /* YAPOR - TABLING */
#define ALLOC_HASH_BUCKETS(BUCKET_PTR, NUM_BUCKETS) \ #define ALLOC_HASH_BUCKETS(BUCKET_PTR, NUM_BUCKETS) \
{ int i; void **ptr; \ { int i; void **ptr; \
ALLOC_BLOCK(ptr, NUM_BUCKETS * sizeof(void *)); \ ALLOC_BLOCK(ptr, NUM_BUCKETS * sizeof(void *)); \
BUCKET_PTR = (void *) ptr; \ BUCKET_PTR = (void *) ptr; \
for (i = NUM_BUCKETS; i != 0; i--) \ for (i = NUM_BUCKETS; i != 0; i--) \
*ptr++ = NULL; \ *ptr++ = NULL; \
} }
#define FREE_HASH_BUCKETS(BUCKET_PTR) FREE_BLOCK(BUCKET_PTR) #define FREE_HASH_BUCKETS(BUCKET_PTR) FREE_BLOCK(BUCKET_PTR)

View File

@ -684,7 +684,7 @@ Int p_abolish_table(void) {
sg_node = TrNode_child(TabEnt_subgoal_trie(tab_ent)); sg_node = TrNode_child(TabEnt_subgoal_trie(tab_ent));
if (sg_node) { if (sg_node) {
TrNode_child(TabEnt_subgoal_trie(tab_ent)) = NULL; TrNode_child(TabEnt_subgoal_trie(tab_ent)) = NULL;
free_subgoal_trie_branch(sg_node, TabEnt_arity(tab_ent), 0); free_subgoal_trie_branch(sg_node, TabEnt_arity(tab_ent), 0, TRAVERSE_POSITION_FIRST);
} }
return (TRUE); return (TRUE);
} }
@ -704,7 +704,7 @@ Int p_abolish_all_tables(void) {
sg_node = TrNode_child(TabEnt_subgoal_trie(tab_ent)); sg_node = TrNode_child(TabEnt_subgoal_trie(tab_ent));
if (sg_node) { if (sg_node) {
TrNode_child(TabEnt_subgoal_trie(tab_ent)) = NULL; TrNode_child(TabEnt_subgoal_trie(tab_ent)) = NULL;
free_subgoal_trie_branch(sg_node, TabEnt_arity(tab_ent), 0); free_subgoal_trie_branch(sg_node, TabEnt_arity(tab_ent), 0, TRAVERSE_POSITION_FIRST);
} }
tab_ent = TabEnt_next(tab_ent); tab_ent = TabEnt_next(tab_ent);
} }

View File

@ -67,8 +67,8 @@ sg_fr_ptr subgoal_search(yamop *preg, CELL **Yaddr);
ans_node_ptr answer_search(sg_fr_ptr sg_fr, CELL *subs_ptr); 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 load_answer_trie(ans_node_ptr ans_node, CELL *subs_ptr);
void private_completion(sg_fr_ptr sg_fr); void private_completion(sg_fr_ptr sg_fr);
void free_subgoal_trie_branch(sg_node_ptr node, int nodes_left, int nodes_extra); void free_subgoal_trie_branch(sg_node_ptr node, int nodes_left, int nodes_extra, int position);
void free_answer_trie_branch(ans_node_ptr node); void free_answer_trie_branch(ans_node_ptr node, int position);
void update_answer_trie(sg_fr_ptr sg_fr); void update_answer_trie(sg_fr_ptr sg_fr);
void traverse_table(tab_ent_ptr tab_ent, int show_table); void traverse_table(tab_ent_ptr tab_ent, int show_table);
void table_stats(void); void table_stats(void);

View File

@ -57,6 +57,23 @@ STD_PROTO(static inline tg_sol_fr_ptr CUT_prune_tg_solution_frames, (tg_sol_fr_p
/* ----------------- **
** Defines **
** ----------------- */
#define TRAVERSE_MODE_NORMAL 0
#define TRAVERSE_MODE_FLOAT 1
#define TRAVERSE_MODE_FLOAT2 2
#define TRAVERSE_MODE_FLOAT_END 3
#define TRAVERSE_MODE_LONG 4
#define TRAVERSE_MODE_LONG_END 5
/* do not change order !!! */
#define TRAVERSE_POSITION_NEXT 0
#define TRAVERSE_POSITION_FIRST 1
#define TRAVERSE_POSITION_LAST 2
/* ----------------------- ** /* ----------------------- **
** Tabling Macros ** ** Tabling Macros **
** ----------------------- */ ** ----------------------- */
@ -609,7 +626,7 @@ void abolish_incomplete_subgoals(choiceptr prune_cp) {
node = TrNode_child(SgFr_answer_trie(sg_fr)); node = TrNode_child(SgFr_answer_trie(sg_fr));
TrNode_child(SgFr_answer_trie(sg_fr)) = NULL; TrNode_child(SgFr_answer_trie(sg_fr)) = NULL;
UNLOCK(SgFr_lock(sg_fr)); UNLOCK(SgFr_lock(sg_fr));
free_answer_trie_branch(node); free_answer_trie_branch(node, TRAVERSE_POSITION_FIRST);
#endif /* INCOMPLETE_TABLING */ #endif /* INCOMPLETE_TABLING */
} }
#ifdef LIMIT_TABLING #ifdef LIMIT_TABLING

View File

@ -25,19 +25,6 @@
#include "tab.macros.h" #include "tab.macros.h"
/* ----------------- **
** Defines **
** ----------------- */
#define TRAVERSE_NORMAL 0
#define TRAVERSE_FLOAT 1
#define TRAVERSE_FLOAT2 2
#define TRAVERSE_FLOAT_END 3
#define TRAVERSE_LONG 4
#define TRAVERSE_LONG_END 5
/* ------------------------------------- ** /* ------------------------------------- **
** Local functions declaration ** ** Local functions declaration **
** ------------------------------------- */ ** ------------------------------------- */
@ -49,10 +36,10 @@ static int update_answer_trie_branch(ans_node_ptr previous_node, ans_node_ptr no
static int update_answer_trie_branch(ans_node_ptr node); static int update_answer_trie_branch(ans_node_ptr node);
#endif /* TABLING_INNER_CUTS */ #endif /* TABLING_INNER_CUTS */
#else #else
static void update_answer_trie_branch(ans_node_ptr node); static void update_answer_trie_branch(ans_node_ptr node, int position);
#endif /* YAPOR */ #endif /* YAPOR */
static void traverse_subgoal_trie(sg_node_ptr sg_node, char *str, int str_index, int *arity, int depth, int mode); static void traverse_subgoal_trie(sg_node_ptr sg_node, char *str, int str_index, int *arity, int depth, int mode, int position);
static void traverse_answer_trie(ans_node_ptr ans_node, char *str, int str_index, int *arity, int var_index, int depth, int mode); static void traverse_answer_trie(ans_node_ptr ans_node, char *str, int str_index, int *arity, int var_index, int depth, int mode, int position);
@ -1104,9 +1091,14 @@ void private_completion(sg_fr_ptr sg_fr) {
} }
void free_subgoal_trie_branch(sg_node_ptr node, int nodes_left, int nodes_extra) { void free_subgoal_trie_branch(sg_node_ptr node, int nodes_left, int nodes_extra, int position) {
if (TrNode_next(node)) int current_nodes_left = 0, current_nodes_extra = 0;
free_subgoal_trie_branch(TrNode_next(node), nodes_left, nodes_extra);
/* save current state if first sibling node */
if (position == TRAVERSE_POSITION_FIRST) {
current_nodes_left = nodes_left;
current_nodes_extra = nodes_extra;
}
if (nodes_extra) { if (nodes_extra) {
#ifdef TRIE_COMPACT_PAIRS #ifdef TRIE_COMPACT_PAIRS
@ -1148,7 +1140,7 @@ void free_subgoal_trie_branch(sg_node_ptr node, int nodes_left, int nodes_extra)
} }
} }
if (nodes_left) if (nodes_left)
free_subgoal_trie_branch(TrNode_child(node), nodes_left, nodes_extra); free_subgoal_trie_branch(TrNode_child(node), nodes_left, nodes_extra, TRAVERSE_POSITION_FIRST);
else { else {
sg_fr_ptr sg_fr; sg_fr_ptr sg_fr;
ans_node_ptr ans_node; ans_node_ptr ans_node;
@ -1156,7 +1148,7 @@ void free_subgoal_trie_branch(sg_node_ptr node, int nodes_left, int nodes_extra)
free_answer_hash_chain(SgFr_hash_chain(sg_fr)); free_answer_hash_chain(SgFr_hash_chain(sg_fr));
ans_node = SgFr_answer_trie(sg_fr); ans_node = SgFr_answer_trie(sg_fr);
if (TrNode_child(ans_node)) if (TrNode_child(ans_node))
free_answer_trie_branch(TrNode_child(ans_node)); free_answer_trie_branch(TrNode_child(ans_node), TRAVERSE_POSITION_FIRST);
FREE_ANSWER_TRIE_NODE(ans_node); FREE_ANSWER_TRIE_NODE(ans_node);
#ifdef LIMIT_TABLING #ifdef LIMIT_TABLING
remove_from_global_sg_fr_list(sg_fr); remove_from_global_sg_fr_list(sg_fr);
@ -1164,21 +1156,41 @@ void free_subgoal_trie_branch(sg_node_ptr node, int nodes_left, int nodes_extra)
FREE_SUBGOAL_FRAME(sg_fr); FREE_SUBGOAL_FRAME(sg_fr);
} }
FREE_SUBGOAL_TRIE_NODE(node); if (position == TRAVERSE_POSITION_FIRST) {
sg_node_ptr next = TrNode_next(node);
FREE_SUBGOAL_TRIE_NODE(node);
/* restore the initial state */
nodes_left = current_nodes_left;
nodes_extra = current_nodes_extra;
while (next) {
node = next;
next = TrNode_next(node);
free_subgoal_trie_branch(node, nodes_left, nodes_extra, TRAVERSE_POSITION_NEXT);
}
} else
FREE_SUBGOAL_TRIE_NODE(node);
return; return;
} }
void free_answer_trie_branch(ans_node_ptr node) { void free_answer_trie_branch(ans_node_ptr node, int position) {
#ifdef TABLING_INNER_CUTS #ifdef TABLING_INNER_CUTS
if (TrNode_child(node) && ! IS_ANSWER_LEAF_NODE(node)) if (TrNode_child(node) && ! IS_ANSWER_LEAF_NODE(node))
#else #else
if (! IS_ANSWER_LEAF_NODE(node)) if (! IS_ANSWER_LEAF_NODE(node))
#endif /* TABLING_INNER_CUTS */ #endif /* TABLING_INNER_CUTS */
free_answer_trie_branch(TrNode_child(node)); free_answer_trie_branch(TrNode_child(node), TRAVERSE_POSITION_FIRST);
if (TrNode_next(node))
free_answer_trie_branch(TrNode_next(node)); if (position == TRAVERSE_POSITION_FIRST) {
FREE_ANSWER_TRIE_NODE(node); ans_node_ptr next = TrNode_next(node);
FREE_ANSWER_TRIE_NODE(node);
while (next) {
node = next;
next = TrNode_next(node);
free_answer_trie_branch(node, TRAVERSE_POSITION_NEXT);
}
} else
FREE_ANSWER_TRIE_NODE(node);
return; return;
} }
@ -1188,16 +1200,20 @@ void update_answer_trie(sg_fr_ptr sg_fr) {
free_answer_hash_chain(SgFr_hash_chain(sg_fr)); free_answer_hash_chain(SgFr_hash_chain(sg_fr));
SgFr_hash_chain(sg_fr) = NULL; SgFr_hash_chain(sg_fr) = NULL;
SgFr_state(sg_fr) += 2; /* complete --> compiled : complete_in_use --> compiled_in_use */
node = TrNode_child(SgFr_answer_trie(sg_fr)); node = TrNode_child(SgFr_answer_trie(sg_fr));
if (node) { if (node) {
#ifdef YAPOR
TrNode_instr(node) -= 1; TrNode_instr(node) -= 1;
#ifdef TABLING_INNER_CUTS #ifdef TABLING_INNER_CUTS
update_answer_trie_branch(NULL, node); update_answer_trie_branch(NULL, node);
#else #else
update_answer_trie_branch(node); update_answer_trie_branch(node);
#endif /* TABLING_INNER_CUTS */ #endif /* TABLING_INNER_CUTS */
#else /* TABLING */
update_answer_trie_branch(node, TRAVERSE_POSITION_FIRST);
#endif /* YAPOR */
} }
SgFr_state(sg_fr) += 2; /* complete --> compiled : complete_in_use --> compiled_in_use */
return; return;
} }
@ -1265,7 +1281,7 @@ void traverse_table(tab_ent_ptr tab_ent, int show_table) {
int *arity = (int *) malloc(sizeof(int) * ARITY_ARRAY_SIZE); int *arity = (int *) malloc(sizeof(int) * ARITY_ARRAY_SIZE);
arity[0] = 1; arity[0] = 1;
arity[1] = TabEnt_arity(tab_ent); arity[1] = TabEnt_arity(tab_ent);
traverse_subgoal_trie(sg_node, str, str_index, arity, 1, TRAVERSE_NORMAL); traverse_subgoal_trie(sg_node, str, str_index, arity, 1, TRAVERSE_MODE_NORMAL, TRAVERSE_POSITION_FIRST);
free(str); free(str);
free(arity); free(arity);
} else { } else {
@ -1399,39 +1415,43 @@ int update_answer_trie_branch(ans_node_ptr node) {
#endif /* TABLING_INNER_CUTS */ #endif /* TABLING_INNER_CUTS */
#else /* TABLING */ #else /* TABLING */
static static
void update_answer_trie_branch(ans_node_ptr node) { void update_answer_trie_branch(ans_node_ptr node, int position) {
if (! IS_ANSWER_LEAF_NODE(node)) { if (! IS_ANSWER_LEAF_NODE(node))
TrNode_instr(TrNode_child(node)) -= 1; /* retry --> try */ update_answer_trie_branch(TrNode_child(node), TRAVERSE_POSITION_FIRST); /* retry --> try */
update_answer_trie_branch(TrNode_child(node)); if (position == TRAVERSE_POSITION_FIRST) {
ans_node_ptr next = TrNode_next(node);
if (next) {
while (TrNode_next(next)) {
update_answer_trie_branch(next, TRAVERSE_POSITION_NEXT); /* retry --> retry */
next = TrNode_next(next);
}
update_answer_trie_branch(next, TRAVERSE_POSITION_LAST); /* retry --> trust */
} else
position += TRAVERSE_POSITION_LAST; /* try --> do */
} }
if (TrNode_next(node)) { TrNode_instr(node) = Yap_opcode(TrNode_instr(node) - position);
update_answer_trie_branch(TrNode_next(node));
} else {
TrNode_instr(node) -= 2; /* retry --> trust : try --> do */
}
TrNode_instr(node) = Yap_opcode(TrNode_instr(node));
return; return;
} }
#endif /* YAPOR */ #endif /* YAPOR */
static static
void traverse_subgoal_trie(sg_node_ptr sg_node, char *str, int str_index, int *arity, int depth, int mode) { void traverse_subgoal_trie(sg_node_ptr sg_node, char *str, int str_index, int *arity, int depth, int mode, int position) {
int *current_arity = NULL, current_str_index = 0, current_mode = 0;
Term t; Term t;
/* test if hashing */ /* test if hashing */
if (IS_SUBGOAL_HASH(sg_node)) { if (IS_SUBGOAL_HASH(sg_node)) {
sg_node_ptr *bucket, *last_bucket; sg_node_ptr *bucket, *last_bucket;
sg_hash_ptr hash; sg_hash_ptr hash;
int *current_arity = (int *) malloc(sizeof(int) * (arity[0] + 1));
memcpy(current_arity, arity, sizeof(int) * (arity[0] + 1));
hash = (sg_hash_ptr) sg_node; hash = (sg_hash_ptr) sg_node;
bucket = Hash_buckets(hash); bucket = Hash_buckets(hash);
last_bucket = bucket + Hash_num_buckets(hash); last_bucket = bucket + Hash_num_buckets(hash);
current_arity = (int *) malloc(sizeof(int) * (arity[0] + 1));
memcpy(current_arity, arity, sizeof(int) * (arity[0] + 1));
do { do {
if (*bucket) { if (*bucket) {
sg_node = *bucket; traverse_subgoal_trie(*bucket, str, str_index, arity, depth, mode, TRAVERSE_POSITION_FIRST);
traverse_subgoal_trie(sg_node, str, str_index, arity, depth, mode);
memcpy(arity, current_arity, sizeof(int) * (current_arity[0] + 1)); memcpy(arity, current_arity, sizeof(int) * (current_arity[0] + 1));
#ifdef TRIE_COMPACT_PAIRS #ifdef TRIE_COMPACT_PAIRS
if (arity[arity[0]] == -2 && str[str_index - 1] != '[') if (arity[arity[0]] == -2 && str[str_index - 1] != '[')
@ -1446,37 +1466,29 @@ void traverse_subgoal_trie(sg_node_ptr sg_node, char *str, int str_index, int *a
return; return;
} }
/* test if sibling node */ /* save current state if first sibling node */
if (TrNode_next(sg_node)) { if (position == TRAVERSE_POSITION_FIRST) {
int *current_arity = (int *) malloc(sizeof(int) * (arity[0] + 1)); current_arity = (int *) malloc(sizeof(int) * (arity[0] + 1));
memcpy(current_arity, arity, sizeof(int) * (arity[0] + 1)); memcpy(current_arity, arity, sizeof(int) * (arity[0] + 1));
traverse_subgoal_trie(TrNode_next(sg_node), str, str_index, arity, depth, mode); current_str_index = str_index;
memcpy(arity, current_arity, sizeof(int) * (current_arity[0] + 1)); current_mode = mode;
free(current_arity);
#ifdef TRIE_COMPACT_PAIRS
if (arity[arity[0]] == -2 && str[str_index - 1] != '[')
str[str_index - 1] = ',';
#else
if (arity[arity[0]] == -1)
str[str_index - 1] = '|';
#endif /* TRIE_COMPACT_PAIRS */
} }
/* test the node type */ /* test the node type */
t = TrNode_entry(sg_node); t = TrNode_entry(sg_node);
#if SIZEOF_DOUBLE == 2 * SIZEOF_INT_P #if SIZEOF_DOUBLE == 2 * SIZEOF_INT_P
if (mode == TRAVERSE_FLOAT) { if (mode == TRAVERSE_MODE_FLOAT) {
arity[0]++; arity[0]++;
arity[arity[0]] = (int) t; arity[arity[0]] = (int) t;
mode = TRAVERSE_FLOAT2; mode = TRAVERSE_MODE_FLOAT2;
} else if (mode == TRAVERSE_FLOAT2) { } else if (mode == TRAVERSE_MODE_FLOAT2) {
volatile Float dbl; volatile Float dbl;
volatile Term *t_dbl = (Term *)((void *) &dbl); volatile Term *t_dbl = (Term *)((void *) &dbl);
*t_dbl = t; *t_dbl = t;
*(t_dbl + 1) = (Term) arity[arity[0]]; *(t_dbl + 1) = (Term) arity[arity[0]];
arity[0]--; arity[0]--;
#else /* SIZEOF_DOUBLE == SIZEOF_INT_P */ #else /* SIZEOF_DOUBLE == SIZEOF_INT_P */
if (mode == TRAVERSE_FLOAT) { if (mode == TRAVERSE_MODE_FLOAT) {
volatile Float dbl; volatile Float dbl;
volatile Term *t_dbl = (Term *)((void *) &dbl); volatile Term *t_dbl = (Term *)((void *) &dbl);
*t_dbl = t; *t_dbl = t;
@ -1507,8 +1519,8 @@ void traverse_subgoal_trie(sg_node_ptr sg_node, char *str, int str_index, int *a
} }
} }
} }
mode = TRAVERSE_NORMAL; mode = TRAVERSE_MODE_NORMAL;
} else if (mode == TRAVERSE_LONG) { } else if (mode == TRAVERSE_MODE_LONG) {
Int li = (Int) t; Int li = (Int) t;
#if SHORT_INTS #if SHORT_INTS
str_index += sprintf(& str[str_index], "%ld", li); str_index += sprintf(& str[str_index], "%ld", li);
@ -1540,7 +1552,7 @@ void traverse_subgoal_trie(sg_node_ptr sg_node, char *str, int str_index, int *a
} }
} }
} }
mode = TRAVERSE_NORMAL; mode = TRAVERSE_MODE_NORMAL;
} else if (IsVarTerm(t)) { } else if (IsVarTerm(t)) {
#if SHORT_INTS #if SHORT_INTS
str_index += sprintf(& str[str_index], "VAR%ld", VarIndexOfTableTerm(t)); str_index += sprintf(& str[str_index], "VAR%ld", VarIndexOfTableTerm(t));
@ -1656,9 +1668,9 @@ void traverse_subgoal_trie(sg_node_ptr sg_node, char *str, int str_index, int *a
} else if (IsApplTerm(t)) { } else if (IsApplTerm(t)) {
Functor f = (Functor) RepAppl(t); Functor f = (Functor) RepAppl(t);
if (f == FunctorDouble) { if (f == FunctorDouble) {
mode = TRAVERSE_FLOAT; mode = TRAVERSE_MODE_FLOAT;
} else if (f == FunctorLongInt) { } else if (f == FunctorLongInt) {
mode = TRAVERSE_LONG; mode = TRAVERSE_MODE_LONG;
} else { } else {
str_index += sprintf(& str[str_index], "%s(", AtomName(NameOfFunctor(f))); str_index += sprintf(& str[str_index], "%s(", AtomName(NameOfFunctor(f)));
arity[0]++; arity[0]++;
@ -1702,39 +1714,59 @@ void traverse_subgoal_trie(sg_node_ptr sg_node, char *str, int str_index, int *a
SHOW_TABLE(" TRUE\n"); SHOW_TABLE(" TRUE\n");
} else { } else {
arity[0] = 0; arity[0] = 0;
traverse_answer_trie(TrNode_child(SgFr_answer_trie(sg_fr)), &str[str_index], 0, arity, 0, 1, TRAVERSE_NORMAL); traverse_answer_trie(TrNode_child(SgFr_answer_trie(sg_fr)), &str[str_index], 0, arity, 0, 1, TRAVERSE_MODE_NORMAL, TRAVERSE_POSITION_FIRST);
if (SgFr_state(sg_fr) < complete) { if (SgFr_state(sg_fr) < complete) {
TrStat_sg_incomplete++; TrStat_sg_incomplete++;
SHOW_TABLE(" ---> INCOMPLETE\n"); SHOW_TABLE(" ---> INCOMPLETE\n");
} }
} }
} }
/* ... or continue with child node */ /* ... or continue with child node */
else else
traverse_subgoal_trie(TrNode_child(sg_node), str, str_index, arity, depth + 1, mode); traverse_subgoal_trie(TrNode_child(sg_node), str, str_index, arity, depth + 1, mode, TRAVERSE_POSITION_FIRST);
/* continue iteratively with sibling nodes */
if (position == TRAVERSE_POSITION_FIRST) {
/* restore the initial state */
str_index = current_str_index;
mode = current_mode;
sg_node = TrNode_next(sg_node);
while (sg_node) {
memcpy(arity, current_arity, sizeof(int) * (current_arity[0] + 1));
#ifdef TRIE_COMPACT_PAIRS
if (arity[arity[0]] == -2 && str[str_index - 1] != '[')
str[str_index - 1] = ',';
#else
if (arity[arity[0]] == -1)
str[str_index - 1] = '|';
#endif /* TRIE_COMPACT_PAIRS */
traverse_subgoal_trie(sg_node, str, str_index, arity, depth, mode, TRAVERSE_POSITION_NEXT);
sg_node = TrNode_next(sg_node);
}
free(current_arity);
}
return; return;
} }
static static
void traverse_answer_trie(ans_node_ptr ans_node, char *str, int str_index, int *arity, int var_index, int depth, int mode) { void traverse_answer_trie(ans_node_ptr ans_node, char *str, int str_index, int *arity, int var_index, int depth, int mode, int position) {
int *current_arity = NULL, current_str_index = 0, current_var_index = 0, current_mode = 0;
Term t; Term t;
/* test if hashing */ /* test if hashing */
if (IS_ANSWER_HASH(ans_node)) { if (IS_ANSWER_HASH(ans_node)) {
ans_node_ptr *bucket, *last_bucket; ans_node_ptr *bucket, *last_bucket;
ans_hash_ptr hash; ans_hash_ptr hash;
int *current_arity = (int *) malloc(sizeof(int) * (arity[0] + 1));
memcpy(current_arity, arity, sizeof(int) * (arity[0] + 1));
hash = (ans_hash_ptr) ans_node; hash = (ans_hash_ptr) ans_node;
bucket = Hash_buckets(hash); bucket = Hash_buckets(hash);
last_bucket = bucket + Hash_num_buckets(hash); last_bucket = bucket + Hash_num_buckets(hash);
current_arity = (int *) malloc(sizeof(int) * (arity[0] + 1));
memcpy(current_arity, arity, sizeof(int) * (arity[0] + 1));
do { do {
if (*bucket) { if (*bucket) {
ans_node = *bucket; traverse_answer_trie(*bucket, str, str_index, arity, var_index, depth, mode, TRAVERSE_POSITION_FIRST);
traverse_answer_trie(ans_node, str, str_index, arity, var_index, depth, mode);
memcpy(arity, current_arity, sizeof(int) * (current_arity[0] + 1)); memcpy(arity, current_arity, sizeof(int) * (current_arity[0] + 1));
#ifdef TRIE_COMPACT_PAIRS #ifdef TRIE_COMPACT_PAIRS
if (arity[arity[0]] == -2 && str[str_index - 1] != '[') if (arity[arity[0]] == -2 && str[str_index - 1] != '[')
@ -1749,36 +1781,29 @@ void traverse_answer_trie(ans_node_ptr ans_node, char *str, int str_index, int *
return; return;
} }
/* test if sibling node */ /* save current state if first sibling node */
if (TrNode_next(ans_node)) { if (position == TRAVERSE_POSITION_FIRST) {
int *current_arity = (int *) malloc(sizeof(int) * (arity[0] + 1)); current_arity = (int *) malloc(sizeof(int) * (arity[0] + 1));
memcpy(current_arity, arity, sizeof(int) * (arity[0] + 1)); memcpy(current_arity, arity, sizeof(int) * (arity[0] + 1));
traverse_answer_trie(TrNode_next(ans_node), str, str_index, arity, var_index, depth, mode); current_str_index = str_index;
memcpy(arity, current_arity, sizeof(int) * (current_arity[0] + 1)); current_var_index = var_index;
free(current_arity); current_mode = mode;
#ifdef TRIE_COMPACT_PAIRS
if (arity[arity[0]] == -2 && str[str_index - 1] != '[')
str[str_index - 1] = ',';
#else
if (arity[arity[0]] == -1)
str[str_index - 1] = '|';
#endif /* TRIE_COMPACT_PAIRS */
} }
/* print VAR when starting a term */ /* print VAR when starting a term */
if (arity[0] == 0 && mode == TRAVERSE_NORMAL) { if (arity[0] == 0 && mode == TRAVERSE_MODE_NORMAL) {
str_index += sprintf(& str[str_index], " VAR%d: ", var_index); str_index += sprintf(& str[str_index], " VAR%d: ", var_index);
var_index++; var_index++;
} }
/* test the node type */ /* test the node type */
t = TrNode_entry(ans_node); t = TrNode_entry(ans_node);
if (mode == TRAVERSE_FLOAT) { if (mode == TRAVERSE_MODE_FLOAT) {
#if SIZEOF_DOUBLE == 2 * SIZEOF_INT_P #if SIZEOF_DOUBLE == 2 * SIZEOF_INT_P
arity[0]++; arity[0]++;
arity[arity[0]] = (int) t; arity[arity[0]] = (int) t;
mode = TRAVERSE_FLOAT2; mode = TRAVERSE_MODE_FLOAT2;
} else if (mode == TRAVERSE_FLOAT2) { } else if (mode == TRAVERSE_MODE_FLOAT2) {
volatile Float dbl; volatile Float dbl;
volatile Term *t_dbl = (Term *)((void *) &dbl); volatile Term *t_dbl = (Term *)((void *) &dbl);
*t_dbl = t; *t_dbl = t;
@ -1815,10 +1840,10 @@ void traverse_answer_trie(ans_node_ptr ans_node, char *str, int str_index, int *
} }
} }
} }
mode = TRAVERSE_FLOAT_END; mode = TRAVERSE_MODE_FLOAT_END;
} else if (mode == TRAVERSE_FLOAT_END) { } else if (mode == TRAVERSE_MODE_FLOAT_END) {
mode = TRAVERSE_NORMAL; mode = TRAVERSE_MODE_NORMAL;
} else if (mode == TRAVERSE_LONG) { } else if (mode == TRAVERSE_MODE_LONG) {
Int li = (Int) t; Int li = (Int) t;
#if SHORT_INTS #if SHORT_INTS
str_index += sprintf(& str[str_index], "%ld", li); str_index += sprintf(& str[str_index], "%ld", li);
@ -1850,9 +1875,9 @@ void traverse_answer_trie(ans_node_ptr ans_node, char *str, int str_index, int *
} }
} }
} }
mode = TRAVERSE_LONG_END; mode = TRAVERSE_MODE_LONG_END;
} else if (mode == TRAVERSE_LONG_END) { } else if (mode == TRAVERSE_MODE_LONG_END) {
mode = TRAVERSE_NORMAL; mode = TRAVERSE_MODE_NORMAL;
} else if (IsVarTerm(t)) { } else if (IsVarTerm(t)) {
#if SHORT_INTS #if SHORT_INTS
str_index += sprintf(& str[str_index], "ANSVAR%ld", VarIndexOfTableTerm(t)); str_index += sprintf(& str[str_index], "ANSVAR%ld", VarIndexOfTableTerm(t));
@ -1968,9 +1993,9 @@ void traverse_answer_trie(ans_node_ptr ans_node, char *str, int str_index, int *
} else if (IsApplTerm(t)) { } else if (IsApplTerm(t)) {
Functor f = (Functor) RepAppl(t); Functor f = (Functor) RepAppl(t);
if (f == FunctorDouble) { if (f == FunctorDouble) {
mode = TRAVERSE_FLOAT; mode = TRAVERSE_MODE_FLOAT;
} else if (f == FunctorLongInt) { } else if (f == FunctorLongInt) {
mode = TRAVERSE_LONG; mode = TRAVERSE_MODE_LONG;
} else { } else {
str_index += sprintf(& str[str_index], "%s(", AtomName(NameOfFunctor(f))); str_index += sprintf(& str[str_index], "%s(", AtomName(NameOfFunctor(f)));
arity[0]++; arity[0]++;
@ -1992,16 +2017,36 @@ void traverse_answer_trie(ans_node_ptr ans_node, char *str, int str_index, int *
else if (depth > TrStat_ans_max_depth) else if (depth > TrStat_ans_max_depth)
TrStat_ans_max_depth = depth; TrStat_ans_max_depth = depth;
} }
#ifdef TABLING_INNER_CUTS #ifdef TABLING_INNER_CUTS
/* ... or continue with pruned node */ /* ... or continue with pruned node */
else if (TrNode_child(ans_node) == NULL) else if (TrNode_child(ans_node) == NULL)
TrStat_ans_pruned++; TrStat_ans_pruned++;
#endif /* TABLING_INNER_CUTS */ #endif /* TABLING_INNER_CUTS */
/* ... or continue with child node */ /* ... or continue with child node */
else else
traverse_answer_trie(TrNode_child(ans_node), str, str_index, arity, var_index, depth + 1, mode); traverse_answer_trie(TrNode_child(ans_node), str, str_index, arity, var_index, depth + 1, mode, TRAVERSE_POSITION_FIRST);
/* continue iteratively with sibling nodes */
if (position == TRAVERSE_POSITION_FIRST) {
/* restore the initial state */
str_index = current_str_index;
var_index = current_var_index;
mode = current_mode;
ans_node = TrNode_next(ans_node);
while (ans_node) {
memcpy(arity, current_arity, sizeof(int) * (current_arity[0] + 1));
#ifdef TRIE_COMPACT_PAIRS
if (arity[arity[0]] == -2 && str[str_index - 1] != '[')
str[str_index - 1] = ',';
#else
if (arity[arity[0]] == -1)
str[str_index - 1] = '|';
#endif /* TRIE_COMPACT_PAIRS */
traverse_answer_trie(ans_node, str, str_index, arity, var_index, depth, mode, TRAVERSE_POSITION_NEXT);
ans_node = TrNode_next(ans_node);
}
free(current_arity);
}
return; return;
} }