This commit is contained in:
Vitor Santos Costa 2019-02-11 09:28:46 +00:00
parent 3fdc260ee6
commit ac60bee30d
3 changed files with 460 additions and 369 deletions

274
C/terms.c
View File

@ -28,7 +28,8 @@
#include "YapHeap.h"
#define debug_pop_text_stack(l) [ if (to_visit != to_visit0) printf("%d\n",__LINE__); pop_text_stack(l) }
#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"
@ -39,7 +40,6 @@
#define Malloc malloc
#define Realloc realloc
static int expand_vts(int args USES_REGS) {
UInt expand = LOCAL_Error_Size;
yap_error_number yap_errno = LOCAL_Error_TYPE;
@ -67,8 +67,6 @@ static int expand_vts(int args USES_REGS) {
return true;
}
static inline void clean_tr(tr_fr_ptr TR0 USES_REGS) {
tr_fr_ptr pt0 = TR;
while (pt0 != TR0) {
@ -88,12 +86,30 @@ static inline void clean_tr(tr_fr_ptr TR0 USES_REGS) {
TR = TR0;
}
static inline bool IS_VISIT_MARKER(Term d0, void *to_visit, void *to_visit0) {
return IsPairTerm(d0) && RepPair(d0)>=(CELL*)to_visit0 && RepPair(d0) <= (CELL*)to_visit;
}
//#define CELL *pt0, *pt0_end, *ptf;
//} non_singletons_t;
#define IS_VISIT_MARKER \
(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 && \
RepPair(d0) <= (CELL *)to_visit) { \
/*fprintf(stderr,"+%ld at %s\n", to_visit-to_visit0, __FUNCTION__);*/ \
*ptf++ = BREAK_LOOP(to_visit - to_visit0); \
continue; \
}
#define CYC_MARK_APPL \
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; \
}
typedef struct {
Term old_var;
@ -113,7 +129,6 @@ typedef struct non_single_struct_t {
*to_visit0 = to_visit, \
*to_visit_max = to_visit + 1024; \
\
/*fprintf(stderr, "%ld at %s\n", to_visit - to_visit0, __FUNCTION__);*/ \
while (to_visit >= to_visit0) { \
CELL d0; \
CELL *ptd0; \
@ -123,6 +138,7 @@ while (pt0 < pt0_end) { \
ptd0 = pt0; \
d0 = *ptd0; \
list_loop: \
/*fprintf(stderr, "%ld at %s\n", to_visit - to_visit0, __FUNCTION__);*/ \
deref_head(d0, var_in_term_unk); \
var_in_term_nvar : { \
if (IsPairTerm(d0)) { \
@ -132,7 +148,7 @@ list_loop: \
ptd0 = RepPair(d0); \
d0 = ptd0[0]; \
LIST0; \
if (IS_VISIT_MARKER(d0,to_visit,to_visit0)) \
if (IS_VISIT_MARKER) \
goto restart; \
to_visit->pt0 = pt0; \
to_visit->pt0_end = pt0_end; \
@ -144,16 +160,16 @@ list_loop: \
pt0_end = pt0 + 1; \
goto list_loop; \
} else if (IsApplTerm(d0)) { \
Functor f; \
register Functor f; \
/* 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; \
} \
STRUCT0; \
if ( IS_VISIT_MARKER(d0,to_visit,to_visit0)) { \
if (IS_VISIT_MARKER) { \
\
continue; \
} \
@ -227,23 +243,22 @@ list_loop: \
}
#define CYC_LIST \
if (IS_VISIT_MARKER(d0,to_visit,to_visit0)) { \
if (d0 == TermFreeTerm) { \
/*fprintf(stderr,"+%ld at %s\n", to_visit-to_visit0, __FUNCTION__);*/ \
while (to_visit > to_visit0) { \
to_visit--; \
to_visit->ptd0[0] = \
to_visit->d0; \
to_visit->ptd0[0] = to_visit->d0; \
} \
pop_text_stack(lvl); /*fprintf(stderr,"<%ld at %s\n", to_visit-to_visit0, __FUNCTION__);*/ \
pop_text_stack(lvl); /*fprintf(stderr,"<%ld at %s\n", to_visit-to_visit0, \
__FUNCTION__);*/ \
return true; \
}
#define CYC_APPL \
if (IS_VISIT_MARKER(d0,to_visit,to_visit0)) { \
if (IsAtomTerm((CELL)f)) { \
while (to_visit > to_visit0) { \
to_visit--; \
to_visit->ptd0[0] = \
to_visit->d0; \
to_visit->ptd0[0] = to_visit->d0; \
} \
/*fprintf(stderr,"<%ld at %s\n", to_visit-to_visit0, __FUNCTION__);*/ \
return true; \
@ -252,8 +267,7 @@ while (to_visit > to_visit0) { \
/**
@brief routine to locate all variables in a term, and its applications */
static Term
cyclic_complex_term( CELL *pt0, CELL *pt0_end USES_REGS) {
static Term cyclic_complex_term(CELL *pt0, CELL *pt0_end USES_REGS) {
int lvl = push_text_stack();
WALK_COMPLEX_TERM__(CYC_LIST, CYC_APPL, {});
/* leave an empty slot to fill in later */
@ -267,9 +281,9 @@ cyclic_complex_term( CELL *pt0, CELL *pt0_end USES_REGS) {
bool Yap_IsCyclicTerm(Term t USES_REGS) {
if (IsVarTerm(t)) {
return t;
return false;
} else if (IsPrimitiveTerm(t)) {
return t;
return false;
} else {
return cyclic_complex_term(&(t)-1, &(t)PASS_REGS);
}
@ -295,54 +309,135 @@ static Term BREAK_LOOP(Int ddep) {
return MkAtomTerm(Yap_LookupAtom(buf));
}
/**
@brief routine to locate all variables in a term, and its applications */
#define CYC_MARK_LIST(d0) \
if (IS_VISIT_MARKER(d0,to_visit,to_visit0)) { \
/*fprintf(stderr,"+%ld at %s\n", to_visit-to_visit0, __FUNCTION__);*/ \
MaBind(ptd0, BREAK_LOOP(d0)); \
} \
#define CYC_MARK_APPL(d0) \
if (IS_VISIT_MARKER(d0,to_visit,to_visit0)) { \
/*fprintf(stderr,"+%ld at %s\n", to_visit-to_visit0, __FUNCTION__);*/ \
MaBind(ptd0, BREAK_LOOP(d0)); \
} \
static Term cycles_in_complex_term(register CELL *pt0,
static int cycles_in_complex_term(register CELL *pt0,
register CELL *pt0_end USES_REGS) {
int lvl = push_text_stack(); \
WALK_COMPLEX_TERM__(CYC_MARK_LIST(d0), CYC_MARK_APPL(d0), {});
/* leave an empty slot to fill in later */
END_WALK();
int lvl = push_text_stack();
int rc = 0;
CELL *ptf;
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;
ptf = HR;
while (to_visit >= to_visit0) {
CELL d0;
CELL *ptd0;
restart:
while (pt0 < pt0_end) {
++pt0;
ptd0 = pt0;
d0 = *ptd0;
list_loop:
deref_head(d0, var_in_term_unk);
var_in_term_nvar : {
if (IsPairTerm(d0)) {
if (to_visit + 32 >= to_visit_max) {
goto aux_overflow;
}
ptd0 = RepPair(d0);
d0 = ptd0[0];
if (IS_VISIT_MARKER) {
rc++;
*ptf++ = BREAK_LOOP(to_visit - to_visit0);
continue;
}
*ptf++ = AbsPair(HR);
to_visit->pt0 = pt0;
to_visit->pt0_end = pt0_end;
to_visit->ptd0 = ptd0;
to_visit->d0 = d0;
to_visit->ptf = ptf;
to_visit++;
ptf = HR;
HR += 2;
*ptd0 = VISIT_MARKER;
pt0 = ptd0;
pt0_end = pt0+1;
ptf = HR - 2;
goto list_loop;
} else if (IsApplTerm(d0)) {
register Functor f;
/* store the terms to visit */
ptd0 = RepAppl(d0);
f = (Functor)(d0 = *ptd0);
if (IsExtensionFunctor(f)) {
*ptf++ = d0;
continue;
}
if (to_visit + 32 >= to_visit_max) {
goto aux_overflow;
}
if (IS_VISIT_MARKER) {
rc++;
*ptf++ = BREAK_LOOP(to_visit - to_visit0);
continue;
}
*ptf++ = AbsAppl(HR);
to_visit->pt0 = pt0;
to_visit->pt0_end = pt0_end;
to_visit->ptd0 = ptd0;
to_visit->d0 = d0;
to_visit->ptf = ptf;
to_visit++;
*ptd0 = VISIT_MARKER;
*HR++ = (CELL)f;
ptf = HR;
Term d1 = ArityOfFunctor(f);
pt0 = ptd0;
pt0_end = ptd0 + (d1);
HR+=d1;
continue;
} else {
*ptf++ = d0;
continue;
}
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) {
pt0 = to_visit->pt0;
pt0_end = to_visit->pt0_end;
*to_visit->ptd0 = to_visit->d0;
}
}
pop_text_stack(lvl);
return false;
return rc;
def_aux_overflow();
return -1;
}
bool Yap_CyclesInTerm(Term t USES_REGS) {
Term Yap_CyclesInTerm(Term t USES_REGS) {
if (IsVarTerm(t)) {
return t;
} else if (IsPrimitiveTerm(t)) {
return t;
} else {
return cycles_in_complex_term(&(t)-1, &(t) PASS_REGS);
CELL *Hi = HR;
if ( cycles_in_complex_term(&(t)-1, &(t)PASS_REGS) >0) {
return IsPairTerm(t) ? AbsPair(Hi) : AbsAppl(Hi);
} else {
HR = Hi;
return t;
}
}
}
/** @pred cycles_in_term( + _T_ )
Succeeds if the graph representation of the term has markers in every loop. Say,
the representation of a term `X` that obeys the equation `X=[X]`
Succeeds if the graph representation of the term has markers in every
loop. Say, the representation of a term `X` that obeys the equation `X=[X]`
term has a loop from the list to its head.
@ -358,7 +453,7 @@ static Int cycles_in_term(USES_REGS1) /* cyclic_term(+T) */
static bool ground_complex_term(register CELL * pt0,
register CELL * pt0_end USES_REGS) {
int lvl = push_text_stack(); \
int lvl = push_text_stack();
WALK_COMPLEX_TERM();
/* leave an empty slot to fill in later */
while (to_visit > to_visit0) {
@ -407,7 +502,7 @@ static Int ground(USES_REGS1) /* ground(+T) */
static Int var_in_complex_term(register CELL * pt0, register CELL * pt0_end,
Term v USES_REGS) {
int lvl = push_text_stack(); \
int lvl = push_text_stack();
WALK_COMPLEX_TERM();
if ((CELL)ptd0 == v) { /* we found it */
@ -438,8 +533,8 @@ static Int var_in_complex_term(register CELL *pt0, register CELL *pt0_end,
def_aux_overflow();
}
static Int var_in_term(Term v,
Term t USES_REGS) /* variables in term t */
static Int var_in_term(
Term v, Term t USES_REGS) /* variables in term t */
{
must_be_variable(v);
t = Deref(t);
@ -474,7 +569,7 @@ static Term vars_in_complex_term(register CELL *pt0, register CELL *pt0_end,
CELL output = AbsPair(HR);
int lvl = push_text_stack();
push_text_stack(); \
push_text_stack();
WALK_COMPLEX_TERM();
/* do or pt2 are unbound */
*ptd0 = TermNil;
@ -520,13 +615,15 @@ static Term vars_in_complex_term(register CELL *pt0, register CELL *pt0_end,
}
/**
* @pred variables_in_term( +_T_, +_SetOfVariables_, +_ExtendedSetOfVariables_ )
* @pred variables_in_term( +_T_, +_SetOfVariables_, +_ExtendedSetOfVariables_
* )
*
* _SetOfVariables_ must be a list of unbound variables. If so,
* _ExtendedSetOfVariables_ will include all te variables in the union
* of `vars(_T_)` and _SetOfVariables_.
*/
static Int variables_in_term(USES_REGS1) /* variables in term t */
static Int variables_in_term(
USES_REGS1) /* variables in term t */
{
Term out, inp;
int count;
@ -574,7 +671,8 @@ restart:
*/
static Int p_term_variables3(USES_REGS1) /* variables in term t */
static Int p_term_variables3(
USES_REGS1) /* variables in term t */
{
Term out;
@ -601,8 +699,8 @@ static Int p_term_variables3(USES_REGS1) /* variables in term t */
/**
* Exports a nil-terminated list with all the variables in a term.
* @param[t] the term
* @param[arity] the arity of the calling predicate (required for exact garbage
* collection).
* @param[arity] the arity of the calling predicate (required for exact
* garbage collection).
* @param[USES_REGS] threading
*/
Term Yap_TermVariables(
@ -637,7 +735,8 @@ Term Yap_TermVariables(
*/
static Int p_term_variables(USES_REGS1) /* variables in term t */
static Int p_term_variables(
USES_REGS1) /* variables in term t */
{
Term out;
@ -665,12 +764,12 @@ typedef struct att_rec {
CELL oval;
} att_rec_t;
static Term attvars_in_complex_term(register CELL *pt0, register CELL *pt0_end,
Term inp USES_REGS) {
static Term attvars_in_complex_term(
register CELL * pt0, register CELL * pt0_end, Term inp USES_REGS) {
register tr_fr_ptr TR0 = TR;
CELL *InitialH = HR;
CELL output = inp;
int lvl = push_text_stack(); \
int lvl = push_text_stack();
WALK_COMPLEX_TERM();
if (IsAttVar(ptd0)) {
@ -748,14 +847,14 @@ static Int p_term_attvars(USES_REGS1) /* variables in term t */
return Yap_unify(ARG2, out);
}
/** @brief output the difference between variables in _T_ and variables in some
* list.
/** @brief output the difference between variables in _T_ and variables in
* some list.
*/
static Term new_vars_in_complex_term(register CELL *pt0, register CELL *pt0_end,
Term inp USES_REGS) {
static Term new_vars_in_complex_term(
register CELL * pt0, register CELL * pt0_end, Term inp USES_REGS) {
register tr_fr_ptr TR0 = TR;
CELL *InitialH = HR;
int lvl = push_text_stack(); \
int lvl = push_text_stack();
HB = ASP;
CELL output = TermNil;
{
@ -805,14 +904,14 @@ static Term new_vars_in_complex_term(register CELL *pt0, register CELL *pt0_end,
Unify _Variables_ with the list of all variables of term
_Term_ that do not occur in _CurrentVariables_. The variables occur in the
order of their first appearance when traversing the term depth-first,
_Term_ that do not occur in _CurrentVariables_. The variables occur in
the order of their first appearance when traversing the term depth-first,
left-to-right.
*/
static Int
p_new_variables_in_term(USES_REGS1) /* variables within term t */
static Int p_new_variables_in_term(
USES_REGS1) /* variables within term t */
{
Term out;
@ -843,8 +942,8 @@ p_new_variables_in_term(USES_REGS1) /* variables within term t */
*ptd0 = TermNil; \
}
static Term vars_within_complex_term(register CELL *pt0, register CELL *pt0_end,
Term inp USES_REGS) {
static Term vars_within_complex_term(
register CELL * pt0, register CELL * pt0_end, Term inp USES_REGS) {
tr_fr_ptr TR0 = TR;
CELL *InitialH = HR;
@ -938,7 +1037,6 @@ static Term free_vars_in_complex_term(CELL *pt0, CELL *pt0_end,
TrailTerm(TR++) = (CELL)ptd0;
END_WALK();
clean_tr(TR0 PASS_REGS);
pop_text_stack(lvl);
return o;
@ -981,8 +1079,8 @@ static Term bind_vars_in_complex_term(CELL *pt0, CELL *pt0_end,
def_trail_overflow();
}
static Int
p_free_variables_in_term(USES_REGS1) /* variables within term t */
static Int p_free_variables_in_term(
USES_REGS1) /* variables within term t */
{
Term out;
Term t, t0;
@ -1043,7 +1141,8 @@ p_free_variables_in_term(USES_REGS1) /* variables within term t */
*pt2 = TermRefoundVar; \
}
static Term non_singletons_in_complex_term(CELL *pt0, CELL *pt0_end USES_REGS) {
static Term non_singletons_in_complex_term(CELL * pt0,
CELL * pt0_end USES_REGS) {
tr_fr_ptr TR0 = TR;
CELL *InitialH = HR;
HB = (CELL *)ASP;
@ -1145,7 +1244,6 @@ static Int numbervars_in_complex_term(CELL *pt0, CELL *pt0_end, Int numbv,
def_aux_overflow();
def_global_overflow();
}
Int Yap_NumberVars(Term inp, Int numbv,
@ -1207,7 +1305,8 @@ static Int p_numbervars(USES_REGS1) {
goto restart; \
}
static int max_numbered_var(CELL *pt0, CELL *pt0_end, Int *maxp USES_REGS) {
static int max_numbered_var(CELL * pt0, CELL * pt0_end,
Int * maxp USES_REGS) {
int lvl = push_text_stack();
WALK_COMPLEX_TERM__({}, MAX_NUMBERED, {});
END_WALK();
@ -1256,7 +1355,6 @@ static Int largest_numbervar(USES_REGS1) {
return Yap_unify(MaxNumberedVar(Deref(ARG1), 2 PASS_REGS), ARG2);
}
static Term UNFOLD_LOOP(Term t, Term * b) {
Term os[2], o;
os[0] = o = MkVarTerm();
@ -1267,7 +1365,6 @@ static Term UNFOLD_LOOP(Term t, Term *b) {
return o;
}
typedef struct block_connector {
Int me; //> index in the array;
Term source; //> source;
@ -1276,17 +1373,13 @@ typedef struct block_connector {
CELL reference; //> term used to refer the copy.
} cl_connector;
static bool
dataid(Term t, cl_connector *q)
{
static bool dataid(Term t, cl_connector * q) {
Int i = IntegerOfTerm(t);
cl_connector *d = q + i;
return d->me == i; //&& d->source == (void *;
}
static Int
create_entry(Term t, Int i, Int j, cl_connector *q, Int max)
{
static Int create_entry(Term t, Int i, Int j, cl_connector * q, Int max) {
Term ref, h, *s, *ostart;
bool pair = false;
ssize_t n;
@ -1318,12 +1411,10 @@ create_entry(Term t, Int i, Int j, cl_connector *q, Int max)
return max;
}
Int cp_link(Term t,Int i, Int j, cl_connector *q, Int max, CELL *tailp)
{
Int cp_link(Term t, Int i, Int j, cl_connector * q, Int max, CELL * tailp) {
Int me;
t = Deref(t);
printf("%lx i=%ld,max=%ld,H=%p\n", t, i, max, HR), t = Deref(t);
if (IsVarTerm(t) || IsPrimitiveTerm(t)) {
if (IsIntegerTerm(t) && dataid(t, q)) {
t = q[IntegerOfTerm(t)].header;
@ -1391,7 +1482,6 @@ Term Yap_BreakCycles(Term inp, UInt arity, Term *listp USES_REGS) {
}
pop_text_stack(lvl);
HB = B->cp_h;
return q[0].reference;
}

View File

@ -1105,7 +1105,7 @@ void Yap_plwrite(Term t, StreamDesc *mywrite, int max_depth, int flags,
wglb.lw = separator;
if ((flags & Handle_cyclics_f) ){
Yap_CyclesInTerm(t, 3, NULL PASS_REGS);
t = Yap_CyclesInTerm(t PASS_REGS);
}
/* protect slots for portray */

View File

@ -445,6 +445,7 @@ bool Yap_isDirectory(const char *FileName);
extern bool Yap_Exists(const char *f);
/* terms.c */
extern Term Yap_CyclesInTerm(Term t USES_REGS);
extern bool Yap_IsCyclicTerm(Term inp USES_REGS);
extern Term Yap_BreakCycles(Term inp, UInt arity, Term *listp USES_REGS);
extern void Yap_InitTermCPreds(void);