This commit is contained in:
Vitor Santos Costa 2019-02-04 10:42:23 +00:00
parent 7045b6ef36
commit d874dc5857
6 changed files with 53 additions and 457 deletions

View File

@ -133,7 +133,7 @@ typedef struct {
typedef struct non_single_struct_t {
CELL *ptd0;
CELL d0;
CELL *pt0, *pt0_end;
CELL *pt0, *pt0_end, *ptf;
} non_singletons_t;
#define WALK_COMPLEX_TERM__(LIST0, STRUCT0, PRIMI0) \
@ -224,11 +224,11 @@ typedef struct non_single_struct_t {
#define def_trail_overflow() \
trail_overflow : { \
pop_text_stack(lvl); \
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; \
}
@ -760,7 +760,6 @@ static Term new_vars_in_complex_term(register CELL *pt0, register CELL *pt0_end,
TrailTerm(TR++) = t;
if ((tr_fr_ptr)LOCAL_TrailTop - TR < 1024) {
if (!Yap_growtrail((TR - TR0) * sizeof(tr_fr_ptr *), true)) {
pop_text_stack(lvl);
goto trail_overflow;
}
}
@ -812,7 +811,7 @@ static Term new_vars_in_complex_term(register CELL *pt0, register CELL *pt0_end,
HR[-1] = TermNil;
return output;
} else {
return TermNil;
return 0;
}
def_aux_overflow();
@ -1349,7 +1348,8 @@ static Term UNFOLD_LOOP(Term t, Term *b, Term l) {
return o;
}
static int loops_in_complex_term(CELL *pt0, CELL *pt0_end, Term *listp,
static int loops_in_complex_term(CELL *pt0, CELL *pt0_end,
Term *listp,
Term tail USES_REGS) {
int lvl = push_text_stack();
@ -1360,6 +1360,7 @@ static int loops_in_complex_term(CELL *pt0, CELL *pt0_end, Term *listp,
to_visit0 = to_visit;
to_visit_max = to_visit0 + 1024;
CELL *ptf = HR-1;
restart:
while (pt0 < pt0_end) {
CELL d0;
@ -1375,7 +1376,6 @@ restart:
goto aux_overflow;
}
CELL *headp = RepPair(d0);
d0 = headp[0];
if (IsAtomTerm(d0) && (CELL *)AtomOfTerm(d0) >= (CELL *)to_visit0 &&
(CELL *)AtomOfTerm(d0) < (CELL *)to_visit_max) {
@ -1383,22 +1383,26 @@ restart:
struct non_single_struct_t *v0 =
(struct non_single_struct_t *)AtomOfTerm(d0);
if (listp) {
*ptd0 = UNFOLD_LOOP(AbsPair(headp), listp, tail);
*ptf = UNFOLD_LOOP(AbsPair(v0->ptf-1), listp, tail);
ptf++;
} else {
*ptd0 = BREAK_LOOP(to_visit - v0);
*ptf++ = BREAK_LOOP(to_visit - v0);
}
goto restart;
continue;
}
*ptf++ = AbsPair(HR);
to_visit->pt0 = pt0;
to_visit->pt0_end = pt0_end;
to_visit->ptd0 = headp;
to_visit->ptf = ptf;
to_visit->d0 = d0;
*headp = MkAtomTerm((AtomEntry *)to_visit);
to_visit++;
pt0 = headp;
pt0_end = pt0 + 1;
ptd0 = pt0;
ptf = HR;
HR+=2;
goto list_loop;
} else if (IsApplTerm(d0)) {
register Functor f;
@ -1406,35 +1410,44 @@ restart:
/* store the terms to visit */
ap2 = RepAppl(d0);
f = (Functor)(*ap2);
if (IsExtensionFunctor(f))
if (IsExtensionFunctor(f)) {
*ptf++ = d0;
continue;
}
if (IsAtomTerm((CELL)f)) {
struct non_single_struct_t *v0 = (struct non_single_struct_t *)AtomOfTerm(*ap2);
if (listp) {
*ptd0 = UNFOLD_LOOP(AbsAppl(ap2), listp, tail);
*ptf = UNFOLD_LOOP(AbsAppl(v0->ptf-1), listp, tail);
ptf++;
} else {
*ptd0 = BREAK_LOOP(to_visit -
(struct non_single_struct_t *)AtomOfTerm(*ap2));
*ptf++ = BREAK_LOOP(to_visit - v0);
}
goto restart;
continue;
}
// STRUCT0;
if (to_visit + 32 >= to_visit_max) {
goto aux_overflow;
}
*ptf++ = AbsAppl(HR);
HR[0] = (CELL)f;
to_visit->pt0 = pt0;
to_visit->pt0_end = pt0_end;
to_visit->ptd0 = ap2;
to_visit->d0 = *ap2;
to_visit->ptf = ptf;
*ap2 = MkAtomTerm((AtomEntry *)to_visit);
to_visit++;
pt0 = ap2;
pt0_end = ap2 + (ArityOfFunctor(f));
ptf = HR+1;
HR = ptf +ArityOfFunctor(f);
} else {
*ptf++ = d0;
}
goto restart;
derefa_body(d0, ptd0, vars_in_term_unk, vars_in_term_nvar);
*ptf++ = d0;
goto restart;
}
/* Do we still have compound terms to visit */
@ -1442,10 +1455,10 @@ restart:
to_visit--;
pt0 = to_visit->pt0;
ptf = to_visit->ptf;
pt0_end = to_visit->pt0_end;
CELL *ptd0 = to_visit->ptd0;
if (!IsVarTerm(*ptd0))
*ptd0 = to_visit->d0;
*ptd0 = to_visit->d0;
goto restart;
}
@ -1461,11 +1474,15 @@ Term Yap_BreakCycles(Term inp, UInt arity, Term *listp, Term tail USES_REGS) {
return t;
} else {
Int res;
CELL *op = HR;
HR++;
res = loops_in_complex_term((&t) - 1, &t, listp, tail PASS_REGS);
if (res < 0)
return -1;
return t;
if (IsPairTerm(t))
return AbsPair(op);
else
return AbsAppl(op);
}
}
@ -1481,7 +1498,7 @@ Term Yap_BreakCycles(Term inp, UInt arity, Term *listp, Term tail USES_REGS) {
*/
static Int p_break_rational(USES_REGS1) {
Term t = Yap_CopyTerm(Deref(ARG1));
Term t = (ARG1);
Term l = Deref(ARG4), k;
if (IsVarTerm(l))
Yap_unify(l, MkVarTerm());

View File

@ -590,433 +590,6 @@ add_to_list( Term inp, Term v, Term t PASS_REGS)
}
static int
break_rationals_complex_term(CELL *pt0, CELL *pt0_end, CELL *ptf, Term *vout, Term vin,CELL *HLow USES_REGS)
{
struct bp_frame *to_visit0, *to_visit = (struct bp_frame *)Yap_PreAllocCodeSpace() ;
CELL *HB0 = HB;
tr_fr_ptr TR0 = TR;
HB = HR;
to_visit0 = to_visit;
loop:
while (pt0 < pt0_end) {
register CELL d0;
register CELL *ptd0;
++ pt0;
ptd0 = pt0;
d0 = *ptd0;
deref_head(d0, copy_term_unk);
copy_term_nvar:
{
if (IsPairTerm(d0)) {
CELL *headp = RepPair(d0);
//fprintf(stderr, "%d \n", RepPair(headp[0])- ptf);
if (IsVarTerm(headp[0]) && IN_BETWEEN(HB, (headp[0]),HR)) {
Term v = MkVarTerm();
*ptf = v;
vin = add_to_list(vin, (CELL)(ptf), AbsPair(ptf) );
ptf++;
continue;
}
if (to_visit+1 >= (struct bp_frame *)AuxSp) {
goto heap_overflow;
}
*ptf++ = (CELL)(HR);
to_visit->start_cp = pt0;
to_visit->end_cp = pt0_end;
to_visit->to = ptf;
to_visit->oldp = headp;
d0 = to_visit->oldv = headp[0];
/* fool the system into thinking we had a variable there */
to_visit ++;
pt0 = headp;
pt0_end = headp + 1;
ptf = HR;
*headp = AbsPair(HR);
HR += 2;
if (HR > ASP - 2048) {
goto overflow;
}
if (IsVarTerm(d0) && d0 == (CELL)headp) {
RESET_VARIABLE(ptf);
ptf++;
continue;
}
d0 = Deref(d0);
if (!IsVarTerm(d0)) {
goto copy_term_nvar;
} else {
*ptf++ = d0;
}
continue;
} else if (IsApplTerm(d0)) {
register Functor f;
register CELL *headp;
/* store the terms to visit */
headp = RepAppl(d0)+1;
f = (Functor)(headp[-1]);
if (IsExtensionFunctor(f)) {
*ptf++ = d0; /* you can just copy other extensions. */
continue;
}
if (IsApplTerm(headp[0]) && IN_BETWEEN(HB, RepAppl(headp[0]),HR)) {
RESET_VARIABLE(ptf);
vin = add_to_list(vin, (CELL)ptf, headp[0] );
ptf++;
continue;
}
arity_t arity = ArityOfFunctor(f);
if (to_visit+1 >= (struct bp_frame *)AuxSp) {
goto heap_overflow;
}
*ptf++ = AbsAppl(HR);
to_visit->start_cp = pt0;
to_visit->end_cp = pt0_end;
to_visit->to = ptf;
to_visit->oldp = headp;
d0 = to_visit->oldv = headp[0];
/* fool the system into thinking we had a variable there */
to_visit ++;
pt0 = headp;
pt0_end = headp + (arity-1);
ptf = HR;
if (HR > ASP - 2048) {
goto overflow;
}
*ptf++ =(CELL)f;
*headp = AbsAppl(HR);
HR += (arity+1);
d0 = Deref(d0);
if (!IsVarTerm(d0)) {
goto copy_term_nvar;
} else {
*ptf++ = d0;
}
continue;
} else {
/* just copy atoms or integers */
*ptf++ = d0;
}
continue;
}
derefa_body(d0, ptd0, copy_term_unk, copy_term_nvar);
*ptf++ = (CELL) ptd0;
}
/* Do we still have compound terms to visit */
if (to_visit > to_visit0) {
to_visit --;
*to_visit->oldp = to_visit->oldv;
ptf = to_visit->to;
pt0 = to_visit->start_cp;
pt0_end = to_visit->end_cp;
goto loop;
}
/* restore our nice, friendly, term to its original state */
HB = HB0;
*vout = vin;
return true;
overflow:
/* oops, we're in trouble */
HR = HLow;
/* we've done it */
/* restore our nice, friendly, term to its original state */
HB = HB0;
#ifdef RATIONAL_TREES
while (to_visit > to_visit0) {
to_visit --;
pt0 = to_visit->start_cp;
pt0_end = to_visit->end_cp;
ptf = to_visit->to;
*to_visit->oldp = to_visit->oldv;
}
#endif
reset_trail(TR0);
/* follow chain of multi-assigned variables */
return -1;
heap_overflow:
/* oops, we're in trouble */
HR = HLow;
/* we've done it */
/* restore our nice, friendly, term to its original state */
HB = HB0;
#ifdef RATIONAL_TREES
while (to_visit > to_visit0) {
to_visit --;
pt0 = to_visit->start_cp;
pt0_end = to_visit->end_cp;
ptf = to_visit->to;
*to_visit->oldp = to_visit->oldv;
}
#endif
reset_trail(TR0);
LOCAL_Error_Size = (ADDR)AuxSp-(ADDR)to_visit0;
return -3;
}
Term
Yap_BreakRational(Term inp, UInt arity, Term *to, Term ti USES_REGS) {
Term t = Deref(inp);
Term tii = ti;
tr_fr_ptr TR0 = TR;
if (IsVarTerm(t)) {
*to = ti;
return t;
} else if (IsPrimitiveTerm(t)) {
*to = ti;
return t;
} else if (IsPairTerm(t)) {
CELL *ap;
CELL *Hi;
restart_list:
ap = RepPair(t);
Hi = HR;
HR += 2;
{
Int res;
if ((res = break_rationals_complex_term(ap-1, ap+1, Hi, to, ti, Hi PASS_REGS)) < 0) {
HR = Hi;
if ((t = handle_cp_overflow(res, TR0, arity, t))== 0L)
return FALSE;
goto restart_list;
} else if (*to == tii) {
HR = Hi;
return t;
} else {
return AbsPair(Hi);
}
}
} else {
Functor f;
CELL *HB0;
CELL *ap;
restart_appl:
f = FunctorOfTerm(t);
if (IsExtensionFunctor(f)) {
*to = ti;
return t;
}
HB0 = HR;
ap = RepAppl(t);
HR[0] = (CELL)f;
arity = ArityOfFunctor(f);
HR += 1+arity;
{
Int res;
if ((res = break_rationals_complex_term(ap, ap+(arity), HB0+1, to, ti, HB0 PASS_REGS)) < 0) {
HR = HB0;
if ((t = handle_cp_overflow(res, TR0, arity, t))== 0L)
return FALSE;
goto restart_appl;
} else if (*to == ti) {
HR = HB0;
return t;
} else {
return AbsAppl(HB0);
}
}
}
}
static int
break_complex_term(CELL *pt0, CELL *pt0_end, CELL *ptf, Term *of, Term oi, CELL *HLow USES_REGS)
{
struct copy_frame *to_visit0, *to_visit = (struct copy_frame *)Yap_PreAllocCodeSpace();
CELL *HB0 = HB;
tr_fr_ptr TR0 = TR;
CELL new = 0L;
HB = HLow;
to_visit0 = to_visit;
loop:
while (pt0 < pt0_end) {
register CELL d0;
register CELL *ptd0;
++ pt0;
ptd0 = pt0;
d0 = *ptd0;
if (new) {
/* mark cell as pointing to new copy */
/* we can only mark after reading the value of the first argument */
TrailedMaBind(pt0, new);
new = 0L;
}
deref_head(d0, break_rationals_unk);
break_rationals_nvar:
{
CELL first;
CELL *newp;
if (IsPairTerm(d0)) {
CELL *ap2 = RepPair(d0);
if (IsVarTerm(first = *ap2) && (newp = (CELL*)first) && newp >= HB && newp < HR) {
// found a marked term:
found_term:
if (!IsVarTerm(*newp)) {
Term v = (CELL)newp, t = *newp;
RESET_VARIABLE(newp);
oi = add_to_list( oi, v, t PASS_REGS);
}
*ptf++ = (CELL)newp;
continue;
}
new = (CELL)ptf;
*ptf++ = AbsPair(HR);
if (pt0 < pt0_end) {
if (to_visit+1 >= (struct copy_frame *)AuxSp) {
goto heap_overflow;
}
to_visit->start_cp = pt0;
to_visit->end_cp = pt0_end;
to_visit->to = ptf;
to_visit ++;
}
pt0 = ap2 - 1;
pt0_end = ap2 + 1;
ptf = HR;
HR += 2;
if (HR > ASP - 2048) {
goto overflow;
}
} else if (IsApplTerm(d0)) {
register Functor f;
register CELL *ap2;
/* store the terms to visit */
ap2 = RepAppl(d0);
f = (Functor)(*ap2);
if (IsExtensionFunctor(f)) {
*ptf++ = d0; /* you can just share extensions, what about DB? */
continue;
}
if (IsVarTerm(first = ap2[1]) && (newp = (CELL*)first) && newp >= HB && newp < HR) {
goto found_term;
}
// new
/* store the terms to visit */
new = (CELL)ptf;
*ptf++ = AbsAppl(HR);
if (pt0 < pt0_end) {
if (to_visit+1 >= (struct copy_frame *)AuxSp) {
goto heap_overflow;
}
to_visit->start_cp = pt0;
to_visit->end_cp = pt0_end;
to_visit->to = ptf;
to_visit ++;
}
d0 = ArityOfFunctor(f);
pt0 = ap2;
pt0_end = ap2 + d0;
/* store the functor for the new term */
HR[0] = (CELL)f;
ptf = HR+1;
HR += 1+d0;
if (HR > ASP - 2048) {
goto overflow;
}
} else {
/* just copy atoms or integers */
*ptf++ = d0;
}
continue;
}
derefa_body(d0, ptd0, break_rationals_unk, break_rationals_nvar);
*ptf++ = d0;
}
/* Do we still have compound terms to visit */
if (to_visit > to_visit0) {
to_visit --;
pt0 = to_visit->start_cp;
pt0_end = to_visit->end_cp;
ptf = to_visit->to;
goto loop;
}
/* restore our nice, friendly, term to its original state */
HB = HB0;
reset_trail(TR0);
*of = oi;
return TRUE;
overflow:
/* oops, we're in trouble */
HR = HLow;
/* we've done it */
/* restore our nice, friendly, term to its original state */
HB = HB0;
while (to_visit > to_visit0) {
to_visit --;
pt0 = to_visit->start_cp;
pt0_end = to_visit->end_cp;
ptf = to_visit->to;
}
reset_trail(TR0);
/* follow chain of multi-assigned variables */
return -1;
heap_overflow:
/* oops, we're in trouble */
HR = HLow;
/* we've done it */
/* restore our nice, friendly, term to its original state */
HB = HB0;
while (to_visit > to_visit0) {
to_visit --;
pt0 = to_visit->start_cp;
pt0_end = to_visit->end_cp;
ptf = to_visit->to;
}
reset_trail(TR0);
LOCAL_Error_Size = (ADDR)AuxSp-(ADDR)to_visit0;
return -3;
}
Term
Yap_BreakTerm(Term inp, UInt arity, Term *to, Term ti USES_REGS) {
Term t = Deref(inp);
tr_fr_ptr TR0 = TR;
if (IsVarTerm(t)) {
*to = ti;
return t;
} else if (IsPrimitiveTerm(t)) {
*to = ti;
return t;
} else {
CELL *ap;
CELL *Hi = HR;
restart_term:
ap = &t;
Hi = HR++;
{
int res;
if ((res = break_complex_term(ap-1, ap, Hi, to, ti, Hi PASS_REGS)) < 0) {
HR = Hi;
if ((t = handle_cp_overflow(res, TR0, arity, t))== 0L)
return FALSE;
goto restart_term;
}
}
return Hi[0];
}
}
/*
FAST EXPORT ROUTINE. Export a Prolog term to something like:

View File

@ -1084,16 +1084,16 @@ void Yap_plwrite(Term t, StreamDesc *mywrite, int max_depth, int flags,
yhandle_t lvl = push_text_stack();
struct write_globs wglb;
struct rewind_term rwt;
t = Deref(t);
rwt.parent = NULL;
wglb.stream = mywrite;
wglb.Ignore_ops = flags & Ignore_ops_f;
wglb.Write_strings = flags & BackQuote_String_f;
if (!(flags & Ignore_cyclics_f) && Yap_IsCyclicTerm(t)) {
writeTerm(Yap_BreakCycles(t, 1, NULL, TermNil PASS_REGS), priority, 1, false, &wglb, &rwt);
} else {
/* protect slots for portray */
writeTerm(t, priority, 1, false, &wglb, &rwt);
if ((flags & Handle_cyclics_f) && Yap_IsCyclicTerm(t) ){
t = Yap_BreakCycles(t, 3, NULL, TermNil PASS_REGS);
}
/* protect slots for portray */
writeTerm(t, priority, 1, false, &wglb, &rwt);
if (flags & New_Line_f) {
if (flags & Fullstop_f) {
wrputc('.', wglb.stream);

View File

@ -194,7 +194,7 @@ typedef enum { /* we accept two domains for the moment, IPV6 may follow */
#define Handle_vars_f 0x04
#define Use_portray_f 0x08
#define To_heap_f 0x10
#define Ignore_cyclics_f 0x20
#define Handle_cyclics_f 0x20
#define Use_SWI_Stream_f 0x40
#define BackQuote_String_f 0x80
#define AttVar_None_f 0x100

View File

@ -231,8 +231,9 @@ static bool write_term(int output_stream, Term t, xarg *args USES_REGS) {
goto end;
}
}
if (args[WRITE_CYCLES].used && args[WRITE_CYCLES].tvalue == TermFalse) {
flags |= Ignore_cyclics_f;
if (!args[WRITE_CYCLES].used || (args[WRITE_CYCLES].used
&& args[WRITE_CYCLES].tvalue == TermTrue)) {
flags |= Handle_cyclics_f;
}
if (args[WRITE_QUOTED].used && args[WRITE_QUOTED].tvalue == TermTrue) {
flags |= Quote_illegal_f;

View File

@ -14,6 +14,11 @@ main :-
fail.
main :-
main( writeln(X), X).
main :-
writeln('-----------------------'),
fail.
main :-
main((rational_term_to_tree(X,A,B,[]),writeln(A:B)), X).
main.
main(G, X) :-