This commit is contained in:
Vítor Santos Costa 2019-02-21 20:19:31 +00:00
parent 84721e1005
commit 7dca1f1390
2 changed files with 44 additions and 86 deletions

129
C/terms.c
View File

@ -580,8 +580,7 @@ static Term vars_in_complex_term(CELL *pt0_, CELL *pt0_end_ ,
CELL output = AbsPair(HR); CELL output = AbsPair(HR);
WALK_COMPLEX_TERM(); WALK_COMPLEX_TERM();
/* do or pt2 are unbound */ /* do or pt2 are unbound */
*ptd0 = TermNil;
/* leave an empty slot to fill in later */
if (HR + 1024 > ASP) { if (HR + 1024 > ASP) {
goto global_overflow; goto global_overflow;
} }
@ -591,12 +590,10 @@ static Term vars_in_complex_term(CELL *pt0_, CELL *pt0_end_ ,
/* next make sure noone will see this as a variable again */ /* next make sure noone will see this as a variable again */
if (TR > (tr_fr_ptr)LOCAL_TrailTop - 256) { if (TR > (tr_fr_ptr)LOCAL_TrailTop - 256) {
/* Trail overflow */ /* Trail overflow */
if (!Yap_growtrail((TR - TR0) * sizeof(tr_fr_ptr *), true)) {
goto trail_overflow; goto trail_overflow;
}
} }
TrailTerm(TR++) = (CELL)ptd0; TrailTerm(TR++) = (CELL)ptd0;
*ptd0 = TermFoundVar;
END_WALK(); END_WALK();
clean_tr(TR0-count PASS_REGS); clean_tr(TR0-count PASS_REGS);
@ -607,7 +604,7 @@ static Term vars_in_complex_term(CELL *pt0_, CELL *pt0_end_ ,
Term t2 = Deref(inp); Term t2 = Deref(inp);
if (IsVarTerm(t2)) { if (IsVarTerm(t2)) {
RESET_VARIABLE(HR - 1); RESET_VARIABLE(HR - 1);
Yap_unify((CELL)(HR - 1), inp); Yap_unify((CELL)(HR - 1), t2);
} else { } else {
HR[-1] = t2; /* don't need to trail */ HR[-1] = t2; /* don't need to trail */
} }
@ -694,6 +691,22 @@ Term Yap_TermVariables(
return out; return out;
} }
static Term Yap_TermAddVariables(
Term t, Term vs USES_REGS) /* variables in term t */
{
Term out;
t = Deref(t);
if (IsVarTerm(t)) {
return MkPairTerm(t, TermNil);
} else if (IsPrimitiveTerm(t)) {
return TermNil;
} else {
out = vars_in_complex_term(&(t)-1, &(t), vs PASS_REGS);
}
return out;
}
/** @pred term_variables(? _Term_, - _Variables_) is iso /** @pred term_variables(? _Term_, - _Variables_) is iso
@ -798,7 +811,6 @@ static Term new_vars_in_complex_term(
Int n=0; Int n=0;
CELL output = TermNil; CELL output = TermNil;
{ {
tr_fr_ptr myTR0 = TR;
while (!IsVarTerm(inp) && IsPairTerm(inp)) { while (!IsVarTerm(inp) && IsPairTerm(inp)) {
Term t = HeadOfTerm(inp); Term t = HeadOfTerm(inp);
if (IsVarTerm(t)) { if (IsVarTerm(t)) {
@ -807,7 +819,7 @@ static Term new_vars_in_complex_term(
*VarOfTerm(t) = TermFoundVar; *VarOfTerm(t) = TermFoundVar;
if ((tr_fr_ptr)LOCAL_TrailTop - TR < 1024) { if ((tr_fr_ptr)LOCAL_TrailTop - TR < 1024) {
if (!Yap_growtrail((TR - myTR0) * sizeof(tr_fr_ptr *), true)) { if (!Yap_growtrail(n * sizeof(tr_fr_ptr *), true)) {
goto trail_overflow; goto trail_overflow;
} }
} }
@ -820,9 +832,7 @@ static Term new_vars_in_complex_term(
TrailTerm(TR++) = *ptd0; TrailTerm(TR++) = *ptd0;
*ptd0 = TermFoundVar; *ptd0 = TermFoundVar;
if ((tr_fr_ptr)LOCAL_TrailTop - TR < 1024) { if ((tr_fr_ptr)LOCAL_TrailTop - TR < 1024) {
if (!Yap_growtrail((TR - TR0) * sizeof(tr_fr_ptr *), true)) {
goto trail_overflow; goto trail_overflow;
}
} }
/* leave an empty slot to fill in later */ /* leave an empty slot to fill in later */
if (HR + 1024 > ASP) { if (HR + 1024 > ASP) {
@ -832,7 +842,7 @@ END_WALK();
clean_tr(TR0-n PASS_REGS); clean_tr(TR0-n PASS_REGS);
pop_text_stack(lvl); pop_text_stack(lvl);
HB = B->cp_h;
return output; return output;
def_aux_overflow(); def_aux_overflow();
@ -939,91 +949,37 @@ static Int p_variables_within_term(USES_REGS1) /* variables within term t */
return Yap_unify(ARG3, out); return Yap_unify(ARG3, out);
} }
static Term free_vars_in_complex_term(CELL * pt0_, CELL * pt0_end_
USES_REGS) {
Term o = TermNil;
WALK_COMPLEX_TERM();
/* do or pt2 are unbound */
*ptd0 = TermNil;
/* leave an empty slot to fill in later */
if (HR + 1024 > ASP) {
o = TermNil;
goto global_overflow;
}
HR[0] = (CELL)ptd0;
HR[1] = o;
o = AbsPair(HR);
HR += 2;
/* next make sure noone will see this as a variable again */
if (TR > (tr_fr_ptr)LOCAL_TrailTop - 256) {
/* Trail overflow */
if (!Yap_growtrail((TR - TR0) * sizeof(tr_fr_ptr *), true)) {
goto trail_overflow;
}
}
TrailTerm(TR++) = (CELL)ptd0;
END_WALK();
clean_tr(TR0 PASS_REGS);
pop_text_stack(lvl);
return o;
def_aux_overflow();
def_trail_overflow();
def_global_overflow();
}
static Term bind_vars_in_complex_term(CELL * pt0_, CELL * pt0_end_ USES_REGS) {
WALK_COMPLEX_TERM();
/* do or pt2 are unbound */
*ptd0 = TermFoundVar;
/* next make sure noone will see this as a variable again */
if (TR > (tr_fr_ptr)LOCAL_TrailTop - 256) {
goto trail_overflow;
}
TrailTerm(TR++) = (CELL)ptd0;
END_WALK();
pop_text_stack(lvl);
return TermNil;
def_aux_overflow();
def_trail_overflow();
}
/* variables within term t */ /* variables within term t */
static Int p_free_variables_in_term( static Int free_variables_in_term(
USES_REGS1) USES_REGS1)
{ {
Term out; Term out;
Term t, t0; Term t, t0;
Term found_module = 0L; Term found_module = 0L;
Term vlist = TermNil;
t = t0 = Deref(ARG1); t = t0 = Deref(ARG1);
while (!IsVarTerm(t) && IsApplTerm(t)) { Int delta = 0;
Functor f = FunctorOfTerm(t); while (!IsVarTerm(t) && IsApplTerm(t)) {
if (f == FunctorHat) { Functor f = FunctorOfTerm(t);
out = bind_vars_in_complex_term(RepAppl(t), RepAppl(t) + 1 PASS_REGS); if (f == FunctorHat) {
} else if (f == FunctorModule) { vlist = Yap_TermAddVariables(ArgOfTerm(1,t), vlist PASS_REGS);
found_module = ArgOfTerm(1, t); } else if (f == FunctorModule) {
} else if (f == FunctorCall) { found_module = ArgOfTerm(1, t);
t = ArgOfTerm(1, t); } else if (f == FunctorCall) {
} else if (f == FunctorExecuteInMod) { t = ArgOfTerm(1, t);
found_module = ArgOfTerm(2, t); } else if (f == FunctorExecuteInMod) {
t = ArgOfTerm(1, t); found_module = ArgOfTerm(2, t);
} else { t = ArgOfTerm(1, t);
break; } else {
} break;
t = ArgOfTerm(2, t); }
t = ArgOfTerm(2, t);
} }
if (IsPrimitiveTerm(t)) if (IsPrimitiveTerm(t))
out = TermNil; out = TermNil;
else { else {
out = free_vars_in_complex_term(&(t)-1, &(t) PASS_REGS); out = new_vars_in_complex_term(&(t)-1, &(t), vlist PASS_REGS);
} }
if (found_module && t != t0) { if (found_module && t != t0) {
@ -1428,7 +1384,8 @@ void Yap_InitTermCPreds(void) {
Yap_InitCPred("term_variables", 3, term_variables3, 0); Yap_InitCPred("term_variables", 3, term_variables3, 0);
Yap_InitCPred("$variables_in_term", 3, variables_in_term, 0); Yap_InitCPred("$variables_in_term", 3, variables_in_term, 0);
Yap_InitCPred("$free_variables_in_term", 3, p_free_variables_in_term, 0); Yap_InitCPred("$free_variables_in_term", 3, free_variables_in_term, 0);
Yap_InitCPred("free_variables_in_term", 3, free_variables_in_term, 0);
Yap_InitCPred("term_attvars", 2, term_attvars, 0); Yap_InitCPred("term_attvars", 2, term_attvars, 0);

View File

@ -230,6 +230,7 @@ bagof(Template, Generator, Bag) :-
'$bagof'(Template, Generator, Bag) :- '$bagof'(Template, Generator, Bag) :-
'$free_variables_in_term'(Template^Generator, StrippedGenerator, Key), '$free_variables_in_term'(Template^Generator, StrippedGenerator, Key),
%format('TemplateV=~w v=~w ~w~n',[TemplateV,Key, StrippedGenerator]), %format('TemplateV=~w v=~w ~w~n',[TemplateV,Key, StrippedGenerator]),
( Key \== '$' -> ( Key \== '$' ->
'$findall_with_common_vars'(Key-Template, StrippedGenerator, Bags0), '$findall_with_common_vars'(Key-Template, StrippedGenerator, Bags0),
'$keysort'(Bags0, Bags), '$keysort'(Bags0, Bags),