Merge branch 'rtries' of git.dcc.fc.up.pt:yap-6.3

Conflicts:
	OPTYap/tab.insts.i
	OPTYap/tab.tries.c
	OPTYap/tab.tries.i
This commit is contained in:
Vitor Santos Costa 2014-02-13 11:57:46 +00:00
commit d0efa26d8b
15 changed files with 1556 additions and 1031 deletions

View File

@ -1680,6 +1680,8 @@ p_access_yap_flags( USES_REGS1 )
tout = MkPairTerm(MkAtomTerm(AtomLocal), tout); tout = MkPairTerm(MkAtomTerm(AtomLocal), tout);
else if (IsMode_Batched(yap_flags[flag])) else if (IsMode_Batched(yap_flags[flag]))
tout = MkPairTerm(MkAtomTerm(AtomBatched), tout); tout = MkPairTerm(MkAtomTerm(AtomBatched), tout);
else if (IsMode_CoInductive(yap_flags[flag]))
tout = MkPairTerm(MkAtomTerm(AtomCoInductive), tout);
#else #else
tout = MkAtomTerm(AtomFalse); tout = MkAtomTerm(AtomFalse);
#endif /* TABLING */ #endif /* TABLING */
@ -1822,6 +1824,13 @@ p_set_yap_flags( USES_REGS1 )
tab_ent = TabEnt_next(tab_ent); tab_ent = TabEnt_next(tab_ent);
} }
SetMode_GlobalTrie(yap_flags[TABLING_MODE_FLAG]); SetMode_GlobalTrie(yap_flags[TABLING_MODE_FLAG]);
} else if (value == 7) { /* CoInductive */
tab_ent_ptr tab_ent = GLOBAL_root_tab_ent;
while(tab_ent) {
SetMode_CoInductive(TabEnt_mode(tab_ent));
tab_ent = TabEnt_next(tab_ent);
}
SetMode_CoInductive(yap_flags[TABLING_MODE_FLAG]);
} }
break; break;
#endif /* TABLING */ #endif /* TABLING */

View File

@ -54,6 +54,7 @@
AtomColomn = Yap_LookupAtom(":"); AtomColomn = Yap_LookupAtom(":");
AtomCodeSpace = Yap_LookupAtom("code_space"); AtomCodeSpace = Yap_LookupAtom("code_space");
AtomCodes = Yap_LookupAtom("codes"); AtomCodes = Yap_LookupAtom("codes");
AtomCoInductive = Yap_LookupAtom("coinductive");
AtomComma = Yap_LookupAtom(","); AtomComma = Yap_LookupAtom(",");
AtomCommentHook = Yap_LookupAtom("comment_hook"); AtomCommentHook = Yap_LookupAtom("comment_hook");
AtomCompound = Yap_LookupAtom("compound"); AtomCompound = Yap_LookupAtom("compound");

View File

@ -54,6 +54,7 @@
AtomColomn = AtomAdjust(AtomColomn); AtomColomn = AtomAdjust(AtomColomn);
AtomCodeSpace = AtomAdjust(AtomCodeSpace); AtomCodeSpace = AtomAdjust(AtomCodeSpace);
AtomCodes = AtomAdjust(AtomCodes); AtomCodes = AtomAdjust(AtomCodes);
AtomCoInductive = AtomAdjust(AtomCoInductive);
AtomComma = AtomAdjust(AtomComma); AtomComma = AtomAdjust(AtomComma);
AtomCommentHook = AtomAdjust(AtomCommentHook); AtomCommentHook = AtomAdjust(AtomCommentHook);
AtomCompound = AtomAdjust(AtomCompound); AtomCompound = AtomAdjust(AtomCompound);

View File

@ -106,6 +106,8 @@
#define AtomCodeSpace Yap_heap_regs->AtomCodeSpace_ #define AtomCodeSpace Yap_heap_regs->AtomCodeSpace_
Atom AtomCodes_; Atom AtomCodes_;
#define AtomCodes Yap_heap_regs->AtomCodes_ #define AtomCodes Yap_heap_regs->AtomCodes_
Atom AtomCoInductive_;
#define AtomCoInductive Yap_heap_regs->AtomCoInductive_
Atom AtomComma_; Atom AtomComma_;
#define AtomComma Yap_heap_regs->AtomComma_ #define AtomComma Yap_heap_regs->AtomComma_
Atom AtomCommentHook_; Atom AtomCommentHook_;

110
ICLP2014_examples.yap Normal file
View File

@ -0,0 +1,110 @@
:- initialization(yap_flag(tabling_mode, load_answers)).
% Required to activate rational term support within the table space.
/*
ICLP2014 submission - instack/2
*/
instack(E, [H|T]) :- E == H.
instack(E, [_H|T]) :- instack(E, T).
/*
ICLP2014 submission - Example 1. member_1/2
Cyclic safe predicate with the use of instack/2 predicate.
*/
member_1(E, L) :-
member(E, L, []).
member(E, [E|_T], _).
member(_E, L, S) :-
instack(L, S),
!,
fail.
member(E, [H|T], S) :-
member(E, T, [[H|T]|S]).
/*
ICLP2014 submission - Example 2. member_2/2
Cyclic safe predicate with the use of tabling.
*/
:- table member_2/2.
member_2(E, [E|_T]).
member_2(E, [_H|T]) :-
member_2(E, T).
/*
ICLP2014 submission - Example 3. bin/1
*/
:- table bin/1.
:- tabling_mode(bin/1, coinductive).
% The two above directives are the equivalent of the :- coinductive bin/1 directive
bin([0|T]) :- bin(T).
bin([1|T]) :- bin(T).
/*
ICLP2014 submission - Example 4. comember/2
*/
:- table comember/2.
:- tabling_mode(comember/2, coinductive).
% The two above directives are the equivalent of the :- coinductive comember/2 directive
comember(H, L) :-
drop(H, L, L1),
comember(H, L1).
:- table(drop/3).
drop(H, [H|T], T).
drop(H, [_|T], T1) :- drop(H, T, T1).
%%%%%%%%%%
/*
ICLP2014 submission - Example 5. alternative drop_2/3 definition.
This definition uses instack instead of tabling.
*/
drop_2(E, L, NL) :-
drop(E, L, NL, []).
drop(_E, L, _NL, S) :-
instack(L, S),
!,
fail.
drop(E, [E|T], T, _).
drop(E, [H|T], T1, S) :-
drop(E, T, T1, [[H|T]|S]).
/*
ICLP2014 submission - Example 6. canonical_term/2
The following predicate takes a rational term and returns
the same rational term in canonical form.
*/
canonical_term(Term, Canonical) :-
Term =.. InList,
decompose_cyclic_term(Term, InList, OutList, OpenEnd, [Term]),
Canonical =.. OutList,
Canonical = OpenEnd.
decompose_cyclic_term(_CyclicTerm, [], [], _OpenEnd, _Stack).
decompose_cyclic_term(CyclicTerm, [Term|Tail], [Term|NewTail], OpenEnd, Stack) :-
acyclic_term(Term), !,
decompose_cyclic_term(CyclicTerm, Tail, NewTail, OpenEnd, Stack).
decompose_cyclic_term(CyclicTerm, [Term|Tail], [OpenEnd|NewTail], OpenEnd, Stack) :-
CyclicTerm == Term, !,
decompose_cyclic_term(CyclicTerm, Tail, NewTail, OpenEnd, Stack).
decompose_cyclic_term(CyclicTerm, [Term|Tail], [Canonical|NewTail], OpenEnd, Stack) :-
\+ instack(Term, Stack), !,
Term =.. InList,
decompose_cyclic_term(Term, InList, OutList, OpenEnd2, [Term|Stack]),
Canonical =.. OutList,
( Canonical = OpenEnd2,
Canonical == Term,
!
; OpenEnd2 = OpenEnd
),
decompose_cyclic_term(CyclicTerm, Tail, NewTail, OpenEnd, Stack).
decompose_cyclic_term(CyclicTerm, [_Term|Tail], [OpenEnd|NewTail], OpenEnd, Stack) :-
decompose_cyclic_term(CyclicTerm, Tail, NewTail, OpenEnd, Stack).

View File

@ -148,6 +148,10 @@
**************************************************/ **************************************************/
/* #define OUTPUT_THREADS_TABLING 1 */ /* #define OUTPUT_THREADS_TABLING 1 */
/*********************************************************
** support rational terms ? (optional) **
*********************************************************/
#define TRIE_RATIONAL_TERMS 1

View File

