Adding rational term support for tabling tries

This commit is contained in:
Theo 2013-12-19 10:56:52 +00:00
parent 30828eba98
commit 1f0f9968df
4 changed files with 553 additions and 207 deletions

View File

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

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

@ -163,6 +163,12 @@ static struct trie_statistics{
free_global_trie_branch(NODE PASS_REGS)
#endif /* GLOBAL_TRIE_FOR_SUBTERMS */
/******************************
** Rational Terms Support **
******************************/
#ifdef TRIE_RATIONAL_TERMS
#include "tab.rational.i"
#endif /* RATIONAL TERM SUPPORT FOR TRIES */
/******************************
@ -200,7 +206,13 @@ static struct trie_statistics{
#define MODE_TERMS_LOOP
#define INCLUDE_SUBGOAL_SEARCH_LOOP /* subgoal_search_terms_loop */
#define INCLUDE_ANSWER_SEARCH_LOOP /* answer_search_terms_loop */
#ifdef TRIE_RATIONAL_TERMS
#undef TRIE_RATIONAL_TERMS
#include "tab.tries.i"
#define TRIE_RATIONAL_TERMS
#else
#include "tab.tries.i"
#endif
#undef INCLUDE_ANSWER_SEARCH_LOOP
#undef INCLUDE_SUBGOAL_SEARCH_LOOP
#undef MODE_TERMS_LOOP
@ -209,7 +221,13 @@ static struct trie_statistics{
#define INCLUDE_SUBGOAL_SEARCH_LOOP /* subgoal_search_global_trie_(terms)_loop */
#define INCLUDE_ANSWER_SEARCH_LOOP /* answer_search_global_trie_(terms)_loop */
#define INCLUDE_LOAD_ANSWER_LOOP /* load_substitution_loop */
#ifdef TRIE_RATIONAL_TERMS
#undef TRIE_RATIONAL_TERMS
#include "tab.tries.i"
#define TRIE_RATIONAL_TERMS
#else
#include "tab.tries.i"
#endif
#undef INCLUDE_LOAD_ANSWER_LOOP
#undef INCLUDE_ANSWER_SEARCH_LOOP
#undef INCLUDE_SUBGOAL_SEARCH_LOOP
@ -899,6 +917,13 @@ static inline void traverse_trie_node(Term t, char *str, int *str_index_ptr, int
} else if (mode == TRAVERSE_MODE_LONGINT_END) {
mode = TRAVERSE_MODE_NORMAL;
} else if (IsVarTerm(t)) {
#ifdef TRIE_RATIONAL_TERMS
if (t > VarIndexOfTableTerm(MAX_TABLE_VARS) && TrNode_child((gt_node_ptr) t) != 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)) {
TrStat_gt_refs++;
/* (type % 2 + 2): TRAVERSE_TYPE_ANSWER --> TRAVERSE_TYPE_GT_ANSWER */

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;
#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 {
if (IsVarTerm(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);
#else /* ! MODE_TERMS_LOOP */
} 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)
/* for the global trie, it is safe to start here in the first iteration */
subgoal_search_loop_non_atomic:
#endif /* MODE_GLOBAL_TRIE_LOOP */
#ifdef TRIE_COMPACT_PAIRS
if (IsPairTerm(t)) {
#ifdef TRIE_RATIONAL_TERMS
CyclicTerm = NULL;
#endif /* RATIONAL TERM SUPPORT FOR TRIES */
CELL *aux_pair = RepPair(t);
if (aux_pair == PairTermMark) {
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)) {
#endif /* RATIONAL TERM SUPPORT FOR TRIES */
aux_pair = RepPair(t);
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) {
SUBGOAL_CHECK_INSERT_ENTRY(tab_ent, current_node, CompactPairEndList);
} 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(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);
} else {
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);
#endif /* MODE_GLOBAL_TRIE_LOOP && GLOBAL_TRIE_FOR_SUBTERMS */
} 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);
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) {
SUBGOAL_CHECK_INSERT_ENTRY(tab_ent, current_node, CompactPairEndList);
} 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(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);
}
#if defined(MODE_GLOBAL_TRIE_LOOP) && defined(GLOBAL_TRIE_FOR_SUBTERMS)
@ -1165,20 +1227,35 @@ static inline sg_node_ptr subgoal_search_loop(tab_ent_ptr tab_ent, sg_node_ptr c
} else if (f == FunctorBigInt) {
Yap_Error(INTERNAL_ERROR, TermNil, "subgoal_search_loop: unsupported type tag FunctorBigInt");
} else {
#ifdef TRIE_RATIONAL_TERMS
term_array_push(&Ts, (void *) t, (void *) current_node);
#endif /* RATIONAL TERM SUPPORT FOR TRIES */
int i;
CELL *aux_appl = RepAppl(t);
SUBGOAL_CHECK_INSERT_ENTRY(tab_ent, current_node, AbsAppl((Term *)f));
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);
}
}
} else {
Yap_Error(INTERNAL_ERROR, TermNil, "subgoal_search_loop: unknown type tag");
#endif /* MODE_TERMS_LOOP */
}
t = STACK_POP_DOWN(stack_terms);
} while (t);
#ifdef TRIE_RATIONAL_TERMS
term_array_free(&Ts);
#endif /* RATIONAL TERM SUPPORT FOR TRIES */
*subs_arity_ptr = subs_arity;
*stack_vars_ptr = stack_vars;
return current_node;
@ -1256,6 +1333,12 @@ static inline ans_node_ptr answer_search_loop(sg_fr_ptr sg_fr, ans_node_ptr curr
goto answer_search_loop_non_atomic;
#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 {
if (IsVarTerm(t)) {
t = Deref(t);
@ -1290,18 +1373,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);
#else /* ! MODE_TERMS_LOOP */
} 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)
/* for the global trie, it is safe to start here in the first iteration */
answer_search_loop_non_atomic:
#endif /* MODE_GLOBAL_TRIE_LOOP */
#ifdef TRIE_COMPACT_PAIRS
if (IsPairTerm(t)) {
#ifdef TRIE_RATIONAL_TERMS
CyclicTerm = NULL;
#endif /* RATIONAL TERM SUPPORT FOR TRIES */
CELL *aux_pair = RepPair(t);
if (aux_pair == PairTermMark) {
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)) {
#endif /* RATIONAL TERM SUPPORT FOR TRIES */
aux_pair = RepPair(t);
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) {
ANSWER_CHECK_INSERT_ENTRY(sg_fr, current_node, CompactPairEndList, _trie_retry_pair);
} else {
@ -1312,6 +1420,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);
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);
} else {
ANSWER_CHECK_INSERT_ENTRY(sg_fr, current_node, CompactPairEndTerm, _trie_retry_null);
@ -1323,8 +1440,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);
#endif /* MODE_GLOBAL_TRIE_LOOP && GLOBAL_TRIE_FOR_SUBTERMS */
} 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);
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) {
ANSWER_CHECK_INSERT_ENTRY(sg_fr, current_node, CompactPairEndList, _trie_retry_pair);
in_pair = 0;
@ -1334,6 +1465,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);
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);
}
#if defined(MODE_GLOBAL_TRIE_LOOP) && defined(GLOBAL_TRIE_FOR_SUBTERMS)
@ -1379,13 +1519,26 @@ static inline ans_node_ptr answer_search_loop(sg_fr_ptr sg_fr, ans_node_ptr curr
} else if (f == FunctorBigInt) {
Yap_Error(INTERNAL_ERROR, TermNil, "answer_search_loop: unsupported type tag FunctorBigInt");
} else {
#ifdef TRIE_RATIONAL_TERMS
term_array_push(&Ts, (void *) t, (void *) current_node);
#endif /* RATIONAL TERM SUPPORT FOR TRIES */
int i;
CELL *aux_appl = RepAppl(t);
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);
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);
}
}
#ifdef TRIE_COMPACT_PAIRS
in_pair = 0;
#endif /* TRIE_COMPACT_PAIRS */
@ -1395,7 +1548,9 @@ static inline ans_node_ptr answer_search_loop(sg_fr_ptr sg_fr, ans_node_ptr curr
}
t = STACK_POP_DOWN(stack_terms);
} while (t);
#ifdef TRIE_RATIONAL_TERMS
term_array_free(&Ts);
#endif /* RATIONAL TERM SUPPORT FOR TRIES */
*vars_arity_ptr = vars_arity;
return current_node;
@ -1687,8 +1842,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));
#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 {
#ifdef TRIE_RATIONAL_TERMS
CyclicTerm = term_array_member(Ts, (void *) current_node);
#endif /* RATIONAL TERM SUPPORT FOR TRIES */
if (IsVarTerm(t)) {
#ifdef TRIE_RATIONAL_TERMS
if (t > VarIndexOfTableTerm(MAX_TABLE_VARS) && TrNode_child((gt_node_ptr) t) != 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 (t > VarIndexOfTableTerm(MAX_TABLE_VARS)) {
stack_terms = load_substitution_loop((gt_node_ptr) t, &vars_arity, stack_terms PASS_REGS);
@ -1704,16 +1886,40 @@ static inline CELL *load_answer_loop(ans_node_ptr current_node USES_REGS) {
stack_vars_base[var_index] = MkVarTerm();
STACK_PUSH_UP(stack_vars_base[var_index], stack_terms);
}
}
} else if (IsAtomOrIntTerm(t)) {
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);
} else if (IsPairTerm(t)) {
#ifdef TRIE_COMPACT_PAIRS
if (t == CompactPairInit) {
Term *stack_aux = stack_terms_base - stack_terms_pair_offset;
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)) {
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);
}
stack_terms = stack_terms_base - stack_terms_pair_offset;
@ -1723,10 +1929,27 @@ static inline CELL *load_answer_loop(ans_node_ptr current_node USES_REGS) {
Term last;
AUX_STACK_CHECK_EXPAND(stack_terms, stack_terms_limit + 1);
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_terms_pair_offset = (int) (stack_terms_base - stack_terms);
if (t == CompactPairEndList)
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);
}
#else /* ! TRIE_COMPACT_PAIRS */
@ -1765,10 +1988,27 @@ static inline CELL *load_answer_loop(ans_node_ptr current_node USES_REGS) {
AUX_STACK_CHECK_EXPAND(stack_terms, stack_terms_limit);
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);
current_node = TrNode_parent(current_node);
} while (current_node);
#ifdef TRIE_RATIONAL_TERMS
term_array_free(&Ts);
#endif /* RATIONAL TERM SUPPORT FOR TRIES */
#ifdef MODE_GLOBAL_TRIE_LOOP
*vars_arity_ptr = vars_arity;
#endif /* MODE_GLOBAL_TRIE_LOOP */