From cf5d68eddaac093b1e64f51bc83ba58551ef7bde Mon Sep 17 00:00:00 2001 From: Ricardo Rocha Date: Wed, 5 Aug 2009 05:48:00 +0100 Subject: [PATCH] fix recursive functions that manipulate tries --- OPTYap/opt.macros.h | 582 ++++++++++++++++++++++---------------------- OPTYap/opt.preds.c | 4 +- OPTYap/opt.proto.h | 4 +- OPTYap/tab.macros.h | 19 +- OPTYap/tab.tries.c | 251 +++++++++++-------- 5 files changed, 461 insertions(+), 399 deletions(-) diff --git a/OPTYap/opt.macros.h b/OPTYap/opt.macros.h index 254178178..dd1c1bf19 100644 --- a/OPTYap/opt.macros.h +++ b/OPTYap/opt.macros.h @@ -52,335 +52,335 @@ extern int Yap_page_size; #define UPDATE_STATS(STAT, VALUE) STAT += VALUE -#ifdef MALLOC_MEMORY_ALLOC_SCHEME /* ------------------------------------------------ */ -#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) \ +#ifdef MALLOC_MEMORY_ALLOC_SCHEME /* ---------------------------------------------------------------- */ +#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) \ 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) -#define FREE_STRUCT(STR, STR_PAGES, STR_TYPE) \ - UPDATE_STATS(Pg_str_in_use(STR_PAGES), -1); \ +#define FREE_STRUCT(STR, STR_PAGES, STR_TYPE) \ + UPDATE_STATS(Pg_str_in_use(STR_PAGES), -1); \ free(STR) -#elif YAP_MEMORY_ALLOC_SCHEME /* ---------------------------------------------------- */ -#define ALLOC_STRUCT(STR, STR_PAGES, STR_TYPE) \ - { char *ptr = Yap_AllocCodeSpace(sizeof(STR_TYPE) + sizeof(CELL)); \ - if (ptr) { \ - *ptr = 'y'; \ - ptr += sizeof(CELL); \ - STR = (STR_TYPE *)ptr; \ - } else { \ - ptr = (char *)malloc(sizeof(STR_TYPE) + sizeof(CELL)); \ - if (ptr) { \ - *ptr = 'm'; \ - ptr += sizeof(CELL); \ - STR = (STR_TYPE *)ptr; \ - } else { \ - Yap_Error(FATAL_ERROR, TermNil, "malloc error (ALLOC_STRUCT)"); \ - STR = NULL; \ - } \ - } \ - UPDATE_STATS(Pg_str_in_use(STR_PAGES), 1); \ +#elif YAP_MEMORY_ALLOC_SCHEME /* -------------------------------------------------------------------- */ +#define ALLOC_STRUCT(STR, STR_PAGES, STR_TYPE) \ + { char *ptr = Yap_AllocCodeSpace(sizeof(STR_TYPE) + sizeof(CELL)); \ + if (ptr) { \ + *ptr = 'y'; \ + ptr += sizeof(CELL); \ + STR = (STR_TYPE *)ptr; \ + } else { \ + ptr = (char *)malloc(sizeof(STR_TYPE) + sizeof(CELL)); \ + if (ptr) { \ + *ptr = 'm'; \ + ptr += sizeof(CELL); \ + STR = (STR_TYPE *)ptr; \ + } else { \ + Yap_Error(FATAL_ERROR, TermNil, "malloc error (ALLOC_STRUCT)"); \ + STR = NULL; \ + } \ + } \ + 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) -#define FREE_STRUCT(STR, STR_PAGES, STR_TYPE) \ - { char *ptr = (char *)(STR) - sizeof(CELL); \ - if (ptr[0] == 'y') { \ - Yap_FreeCodeSpace(ptr); \ - } else \ - free(ptr); \ - UPDATE_STATS(Pg_str_in_use(STR_PAGES), -1); \ +#define FREE_STRUCT(STR, STR_PAGES, STR_TYPE) \ + { char *ptr = (char *)(STR) - sizeof(CELL); \ + if (ptr[0] == 'y') { \ + Yap_FreeCodeSpace(ptr); \ + } else \ + free(ptr); \ + UPDATE_STATS(Pg_str_in_use(STR_PAGES), -1); \ } -#elif SHM_MEMORY_ALLOC_SCHEME /* ---------------------------------------------------- */ +#elif SHM_MEMORY_ALLOC_SCHEME /* -------------------------------------------------------------------- */ #ifdef LIMIT_TABLING -#define INIT_PAGE(PG_HD, STR_PAGES, STR_TYPE) \ - { int i; \ - STR_TYPE *aux_str; \ - PgHd_str_in_use(PG_HD) = 0; \ - PgHd_previous(PG_HD) = NULL; \ - aux_str = (STR_TYPE *) (PG_HD + 1); \ - PgHd_free_str(PG_HD) = (void *) aux_str; \ - for (i = 1; i < Pg_str_per_pg(STR_PAGES); i++) { \ - STRUCT_NEXT(aux_str) = aux_str + 1; \ - aux_str++; \ - } \ - STRUCT_NEXT(aux_str) = NULL; \ - LOCK(Pg_lock(STR_PAGES)); \ - if ((PgHd_next(PG_HD) = Pg_free_pg(STR_PAGES)) != NULL) \ - PgHd_previous(PgHd_next(PG_HD)) = PG_HD; \ - Pg_free_pg(STR_PAGES) = PG_HD; \ - UPDATE_STATS(Pg_pg_alloc(STR_PAGES), 1); \ +#define INIT_PAGE(PG_HD, STR_PAGES, STR_TYPE) \ + { int i; \ + STR_TYPE *aux_str; \ + PgHd_str_in_use(PG_HD) = 0; \ + PgHd_previous(PG_HD) = NULL; \ + aux_str = (STR_TYPE *) (PG_HD + 1); \ + PgHd_free_str(PG_HD) = (void *) aux_str; \ + for (i = 1; i < Pg_str_per_pg(STR_PAGES); i++) { \ + STRUCT_NEXT(aux_str) = aux_str + 1; \ + aux_str++; \ + } \ + STRUCT_NEXT(aux_str) = NULL; \ + LOCK(Pg_lock(STR_PAGES)); \ + if ((PgHd_next(PG_HD) = Pg_free_pg(STR_PAGES)) != NULL) \ + PgHd_previous(PgHd_next(PG_HD)) = PG_HD; \ + Pg_free_pg(STR_PAGES) = PG_HD; \ + UPDATE_STATS(Pg_pg_alloc(STR_PAGES), 1); \ } -#define ALLOC_PAGE(PG_HD) \ - { int i, shmid; \ - pg_hd_ptr aux_pg_hd; \ - if ((shmid = shmget(IPC_PRIVATE, SHMMAX, SHM_R|SHM_W)) == -1) \ - Yap_Error(FATAL_ERROR, TermNil, "shmget error (ALLOC_PAGE)"); \ - if ((PG_HD = (pg_hd_ptr) shmat(shmid, NULL, 0)) == (void *) -1) \ - Yap_Error(FATAL_ERROR, TermNil, "shmat error (ALLOC_PAGE)"); \ - if (shmctl(shmid, IPC_RMID, 0) != 0) \ - Yap_Error(FATAL_ERROR, TermNil, "shmctl error (ALLOC_PAGE)"); \ - aux_pg_hd = (pg_hd_ptr)(((void *)PG_HD) + Yap_page_size); \ - Pg_free_pg(GLOBAL_PAGES_void) = aux_pg_hd; \ - for (i = 2; i < SHMMAX / Yap_page_size; i++) { \ - PgHd_next(aux_pg_hd) = (pg_hd_ptr)(((void *)aux_pg_hd) + Yap_page_size); \ - aux_pg_hd = PgHd_next(aux_pg_hd); \ - } \ - PgHd_next(aux_pg_hd) = NULL; \ - UPDATE_STATS(Pg_pg_alloc(GLOBAL_PAGES_void), SHMMAX / Yap_page_size); \ +#define ALLOC_PAGE(PG_HD) \ + { int i, shmid; \ + pg_hd_ptr aux_pg_hd; \ + if ((shmid = shmget(IPC_PRIVATE, SHMMAX, SHM_R|SHM_W)) == -1) \ + Yap_Error(FATAL_ERROR, TermNil, "shmget error (ALLOC_PAGE)"); \ + if ((PG_HD = (pg_hd_ptr) shmat(shmid, NULL, 0)) == (void *) -1) \ + Yap_Error(FATAL_ERROR, TermNil, "shmat error (ALLOC_PAGE)"); \ + if (shmctl(shmid, IPC_RMID, 0) != 0) \ + Yap_Error(FATAL_ERROR, TermNil, "shmctl error (ALLOC_PAGE)"); \ + aux_pg_hd = (pg_hd_ptr)(((void *)PG_HD) + Yap_page_size); \ + Pg_free_pg(GLOBAL_PAGES_void) = aux_pg_hd; \ + for (i = 2; i < SHMMAX / Yap_page_size; i++) { \ + PgHd_next(aux_pg_hd) = (pg_hd_ptr)(((void *)aux_pg_hd) + Yap_page_size); \ + aux_pg_hd = PgHd_next(aux_pg_hd); \ + } \ + PgHd_next(aux_pg_hd) = NULL; \ + UPDATE_STATS(Pg_pg_alloc(GLOBAL_PAGES_void), SHMMAX / Yap_page_size); \ } -#define RECOVER_UNUSED_SPACE(STR_PAGES) \ - { sg_fr_ptr sg_fr = GLOBAL_check_sg_fr; \ - do { \ - if (sg_fr) \ - sg_fr = SgFr_next(sg_fr); \ - else \ - sg_fr = GLOBAL_first_sg_fr; \ - if (sg_fr == NULL) \ - Yap_Error(FATAL_ERROR, TermNil, "no space left (RECOVER_UNUSED_SPACE)"); \ - /* see function 'InteractSIGINT' in file 'sysbits.c' */ \ - /* Yap_Error(PURE_ABORT, TermNil, ""); */ \ - /* restore_absmi_regs(&Yap_standard_regs); */ \ - /* siglongjmp (Yap_RestartEnv, 1); */ \ - if (SgFr_first_answer(sg_fr) && \ - SgFr_first_answer(sg_fr) != SgFr_answer_trie(sg_fr)) { \ - SgFr_state(sg_fr) = ready; \ - free_answer_hash_chain(SgFr_hash_chain(sg_fr)); \ - SgFr_hash_chain(sg_fr) = NULL; \ - SgFr_first_answer(sg_fr) = NULL; \ - SgFr_last_answer(sg_fr) = NULL; \ - free_answer_trie_branch(TrNode_child(SgFr_answer_trie(sg_fr))); \ - TrNode_child(SgFr_answer_trie(sg_fr)) = NULL; \ - } \ - } while (Pg_free_pg(GLOBAL_PAGES_void) == Pg_free_pg(STR_PAGES)); \ - GLOBAL_check_sg_fr = sg_fr; \ +#define RECOVER_UNUSED_SPACE(STR_PAGES) \ + { sg_fr_ptr sg_fr = GLOBAL_check_sg_fr; \ + do { \ + if (sg_fr) \ + sg_fr = SgFr_next(sg_fr); \ + else \ + sg_fr = GLOBAL_first_sg_fr; \ + if (sg_fr == NULL) \ + Yap_Error(FATAL_ERROR, TermNil, "no space left (RECOVER_UNUSED_SPACE)"); \ + /* see function 'InteractSIGINT' in file 'sysbits.c' */ \ + /* Yap_Error(PURE_ABORT, TermNil, ""); */ \ + /* restore_absmi_regs(&Yap_standard_regs); */ \ + /* siglongjmp (Yap_RestartEnv, 1); */ \ + if (SgFr_first_answer(sg_fr) && \ + SgFr_first_answer(sg_fr) != SgFr_answer_trie(sg_fr)) { \ + SgFr_state(sg_fr) = ready; \ + free_answer_hash_chain(SgFr_hash_chain(sg_fr)); \ + SgFr_hash_chain(sg_fr) = NULL; \ + SgFr_first_answer(sg_fr) = NULL; \ + SgFr_last_answer(sg_fr) = NULL; \ + free_answer_trie_branch(TrNode_child(SgFr_answer_trie(sg_fr)), TRAVERSE_POSITION_FIRST); \ + TrNode_child(SgFr_answer_trie(sg_fr)) = NULL; \ + } \ + } while (Pg_free_pg(GLOBAL_PAGES_void) == Pg_free_pg(STR_PAGES)); \ + GLOBAL_check_sg_fr = sg_fr; \ } -#define ALLOC_STRUCT(STR, STR_PAGES, STR_TYPE) \ - { pg_hd_ptr pg_hd; \ - LOCK(Pg_lock(STR_PAGES)); \ - pg_hd = Pg_free_pg(STR_PAGES); \ - while (pg_hd == NULL) { \ - UNLOCK(Pg_lock(STR_PAGES)); \ - LOCK(Pg_lock(GLOBAL_PAGES_void)); \ - if (Pg_free_pg(GLOBAL_PAGES_void)) { \ - pg_hd = Pg_free_pg(GLOBAL_PAGES_void); \ - Pg_free_pg(GLOBAL_PAGES_void) = PgHd_next(pg_hd); \ - UPDATE_STATS(Pg_str_in_use(GLOBAL_PAGES_void), 1); \ - UNLOCK(Pg_lock(GLOBAL_PAGES_void)); \ - INIT_PAGE(pg_hd, STR_PAGES, STR_TYPE); \ - } else if (GLOBAL_MAX_PAGES != Pg_pg_alloc(GLOBAL_PAGES_void)) { \ - ALLOC_PAGE(pg_hd); \ - UPDATE_STATS(Pg_str_in_use(GLOBAL_PAGES_void), 1); \ - UNLOCK(Pg_lock(GLOBAL_PAGES_void)); \ - INIT_PAGE(pg_hd, STR_PAGES, STR_TYPE); \ - } else { \ - UNLOCK(Pg_lock(GLOBAL_PAGES_void)); \ - RECOVER_UNUSED_SPACE(STR_PAGES); \ - LOCK(Pg_lock(STR_PAGES)); \ - pg_hd = Pg_free_pg(STR_PAGES); \ - } \ - } \ - PgHd_str_in_use(pg_hd)++; \ - STR = (STR_TYPE *) PgHd_free_str(pg_hd); \ - if ((PgHd_free_str(pg_hd) = (void *) STRUCT_NEXT(STR)) == NULL) \ - if ((Pg_free_pg(STR_PAGES) = PgHd_next(pg_hd)) != NULL) \ - PgHd_previous(PgHd_next(pg_hd)) = NULL; \ - UPDATE_STATS(Pg_str_in_use(STR_PAGES), 1); \ - UNLOCK(Pg_lock(STR_PAGES)); \ +#define ALLOC_STRUCT(STR, STR_PAGES, STR_TYPE) \ + { pg_hd_ptr pg_hd; \ + LOCK(Pg_lock(STR_PAGES)); \ + pg_hd = Pg_free_pg(STR_PAGES); \ + while (pg_hd == NULL) { \ + UNLOCK(Pg_lock(STR_PAGES)); \ + LOCK(Pg_lock(GLOBAL_PAGES_void)); \ + if (Pg_free_pg(GLOBAL_PAGES_void)) { \ + pg_hd = Pg_free_pg(GLOBAL_PAGES_void); \ + Pg_free_pg(GLOBAL_PAGES_void) = PgHd_next(pg_hd); \ + UPDATE_STATS(Pg_str_in_use(GLOBAL_PAGES_void), 1); \ + UNLOCK(Pg_lock(GLOBAL_PAGES_void)); \ + INIT_PAGE(pg_hd, STR_PAGES, STR_TYPE); \ + } else if (GLOBAL_MAX_PAGES != Pg_pg_alloc(GLOBAL_PAGES_void)) { \ + ALLOC_PAGE(pg_hd); \ + UPDATE_STATS(Pg_str_in_use(GLOBAL_PAGES_void), 1); \ + UNLOCK(Pg_lock(GLOBAL_PAGES_void)); \ + INIT_PAGE(pg_hd, STR_PAGES, STR_TYPE); \ + } else { \ + UNLOCK(Pg_lock(GLOBAL_PAGES_void)); \ + RECOVER_UNUSED_SPACE(STR_PAGES); \ + LOCK(Pg_lock(STR_PAGES)); \ + pg_hd = Pg_free_pg(STR_PAGES); \ + } \ + } \ + PgHd_str_in_use(pg_hd)++; \ + STR = (STR_TYPE *) PgHd_free_str(pg_hd); \ + if ((PgHd_free_str(pg_hd) = (void *) STRUCT_NEXT(STR)) == NULL) \ + if ((Pg_free_pg(STR_PAGES) = PgHd_next(pg_hd)) != NULL) \ + PgHd_previous(PgHd_next(pg_hd)) = NULL; \ + UPDATE_STATS(Pg_str_in_use(STR_PAGES), 1); \ + UNLOCK(Pg_lock(STR_PAGES)); \ } -#define ALLOC_NEXT_FREE_STRUCT(STR, STR_PAGES, STR_TYPE) \ - if ((STR = LOCAL_next_free_ans_node) == NULL) { \ - pg_hd_ptr pg_hd; \ - LOCK(Pg_lock(STR_PAGES)); \ - pg_hd = Pg_free_pg(STR_PAGES); \ - while (pg_hd == NULL) { \ - UNLOCK(Pg_lock(STR_PAGES)); \ - LOCK(Pg_lock(GLOBAL_PAGES_void)); \ - if (Pg_free_pg(GLOBAL_PAGES_void)) { \ - pg_hd = Pg_free_pg(GLOBAL_PAGES_void); \ - Pg_free_pg(GLOBAL_PAGES_void) = PgHd_next(pg_hd); \ - UPDATE_STATS(Pg_str_in_use(GLOBAL_PAGES_void), 1); \ - UNLOCK(Pg_lock(GLOBAL_PAGES_void)); \ - INIT_PAGE(pg_hd, STR_PAGES, STR_TYPE); \ - } else if (GLOBAL_MAX_PAGES != Pg_pg_alloc(GLOBAL_PAGES_void)) { \ - ALLOC_PAGE(pg_hd); \ - UPDATE_STATS(Pg_str_in_use(GLOBAL_PAGES_void), 1); \ - UNLOCK(Pg_lock(GLOBAL_PAGES_void)); \ - INIT_PAGE(pg_hd, STR_PAGES, STR_TYPE); \ - } else { \ - UNLOCK(Pg_lock(GLOBAL_PAGES_void)); \ - RECOVER_UNUSED_SPACE(STR_PAGES); \ - LOCK(Pg_lock(STR_PAGES)); \ - pg_hd = Pg_free_pg(STR_PAGES); \ - } \ - } \ - PgHd_str_in_use(pg_hd) = Pg_str_per_pg(STR_PAGES); \ - STR = (STR_TYPE *) PgHd_free_str(pg_hd); \ - PgHd_free_str(pg_hd) = NULL; \ - 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), Pg_str_per_pg(STR_PAGES)); \ - UNLOCK(Pg_lock(STR_PAGES)); \ - } \ +#define ALLOC_NEXT_FREE_STRUCT(STR, STR_PAGES, STR_TYPE) \ + if ((STR = LOCAL_next_free_ans_node) == NULL) { \ + pg_hd_ptr pg_hd; \ + LOCK(Pg_lock(STR_PAGES)); \ + pg_hd = Pg_free_pg(STR_PAGES); \ + while (pg_hd == NULL) { \ + UNLOCK(Pg_lock(STR_PAGES)); \ + LOCK(Pg_lock(GLOBAL_PAGES_void)); \ + if (Pg_free_pg(GLOBAL_PAGES_void)) { \ + pg_hd = Pg_free_pg(GLOBAL_PAGES_void); \ + Pg_free_pg(GLOBAL_PAGES_void) = PgHd_next(pg_hd); \ + UPDATE_STATS(Pg_str_in_use(GLOBAL_PAGES_void), 1); \ + UNLOCK(Pg_lock(GLOBAL_PAGES_void)); \ + INIT_PAGE(pg_hd, STR_PAGES, STR_TYPE); \ + } else if (GLOBAL_MAX_PAGES != Pg_pg_alloc(GLOBAL_PAGES_void)) { \ + ALLOC_PAGE(pg_hd); \ + UPDATE_STATS(Pg_str_in_use(GLOBAL_PAGES_void), 1); \ + UNLOCK(Pg_lock(GLOBAL_PAGES_void)); \ + INIT_PAGE(pg_hd, STR_PAGES, STR_TYPE); \ + } else { \ + UNLOCK(Pg_lock(GLOBAL_PAGES_void)); \ + RECOVER_UNUSED_SPACE(STR_PAGES); \ + LOCK(Pg_lock(STR_PAGES)); \ + pg_hd = Pg_free_pg(STR_PAGES); \ + } \ + } \ + PgHd_str_in_use(pg_hd) = Pg_str_per_pg(STR_PAGES); \ + STR = (STR_TYPE *) PgHd_free_str(pg_hd); \ + PgHd_free_str(pg_hd) = NULL; \ + 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), Pg_str_per_pg(STR_PAGES)); \ + UNLOCK(Pg_lock(STR_PAGES)); \ + } \ LOCAL_next_free_ans_node = STRUCT_NEXT(STR) #else -#define ALLOC_PAGE(PG_HD) \ - LOCK(Pg_lock(GLOBAL_PAGES_void)); \ - if (Pg_free_pg(GLOBAL_PAGES_void) == NULL) { \ - int i, shmid; \ - pg_hd_ptr pg_hd, aux_pg_hd; \ - if ((shmid = shmget(IPC_PRIVATE, SHMMAX, SHM_R|SHM_W)) == -1) \ - Yap_Error(FATAL_ERROR, TermNil, "shmget error (ALLOC_PAGE)"); \ - if ((pg_hd = (pg_hd_ptr) shmat(shmid, NULL, 0)) == (void *) -1) \ - Yap_Error(FATAL_ERROR, TermNil, "shmat error (ALLOC_PAGE)"); \ - if (shmctl(shmid, IPC_RMID, 0) != 0) \ - Yap_Error(FATAL_ERROR, TermNil, "shmctl error (ALLOC_PAGE)"); \ - Pg_free_pg(GLOBAL_PAGES_void) = pg_hd; \ - for (i = 1; i < SHMMAX / Yap_page_size; i++) { \ - aux_pg_hd = (pg_hd_ptr)(((void *)pg_hd) + Yap_page_size); \ - PgHd_next(pg_hd) = aux_pg_hd; \ - pg_hd = aux_pg_hd; \ - } \ - PgHd_next(pg_hd) = NULL; \ - UPDATE_STATS(Pg_pg_alloc(GLOBAL_PAGES_void), SHMMAX / Yap_page_size); \ - } \ - UPDATE_STATS(Pg_str_in_use(GLOBAL_PAGES_void), 1); \ - PG_HD = Pg_free_pg(GLOBAL_PAGES_void); \ - Pg_free_pg(GLOBAL_PAGES_void) = PgHd_next(PG_HD); \ +#define ALLOC_PAGE(PG_HD) \ + LOCK(Pg_lock(GLOBAL_PAGES_void)); \ + if (Pg_free_pg(GLOBAL_PAGES_void) == NULL) { \ + int i, shmid; \ + pg_hd_ptr pg_hd, aux_pg_hd; \ + if ((shmid = shmget(IPC_PRIVATE, SHMMAX, SHM_R|SHM_W)) == -1) \ + Yap_Error(FATAL_ERROR, TermNil, "shmget error (ALLOC_PAGE)"); \ + if ((pg_hd = (pg_hd_ptr) shmat(shmid, NULL, 0)) == (void *) -1) \ + Yap_Error(FATAL_ERROR, TermNil, "shmat error (ALLOC_PAGE)"); \ + if (shmctl(shmid, IPC_RMID, 0) != 0) \ + Yap_Error(FATAL_ERROR, TermNil, "shmctl error (ALLOC_PAGE)"); \ + Pg_free_pg(GLOBAL_PAGES_void) = pg_hd; \ + for (i = 1; i < SHMMAX / Yap_page_size; i++) { \ + aux_pg_hd = (pg_hd_ptr)(((void *)pg_hd) + Yap_page_size); \ + PgHd_next(pg_hd) = aux_pg_hd; \ + pg_hd = aux_pg_hd; \ + } \ + PgHd_next(pg_hd) = NULL; \ + UPDATE_STATS(Pg_pg_alloc(GLOBAL_PAGES_void), SHMMAX / Yap_page_size); \ + } \ + UPDATE_STATS(Pg_str_in_use(GLOBAL_PAGES_void), 1); \ + PG_HD = Pg_free_pg(GLOBAL_PAGES_void); \ + Pg_free_pg(GLOBAL_PAGES_void) = PgHd_next(PG_HD); \ UNLOCK(Pg_lock(GLOBAL_PAGES_void)) -#define ALLOC_STRUCT(STR, STR_PAGES, STR_TYPE) \ - { pg_hd_ptr pg_hd; \ - LOCK(Pg_lock(STR_PAGES)); \ - UPDATE_STATS(Pg_str_in_use(STR_PAGES), 1); \ - if (Pg_free_pg(STR_PAGES)) { \ - pg_hd = Pg_free_pg(STR_PAGES); \ - PgHd_str_in_use(pg_hd)++; \ - STR = (STR_TYPE *) PgHd_free_str(pg_hd); \ - if ((PgHd_free_str(pg_hd) = (void *) STRUCT_NEXT(STR)) == NULL) \ - if ((Pg_free_pg(STR_PAGES) = PgHd_next(pg_hd)) != NULL) \ - PgHd_previous(PgHd_next(pg_hd)) = NULL; \ - UNLOCK(Pg_lock(STR_PAGES)); \ - } else { \ - int i; \ - UPDATE_STATS(Pg_pg_alloc(STR_PAGES), 1); \ - UNLOCK(Pg_lock(STR_PAGES)); \ - ALLOC_PAGE(pg_hd); \ - PgHd_str_in_use(pg_hd) = 1; \ - PgHd_previous(pg_hd) = NULL; \ - STR = (STR_TYPE *) (pg_hd + 1); \ - PgHd_free_str(pg_hd) = (void *) ++STR; \ - for (i = Pg_str_per_pg(STR_PAGES); i != 2; i--) { \ - STRUCT_NEXT(STR) = STR + 1; \ - STR++; \ - } \ - STRUCT_NEXT(STR) = NULL; \ - STR = (STR_TYPE *) (pg_hd + 1); \ - LOCK(Pg_lock(STR_PAGES)); \ - if ((PgHd_next(pg_hd) = Pg_free_pg(STR_PAGES)) != NULL) \ - PgHd_previous(PgHd_next(pg_hd)) = pg_hd; \ - Pg_free_pg(STR_PAGES) = pg_hd; \ - UNLOCK(Pg_lock(STR_PAGES)); \ - } \ +#define ALLOC_STRUCT(STR, STR_PAGES, STR_TYPE) \ + { pg_hd_ptr pg_hd; \ + LOCK(Pg_lock(STR_PAGES)); \ + UPDATE_STATS(Pg_str_in_use(STR_PAGES), 1); \ + if (Pg_free_pg(STR_PAGES)) { \ + pg_hd = Pg_free_pg(STR_PAGES); \ + PgHd_str_in_use(pg_hd)++; \ + STR = (STR_TYPE *) PgHd_free_str(pg_hd); \ + if ((PgHd_free_str(pg_hd) = (void *) STRUCT_NEXT(STR)) == NULL) \ + if ((Pg_free_pg(STR_PAGES) = PgHd_next(pg_hd)) != NULL) \ + PgHd_previous(PgHd_next(pg_hd)) = NULL; \ + UNLOCK(Pg_lock(STR_PAGES)); \ + } else { \ + int i; \ + UPDATE_STATS(Pg_pg_alloc(STR_PAGES), 1); \ + UNLOCK(Pg_lock(STR_PAGES)); \ + ALLOC_PAGE(pg_hd); \ + PgHd_str_in_use(pg_hd) = 1; \ + PgHd_previous(pg_hd) = NULL; \ + STR = (STR_TYPE *) (pg_hd + 1); \ + PgHd_free_str(pg_hd) = (void *) ++STR; \ + for (i = Pg_str_per_pg(STR_PAGES); i != 2; i--) { \ + STRUCT_NEXT(STR) = STR + 1; \ + STR++; \ + } \ + STRUCT_NEXT(STR) = NULL; \ + STR = (STR_TYPE *) (pg_hd + 1); \ + LOCK(Pg_lock(STR_PAGES)); \ + if ((PgHd_next(pg_hd) = Pg_free_pg(STR_PAGES)) != NULL) \ + PgHd_previous(PgHd_next(pg_hd)) = pg_hd; \ + Pg_free_pg(STR_PAGES) = pg_hd; \ + UNLOCK(Pg_lock(STR_PAGES)); \ + } \ } -#define ALLOC_NEXT_FREE_STRUCT(STR, STR_PAGES, STR_TYPE) \ - if ((STR = LOCAL_next_free_ans_node) == NULL) { \ - pg_hd_ptr pg_hd; \ - LOCK(Pg_lock(STR_PAGES)); \ - UPDATE_STATS(Pg_str_in_use(STR_PAGES), Pg_str_per_pg(STR_PAGES)); \ - if (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)); \ - PgHd_str_in_use(pg_hd) = Pg_str_per_pg(STR_PAGES); \ - STR = (STR_TYPE *) PgHd_free_str(pg_hd); \ - PgHd_free_str(pg_hd) = NULL; \ - Pg_free_pg(STR_PAGES) = PgHd_next(pg_hd); \ - UNLOCK(Pg_lock(STR_PAGES)); \ - } else { \ - int i; \ - UPDATE_STATS(Pg_pg_alloc(STR_PAGES), 1); \ - UNLOCK(Pg_lock(STR_PAGES)); \ - ALLOC_PAGE(pg_hd); \ - PgHd_str_in_use(pg_hd) = Pg_str_per_pg(STR_PAGES); \ - PgHd_free_str(pg_hd) = NULL; \ - PgHd_previous(pg_hd) = NULL; \ - PgHd_next(pg_hd) = NULL; \ - STR = (STR_TYPE *) (pg_hd + 1); \ - for (i = Pg_str_per_pg(STR_PAGES); i != 1; i--) { \ - STRUCT_NEXT(STR) = STR + 1; \ - STR++; \ - } \ - STRUCT_NEXT(STR) = NULL; \ - STR = (STR_TYPE *) (pg_hd + 1); \ - } \ - } \ +#define ALLOC_NEXT_FREE_STRUCT(STR, STR_PAGES, STR_TYPE) \ + if ((STR = LOCAL_next_free_ans_node) == NULL) { \ + pg_hd_ptr pg_hd; \ + LOCK(Pg_lock(STR_PAGES)); \ + UPDATE_STATS(Pg_str_in_use(STR_PAGES), Pg_str_per_pg(STR_PAGES)); \ + if (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)); \ + PgHd_str_in_use(pg_hd) = Pg_str_per_pg(STR_PAGES); \ + STR = (STR_TYPE *) PgHd_free_str(pg_hd); \ + PgHd_free_str(pg_hd) = NULL; \ + Pg_free_pg(STR_PAGES) = PgHd_next(pg_hd); \ + UNLOCK(Pg_lock(STR_PAGES)); \ + } else { \ + int i; \ + UPDATE_STATS(Pg_pg_alloc(STR_PAGES), 1); \ + UNLOCK(Pg_lock(STR_PAGES)); \ + ALLOC_PAGE(pg_hd); \ + PgHd_str_in_use(pg_hd) = Pg_str_per_pg(STR_PAGES); \ + PgHd_free_str(pg_hd) = NULL; \ + PgHd_previous(pg_hd) = NULL; \ + PgHd_next(pg_hd) = NULL; \ + STR = (STR_TYPE *) (pg_hd + 1); \ + for (i = Pg_str_per_pg(STR_PAGES); i != 1; i--) { \ + STRUCT_NEXT(STR) = STR + 1; \ + STR++; \ + } \ + STRUCT_NEXT(STR) = NULL; \ + STR = (STR_TYPE *) (pg_hd + 1); \ + } \ + } \ LOCAL_next_free_ans_node = STRUCT_NEXT(STR) #endif /* LIMIT_TABLING */ -#define FREE_PAGE(PG_HD) \ - LOCK(Pg_lock(GLOBAL_PAGES_void)); \ - UPDATE_STATS(Pg_str_in_use(GLOBAL_PAGES_void), -1); \ - PgHd_next(PG_HD) = Pg_free_pg(GLOBAL_PAGES_void); \ - Pg_free_pg(GLOBAL_PAGES_void) = PG_HD; \ +#define FREE_PAGE(PG_HD) \ + LOCK(Pg_lock(GLOBAL_PAGES_void)); \ + UPDATE_STATS(Pg_str_in_use(GLOBAL_PAGES_void), -1); \ + PgHd_next(PG_HD) = Pg_free_pg(GLOBAL_PAGES_void); \ + Pg_free_pg(GLOBAL_PAGES_void) = PG_HD; \ UNLOCK(Pg_lock(GLOBAL_PAGES_void)) -#define FREE_STRUCT(STR, STR_PAGES, STR_TYPE) \ - { pg_hd_ptr pg_hd; \ - pg_hd = PAGE_HEADER(STR); \ - LOCK(Pg_lock(STR_PAGES)); \ - UPDATE_STATS(Pg_str_in_use(STR_PAGES), -1); \ - if (--PgHd_str_in_use(pg_hd) == 0) { \ - UPDATE_STATS(Pg_pg_alloc(STR_PAGES), -1); \ - if (PgHd_previous(pg_hd)) { \ - if ((PgHd_next(PgHd_previous(pg_hd)) = PgHd_next(pg_hd)) != NULL) \ - PgHd_previous(PgHd_next(pg_hd)) = PgHd_previous(pg_hd); \ - } else { \ - if ((Pg_free_pg(STR_PAGES) = PgHd_next(pg_hd)) != NULL) \ - PgHd_previous(PgHd_next(pg_hd)) = NULL; \ - } \ - UNLOCK(Pg_lock(STR_PAGES)); \ - FREE_PAGE(pg_hd); \ - } else { \ - if ((STRUCT_NEXT(STR) = (STR_TYPE *) PgHd_free_str(pg_hd)) == NULL) { \ - PgHd_previous(pg_hd) = NULL; \ - if ((PgHd_next(pg_hd) = Pg_free_pg(STR_PAGES)) != NULL) \ - PgHd_previous(PgHd_next(pg_hd)) = pg_hd; \ - Pg_free_pg(STR_PAGES) = pg_hd; \ - } \ - PgHd_free_str(pg_hd) = (void *) STR; \ - UNLOCK(Pg_lock(STR_PAGES)); \ - } \ +#define FREE_STRUCT(STR, STR_PAGES, STR_TYPE) \ + { pg_hd_ptr pg_hd; \ + pg_hd = PAGE_HEADER(STR); \ + LOCK(Pg_lock(STR_PAGES)); \ + UPDATE_STATS(Pg_str_in_use(STR_PAGES), -1); \ + if (--PgHd_str_in_use(pg_hd) == 0) { \ + UPDATE_STATS(Pg_pg_alloc(STR_PAGES), -1); \ + if (PgHd_previous(pg_hd)) { \ + if ((PgHd_next(PgHd_previous(pg_hd)) = PgHd_next(pg_hd)) != NULL) \ + PgHd_previous(PgHd_next(pg_hd)) = PgHd_previous(pg_hd); \ + } else { \ + if ((Pg_free_pg(STR_PAGES) = PgHd_next(pg_hd)) != NULL) \ + PgHd_previous(PgHd_next(pg_hd)) = NULL; \ + } \ + UNLOCK(Pg_lock(STR_PAGES)); \ + FREE_PAGE(pg_hd); \ + } else { \ + if ((STRUCT_NEXT(STR) = (STR_TYPE *) PgHd_free_str(pg_hd)) == NULL) { \ + PgHd_previous(pg_hd) = NULL; \ + if ((PgHd_next(pg_hd) = Pg_free_pg(STR_PAGES)) != NULL) \ + PgHd_previous(PgHd_next(pg_hd)) = pg_hd; \ + Pg_free_pg(STR_PAGES) = pg_hd; \ + } \ + PgHd_free_str(pg_hd) = (void *) STR; \ + UNLOCK(Pg_lock(STR_PAGES)); \ + } \ } -#endif /* --------------------------- MEMORY_ALLOC_SCHEME ---------------------------- */ +#endif /* --------------------------- MEMORY_ALLOC_SCHEME -------------------------------------------- */ #ifdef YAPOR -#define ALLOC_BLOCK(BLOCK, SIZE) \ - if ((BLOCK = (void *) Yap_AllocCodeSpace(SIZE)) == NULL) \ +#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) \ +#define FREE_BLOCK(BLOCK) \ Yap_FreeCodeSpace((char *) (BLOCK)) #else /* TABLING */ -#define ALLOC_BLOCK(BLOCK, SIZE) \ - if ((BLOCK = malloc(SIZE)) == NULL) \ +#define ALLOC_BLOCK(BLOCK, SIZE) \ + if ((BLOCK = malloc(SIZE)) == NULL) \ Yap_Error(FATAL_ERROR, TermNil, "malloc error (ALLOC_BLOCK)") -#define FREE_BLOCK(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 *)); \ - BUCKET_PTR = (void *) ptr; \ - for (i = NUM_BUCKETS; i != 0; i--) \ - *ptr++ = NULL; \ +#define ALLOC_HASH_BUCKETS(BUCKET_PTR, NUM_BUCKETS) \ + { int i; void **ptr; \ + ALLOC_BLOCK(ptr, NUM_BUCKETS * sizeof(void *)); \ + BUCKET_PTR = (void *) ptr; \ + for (i = NUM_BUCKETS; i != 0; i--) \ + *ptr++ = NULL; \ } #define FREE_HASH_BUCKETS(BUCKET_PTR) FREE_BLOCK(BUCKET_PTR) diff --git a/OPTYap/opt.preds.c b/OPTYap/opt.preds.c index 3143936fc..2bac304f0 100644 --- a/OPTYap/opt.preds.c +++ b/OPTYap/opt.preds.c @@ -684,7 +684,7 @@ Int p_abolish_table(void) { sg_node = TrNode_child(TabEnt_subgoal_trie(tab_ent)); if (sg_node) { 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); } @@ -704,7 +704,7 @@ Int p_abolish_all_tables(void) { sg_node = TrNode_child(TabEnt_subgoal_trie(tab_ent)); if (sg_node) { 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); } diff --git a/OPTYap/opt.proto.h b/OPTYap/opt.proto.h index bdbe62aab..a26522a55 100644 --- a/OPTYap/opt.proto.h +++ b/OPTYap/opt.proto.h @@ -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); 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 nodes_left, int nodes_extra); -void free_answer_trie_branch(ans_node_ptr node); +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, int position); void update_answer_trie(sg_fr_ptr sg_fr); void traverse_table(tab_ent_ptr tab_ent, int show_table); void table_stats(void); diff --git a/OPTYap/tab.macros.h b/OPTYap/tab.macros.h index b90ea8bd0..6be6aec68 100644 --- a/OPTYap/tab.macros.h +++ b/OPTYap/tab.macros.h @@ -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 ** ** ----------------------- */ @@ -609,7 +626,7 @@ void abolish_incomplete_subgoals(choiceptr prune_cp) { node = TrNode_child(SgFr_answer_trie(sg_fr)); TrNode_child(SgFr_answer_trie(sg_fr)) = NULL; UNLOCK(SgFr_lock(sg_fr)); - free_answer_trie_branch(node); + free_answer_trie_branch(node, TRAVERSE_POSITION_FIRST); #endif /* INCOMPLETE_TABLING */ } #ifdef LIMIT_TABLING diff --git a/OPTYap/tab.tries.c b/OPTYap/tab.tries.c index 4f83695ae..8913a101f 100644 --- a/OPTYap/tab.tries.c +++ b/OPTYap/tab.tries.c @@ -25,19 +25,6 @@ #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 ** ** ------------------------------------- */ @@ -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); #endif /* TABLING_INNER_CUTS */ #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 */ -static void traverse_subgoal_trie(sg_node_ptr sg_node, char *str, int str_index, int *arity, 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); +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, 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) { - if (TrNode_next(node)) - free_subgoal_trie_branch(TrNode_next(node), nodes_left, nodes_extra); +void free_subgoal_trie_branch(sg_node_ptr node, int nodes_left, int nodes_extra, int position) { + int current_nodes_left = 0, current_nodes_extra = 0; + + /* 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) { #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) - 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 { sg_fr_ptr sg_fr; 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)); ans_node = SgFr_answer_trie(sg_fr); 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); #ifdef LIMIT_TABLING 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_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; } -void free_answer_trie_branch(ans_node_ptr node) { +void free_answer_trie_branch(ans_node_ptr node, int position) { #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); + free_answer_trie_branch(TrNode_child(node), TRAVERSE_POSITION_FIRST); + + if (position == TRAVERSE_POSITION_FIRST) { + 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; } @@ -1188,16 +1200,20 @@ void update_answer_trie(sg_fr_ptr sg_fr) { free_answer_hash_chain(SgFr_hash_chain(sg_fr)); 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)); if (node) { +#ifdef YAPOR TrNode_instr(node) -= 1; #ifdef TABLING_INNER_CUTS update_answer_trie_branch(NULL, node); #else update_answer_trie_branch(node); #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; } @@ -1265,7 +1281,7 @@ void traverse_table(tab_ent_ptr tab_ent, int show_table) { int *arity = (int *) malloc(sizeof(int) * ARITY_ARRAY_SIZE); arity[0] = 1; 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(arity); } else { @@ -1399,39 +1415,43 @@ int update_answer_trie_branch(ans_node_ptr node) { #endif /* TABLING_INNER_CUTS */ #else /* TABLING */ static -void update_answer_trie_branch(ans_node_ptr node) { - if (! IS_ANSWER_LEAF_NODE(node)) { - TrNode_instr(TrNode_child(node)) -= 1; /* retry --> try */ - update_answer_trie_branch(TrNode_child(node)); +void update_answer_trie_branch(ans_node_ptr node, int position) { + if (! IS_ANSWER_LEAF_NODE(node)) + update_answer_trie_branch(TrNode_child(node), TRAVERSE_POSITION_FIRST); /* retry --> try */ + 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)) { - update_answer_trie_branch(TrNode_next(node)); - } else { - TrNode_instr(node) -= 2; /* retry --> trust : try --> do */ - } - TrNode_instr(node) = Yap_opcode(TrNode_instr(node)); + TrNode_instr(node) = Yap_opcode(TrNode_instr(node) - position); return; } #endif /* YAPOR */ 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; /* test if hashing */ if (IS_SUBGOAL_HASH(sg_node)) { sg_node_ptr *bucket, *last_bucket; 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; bucket = Hash_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 { if (*bucket) { - sg_node = *bucket; - traverse_subgoal_trie(sg_node, str, str_index, arity, depth, mode); + traverse_subgoal_trie(*bucket, str, str_index, arity, depth, mode, TRAVERSE_POSITION_FIRST); memcpy(arity, current_arity, sizeof(int) * (current_arity[0] + 1)); #ifdef TRIE_COMPACT_PAIRS 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; } - /* test if sibling node */ - if (TrNode_next(sg_node)) { - int *current_arity = (int *) malloc(sizeof(int) * (arity[0] + 1)); + /* save current state if first sibling node */ + if (position == TRAVERSE_POSITION_FIRST) { + current_arity = (int *) malloc(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); - memcpy(arity, current_arity, sizeof(int) * (current_arity[0] + 1)); - 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 */ + current_str_index = str_index; + current_mode = mode; } /* test the node type */ t = TrNode_entry(sg_node); #if SIZEOF_DOUBLE == 2 * SIZEOF_INT_P - if (mode == TRAVERSE_FLOAT) { + if (mode == TRAVERSE_MODE_FLOAT) { arity[0]++; arity[arity[0]] = (int) t; - mode = TRAVERSE_FLOAT2; - } else if (mode == TRAVERSE_FLOAT2) { + mode = TRAVERSE_MODE_FLOAT2; + } else if (mode == TRAVERSE_MODE_FLOAT2) { volatile Float dbl; volatile Term *t_dbl = (Term *)((void *) &dbl); *t_dbl = t; *(t_dbl + 1) = (Term) arity[arity[0]]; arity[0]--; #else /* SIZEOF_DOUBLE == SIZEOF_INT_P */ - if (mode == TRAVERSE_FLOAT) { + if (mode == TRAVERSE_MODE_FLOAT) { volatile Float dbl; volatile Term *t_dbl = (Term *)((void *) &dbl); *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; - } else if (mode == TRAVERSE_LONG) { + mode = TRAVERSE_MODE_NORMAL; + } else if (mode == TRAVERSE_MODE_LONG) { Int li = (Int) t; #if SHORT_INTS 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)) { #if SHORT_INTS 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)) { Functor f = (Functor) RepAppl(t); if (f == FunctorDouble) { - mode = TRAVERSE_FLOAT; + mode = TRAVERSE_MODE_FLOAT; } else if (f == FunctorLongInt) { - mode = TRAVERSE_LONG; + mode = TRAVERSE_MODE_LONG; } else { str_index += sprintf(& str[str_index], "%s(", AtomName(NameOfFunctor(f))); 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"); } else { 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) { TrStat_sg_incomplete++; SHOW_TABLE(" ---> INCOMPLETE\n"); } } } - /* ... or continue with child node */ 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; } 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; /* test if hashing */ if (IS_ANSWER_HASH(ans_node)) { ans_node_ptr *bucket, *last_bucket; 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; bucket = Hash_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 { if (*bucket) { - ans_node = *bucket; - traverse_answer_trie(ans_node, str, str_index, arity, var_index, depth, mode); + traverse_answer_trie(*bucket, str, str_index, arity, var_index, depth, mode, TRAVERSE_POSITION_FIRST); memcpy(arity, current_arity, sizeof(int) * (current_arity[0] + 1)); #ifdef TRIE_COMPACT_PAIRS 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; } - /* test if sibling node */ - if (TrNode_next(ans_node)) { - int *current_arity = (int *) malloc(sizeof(int) * (arity[0] + 1)); + /* save current state if first sibling node */ + if (position == TRAVERSE_POSITION_FIRST) { + current_arity = (int *) malloc(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); - memcpy(arity, current_arity, sizeof(int) * (current_arity[0] + 1)); - 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 */ + current_str_index = str_index; + current_var_index = var_index; + current_mode = mode; } /* 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); var_index++; } /* test the node type */ t = TrNode_entry(ans_node); - if (mode == TRAVERSE_FLOAT) { + if (mode == TRAVERSE_MODE_FLOAT) { #if SIZEOF_DOUBLE == 2 * SIZEOF_INT_P arity[0]++; arity[arity[0]] = (int) t; - mode = TRAVERSE_FLOAT2; - } else if (mode == TRAVERSE_FLOAT2) { + mode = TRAVERSE_MODE_FLOAT2; + } else if (mode == TRAVERSE_MODE_FLOAT2) { volatile Float dbl; volatile Term *t_dbl = (Term *)((void *) &dbl); *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; - } else if (mode == TRAVERSE_FLOAT_END) { - mode = TRAVERSE_NORMAL; - } else if (mode == TRAVERSE_LONG) { + mode = TRAVERSE_MODE_FLOAT_END; + } else if (mode == TRAVERSE_MODE_FLOAT_END) { + mode = TRAVERSE_MODE_NORMAL; + } else if (mode == TRAVERSE_MODE_LONG) { Int li = (Int) t; #if SHORT_INTS 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; - } else if (mode == TRAVERSE_LONG_END) { - mode = TRAVERSE_NORMAL; + mode = TRAVERSE_MODE_LONG_END; + } else if (mode == TRAVERSE_MODE_LONG_END) { + mode = TRAVERSE_MODE_NORMAL; } else if (IsVarTerm(t)) { #if SHORT_INTS 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)) { Functor f = (Functor) RepAppl(t); if (f == FunctorDouble) { - mode = TRAVERSE_FLOAT; + mode = TRAVERSE_MODE_FLOAT; } else if (f == FunctorLongInt) { - mode = TRAVERSE_LONG; + mode = TRAVERSE_MODE_LONG; } else { str_index += sprintf(& str[str_index], "%s(", AtomName(NameOfFunctor(f))); 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) TrStat_ans_max_depth = depth; } - #ifdef TABLING_INNER_CUTS /* ... or continue with pruned node */ else if (TrNode_child(ans_node) == NULL) TrStat_ans_pruned++; #endif /* TABLING_INNER_CUTS */ - /* ... or continue with child node */ 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; }