@ -404,6 +404,8 @@ static Int p_tabling_mode( USES_REGS1 ) {
t = MkPairTerm(MkAtomTerm(AtomBatched), t); t = MkPairTerm(MkAtomTerm(AtomBatched), t);
else if (IsMode_Local(TabEnt_flags(tab_ent))) else if (IsMode_Local(TabEnt_flags(tab_ent)))
t = MkPairTerm(MkAtomTerm(AtomLocal), t); t = MkPairTerm(MkAtomTerm(AtomLocal), t);
if (IsMode_CoInductive(TabEnt_flags(tab_ent)))
t = MkPairTerm(MkAtomTerm(AtomCoInductive), t);
t = MkPairTerm(MkAtomTerm(AtomDefault), t); t = MkPairTerm(MkAtomTerm(AtomDefault), t);
t = MkPairTerm(t, TermNil); t = MkPairTerm(t, TermNil);
if (IsMode_LocalTrie(TabEnt_mode(tab_ent))) if (IsMode_LocalTrie(TabEnt_mode(tab_ent)))
@ -458,6 +460,9 @@ static Int p_tabling_mode( USES_REGS1 ) {
SetMode_GlobalTrie(TabEnt_mode(tab_ent)); SetMode_GlobalTrie(TabEnt_mode(tab_ent));
return(TRUE); return(TRUE);
} }
} else if (value == 7) { /* coinductive */ //only affect the predicate flag. Also it cant be unset
SetMode_CoInductive(TabEnt_flags(tab_ent));
return(TRUE);
} }
} }
return (FALSE); return (FALSE);

View File

