loops
This commit is contained in:
parent
71940dec67
commit
302519868f
208
C/terms.c
208
C/terms.c
@ -29,7 +29,7 @@
|
||||
#include "YapHeap.h"
|
||||
|
||||
#define debug_pop_text_stack(l) [ if (to_visit != to_visit0) printf("%d\n",__LINE__); pop_text_stack(l) \
|
||||
}
|
||||
}
|
||||
|
||||
#include "attvar.h"
|
||||
#include "yapio.h"
|
||||
@ -90,26 +90,26 @@ static inline void clean_tr(tr_fr_ptr TR0 USES_REGS) {
|
||||
//} non_singletons_t;
|
||||
|
||||
#define IS_VISIT_MARKER \
|
||||
(IsPairTerm(d0) && RepPair(d0) >= (CELL *)to_visit0 && \
|
||||
(IsPairTerm(d0) && RepPair(d0) >= (CELL *)to_visit0 && \
|
||||
RepPair(d0) <= (CELL *)to_visit)
|
||||
|
||||
#define VISIT_MARKER AbsPair((CELL *)to_visit)
|
||||
|
||||
#define CYC_MARK_LIST \
|
||||
if (IsPairTerm(d0) && RepPair(d0) >= (CELL *)to_visit0 && \
|
||||
if (IsPairTerm(d0) && RepPair(d0) >= (CELL *)to_visit0 && \
|
||||
RepPair(d0) <= (CELL *)to_visit) { \
|
||||
/*fprintf(stderr,"+%ld at %s\n", to_visit-to_visit0, __FUNCTION__);*/ \
|
||||
*ptf++ = BREAK_LOOP(to_visit - to_visit0); \
|
||||
continue; \
|
||||
}
|
||||
continue; \
|
||||
}
|
||||
|
||||
#define CYC_MARK_APPL \
|
||||
if (IsApplTerm(d0) && RepAppl(d0) >= (Term *)to_visit0 && \
|
||||
if (IsApplTerm(d0) && RepAppl(d0) >= (Term *)to_visit0 && \
|
||||
RepAppl(d0) <= (Term *)to_visit) { \
|
||||
/*fprintf(stderr,"+%ld at %s\n", to_visit-to_visit0, __FUNCTION__);*/ \
|
||||
*ptf++ = BREAK_LOOP(to_visit - to_visit0); \
|
||||
continue; \
|
||||
}
|
||||
continue; \
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
Term old_var;
|
||||
@ -123,24 +123,24 @@ typedef struct non_single_struct_t {
|
||||
} non_singletons_t;
|
||||
|
||||
#define WALK_COMPLEX_TERM__(LIST0, STRUCT0, PRIMI0) \
|
||||
\
|
||||
struct non_single_struct_t *to_visit = Malloc( \
|
||||
\
|
||||
struct non_single_struct_t *to_visit = Malloc( \
|
||||
1024 * sizeof(struct non_single_struct_t)), \
|
||||
*to_visit0 = to_visit, \
|
||||
*to_visit_max = to_visit + 1024; \
|
||||
\
|
||||
while (to_visit >= to_visit0) { \
|
||||
*to_visit0 = to_visit, \
|
||||
*to_visit_max = to_visit + 1024; \
|
||||
\
|
||||
while (to_visit >= to_visit0) { \
|
||||
CELL d0; \
|
||||
CELL *ptd0; \
|
||||
restart: \
|
||||
restart: \
|
||||
while (pt0 < pt0_end) { \
|
||||
++pt0; \
|
||||
ptd0 = pt0; \
|
||||
d0 = *ptd0; \
|
||||
list_loop: \
|
||||
list_loop: \
|
||||
/*fprintf(stderr, "%ld at %s\n", to_visit - to_visit0, __FUNCTION__);*/ \
|
||||
deref_head(d0, var_in_term_unk); \
|
||||
var_in_term_nvar : { \
|
||||
var_in_term_nvar : { \
|
||||
if (IsPairTerm(d0)) { \
|
||||
if (to_visit + 32 >= to_visit_max) { \
|
||||
goto aux_overflow; \
|
||||
@ -164,6 +164,9 @@ var_in_term_nvar : { \
|
||||
/* store the terms to visit */ \
|
||||
ptd0 = RepAppl(d0); \
|
||||
f = (Functor)(d0 = *ptd0); \
|
||||
if (IsExtensionFunctor(f)) {\
|
||||
continue;\
|
||||
}\
|
||||
\
|
||||
if (to_visit + 32 >= to_visit_max) { \
|
||||
goto aux_overflow; \
|
||||
@ -202,11 +205,11 @@ var_in_term_nvar : { \
|
||||
pt0_end = to_visit->pt0_end; \
|
||||
*to_visit->ptd0 = to_visit->d0; \
|
||||
} \
|
||||
} \
|
||||
pop_text_stack(lvl);
|
||||
} \
|
||||
pop_text_stack(lvl);
|
||||
|
||||
#define def_aux_overflow() \
|
||||
aux_overflow : { \
|
||||
aux_overflow : { \
|
||||
size_t d1 = to_visit - to_visit0; \
|
||||
size_t d2 = to_visit_max - to_visit0; \
|
||||
to_visit0 = \
|
||||
@ -214,21 +217,21 @@ var_in_term_nvar : { \
|
||||
to_visit = to_visit0 + d1; \
|
||||
to_visit_max = to_visit0 + (d2 + 128); \
|
||||
pt0--; \
|
||||
} \
|
||||
goto restart;
|
||||
} \
|
||||
goto restart;
|
||||
|
||||
#define def_trail_overflow() \
|
||||
trail_overflow : { \
|
||||
trail_overflow : { \
|
||||
LOCAL_Error_TYPE = RESOURCE_ERROR_TRAIL; \
|
||||
LOCAL_Error_Size = (TR - TR0) * sizeof(tr_fr_ptr *); \
|
||||
clean_tr(TR0 PASS_REGS); \
|
||||
HR = InitialH; \
|
||||
pop_text_stack(lvl); \
|
||||
return 0L; \
|
||||
}
|
||||
}
|
||||
|
||||
#define def_global_overflow() \
|
||||
global_overflow : { \
|
||||
global_overflow : { \
|
||||
while (to_visit > to_visit0) { \
|
||||
to_visit--; \
|
||||
CELL *ptd0 = to_visit->ptd0; \
|
||||
@ -240,27 +243,27 @@ var_in_term_nvar : { \
|
||||
LOCAL_Error_TYPE = RESOURCE_ERROR_STACK; \
|
||||
LOCAL_Error_Size = (ASP - HR) * sizeof(CELL); \
|
||||
return false; \
|
||||
}
|
||||
}
|
||||
|
||||
#define CYC_LIST \
|
||||
if (IS_VISIT_MARKER) { \
|
||||
if (IS_VISIT_MARKER) { \
|
||||
while (to_visit > to_visit0) { \
|
||||
to_visit--; \
|
||||
to_visit->ptd0[0] = to_visit->d0; \
|
||||
} \
|
||||
pop_text_stack(lvl); \
|
||||
return true; \
|
||||
}
|
||||
}
|
||||
|
||||
#define CYC_APPL \
|
||||
if (IS_VISIT_MARKER) { \
|
||||
if (IS_VISIT_MARKER) { \
|
||||
while (to_visit > to_visit0) { \
|
||||
to_visit--; \
|
||||
to_visit->ptd0[0] = to_visit->d0; \
|
||||
} \
|
||||
pop_text_stack(lvl); \
|
||||
return true; \
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@brief routine to locate all variables in a term, and its applications */
|
||||
@ -363,15 +366,15 @@ static int cycles_in_complex_term(register CELL *pt0,
|
||||
/* store the terms to visit */
|
||||
ptd0 = RepAppl(d0);
|
||||
f = (Functor)(d0 = *ptd0);
|
||||
if (IsExtensionFunctor(f)) {
|
||||
*ptf++ = d0;
|
||||
continue;
|
||||
}
|
||||
if (IS_VISIT_MARKER) {
|
||||
rc++;
|
||||
*ptf++ = BREAK_LOOP(to_visit - to_visit0);
|
||||
continue;
|
||||
}
|
||||
if (IsExtensionFunctor(f)) {
|
||||
*ptf++ = d0;
|
||||
continue;
|
||||
}
|
||||
if (to_visit + 32 >= to_visit_max) {
|
||||
goto aux_overflow;
|
||||
}
|
||||
@ -398,22 +401,22 @@ static int cycles_in_complex_term(register CELL *pt0,
|
||||
derefa_body(d0, ptd0, var_in_term_unk, var_in_term_nvar);
|
||||
*ptf++ = d0;
|
||||
}
|
||||
}
|
||||
}
|
||||
/* Do we still have compound terms to visit */
|
||||
to_visit--;
|
||||
if (to_visit >= to_visit0) {
|
||||
to_visit--;
|
||||
if (to_visit >= to_visit0) {
|
||||
pt0 = to_visit->pt0;
|
||||
pt0_end = to_visit->pt0_end;
|
||||
ptf = to_visit->ptf;
|
||||
*to_visit->ptd0 = to_visit->d0;
|
||||
}
|
||||
}
|
||||
pop_text_stack(lvl);
|
||||
}
|
||||
}
|
||||
pop_text_stack(lvl);
|
||||
|
||||
return rc;
|
||||
return rc;
|
||||
|
||||
def_aux_overflow();
|
||||
return -1;
|
||||
def_aux_overflow();
|
||||
return -1;
|
||||
}
|
||||
|
||||
Term Yap_CyclesInTerm(Term t USES_REGS) {
|
||||
@ -515,22 +518,22 @@ static Int var_in_complex_term(register CELL * pt0, register CELL * pt0_end,
|
||||
}
|
||||
pop_text_stack(lvl);
|
||||
return true;
|
||||
}
|
||||
goto restart;
|
||||
END_WALK();
|
||||
}
|
||||
goto restart;
|
||||
END_WALK();
|
||||
|
||||
if (to_visit > to_visit0) {
|
||||
if (to_visit > to_visit0) {
|
||||
to_visit--;
|
||||
|
||||
CELL *ptd0 = to_visit->ptd0;
|
||||
*ptd0 = to_visit->d0;
|
||||
pt0 = to_visit->pt0;
|
||||
pt0_end = to_visit->pt0_end;
|
||||
}
|
||||
pop_text_stack(lvl);
|
||||
return false;
|
||||
}
|
||||
pop_text_stack(lvl);
|
||||
return false;
|
||||
|
||||
def_aux_overflow();
|
||||
def_aux_overflow();
|
||||
}
|
||||
|
||||
static Int var_in_term(
|
||||
@ -655,9 +658,9 @@ static Int variables_in_term(
|
||||
if (!expand_vts(3 PASS_REGS))
|
||||
return false;
|
||||
}
|
||||
} while (out == 0L);
|
||||
clean_tr(TR - count PASS_REGS);
|
||||
return Yap_unify(ARG3, out);
|
||||
} while (out == 0L);
|
||||
clean_tr(TR - count PASS_REGS);
|
||||
return Yap_unify(ARG3, out);
|
||||
}
|
||||
|
||||
/** @pred term_variables(? _Term_, - _Variables_, +_ExternalVars_) is iso
|
||||
@ -880,23 +883,23 @@ static Term new_vars_in_complex_term(
|
||||
if (!Yap_growtrail((TR - TR0) * sizeof(tr_fr_ptr *), true)) {
|
||||
goto trail_overflow;
|
||||
}
|
||||
}
|
||||
}
|
||||
/* leave an empty slot to fill in later */
|
||||
if (HR + 1024 > ASP) {
|
||||
if (HR + 1024 > ASP) {
|
||||
goto global_overflow;
|
||||
}
|
||||
END_WALK();
|
||||
}
|
||||
END_WALK();
|
||||
|
||||
clean_tr(TR0 PASS_REGS);
|
||||
pop_text_stack(lvl);
|
||||
HB = B->cp_h;
|
||||
return output;
|
||||
clean_tr(TR0 PASS_REGS);
|
||||
pop_text_stack(lvl);
|
||||
HB = B->cp_h;
|
||||
return output;
|
||||
|
||||
def_aux_overflow();
|
||||
def_aux_overflow();
|
||||
|
||||
def_trail_overflow();
|
||||
def_trail_overflow();
|
||||
|
||||
def_global_overflow();
|
||||
def_global_overflow();
|
||||
}
|
||||
|
||||
/** @pred new_variables_in_term(+_CurrentVariables_, ? _Term_, -_Variables_)
|
||||
@ -931,7 +934,7 @@ static Int p_new_variables_in_term(
|
||||
}
|
||||
|
||||
#define FOUND_VAR() \
|
||||
if (d0 == TermFoundVar) { \
|
||||
if (d0 == TermFoundVar) { \
|
||||
/* leave an empty slot to fill in later */ \
|
||||
if (HR + 1024 > ASP) { \
|
||||
goto global_overflow; \
|
||||
@ -940,7 +943,7 @@ static Int p_new_variables_in_term(
|
||||
HR += 2; \
|
||||
HR[-2] = (CELL)ptd0; \
|
||||
*ptd0 = TermNil; \
|
||||
}
|
||||
}
|
||||
|
||||
static Term vars_within_complex_term(
|
||||
register CELL * pt0, register CELL * pt0_end, Term inp USES_REGS) {
|
||||
@ -972,13 +975,13 @@ static Term vars_within_complex_term(
|
||||
if (HR != InitialH) {
|
||||
HR[-1] = TermNil;
|
||||
return output;
|
||||
} else {
|
||||
} else {
|
||||
return TermNil;
|
||||
}
|
||||
}
|
||||
|
||||
def_aux_overflow();
|
||||
def_aux_overflow();
|
||||
|
||||
def_global_overflow();
|
||||
def_global_overflow();
|
||||
}
|
||||
|
||||
/** @pred variables_within_term(+_CurrentVariables_, ? _Term_, -_Variables_)
|
||||
@ -1120,18 +1123,18 @@ static Int p_free_variables_in_term(
|
||||
if (!expand_vts(3 PASS_REGS))
|
||||
return false;
|
||||
}
|
||||
} while (out == 0L);
|
||||
if (found_module && t != t0) {
|
||||
} while (out == 0L);
|
||||
if (found_module && t != t0) {
|
||||
Term ts[2];
|
||||
ts[0] = found_module;
|
||||
ts[1] = t;
|
||||
t = Yap_MkApplTerm(FunctorModule, 2, ts);
|
||||
}
|
||||
return Yap_unify(ARG2, t) && Yap_unify(ARG3, out);
|
||||
}
|
||||
return Yap_unify(ARG2, t) && Yap_unify(ARG3, out);
|
||||
}
|
||||
|
||||
#define FOUND_VAR_AGAIN() \
|
||||
if (d0 == TermFoundVar) { \
|
||||
if (d0 == TermFoundVar) { \
|
||||
CELL *pt2 = pt0; \
|
||||
while (IsVarTerm(*pt2)) \
|
||||
pt2 = (CELL *)(*pt2); \
|
||||
@ -1139,7 +1142,7 @@ static Int p_free_variables_in_term(
|
||||
HR[0] = (CELL)pt2; \
|
||||
HR += 2; \
|
||||
*pt2 = TermRefoundVar; \
|
||||
}
|
||||
}
|
||||
|
||||
static Term non_singletons_in_complex_term(CELL * pt0,
|
||||
CELL * pt0_end USES_REGS) {
|
||||
@ -1208,10 +1211,10 @@ static void renumbervar(Term t, Int me USES_REGS) {
|
||||
}
|
||||
|
||||
#define RENUMBER_SINGLES \
|
||||
if (singles) { \
|
||||
if (singles) { \
|
||||
renumbervar(d0, numbv++ PASS_REGS); \
|
||||
goto restart; \
|
||||
}
|
||||
}
|
||||
|
||||
static Int numbervars_in_complex_term(CELL * pt0, CELL * pt0_end, Int numbv,
|
||||
int singles USES_REGS) {
|
||||
@ -1297,13 +1300,13 @@ static Int p_numbervars(USES_REGS1) {
|
||||
}
|
||||
|
||||
#define MAX_NUMBERED \
|
||||
if (FunctorOfTerm(d0) == FunctorDollarVar) { \
|
||||
if (FunctorOfTerm(d0) == FunctorDollarVar) { \
|
||||
Term t1 = ArgOfTerm(1, d0); \
|
||||
Int i; \
|
||||
if (IsIntegerTerm(t1) && ((i = IntegerOfTerm(t1)) > *maxp)) \
|
||||
*maxp = i; \
|
||||
goto restart; \
|
||||
}
|
||||
}
|
||||
|
||||
static int max_numbered_var(CELL * pt0, CELL * pt0_end,
|
||||
Int * maxp USES_REGS) {
|
||||
@ -1382,30 +1385,31 @@ static Int create_entry(Term t, Int i, Int j, cl_connector * q, Int max) {
|
||||
Term ref, h, *s, *ostart;
|
||||
ssize_t n;
|
||||
// first time, create a new term
|
||||
if (i==0)
|
||||
return 0;
|
||||
if (IsVarTerm(t)) {
|
||||
return -1;
|
||||
}
|
||||
if (IsPairTerm(t)) {
|
||||
Int me;
|
||||
s = RepPair(t);
|
||||
h = s[0];
|
||||
if (IsAtomTerm(h)) {
|
||||
return t_ref((cl_connector*)AtomOfTerm(h),q,max);
|
||||
if (IsAtomTerm(h) &&
|
||||
(me = t_ref((cl_connector*)AtomOfTerm(h),q,max)) >= 0 ) {
|
||||
return me;
|
||||
}
|
||||
n = 2;
|
||||
ostart = HR;
|
||||
ref = AbsPair(ostart);
|
||||
HR += 2;
|
||||
q[max].header = Deref(s[0]);
|
||||
} else if (IsApplTerm(t)) {
|
||||
Int me;
|
||||
h = (CELL)FunctorOfTerm(t);
|
||||
n = ArityOfFunctor((Functor)h);
|
||||
if (IsExtensionFunctor((Functor)h)) {
|
||||
return -1;
|
||||
}
|
||||
if (IsAtomTerm(h)) {
|
||||
return t_ref((cl_connector*)AtomOfTerm(h),q,max);
|
||||
if (IsAtomTerm(h) &&
|
||||
(me = t_ref((cl_connector*)AtomOfTerm(h),q,max)) >= 0) {
|
||||
return me;
|
||||
}
|
||||
s = RepAppl(t);
|
||||
q[max].header = s[0];
|
||||
@ -1413,13 +1417,16 @@ static Int create_entry(Term t, Int i, Int j, cl_connector * q, Int max) {
|
||||
ref = AbsAppl(ostart);
|
||||
*ostart++ = s[0];
|
||||
HR=ostart+n;
|
||||
} else if (IsAtomTerm(t) &&
|
||||
(max = t_ref((cl_connector*)AtomOfTerm(t),q,max)) >= 0) {
|
||||
return max;
|
||||
} else {
|
||||
Int me;
|
||||
if (IsAtomTerm(t) &&
|
||||
(me = t_ref((cl_connector*)AtomOfTerm(t),q,max)) >= 0 ) {
|
||||
return me;
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
|
||||
}
|
||||
q[max].header = h;
|
||||
q[max].parent = q[i].copy+j;
|
||||
q[max].source = t;
|
||||
q[max].copy = ostart;
|
||||
@ -1452,9 +1459,9 @@ Int cp_link(Term t, Int i, Int j, cl_connector * q, Int max, CELL * tailp) {
|
||||
q[i].reference = v;
|
||||
}
|
||||
return max;
|
||||
}
|
||||
q[i].copy[j] = t;
|
||||
return me;
|
||||
}
|
||||
q[i].copy[j] = t;
|
||||
return me;
|
||||
}
|
||||
|
||||
Term Yap_BreakCycles(Term inp, UInt arity, Term * listp USES_REGS) {
|
||||
@ -1494,10 +1501,15 @@ Term Yap_BreakCycles(Term inp, UInt arity, Term * listp USES_REGS) {
|
||||
}
|
||||
}
|
||||
|
||||
pop_text_stack(lvl);
|
||||
for (i=0; i< qlen; i++) {
|
||||
CELL *p = IsPairTerm(q[i].source) ? RepPair(q[i].source) : RepAppl(q[i].source);
|
||||
p[0] = q[i].header;
|
||||
}
|
||||
|
||||
HB = B->cp_h;
|
||||
return q[0].reference;
|
||||
pop_text_stack(lvl);
|
||||
|
||||
HB = B->cp_h;
|
||||
return q[0].reference;
|
||||
}
|
||||
|
||||
/** @pred rational_term_to_tree(? _TI_,- _TF_, ?SubTerms, ?MoreSubterms)
|
||||
|
@ -85,7 +85,7 @@ native_sources = ["yap4py/yap_wrap.cxx","yap4py/yapi.cpp"]
|
||||
|
||||
extensions = [Extension('_yap', native_sources,
|
||||
define_macros=[('MAJOR_VERSION', '6'),
|
||||
('MINOR_VERSION', '4'),
|
||||
('MINOR_VERSION', '5'),
|
||||
('_YAP_NOT_INSTALLED_', '1'),
|
||||
('YAP_PYTHON', '1'),
|
||||
('PYTHONSWIG', '1'),
|
||||
@ -115,7 +115,7 @@ package_data = {
|
||||
|
||||
data_files=[]
|
||||
|
||||
version_ns = {'__version__': '6.4.1', 'major-version': '6', 'minor-version': '4', 'patch': '1'}
|
||||
version_ns = {'__version__': '6.5.0', 'major-version': '6', 'minor-version': '5', 'patch': '0'}
|
||||
|
||||
setup_args = dict(
|
||||
name=name,
|
||||
|
@ -94,7 +94,7 @@ undefined_query(G0, M0, Cut) :-
|
||||
'$get_undefined_predicates'(M0:G0, MG), !.
|
||||
|
||||
% undef handler
|
||||
'$undefp_'([M0|G0],MG) :-
|
||||
'$undefp'([M0|G0],MG) :-
|
||||
% make sure we do not loop on undefined predicates
|
||||
'$undef_setup'(M0:G0, Action,Debug,Current, MGI),
|
||||
('$get_undefined_predicates'( MGI, MG )
|
||||
|
@ -72,6 +72,7 @@ d(X, ( X= f(A,A,X)) ).
|
||||
d(X, ( X= f(A,A,g(A))) ).
|
||||
d(X, ( X= f(A,g(X,[A|A]),X)) ).
|
||||
d(X, ( X= f(X,[X,X])) ).
|
||||
d(X, ( X= f(3.14,[22.3,X])) ).
|
||||
d(X, ( X= f(X,[X,g(X)])) ).
|
||||
d(X, ( X= f(_,X/[X])) ).
|
||||
d(X, ( X= f(_,A/[A]), A= f(X,[X,g(X)])) ).
|
||||
|
Reference in New Issue
Block a user