fix overflow in unify_with_occurs_check

git-svn-id: https://yap.svn.sf.net/svnroot/yap/trunk@1361 b08c6af1-5177-4d33-ba66-4b1c6b8b522a
This commit is contained in:
vsc 2005-08-15 14:16:38 +00:00
parent 4eccad5e06
commit 9be7e30889
3 changed files with 76 additions and 26 deletions

View File

@ -26,10 +26,31 @@ STATIC_PROTO(int rtable_hash_op, (OPCODE));
STATIC_PROTO(void InitReverseLookupOpcode, (void)); STATIC_PROTO(void InitReverseLookupOpcode, (void));
#endif #endif
/* support for rational trees and unification with occur checking */
#if USE_SYSTEM_MALLOC
#define address_to_visit_max (&to_visit_max)
#define to_visit_base ((CELL **)AuxSp)
#define TO_VISIT to_visit, to_visit_max
int STD_PROTO(rational_tree_loop,(CELL *, CELL *, CELL **, CELL **));
#else
#define to_visit_max ((CELL **)TR+16)
#define address_to_visit_max NULL
#define to_visit_base ((CELL **)Yap_TrailTop)
#define TO_VISIT to_visit
int STD_PROTO(rational_tree_loop,(CELL *, CELL *, CELL **)); int STD_PROTO(rational_tree_loop,(CELL *, CELL *, CELL **));
#endif
int int
rational_tree_loop(CELL *pt0, CELL *pt0_end, CELL **to_visit0) rational_tree_loop(CELL *pt0, CELL *pt0_end, CELL **to_visit0
#if USE_SYSTEM_MALLOC
, CELL *to_visit_max
#endif
)
{ {
CELL **to_visit = to_visit0; CELL **to_visit = to_visit0;
@ -47,10 +68,13 @@ loop:
if (d0 == TermFoundVar) if (d0 == TermFoundVar)
goto cufail; goto cufail;
if (IsPairTerm(d0)) { if (IsPairTerm(d0)) {
to_visit -= 3;
if (to_visit < to_visit_max) {
to_visit = Yap_shift_visit(to_visit, address_to_visit_max);
}
to_visit[0] = pt0; to_visit[0] = pt0;
to_visit[1] = pt0_end; to_visit[1] = pt0_end;
to_visit[2] = (CELL *)d0; to_visit[2] = (CELL *)d0;
to_visit += 3;
*pt0 = TermFoundVar; *pt0 = TermFoundVar;
pt0_end = (pt0 = RepPair(d0) - 1) + 2; pt0_end = (pt0 = RepPair(d0) - 1) + 2;
continue; continue;
@ -66,10 +90,13 @@ loop:
if (IsExtensionFunctor(f)) { if (IsExtensionFunctor(f)) {
continue; continue;
} }
to_visit -= 3;
if (to_visit < to_visit_max) {
to_visit = Yap_shift_visit(to_visit, address_to_visit_max);
}
to_visit[0] = pt0; to_visit[0] = pt0;
to_visit[1] = pt0_end; to_visit[1] = pt0_end;
to_visit[2] = (CELL *)d0; to_visit[2] = (CELL *)d0;
to_visit += 3;
*pt0 = TermFoundVar; *pt0 = TermFoundVar;
d0 = ArityOfFunctor(f); d0 = ArityOfFunctor(f);
pt0 = ap2; pt0 = ap2;
@ -83,43 +110,45 @@ loop:
} }
/* Do we still have compound terms to visit */ /* Do we still have compound terms to visit */
if (to_visit > to_visit0) { if (to_visit > to_visit0) {
to_visit -= 3;
pt0 = to_visit[0]; pt0 = to_visit[0];
pt0_end = to_visit[1]; pt0_end = to_visit[1];
*pt0 = (CELL)to_visit[2]; *pt0 = (CELL)to_visit[2];
to_visit += 3;
goto loop; goto loop;
} }
return (FALSE); return (FALSE);
cufail: cufail:
#ifdef RATIONAL_TREES
/* we found an infinite term */ /* we found an infinite term */
while (to_visit > to_visit) { while (to_visit > to_visit) {
CELL *pt0; CELL *pt0;
to_visit -= 3;
pt0 = to_visit[0]; pt0 = to_visit[0];
*pt0 = (CELL)to_visit[2]; *pt0 = (CELL)to_visit[2];
to_visit += 3;
} }
#endif
return (TRUE); return (TRUE);
} }
static inline int static inline int
rational_tree(Term d0) { rational_tree(Term d0) {
#if USE_SYSTEM_MALLOC
CELL **to_visit_max = (CELL **)Yap_PreAllocCodeSpace(), **to_visit = (CELL **)AuxSp;
#else
CELL **to_visit = (CELL **)Yap_TrailTop;
#endif
if (IsPairTerm(d0)) { if (IsPairTerm(d0)) {
CELL *pt0 = RepPair(d0); CELL *pt0 = RepPair(d0);
CELL **to_visit = (CELL **)H;
return(rational_tree_loop(pt0-1, pt0+1, to_visit)); return rational_tree_loop(pt0-1, pt0+1, TO_VISIT);
} else if (IsApplTerm(d0)) { } else if (IsApplTerm(d0)) {
CELL *pt0 = RepAppl(d0); CELL *pt0 = RepAppl(d0);
Functor f = (Functor)(*pt0); Functor f = (Functor)(*pt0);
CELL **to_visit = (CELL **)H;
return rational_tree_loop(pt0, pt0+ArityOfFunctor(f), to_visit); return rational_tree_loop(pt0, pt0+ArityOfFunctor(f), TO_VISIT);
} else } else
return(FALSE); return FALSE;
} }
static Int static Int
@ -128,13 +157,17 @@ OCUnify_complex(register CELL *pt0, register CELL *pt0_end,
) )
{ {
register CELL **to_visit;
#if SHADOW_HB #if SHADOW_HB
register CELL *HBREG; register CELL *HBREG;
HBREG = HB; HBREG = HB;
#endif #endif
to_visit = (CELL **) H; #if USE_SYSTEM_MALLOC
CELL **to_visit_max = (CELL **)Yap_PreAllocCodeSpace(), **to_visit = (CELL **)AuxSp;
#else
CELL **to_visit = (CELL **)Yap_TrailTop;
#endif
loop: loop:
while (pt0 < pt0_end) { while (pt0 < pt0_end) {
register CELL *ptd0 = ++pt0; register CELL *ptd0 = ++pt0;
@ -150,7 +183,7 @@ OCUnify_complex(register CELL *pt0, register CELL *pt0_end,
deref_head(d1, unify_comp_nvar_unk); deref_head(d1, unify_comp_nvar_unk);
unify_comp_nvar_nvar: unify_comp_nvar_nvar:
if (d0 == d1) { if (d0 == d1) {
if (rational_tree_loop(pt0-1, pt0, to_visit)) if (rational_tree_loop(pt0-1, pt0, TO_VISIT))
goto cufail; goto cufail;
continue; continue;
} if (IsPairTerm(d0)) { } if (IsPairTerm(d0)) {
@ -159,13 +192,16 @@ OCUnify_complex(register CELL *pt0, register CELL *pt0_end,
} }
/* now link the two structures so that no one else will */ /* now link the two structures so that no one else will */
/* come here */ /* come here */
to_visit -= 5;
if (to_visit < to_visit_max) {
to_visit = Yap_shift_visit(to_visit, address_to_visit_max);
}
to_visit[0] = pt0; to_visit[0] = pt0;
to_visit[1] = pt0_end; to_visit[1] = pt0_end;
to_visit[2] = pt1; to_visit[2] = pt1;
/* we want unification of rational trees to fail */ /* we want unification of rational trees to fail */
to_visit[3] = (CELL *)*pt0; to_visit[3] = (CELL *)*pt0;
to_visit[4] = (CELL *)*pt1; to_visit[4] = (CELL *)*pt1;
to_visit += 5;
*pt0 = TermFoundVar; *pt0 = TermFoundVar;
*pt1 = TermFoundVar; *pt1 = TermFoundVar;
pt0_end = (pt0 = RepPair(d0) - 1) + 2; pt0_end = (pt0 = RepPair(d0) - 1) + 2;
@ -210,12 +246,15 @@ OCUnify_complex(register CELL *pt0, register CELL *pt0_end,
} }
/* now link the two structures so that no one else will */ /* now link the two structures so that no one else will */
/* come here */ /* come here */
to_visit -= 5;
if (to_visit < to_visit_max) {
to_visit = Yap_shift_visit(to_visit, address_to_visit_max);
}
to_visit[0] = pt0; to_visit[0] = pt0;
to_visit[1] = pt0_end; to_visit[1] = pt0_end;
to_visit[2] = pt1; to_visit[2] = pt1;
to_visit[3] = (CELL *)*pt0; to_visit[3] = (CELL *)*pt0;
to_visit[4] = (CELL *)*pt1; to_visit[4] = (CELL *)*pt1;
to_visit += 5;
*pt0 = TermFoundVar; *pt0 = TermFoundVar;
*pt1 = TermFoundVar; *pt1 = TermFoundVar;
d0 = ArityOfFunctor(f); d0 = ArityOfFunctor(f);
@ -238,7 +277,7 @@ OCUnify_complex(register CELL *pt0, register CELL *pt0_end,
if (ptd1 < H0) Yap_WakeUp(ptd1); if (ptd1 < H0) Yap_WakeUp(ptd1);
bind_ocunify1: bind_ocunify1:
#endif #endif
if (rational_tree_loop(ptd1-1, ptd1, to_visit)) if (rational_tree_loop(ptd1-1, ptd1, TO_VISIT))
goto cufail; goto cufail;
continue; continue;
@ -260,7 +299,7 @@ OCUnify_complex(register CELL *pt0, register CELL *pt0_end,
if (ptd0 < H0) Yap_WakeUp(ptd0); if (ptd0 < H0) Yap_WakeUp(ptd0);
bind_ocunify2: bind_ocunify2:
#endif #endif
if (rational_tree_loop(ptd0-1, ptd0, to_visit)) if (rational_tree_loop(ptd0-1, ptd0, TO_VISIT))
goto cufail; goto cufail;
continue; continue;
@ -270,13 +309,13 @@ OCUnify_complex(register CELL *pt0, register CELL *pt0_end,
} }
} }
/* Do we still have compound terms to visit */ /* Do we still have compound terms to visit */
if (to_visit > (CELL **) H) { if (to_visit < to_visit_max) {
to_visit -= 5;
pt0 = to_visit[0]; pt0 = to_visit[0];
pt0_end = to_visit[1]; pt0_end = to_visit[1];
pt1 = to_visit[2]; pt1 = to_visit[2];
*pt0 = (CELL)to_visit[3]; *pt0 = (CELL)to_visit[3];
*pt1 = (CELL)to_visit[4]; *pt1 = (CELL)to_visit[4];
to_visit += 5;
goto loop; goto loop;
} }
/* successful exit */ /* successful exit */
@ -284,13 +323,13 @@ OCUnify_complex(register CELL *pt0, register CELL *pt0_end,
cufail: cufail:
/* failure */ /* failure */
while (to_visit > (CELL **) H) { while (to_visit < to_visit_base) {
CELL *pt0; CELL *pt0;
to_visit -= 5;
pt0 = to_visit[0]; pt0 = to_visit[0];
pt1 = to_visit[2]; pt1 = to_visit[2];
*pt0 = (CELL)to_visit[3]; *pt0 = (CELL)to_visit[3];
*pt1 = (CELL)to_visit[4]; *pt1 = (CELL)to_visit[4];
to_visit += 5;
} }
/* failure */ /* failure */
return (FALSE); return (FALSE);
@ -426,7 +465,7 @@ p_cyclic(void)
Term t = Deref(ARG1); Term t = Deref(ARG1);
if (IsVarTerm(t)) if (IsVarTerm(t))
return(FALSE); return(FALSE);
return(rational_tree(t)); return rational_tree(t);
} }
static Int static Int
@ -435,7 +474,7 @@ p_acyclic(void)
Term t = Deref(ARG1); Term t = Deref(ARG1);
if (IsVarTerm(t)) if (IsVarTerm(t))
return(TRUE); return(TRUE);
return(!rational_tree(t)); return !rational_tree(t);
} }
int int

View File

@ -44,7 +44,7 @@
incorporate_evidence/2 incorporate_evidence/2
]). ]).
:- dynamic solver/1,output/1. :- dynamic solver/1,output/1,use/1.
solver(vel). solver(vel).

View File

@ -1276,6 +1276,17 @@ cufail:
#endif #endif
} }
/* don't pollute name space */
#if USE_SYSTEM_MALLOC
#undef address_to_visit_max
#undef to_visit_base
#else
#undef to_visit_max
#undef address_to_visit_max
#undef to_visit_base
#endif
#endif #endif