@ -513,6 +513,9 @@
GONext(); GONext();
#ifdef INCOMPLETE_TABLING #ifdef INCOMPLETE_TABLING
} else if (SgFr_state(sg_fr) == incomplete) { } else if (SgFr_state(sg_fr) == incomplete) {
if (IsMode_CoInductive(TabEnt_flags(tab_ent))) {
printf("Currently Unsupported\n");
} else {
/* subgoal incomplete --> start by loading the answers already found */ /* subgoal incomplete --> start by loading the answers already found */
ans_node_ptr ans_node = SgFr_first_answer(sg_fr); ans_node_ptr ans_node = SgFr_first_answer(sg_fr);
CELL *subs_ptr = YENV; CELL *subs_ptr = YENV;
@ -525,17 +528,32 @@
load_answer(ans_node, subs_ptr); load_answer(ans_node, subs_ptr);
YENV = ENV; YENV = ENV;
GONext(); GONext();
}
#endif /* INCOMPLETE_TABLING */ #endif /* INCOMPLETE_TABLING */
} else if (SgFr_state(sg_fr) == evaluating) { } else if (SgFr_state(sg_fr) == evaluating) {
if (IsMode_CoInductive(TabEnt_flags(tab_ent))) {
/* Used for coinductive tabling strategy */
CELL *subs_ptr;
subs_ptr = (CELL *) (GEN_CP(SgFr_gen_cp(sg_fr)) + 1);
subs_ptr += SgFr_arity(sg_fr); // Points at the Parent goal Variables
int i;
for (i = 0; i < subs_ptr[0]; i++)
Yap_unify(subs_ptr[i+1], YENV[i+1]);
/* yes answer --> procceed */
UNLOCK_SG_FR(sg_fr);
PREG = (yamop *) CPREG;
PREFETCH_OP(PREG);
YENV = ENV; // Consume the variables
GONext(); // Succeed the goal :-D
} else {
/* subgoal in evaluation */ /* subgoal in evaluation */
choiceptr leader_cp; choiceptr leader_cp;
#if YAPOR
int leader_dep_on_stack; int leader_dep_on_stack;
#endif
find_dependency_node(sg_fr, leader_cp, leader_dep_on_stack); find_dependency_node(sg_fr, leader_cp, leader_dep_on_stack);
UNLOCK_SG_FR(sg_fr); UNLOCK_SG_FR(sg_fr);
find_leader_node(leader_cp, leader_dep_on_stack); find_leader_node(leader_cp, leader_dep_on_stack);
store_consumer_node(tab_ent, sg_fr, leader_cp, leader_dep_on_stack); store_consumer_node(tab_ent, sg_fr, leader_cp, leader_dep_on_stack);
}
#ifdef DEBUG_OPTYAP #ifdef DEBUG_OPTYAP
if (GLOBAL_parallel_mode == PARALLEL_MODE_RUNNING) { if (GLOBAL_parallel_mode == PARALLEL_MODE_RUNNING) {
choiceptr aux_cp; choiceptr aux_cp;
@ -655,6 +673,9 @@
GONext(); GONext();
#ifdef INCOMPLETE_TABLING #ifdef INCOMPLETE_TABLING
} else if (SgFr_state(sg_fr) == incomplete) { } else if (SgFr_state(sg_fr) == incomplete) {
if (IsMode_CoInductive(TabEnt_flags(tab_ent))) {
printf("Currently Unsupported\n");
} else {
/* subgoal incomplete --> start by loading the answers already found */ /* subgoal incomplete --> start by loading the answers already found */
ans_node_ptr ans_node = SgFr_first_answer(sg_fr); ans_node_ptr ans_node = SgFr_first_answer(sg_fr);
CELL *subs_ptr = YENV; CELL *subs_ptr = YENV;
@ -667,17 +688,20 @@
load_answer(ans_node, subs_ptr); load_answer(ans_node, subs_ptr);
YENV = ENV; YENV = ENV;
GONext(); GONext();
}
#endif /* INCOMPLETE_TABLING */ #endif /* INCOMPLETE_TABLING */
} else if (SgFr_state(sg_fr) == evaluating) { } else if (SgFr_state(sg_fr) == evaluating) {
if (IsMode_CoInductive(TabEnt_flags(tab_ent))) {
printf("Currently Unsupported\n");
} else {
/* subgoal in evaluation */ /* subgoal in evaluation */
choiceptr leader_cp; choiceptr leader_cp;
#if YAPOR
int leader_dep_on_stack; int leader_dep_on_stack;
#endif
find_dependency_node(sg_fr, leader_cp, leader_dep_on_stack); find_dependency_node(sg_fr, leader_cp, leader_dep_on_stack);
UNLOCK_SG_FR(sg_fr); UNLOCK_SG_FR(sg_fr);
find_leader_node(leader_cp, leader_dep_on_stack); find_leader_node(leader_cp, leader_dep_on_stack);
store_consumer_node(tab_ent, sg_fr, leader_cp, leader_dep_on_stack); store_consumer_node(tab_ent, sg_fr, leader_cp, leader_dep_on_stack);
}
#ifdef DEBUG_OPTYAP #ifdef DEBUG_OPTYAP
if (GLOBAL_parallel_mode == PARALLEL_MODE_RUNNING) { if (GLOBAL_parallel_mode == PARALLEL_MODE_RUNNING) {
choiceptr aux_cp; choiceptr aux_cp;
@ -797,6 +821,9 @@
GONext(); GONext();
#ifdef INCOMPLETE_TABLING #ifdef INCOMPLETE_TABLING
} else if (SgFr_state(sg_fr) == incomplete) { } else if (SgFr_state(sg_fr) == incomplete) {
if (IsMode_CoInductive(TabEnt_flags(tab_ent))) {
printf("Currently Unsupported\n");
} else {
/* subgoal incomplete --> start by loading the answers already found */ /* subgoal incomplete --> start by loading the answers already found */
ans_node_ptr ans_node = SgFr_first_answer(sg_fr); ans_node_ptr ans_node = SgFr_first_answer(sg_fr);
CELL *subs_ptr = YENV; CELL *subs_ptr = YENV;
@ -809,17 +836,32 @@
load_answer(ans_node, subs_ptr); load_answer(ans_node, subs_ptr);
YENV = ENV; YENV = ENV;
GONext(); GONext();
}
#endif /* INCOMPLETE_TABLING */ #endif /* INCOMPLETE_TABLING */
} else if (SgFr_state(sg_fr) == evaluating) { } else if (SgFr_state(sg_fr) == evaluating) {
if (IsMode_CoInductive(TabEnt_flags(tab_ent))) {
/* Used for coinductive tabling strategy */
CELL *subs_ptr;
subs_ptr = (CELL *) (GEN_CP(SgFr_gen_cp(sg_fr)) + 1);
subs_ptr += SgFr_arity(sg_fr); // Points at the Parent goal Variables
int i;
for (i = 0; i < subs_ptr[0]; i++)
Yap_unify(subs_ptr[i+1], YENV[i+1]);
/* yes answer --> procceed */
UNLOCK_SG_FR(sg_fr);
PREG = (yamop *) CPREG;
PREFETCH_OP(PREG);
YENV = ENV; // Consume the variables
GONext(); // Succeed the goal :-D
} else {
/* subgoal in evaluation */ /* subgoal in evaluation */
choiceptr leader_cp; choiceptr leader_cp;
#if YAPOR
int leader_dep_on_stack; int leader_dep_on_stack;
#endif
find_dependency_node(sg_fr, leader_cp, leader_dep_on_stack); find_dependency_node(sg_fr, leader_cp, leader_dep_on_stack);
UNLOCK_SG_FR(sg_fr); UNLOCK_SG_FR(sg_fr);
find_leader_node(leader_cp, leader_dep_on_stack); find_leader_node(leader_cp, leader_dep_on_stack);
store_consumer_node(tab_ent, sg_fr, leader_cp, leader_dep_on_stack); store_consumer_node(tab_ent, sg_fr, leader_cp, leader_dep_on_stack);
}
#ifdef DEBUG_OPTYAP #ifdef DEBUG_OPTYAP
if (GLOBAL_parallel_mode == PARALLEL_MODE_RUNNING) { if (GLOBAL_parallel_mode == PARALLEL_MODE_RUNNING) {
choiceptr aux_cp; choiceptr aux_cp;

View File

@ -88,6 +88,7 @@ static inline tg_sol_fr_ptr CUT_prune_tg_solution_frames(tg_sol_fr_ptr, int);
#define Flag_LocalTrie 0x100 #define Flag_LocalTrie 0x100
#define Flag_GlobalTrie 0x200 #define Flag_GlobalTrie 0x200
#define Flags_TrieMode (Flag_LocalTrie | Flag_GlobalTrie) #define Flags_TrieMode (Flag_LocalTrie | Flag_GlobalTrie)
#define Flag_CoInductive 0x008
#define SetMode_Batched(X) (X) = ((X) & ~Flags_SchedulingMode) | Flag_Batched #define SetMode_Batched(X) (X) = ((X) & ~Flags_SchedulingMode) | Flag_Batched
#define SetMode_Local(X) (X) = ((X) & ~Flags_SchedulingMode) | Flag_Local #define SetMode_Local(X) (X) = ((X) & ~Flags_SchedulingMode) | Flag_Local
@ -95,12 +96,14 @@ static inline tg_sol_fr_ptr CUT_prune_tg_solution_frames(tg_sol_fr_ptr, int);
#define SetMode_LoadAnswers(X) (X) = ((X) & ~Flags_AnswersMode) | Flag_LoadAnswers #define SetMode_LoadAnswers(X) (X) = ((X) & ~Flags_AnswersMode) | Flag_LoadAnswers
#define SetMode_LocalTrie(X) (X) = ((X) & ~Flags_TrieMode) | Flag_LocalTrie #define SetMode_LocalTrie(X) (X) = ((X) & ~Flags_TrieMode) | Flag_LocalTrie
#define SetMode_GlobalTrie(X) (X) = ((X) & ~Flags_TrieMode) | Flag_GlobalTrie #define SetMode_GlobalTrie(X) (X) = ((X) & ~Flags_TrieMode) | Flag_GlobalTrie
#define SetMode_CoInductive(X) (X) = (X) | Flag_CoInductive
#define IsMode_Batched(X) ((X) & Flag_Batched) #define IsMode_Batched(X) ((X) & Flag_Batched)
#define IsMode_Local(X) ((X) & Flag_Local) #define IsMode_Local(X) ((X) & Flag_Local)
#define IsMode_ExecAnswers(X) ((X) & Flag_ExecAnswers) #define IsMode_ExecAnswers(X) ((X) & Flag_ExecAnswers)
#define IsMode_LoadAnswers(X) ((X) & Flag_LoadAnswers) #define IsMode_LoadAnswers(X) ((X) & Flag_LoadAnswers)
#define IsMode_LocalTrie(X) ((X) & Flag_LocalTrie) #define IsMode_LocalTrie(X) ((X) & Flag_LocalTrie)
#define IsMode_GlobalTrie(X) ((X) & Flag_GlobalTrie) #define IsMode_GlobalTrie(X) ((X) & Flag_GlobalTrie)
#define IsMode_CoInductive(X) ((X) & Flag_CoInductive)

77
OPTYap/tab.rational.i Normal file
View File

@ -0,0 +1,77 @@
/************************************************************************
** **
** The YapTab/YapOr/OPTYap systems **
** **
** YapTab extends the Yap Prolog engine to support sequential tabling **
** YapOr extends the Yap Prolog engine to support or-parallelism **
** OPTYap extends the Yap Prolog engine to support or-parallel tabling **
** **
** **
** Yap Prolog was developed at University of Porto, Portugal **
** **
************************************************************************/
#define RationalMark 7 //0m0...111
#define IsRationalTerm(TERM) ((int) TERM == 7)
typedef struct term_array {
void* *terms;
void* *nodes;
size_t length;
size_t capacity;
} term_array;
void term_array_init(term_array *array, int capacity);
void term_array_free(term_array *array);
void term_array_push(term_array *array, void* t, void* n);
void* term_array_member(term_array array, void* t);
void term_array_init(term_array *array, int capacity) {
array->length = 0;
array->terms = malloc(capacity * sizeof(void*));
if (array->terms != NULL) {
array->capacity = capacity;
} else
Yap_Error(RESOURCE_ERROR_MEMORY, TermNil, "Out of memory."); // Handle out-of-memory
array->capacity = capacity;
array->nodes = malloc(capacity * sizeof(void*));
if (array->nodes == NULL)
Yap_Error(RESOURCE_ERROR_MEMORY, TermNil, "Out of memory."); // Handle out-of-memory
}
void term_array_free(term_array *array) {
free(array->terms);
free(array->nodes);
array->terms = NULL;
array->nodes = NULL;
array->length = 0;
array->capacity = 0;
}
void term_array_push(term_array *array, void* t, void* n) {
if (array->length == array->capacity) {
int new_capacity = array->capacity * 2;
void *new_terms = realloc(array->terms, new_capacity * sizeof(void*));
if (new_terms != NULL) {
array->terms = new_terms;
} else
Yap_Error(RESOURCE_ERROR_MEMORY, TermNil, "Out of memory."); // Handle out-of-memory
void *new_nodes = realloc(array->nodes, new_capacity * sizeof(void *));
if (new_nodes != NULL) {
array->nodes = new_nodes;
} else
Yap_Error(RESOURCE_ERROR_MEMORY, TermNil, "Out of memory."); // Handle out-of-memory
array->capacity = new_capacity;
}
array->terms[array->length] = t;
array->nodes[array->length] = n;
array->length++;
}
void* term_array_member(term_array array, void* t) {
int i;
for (i = 0; i < array.length; i++)
if (array.terms[i] == t) return array.nodes[i];
return NULL;
}

View File

@ -149,7 +149,7 @@ static struct trie_statistics{
#define CHECK_DECREMENT_GLOBAL_TRIE_REFERENCE(REF,MODE) \ #define CHECK_DECREMENT_GLOBAL_TRIE_REFERENCE(REF,MODE) \
if (MODE == TRAVERSE_MODE_NORMAL && IsVarTerm(REF) && REF > VarIndexOfTableTerm(MAX_TABLE_VARS)) { \ if (MODE == TRAVERSE_MODE_NORMAL && IsVarTerm(REF) && REF > VarIndexOfTableTerm(MAX_TABLE_VARS)) { \
register gt_node_ptr gt_node = (gt_node_ptr) (REF); \ register gt_node_ptr gt_node = (gt_node_ptr) (REF); \
TrNode_child(gt_node) = (gt_node_ptr) ((UInt) TrNode_child(gt_node) - 1); \ TrNode_child(gt_node) = (gt_node_ptr) ((unsigned long int) TrNode_child(gt_node) - 1); \
if (TrNode_child(gt_node) == 0) \ if (TrNode_child(gt_node) == 0) \
FREE_GLOBAL_TRIE_BRANCH(gt_node,TRAVERSE_MODE_NORMAL); \ FREE_GLOBAL_TRIE_BRANCH(gt_node,TRAVERSE_MODE_NORMAL); \
} }
@ -164,6 +164,12 @@ static struct trie_statistics{
free_global_trie_branch(NODE PASS_REGS) free_global_trie_branch(NODE PASS_REGS)
#endif /* GLOBAL_TRIE_FOR_SUBTERMS */ #endif /* GLOBAL_TRIE_FOR_SUBTERMS */
/******************************
** Rational Terms Support **
******************************/
#ifdef TRIE_RATIONAL_TERMS
#include "tab.rational.i"
#endif /* RATIONAL TERM SUPPORT FOR TRIES */
/****************************** /******************************
@ -201,7 +207,13 @@ static struct trie_statistics{
#define MODE_TERMS_LOOP #define MODE_TERMS_LOOP
#define INCLUDE_SUBGOAL_SEARCH_LOOP /* subgoal_search_terms_loop */ #define INCLUDE_SUBGOAL_SEARCH_LOOP /* subgoal_search_terms_loop */
#define INCLUDE_ANSWER_SEARCH_LOOP /* answer_search_terms_loop */ #define INCLUDE_ANSWER_SEARCH_LOOP /* answer_search_terms_loop */
#ifdef TRIE_RATIONAL_TERMS
#undef TRIE_RATIONAL_TERMS
#include "tab.tries.i" #include "tab.tries.i"
#define TRIE_RATIONAL_TERMS
#else
#include "tab.tries.i"
#endif
#undef INCLUDE_ANSWER_SEARCH_LOOP #undef INCLUDE_ANSWER_SEARCH_LOOP
#undef INCLUDE_SUBGOAL_SEARCH_LOOP #undef INCLUDE_SUBGOAL_SEARCH_LOOP
#undef MODE_TERMS_LOOP #undef MODE_TERMS_LOOP
@ -210,7 +222,13 @@ static struct trie_statistics{
#define INCLUDE_SUBGOAL_SEARCH_LOOP /* subgoal_search_global_trie_(terms)_loop */ #define INCLUDE_SUBGOAL_SEARCH_LOOP /* subgoal_search_global_trie_(terms)_loop */
#define INCLUDE_ANSWER_SEARCH_LOOP /* answer_search_global_trie_(terms)_loop */ #define INCLUDE_ANSWER_SEARCH_LOOP /* answer_search_global_trie_(terms)_loop */
#define INCLUDE_LOAD_ANSWER_LOOP /* load_substitution_loop */ #define INCLUDE_LOAD_ANSWER_LOOP /* load_substitution_loop */
#ifdef TRIE_RATIONAL_TERMS
#undef TRIE_RATIONAL_TERMS
#include "tab.tries.i" #include "tab.tries.i"
#define TRIE_RATIONAL_TERMS
#else
#include "tab.tries.i"
#endif
#undef INCLUDE_LOAD_ANSWER_LOOP #undef INCLUDE_LOAD_ANSWER_LOOP
#undef INCLUDE_ANSWER_SEARCH_LOOP #undef INCLUDE_ANSWER_SEARCH_LOOP
#undef INCLUDE_SUBGOAL_SEARCH_LOOP #undef INCLUDE_SUBGOAL_SEARCH_LOOP
@ -377,11 +395,6 @@ static struct trie_statistics{
current_node = TrNode_parent(current_node); current_node = TrNode_parent(current_node);
current_node = TrNode_parent(current_node); current_node = TrNode_parent(current_node);
t = MkLongIntTerm(li); t = MkLongIntTerm(li);
} else if (f == FunctorBigInt || f == FunctorString) {
CELL *li = (CELL *)TrNode_entry(current_node);
current_node = TrNode_parent(current_node);
current_node = TrNode_parent(current_node);
t = AbsAppl(li);
} else { } else {
int f_arity = ArityOfFunctor(f); int f_arity = ArityOfFunctor(f);
t = Yap_MkApplTerm(f, f_arity, stack_terms); t = Yap_MkApplTerm(f, f_arity, stack_terms);
@ -571,11 +584,11 @@ static struct trie_statistics{
mode = TRAVERSE_MODE_NORMAL; mode = TRAVERSE_MODE_NORMAL;
} else } else
mode = TRAVERSE_MODE_NORMAL; mode = TRAVERSE_MODE_NORMAL;
} else if (mode == TRAVERSE_MODE_LONGINT) } else if (mode == TRAVERSE_MODE_LONGINT) {
mode = TRAVERSE_MODE_LONGINT_END; mode = TRAVERSE_MODE_LONGINT_END;
} else if (mode == TRAVERSE_MODE_BIGINT_OR_STRING) } else if (mode == TRAVERSE_MODE_BIGINT_OR_STRING) {
mode = TRAVERSE_MODE_BIGINT_OR_STRING_END; mode = TRAVERSE_MODE_BIGINT_OR_STRING_END;
else if (mode == TRAVERSE_MODE_DOUBLE) } else if (mode == TRAVERSE_MODE_DOUBLE)
#if SIZEOF_DOUBLE == 2 * SIZEOF_INT_P #if SIZEOF_DOUBLE == 2 * SIZEOF_INT_P
mode = TRAVERSE_MODE_DOUBLE2; mode = TRAVERSE_MODE_DOUBLE2;
else if (mode == TRAVERSE_MODE_DOUBLE2) else if (mode == TRAVERSE_MODE_DOUBLE2)
@ -829,7 +842,7 @@ static struct trie_statistics{
else { else {
TrStat_gt_terms++; TrStat_gt_terms++;
str[str_index] = 0; str[str_index] = 0;
SHOW_TABLE_STRUCTURE(" TERMx%ld: %s\n", (UInt) TrNode_child(current_node), str); SHOW_TABLE_STRUCTURE(" TERMx%ld: %s\n", (unsigned long int) TrNode_child(current_node), str);
} }
/* restore the initial state and continue with sibling nodes */ /* restore the initial state and continue with sibling nodes */
@ -900,7 +913,11 @@ static struct trie_statistics{
mode = TRAVERSE_MODE_NORMAL; mode = TRAVERSE_MODE_NORMAL;
} else if (mode == TRAVERSE_MODE_LONGINT) { } else if (mode == TRAVERSE_MODE_LONGINT) {
Int li = (Int) t; Int li = (Int) t;
str_index += sprintf(& str[str_index], UInt_FORMAT, li); #if SHORT_INTS
str_index += sprintf(& str[str_index], "%ld", li);
#else
str_index += sprintf(& str[str_index], "%d", li);
#endif /* SHORT_INTS */
traverse_update_arity(str, &str_index, arity); traverse_update_arity(str, &str_index, arity);
if (type == TRAVERSE_TYPE_SUBGOAL) if (type == TRAVERSE_TYPE_SUBGOAL)
mode = TRAVERSE_MODE_NORMAL; mode = TRAVERSE_MODE_NORMAL;
@ -918,6 +935,13 @@ static struct trie_statistics{
} else if (mode == TRAVERSE_MODE_BIGINT_OR_STRING_END) { } else if (mode == TRAVERSE_MODE_BIGINT_OR_STRING_END) {
mode = TRAVERSE_MODE_NORMAL; mode = TRAVERSE_MODE_NORMAL;
} else if (IsVarTerm(t)) { } else if (IsVarTerm(t)) {
#ifdef TRIE_RATIONAL_TERMS
if (t > VarIndexOfTableTerm(MAX_TABLE_VARS) && TrNode_child((gt_node_ptr) t) != (gt_node_ptr)1) { //TODO: substitute the != 1 test to something more appropriate
/* Rational term */
str_index += sprintf(& str[str_index], "**");
traverse_update_arity(str, &str_index, arity);
} else
#endif /* RATIONAL TERM SUPPORT FOR TRIES */
if (t > VarIndexOfTableTerm(MAX_TABLE_VARS)) { if (t > VarIndexOfTableTerm(MAX_TABLE_VARS)) {
TrStat_gt_refs++; TrStat_gt_refs++;
/* (type % 2 + 2): TRAVERSE_TYPE_ANSWER --> TRAVERSE_TYPE_GT_ANSWER */ /* (type % 2 + 2): TRAVERSE_TYPE_ANSWER --> TRAVERSE_TYPE_GT_ANSWER */
@ -931,7 +955,11 @@ static struct trie_statistics{
traverse_update_arity(str, &str_index, arity); traverse_update_arity(str, &str_index, arity);
} }
} else if (IsIntTerm(t)) { } else if (IsIntTerm(t)) {
str_index += sprintf(& str[str_index], Int_FORMAT, IntOfTerm(t)); #if SHORT_INTS
str_index += sprintf(& str[str_index], "%ld", IntOfTerm(t));
#else
str_index += sprintf(& str[str_index], "%d", IntOfTerm(t));
#endif /* SHORT_INTS */
traverse_update_arity(str, &str_index, arity); traverse_update_arity(str, &str_index, arity);
} else if (IsAtomTerm(t)) { } else if (IsAtomTerm(t)) {
#ifndef TRIE_COMPACT_PAIRS #ifndef TRIE_COMPACT_PAIRS

View File

@ -1048,6 +1048,13 @@ static inline sg_node_ptr subgoal_search_loop(tab_ent_ptr tab_ent, sg_node_ptr c
goto subgoal_search_loop_non_atomic; goto subgoal_search_loop_non_atomic;
#endif /* MODE_GLOBAL_TRIE_LOOP */ #endif /* MODE_GLOBAL_TRIE_LOOP */
#ifdef TRIE_RATIONAL_TERMS
/* Needed structures, variables to support rational terms */
term_array Ts;
void* CyclicTerm;
term_array_init(&Ts, 10);
#endif /* RATIONAL TERM SUPPORT FOR TRIES */
do { do {
if (IsVarTerm(t)) { if (IsVarTerm(t)) {
if (IsTableVarTerm(t)) { if (IsTableVarTerm(t)) {
@ -1075,18 +1082,42 @@ static inline sg_node_ptr subgoal_search_loop(tab_ent_ptr tab_ent, sg_node_ptr c
current_node = subgoal_trie_check_insert_gt_entry(tab_ent, current_node, (Term) entry_node PASS_REGS); current_node = subgoal_trie_check_insert_gt_entry(tab_ent, current_node, (Term) entry_node PASS_REGS);
#else /* ! MODE_TERMS_LOOP */ #else /* ! MODE_TERMS_LOOP */
} else } else
#ifdef TRIE_RATIONAL_TERMS
if (IsRationalTerm(t)) {
t = STACK_POP_DOWN(stack_terms);
SUBGOAL_CHECK_INSERT_ENTRY(tab_ent, current_node, t);
} else
#endif /* RATIONAL TERM SUPPORT FOR TRIES */
#if defined(MODE_GLOBAL_TRIE_LOOP) #if defined(MODE_GLOBAL_TRIE_LOOP)
/* for the global trie, it is safe to start here in the first iteration */ /* for the global trie, it is safe to start here in the first iteration */
subgoal_search_loop_non_atomic: subgoal_search_loop_non_atomic:
#endif /* MODE_GLOBAL_TRIE_LOOP */ #endif /* MODE_GLOBAL_TRIE_LOOP */
#ifdef TRIE_COMPACT_PAIRS #ifdef TRIE_COMPACT_PAIRS
if (IsPairTerm(t)) { if (IsPairTerm(t)) {
#ifdef TRIE_RATIONAL_TERMS
CyclicTerm = NULL;
#endif /* RATIONAL TERM SUPPORT FOR TRIES */
CELL *aux_pair = RepPair(t); CELL *aux_pair = RepPair(t);
if (aux_pair == PairTermMark) { if (aux_pair == PairTermMark) {
t = STACK_POP_DOWN(stack_terms); t = STACK_POP_DOWN(stack_terms);
#ifdef TRIE_RATIONAL_TERMS
if (IsPairTerm(t) && ! IsRationalTerm(t)) {
term_array_push(&Ts, (void *) t, (void *) current_node);
#else
if (IsPairTerm(t)) { if (IsPairTerm(t)) {
#endif /* RATIONAL TERM SUPPORT FOR TRIES */
aux_pair = RepPair(t); aux_pair = RepPair(t);
t = Deref(aux_pair[1]); t = Deref(aux_pair[1]);
#ifdef TRIE_RATIONAL_TERMS
if (IsVarTerm(aux_pair[1]) || IsPairTerm(aux_pair[1])) {
CyclicTerm = term_array_member(Ts, (void *) t);
}
if (CyclicTerm != NULL) {
STACK_PUSH_UP((Term) CyclicTerm, stack_terms);
STACK_PUSH_UP((Term) RationalMark, stack_terms);
STACK_PUSH_UP(AbsPair(PairTermMark), stack_terms);
} else
#endif /* RATIONAL TERM SUPPORT FOR TRIES */
if (t == TermNil) { if (t == TermNil) {
SUBGOAL_CHECK_INSERT_ENTRY(tab_ent, current_node, CompactPairEndList); SUBGOAL_CHECK_INSERT_ENTRY(tab_ent, current_node, CompactPairEndList);
} else { } else {
@ -1096,6 +1127,15 @@ static inline sg_node_ptr subgoal_search_loop(tab_ent_ptr tab_ent, sg_node_ptr c
STACK_PUSH_UP(t, stack_terms); STACK_PUSH_UP(t, stack_terms);
STACK_PUSH_UP(AbsPair(PairTermMark), stack_terms); STACK_PUSH_UP(AbsPair(PairTermMark), stack_terms);
} }
#ifdef TRIE_RATIONAL_TERMS
CyclicTerm = NULL;
if (IsVarTerm(aux_pair[0]) || IsPairTerm(aux_pair[0]))
CyclicTerm = term_array_member(Ts, (void *) Deref(aux_pair[0]));
if (CyclicTerm != NULL) {
STACK_PUSH_UP((Term) CyclicTerm, stack_terms);
STACK_PUSH_UP((Term) RationalMark, stack_terms);
} else
#endif /* RATIONAL TERM SUPPORT FOR TRIES */
STACK_PUSH_UP(Deref(aux_pair[0]), stack_terms); STACK_PUSH_UP(Deref(aux_pair[0]), stack_terms);
} else { } else {
SUBGOAL_CHECK_INSERT_ENTRY(tab_ent, current_node, CompactPairEndTerm); SUBGOAL_CHECK_INSERT_ENTRY(tab_ent, current_node, CompactPairEndTerm);
@ -1107,8 +1147,21 @@ static inline sg_node_ptr subgoal_search_loop(tab_ent_ptr tab_ent, sg_node_ptr c
current_node = global_trie_check_insert_gt_entry(current_node, (Term) entry_node PASS_REGS); current_node = global_trie_check_insert_gt_entry(current_node, (Term) entry_node PASS_REGS);
#endif /* MODE_GLOBAL_TRIE_LOOP && GLOBAL_TRIE_FOR_SUBTERMS */ #endif /* MODE_GLOBAL_TRIE_LOOP && GLOBAL_TRIE_FOR_SUBTERMS */
} else { } else {
#ifdef TRIE_RATIONAL_TERMS
term_array_push(&Ts, (void *) t, (void *) current_node);
#endif /* RATIONAL TERM SUPPORT FOR TRIES */
SUBGOAL_CHECK_INSERT_ENTRY(tab_ent, current_node, CompactPairInit); SUBGOAL_CHECK_INSERT_ENTRY(tab_ent, current_node, CompactPairInit);
t = Deref(aux_pair[1]); t = Deref(aux_pair[1]);
#ifdef TRIE_RATIONAL_TERMS
if (IsVarTerm(aux_pair[1]) || IsPairTerm(aux_pair[1])) {
CyclicTerm = term_array_member(Ts, (void *) t);
}
if (CyclicTerm != NULL) {
STACK_PUSH_UP((Term) CyclicTerm, stack_terms);
STACK_PUSH_UP((Term) RationalMark, stack_terms);
STACK_PUSH_UP(AbsPair(PairTermMark), stack_terms);
} else
#endif /* RATIONAL TERM SUPPORT FOR TRIES */
if (t == TermNil) { if (t == TermNil) {
SUBGOAL_CHECK_INSERT_ENTRY(tab_ent, current_node, CompactPairEndList); SUBGOAL_CHECK_INSERT_ENTRY(tab_ent, current_node, CompactPairEndList);
} else { } else {
@ -1116,6 +1169,15 @@ static inline sg_node_ptr subgoal_search_loop(tab_ent_ptr tab_ent, sg_node_ptr c
STACK_PUSH_UP(t, stack_terms); STACK_PUSH_UP(t, stack_terms);
STACK_PUSH_UP(AbsPair(PairTermMark), stack_terms); STACK_PUSH_UP(AbsPair(PairTermMark), stack_terms);
} }
#ifdef TRIE_RATIONAL_TERMS
CyclicTerm = NULL;
if (IsVarTerm(aux_pair[0]) || IsPairTerm(aux_pair[0]))
CyclicTerm = term_array_member(Ts, (void *) Deref(aux_pair[0]));
if (CyclicTerm != NULL) {
STACK_PUSH_UP((Term) CyclicTerm, stack_terms);
STACK_PUSH_UP((Term) RationalMark, stack_terms);
} else
#endif /* RATIONAL TERM SUPPORT FOR TRIES */
STACK_PUSH_UP(Deref(aux_pair[0]), stack_terms); STACK_PUSH_UP(Deref(aux_pair[0]), stack_terms);
} }
#if defined(MODE_GLOBAL_TRIE_LOOP) && defined(GLOBAL_TRIE_FOR_SUBTERMS) #if defined(MODE_GLOBAL_TRIE_LOOP) && defined(GLOBAL_TRIE_FOR_SUBTERMS)
@ -1170,20 +1232,35 @@ static inline sg_node_ptr subgoal_search_loop(tab_ent_ptr tab_ent, sg_node_ptr c
} else if (f == FunctorDBRef) { } else if (f == FunctorDBRef) {
Yap_Error(INTERNAL_ERROR, TermNil, "subgoal_search_loop: unsupported type tag FunctorDBRef"); Yap_Error(INTERNAL_ERROR, TermNil, "subgoal_search_loop: unsupported type tag FunctorDBRef");
} else { } else {
#ifdef TRIE_RATIONAL_TERMS
term_array_push(&Ts, (void *) t, (void *) current_node);
#endif /* RATIONAL TERM SUPPORT FOR TRIES */
int i; int i;
CELL *aux_appl = RepAppl(t); CELL *aux_appl = RepAppl(t);
SUBGOAL_CHECK_INSERT_ENTRY(tab_ent, current_node, AbsAppl((Term *)f)); SUBGOAL_CHECK_INSERT_ENTRY(tab_ent, current_node, AbsAppl((Term *)f));
AUX_STACK_CHECK_EXPAND(stack_terms, stack_terms_limit + ArityOfFunctor(f) - 1); AUX_STACK_CHECK_EXPAND(stack_terms, stack_terms_limit + ArityOfFunctor(f) - 1);
for (i = ArityOfFunctor(f); i >= 1; i--) for (i = ArityOfFunctor(f); i >= 1; i--) {
#ifdef TRIE_RATIONAL_TERMS
CyclicTerm = NULL;
if (IsVarTerm(aux_appl[i]) || IsApplTerm(aux_appl[i]))
CyclicTerm = term_array_member(Ts, (void *) Deref(aux_appl[i]));
if (CyclicTerm != NULL) {
STACK_PUSH_UP((Term) CyclicTerm, stack_terms);
STACK_PUSH_UP((Term) RationalMark, stack_terms);
} else
#endif /* RATIONAL TERM SUPPORT FOR TRIES */
STACK_PUSH_UP(Deref(aux_appl[i]), stack_terms); STACK_PUSH_UP(Deref(aux_appl[i]), stack_terms);
} }
}
} else { } else {
Yap_Error(INTERNAL_ERROR, TermNil, "subgoal_search_loop: unknown type tag"); Yap_Error(INTERNAL_ERROR, TermNil, "subgoal_search_loop: unknown type tag");
#endif /* MODE_TERMS_LOOP */ #endif /* MODE_TERMS_LOOP */
} }
t = STACK_POP_DOWN(stack_terms); t = STACK_POP_DOWN(stack_terms);
} while (t); } while (t);
#ifdef TRIE_RATIONAL_TERMS
term_array_free(&Ts);
#endif /* RATIONAL TERM SUPPORT FOR TRIES */
*subs_arity_ptr = subs_arity; *subs_arity_ptr = subs_arity;
*stack_vars_ptr = stack_vars; *stack_vars_ptr = stack_vars;
return current_node; return current_node;
@ -1261,6 +1338,12 @@ static inline ans_node_ptr answer_search_loop(sg_fr_ptr sg_fr, ans_node_ptr curr
goto answer_search_loop_non_atomic; goto answer_search_loop_non_atomic;
#endif /* MODE_GLOBAL_TRIE_LOOP */ #endif /* MODE_GLOBAL_TRIE_LOOP */
#ifdef TRIE_RATIONAL_TERMS
term_array Ts;
void* CyclicTerm;
term_array_init(&Ts, 10);
#endif /* RATIONAL TERM SUPPORT FOR TRIES */
do { do {
if (IsVarTerm(t)) { if (IsVarTerm(t)) {
t = Deref(t); t = Deref(t);
@ -1295,18 +1378,43 @@ static inline ans_node_ptr answer_search_loop(sg_fr_ptr sg_fr, ans_node_ptr curr
current_node = answer_trie_check_insert_gt_entry(sg_fr, current_node, (Term) entry_node, _trie_retry_gterm + in_pair PASS_REGS); current_node = answer_trie_check_insert_gt_entry(sg_fr, current_node, (Term) entry_node, _trie_retry_gterm + in_pair PASS_REGS);
#else /* ! MODE_TERMS_LOOP */ #else /* ! MODE_TERMS_LOOP */
} else } else
#ifdef TRIE_RATIONAL_TERMS
if (IsRationalTerm(t)) {
t = STACK_POP_DOWN(stack_terms);
ANSWER_CHECK_INSERT_ENTRY(sg_fr, current_node, t, _trie_retry_var + in_pair); //TODO create _trie_.._rational
} else
#endif /* RATIONAL TERM SUPPORT FOR TRIES */
#if defined(MODE_GLOBAL_TRIE_LOOP) #if defined(MODE_GLOBAL_TRIE_LOOP)
/* for the global trie, it is safe to start here in the first iteration */ /* for the global trie, it is safe to start here in the first iteration */
answer_search_loop_non_atomic: answer_search_loop_non_atomic:
#endif /* MODE_GLOBAL_TRIE_LOOP */ #endif /* MODE_GLOBAL_TRIE_LOOP */
#ifdef TRIE_COMPACT_PAIRS #ifdef TRIE_COMPACT_PAIRS
if (IsPairTerm(t)) { if (IsPairTerm(t)) {
#ifdef TRIE_RATIONAL_TERMS
CyclicTerm = NULL;
#endif /* RATIONAL TERM SUPPORT FOR TRIES */
CELL *aux_pair = RepPair(t); CELL *aux_pair = RepPair(t);
if (aux_pair == PairTermMark) { if (aux_pair == PairTermMark) {
t = STACK_POP_DOWN(stack_terms); t = STACK_POP_DOWN(stack_terms);
#ifdef TRIE_RATIONAL_TERMS
if (IsPairTerm(t) && ! IsRationalTerm(t)) {
term_array_push(&Ts, (void *) t, (void *) current_node);
#else
if (IsPairTerm(t)) { if (IsPairTerm(t)) {
#endif /* RATIONAL TERM SUPPORT FOR TRIES */
aux_pair = RepPair(t); aux_pair = RepPair(t);
t = Deref(aux_pair[1]); t = Deref(aux_pair[1]);
#ifdef TRIE_RATIONAL_TERMS
if (IsVarTerm(aux_pair[1]) || IsPairTerm(aux_pair[1])) {
CyclicTerm = term_array_member(Ts, (void *) t);
}
if (CyclicTerm != NULL) {
STACK_PUSH_UP((Term) CyclicTerm, stack_terms); // CyclicTerm
STACK_PUSH_UP((Term) RationalMark, stack_terms);
STACK_PUSH_UP(AbsPair(PairTermMark), stack_terms);
in_pair = 4;
} else
#endif /* RATIONAL TERM SUPPORT FOR TRIES */
if (t == TermNil) { if (t == TermNil) {
ANSWER_CHECK_INSERT_ENTRY(sg_fr, current_node, CompactPairEndList, _trie_retry_pair); ANSWER_CHECK_INSERT_ENTRY(sg_fr, current_node, CompactPairEndList, _trie_retry_pair);
} else { } else {
@ -1317,6 +1425,15 @@ static inline ans_node_ptr answer_search_loop(sg_fr_ptr sg_fr, ans_node_ptr curr
STACK_PUSH_UP(AbsPair(PairTermMark), stack_terms); STACK_PUSH_UP(AbsPair(PairTermMark), stack_terms);
in_pair = 4; in_pair = 4;
} }
#ifdef TRIE_RATIONAL_TERMS
CyclicTerm = NULL;
if (IsVarTerm(aux_pair[0]) || IsPairTerm(aux_pair[0]))
CyclicTerm = term_array_member(Ts, (void *) Deref(aux_pair[0]));
if (CyclicTerm != NULL) {
STACK_PUSH_UP((Term) CyclicTerm, stack_terms);
STACK_PUSH_UP((Term) RationalMark, stack_terms);
} else
#endif /* RATIONAL TERM SUPPORT FOR TRIES */
STACK_PUSH_UP(Deref(aux_pair[0]), stack_terms); STACK_PUSH_UP(Deref(aux_pair[0]), stack_terms);
} else { } else {
ANSWER_CHECK_INSERT_ENTRY(sg_fr, current_node, CompactPairEndTerm, _trie_retry_null); ANSWER_CHECK_INSERT_ENTRY(sg_fr, current_node, CompactPairEndTerm, _trie_retry_null);
@ -1328,8 +1445,22 @@ static inline ans_node_ptr answer_search_loop(sg_fr_ptr sg_fr, ans_node_ptr curr
current_node = global_trie_check_insert_gt_entry(current_node, (Term) entry_node PASS_REGS); current_node = global_trie_check_insert_gt_entry(current_node, (Term) entry_node PASS_REGS);
#endif /* MODE_GLOBAL_TRIE_LOOP && GLOBAL_TRIE_FOR_SUBTERMS */ #endif /* MODE_GLOBAL_TRIE_LOOP && GLOBAL_TRIE_FOR_SUBTERMS */
} else { } else {
#ifdef TRIE_RATIONAL_TERMS
term_array_push(&Ts, (void *) t, (void *) current_node);
#endif /* RATIONAL TERM SUPPORT FOR TRIES */
ANSWER_CHECK_INSERT_ENTRY(sg_fr, current_node, CompactPairInit, _trie_retry_null + in_pair); ANSWER_CHECK_INSERT_ENTRY(sg_fr, current_node, CompactPairInit, _trie_retry_null + in_pair);
t = Deref(aux_pair[1]); t = Deref(aux_pair[1]);
#ifdef TRIE_RATIONAL_TERMS
if (IsVarTerm(aux_pair[1]) || IsPairTerm(aux_pair[1])) {
CyclicTerm = term_array_member(Ts, (void *) t);
}
if (CyclicTerm != NULL) {
STACK_PUSH_UP((Term) CyclicTerm, stack_terms);
STACK_PUSH_UP((Term) RationalMark, stack_terms);
STACK_PUSH_UP(AbsPair(PairTermMark), stack_terms);
in_pair = 4;
} else
#endif /* RATIONAL TERM SUPPORT FOR TRIES */
if (t == TermNil) { if (t == TermNil) {
ANSWER_CHECK_INSERT_ENTRY(sg_fr, current_node, CompactPairEndList, _trie_retry_pair); ANSWER_CHECK_INSERT_ENTRY(sg_fr, current_node, CompactPairEndList, _trie_retry_pair);
in_pair = 0; in_pair = 0;
@ -1339,6 +1470,15 @@ static inline ans_node_ptr answer_search_loop(sg_fr_ptr sg_fr, ans_node_ptr curr
STACK_PUSH_UP(AbsPair(PairTermMark), stack_terms); STACK_PUSH_UP(AbsPair(PairTermMark), stack_terms);
in_pair = 4; in_pair = 4;
} }
#ifdef TRIE_RATIONAL_TERMS
CyclicTerm = NULL;
if (IsVarTerm(aux_pair[0]) || IsPairTerm(aux_pair[0]))
CyclicTerm = term_array_member(Ts, (void *) Deref(aux_pair[0]));
if (CyclicTerm != NULL) {
STACK_PUSH_UP((Term) CyclicTerm, stack_terms);
STACK_PUSH_UP((Term) RationalMark, stack_terms);
} else
#endif /* RATIONAL TERM SUPPORT FOR TRIES */
STACK_PUSH_UP(Deref(aux_pair[0]), stack_terms); STACK_PUSH_UP(Deref(aux_pair[0]), stack_terms);
} }
#if defined(MODE_GLOBAL_TRIE_LOOP) && defined(GLOBAL_TRIE_FOR_SUBTERMS) #if defined(MODE_GLOBAL_TRIE_LOOP) && defined(GLOBAL_TRIE_FOR_SUBTERMS)
@ -1387,13 +1527,26 @@ static inline ans_node_ptr answer_search_loop(sg_fr_ptr sg_fr, ans_node_ptr curr
} else if (f == FunctorDBRef) { } else if (f == FunctorDBRef) {
Yap_Error(INTERNAL_ERROR, TermNil, "answer_search_loop: unsupported type tag FunctorDBRef"); Yap_Error(INTERNAL_ERROR, TermNil, "answer_search_loop: unsupported type tag FunctorDBRef");
} else { } else {
#ifdef TRIE_RATIONAL_TERMS
term_array_push(&Ts, (void *) t, (void *) current_node);
#endif /* RATIONAL TERM SUPPORT FOR TRIES */
int i; int i;
CELL *aux_appl = RepAppl(t); CELL *aux_appl = RepAppl(t);
ANSWER_CHECK_INSERT_ENTRY(sg_fr, current_node, AbsAppl((Term *)f), _trie_retry_appl + in_pair); ANSWER_CHECK_INSERT_ENTRY(sg_fr, current_node, AbsAppl((Term *)f), _trie_retry_appl + in_pair);
AUX_STACK_CHECK_EXPAND(stack_terms, stack_terms_limit + ArityOfFunctor(f) - 1); AUX_STACK_CHECK_EXPAND(stack_terms, stack_terms_limit + ArityOfFunctor(f) - 1);
for (i = ArityOfFunctor(f); i >= 1; i--) for (i = ArityOfFunctor(f); i >= 1; i--) {
#ifdef TRIE_RATIONAL_TERMS
CyclicTerm = NULL;
if (IsVarTerm(aux_appl[i]) || IsApplTerm(aux_appl[i]))
CyclicTerm = term_array_member(Ts, (void *) Deref(aux_appl[i]));
if (CyclicTerm != NULL) {
STACK_PUSH_UP((Term) CyclicTerm, stack_terms);
STACK_PUSH_UP((Term) RationalMark, stack_terms);
} else
#endif /* RATIONAL TERM SUPPORT FOR TRIES */
STACK_PUSH_UP(Deref(aux_appl[i]), stack_terms); STACK_PUSH_UP(Deref(aux_appl[i]), stack_terms);
} }
}
#ifdef TRIE_COMPACT_PAIRS #ifdef TRIE_COMPACT_PAIRS
in_pair = 0; in_pair = 0;
#endif /* TRIE_COMPACT_PAIRS */ #endif /* TRIE_COMPACT_PAIRS */
@ -1403,7 +1556,9 @@ static inline ans_node_ptr answer_search_loop(sg_fr_ptr sg_fr, ans_node_ptr curr
} }
t = STACK_POP_DOWN(stack_terms); t = STACK_POP_DOWN(stack_terms);
} while (t); } while (t);
#ifdef TRIE_RATIONAL_TERMS
term_array_free(&Ts);
#endif /* RATIONAL TERM SUPPORT FOR TRIES */
*vars_arity_ptr = vars_arity; *vars_arity_ptr = vars_arity;
return current_node; return current_node;
@ -1692,8 +1847,35 @@ static inline CELL *load_answer_loop(ans_node_ptr current_node USES_REGS) {
current_node = (ans_node_ptr) UNTAG_ANSWER_NODE(TrNode_parent(current_node)); current_node = (ans_node_ptr) UNTAG_ANSWER_NODE(TrNode_parent(current_node));
#endif /* MODE_GLOBAL_TRIE_LOOP */ #endif /* MODE_GLOBAL_TRIE_LOOP */
#ifdef TRIE_RATIONAL_TERMS
term_array Ts;
void* CyclicTerm;
term_array_init(&Ts, 10);
Term RationalTermTMP; // a temporary temp to be used from the rational code
#endif /* RATIONAL TERM SUPPORT FOR TRIES */
do { do {
#ifdef TRIE_RATIONAL_TERMS
CyclicTerm = term_array_member(Ts, (void *) current_node);
#endif /* RATIONAL TERM SUPPORT FOR TRIES */
if (IsVarTerm(t)) { if (IsVarTerm(t)) {
#ifdef TRIE_RATIONAL_TERMS
if (t > VarIndexOfTableTerm(MAX_TABLE_VARS) && TrNode_child((gt_node_ptr) t) != (gt_node_ptr)(1)) { //TODO: substitute the != 1 test to something more appropriate
/* Rational term */
RationalTermTMP = (Term) term_array_member(Ts, (void *) t);
if (RationalTermTMP) {
/* rational term is assigned a variable already */
AUX_STACK_CHECK_EXPAND(stack_terms, stack_terms_limit);
STACK_PUSH_UP(RationalTermTMP, stack_terms);
} else {
RationalTermTMP = MkVarTerm();
STACK_PUSH_UP(RationalTermTMP, stack_terms);
/* memorize the rational term and assign it a variable */
term_array_push(&Ts, (void *) t, (void *) RationalTermTMP);
}
} else
#endif /* RATIONAL TERM SUPPORT FOR TRIES */
{
#if ! defined(MODE_GLOBAL_TRIE_LOOP) || defined(GLOBAL_TRIE_FOR_SUBTERMS) #if ! defined(MODE_GLOBAL_TRIE_LOOP) || defined(GLOBAL_TRIE_FOR_SUBTERMS)
if (t > VarIndexOfTableTerm(MAX_TABLE_VARS)) { if (t > VarIndexOfTableTerm(MAX_TABLE_VARS)) {
stack_terms = load_substitution_loop((gt_node_ptr) t, &vars_arity, stack_terms PASS_REGS); stack_terms = load_substitution_loop((gt_node_ptr) t, &vars_arity, stack_terms PASS_REGS);
@ -1709,16 +1891,40 @@ static inline CELL *load_answer_loop(ans_node_ptr current_node USES_REGS) {
stack_vars_base[var_index] = MkVarTerm(); stack_vars_base[var_index] = MkVarTerm();
STACK_PUSH_UP(stack_vars_base[var_index], stack_terms); STACK_PUSH_UP(stack_vars_base[var_index], stack_terms);
} }
}
} else if (IsAtomOrIntTerm(t)) { } else if (IsAtomOrIntTerm(t)) {
AUX_STACK_CHECK_EXPAND(stack_terms, stack_terms_limit); AUX_STACK_CHECK_EXPAND(stack_terms, stack_terms_limit);
#ifdef TRIE_RATIONAL_TERMS
if (CyclicTerm) {
AUX_STACK_CHECK_EXPAND(stack_terms, stack_terms_limit + 4);
STACK_PUSH_UP((Term) RationalMark, stack_terms); // Add a rational term marker necessary as we read both ways the stack //
STACK_PUSH_UP(t, stack_terms); // Add the term //
STACK_PUSH_UP(CyclicTerm, stack_terms); // Add the variable that the term will unify with //
STACK_PUSH_UP((Term) RationalMark, stack_terms); // Add a rational term marker necessary as we read both ways the stack //
} else
#endif /* RATIONAL TERM SUPPORT FOR TRIES */
STACK_PUSH_UP(t, stack_terms); STACK_PUSH_UP(t, stack_terms);
} else if (IsPairTerm(t)) { } else if (IsPairTerm(t)) {
#ifdef TRIE_COMPACT_PAIRS #ifdef TRIE_COMPACT_PAIRS
if (t == CompactPairInit) { if (t == CompactPairInit) {
Term *stack_aux = stack_terms_base - stack_terms_pair_offset; Term *stack_aux = stack_terms_base - stack_terms_pair_offset;
Term head, tail = STACK_POP_UP(stack_aux); Term head, tail = STACK_POP_UP(stack_aux);
#ifdef TRIE_RATIONAL_TERMS
if (IsRationalTerm(tail)) {
Yap_Error(INTERNAL_ERROR, tail, "Rational element of a Rational Term appears as the first Tail of a list");
}
#endif /* RATIONAL TERM SUPPORT FOR TRIES */
while (STACK_NOT_EMPTY(stack_aux, stack_terms)) { while (STACK_NOT_EMPTY(stack_aux, stack_terms)) {
head = STACK_POP_UP(stack_aux); head = STACK_POP_UP(stack_aux);
#ifdef TRIE_RATIONAL_TERMS
if (IsRationalTerm(head)) {
head = STACK_POP_UP(stack_aux); // thats the rational term
RationalTermTMP = STACK_POP_UP(stack_aux); // that is the variable to unify with
(void) STACK_POP_UP(stack_aux); // eat the second rational mark
tail = MkPairTerm(head, tail);
Yap_unify(RationalTermTMP, tail);
} else
#endif /* RATIONAL TERM SUPPORT FOR TRIES */
tail = MkPairTerm(head, tail); tail = MkPairTerm(head, tail);
} }
stack_terms = stack_terms_base - stack_terms_pair_offset; stack_terms = stack_terms_base - stack_terms_pair_offset;
@ -1728,10 +1934,27 @@ static inline CELL *load_answer_loop(ans_node_ptr current_node USES_REGS) {
Term last; Term last;
AUX_STACK_CHECK_EXPAND(stack_terms, stack_terms_limit + 1); AUX_STACK_CHECK_EXPAND(stack_terms, stack_terms_limit + 1);
last = STACK_POP_DOWN(stack_terms); last = STACK_POP_DOWN(stack_terms);
#ifdef TRIE_RATIONAL_TERMS
RationalTermTMP = TermNil;
if (IsRationalTerm(last)) { // rather unlikely case the rational term is the last of a list
RationalTermTMP = STACK_POP_DOWN(stack_terms); // in this case we need to invert the term with the end of list
last = STACK_POP_DOWN(stack_terms); // variable to unify with
(void) STACK_POP_DOWN(stack_terms); // eat the second rational mark
}
#endif /* RATIONAL TERM SUPPORT FOR TRIES */
STACK_PUSH_UP(stack_terms_pair_offset, stack_terms); STACK_PUSH_UP(stack_terms_pair_offset, stack_terms);
stack_terms_pair_offset = (int) (stack_terms_base - stack_terms); stack_terms_pair_offset = (int) (stack_terms_base - stack_terms);
if (t == CompactPairEndList) if (t == CompactPairEndList)
STACK_PUSH_UP(TermNil, stack_terms); STACK_PUSH_UP(TermNil, stack_terms);
#ifdef TRIE_RATIONAL_TERMS
if (RationalTermTMP && RationalTermTMP != TermNil) {
/* most probably this never occurs */
STACK_PUSH_UP((Term) RationalMark, stack_terms);
STACK_PUSH_UP(last, stack_terms);
STACK_PUSH_UP(RationalTermTMP, stack_terms);
STACK_PUSH_UP((Term) RationalMark, stack_terms);
} else
#endif /* RATIONAL TERM SUPPORT FOR TRIES */
STACK_PUSH_UP(last, stack_terms); STACK_PUSH_UP(last, stack_terms);
} }
#else /* ! TRIE_COMPACT_PAIRS */ #else /* ! TRIE_COMPACT_PAIRS */
@ -1775,10 +1998,27 @@ static inline CELL *load_answer_loop(ans_node_ptr current_node USES_REGS) {
AUX_STACK_CHECK_EXPAND(stack_terms, stack_terms_limit); AUX_STACK_CHECK_EXPAND(stack_terms, stack_terms_limit);
STACK_PUSH_UP(t, stack_terms); STACK_PUSH_UP(t, stack_terms);
} }
#ifdef TRIE_RATIONAL_TERMS
if (CyclicTerm) {
RationalTermTMP = STACK_POP_DOWN(stack_terms);
if IsRationalTerm(RationalTermTMP) {
//printf("Special Case\n");
} else if (IsPairTerm(RationalTermTMP)) {
Yap_unify((Term) CyclicTerm, RationalTermTMP);
} else if (IsApplTerm(RationalTermTMP)) {
Yap_unify((Term) CyclicTerm, RationalTermTMP);
}
STACK_PUSH_UP(RationalTermTMP, stack_terms);
}
RationalTermTMP = TermNil;
CyclicTerm = NULL;
#endif /* RATIONAL TERM SUPPORT FOR TRIES */
t = TrNode_entry(current_node); t = TrNode_entry(current_node);
current_node = TrNode_parent(current_node); current_node = TrNode_parent(current_node);
} while (current_node); } while (current_node);
#ifdef TRIE_RATIONAL_TERMS
term_array_free(&Ts);
#endif /* RATIONAL TERM SUPPORT FOR TRIES */
#ifdef MODE_GLOBAL_TRIE_LOOP #ifdef MODE_GLOBAL_TRIE_LOOP
*vars_arity_ptr = vars_arity; *vars_arity_ptr = vars_arity;
#endif /* MODE_GLOBAL_TRIE_LOOP */ #endif /* MODE_GLOBAL_TRIE_LOOP */

View File

@ -59,6 +59,7 @@ A CleanCall F "$clean_call"
A Colomn N ":" A Colomn N ":"
A CodeSpace N "code_space" A CodeSpace N "code_space"
A Codes N "codes" A Codes N "codes"
A CoInductive N "coinductive"
A Comma N "," A Comma N ","
A CommentHook N "comment_hook" A CommentHook N "comment_hook"
A Compound N "compound" A Compound N "compound"

View File

@ -185,6 +185,7 @@ yap_flag(tabling_mode,Options) :-
'$transl_to_yap_flag_tabling_mode'(4,load_answers). '$transl_to_yap_flag_tabling_mode'(4,load_answers).
'$transl_to_yap_flag_tabling_mode'(5,local_trie). '$transl_to_yap_flag_tabling_mode'(5,local_trie).
'$transl_to_yap_flag_tabling_mode'(6,global_trie). '$transl_to_yap_flag_tabling_mode'(6,global_trie).
'$transl_to_yap_flag_tabling_mode'(7,coinductive).
yap_flag(informational_messages,X) :- var(X), !, yap_flag(informational_messages,X) :- var(X), !,
yap_flag(verbose, X). yap_flag(verbose, X).

View File

@ -250,6 +250,7 @@ tabling_mode(Pred,Options) :-
'$transl_to_pred_flag_tabling_mode'(4,load_answers). '$transl_to_pred_flag_tabling_mode'(4,load_answers).
'$transl_to_pred_flag_tabling_mode'(5,local_trie). '$transl_to_pred_flag_tabling_mode'(5,local_trie).
'$transl_to_pred_flag_tabling_mode'(6,global_trie). '$transl_to_pred_flag_tabling_mode'(6,global_trie).
'$transl_to_pred_flag_tabling_mode'(7,coinductive).