Yap_unifiable and YAP_Unifiable.

This commit is contained in:
Vítor Santos Costa 2011-10-27 12:35:07 +02:00
parent c57fbf40e6
commit 980c79359f
4 changed files with 86 additions and 22 deletions

View File

@ -605,11 +605,13 @@ InitReverseLookupOpcode(void)
} }
#endif #endif
#define UnifiableGlobalCells(a, b) \ #define UnifyAndTrailGlobalCells(a, b) \
if((a) > (b)) { \ if((a) > (b)) { \
Bind_Global_NonAtt((a),(CELL)(b)); \ *(a) = (CELL)(b); \
DO_TRAIL((a), (CELL)(b)); \
} else if((a) < (b)){ \ } else if((a) < (b)){ \
Bind_Global_NonAtt((b),(CELL) (a)); \ *(b) = (CELL)(a); \
DO_TRAIL((b), (CELL)(a)); \
} }
static int static int
@ -736,7 +738,8 @@ loop:
derefa_body(d1, ptd1, unifiable_comp_nvar_unk, unifiable_comp_nvar_nvar); derefa_body(d1, ptd1, unifiable_comp_nvar_unk, unifiable_comp_nvar_nvar);
/* d1 and pt2 have the unbound value, whereas d0 is bound */ /* d1 and pt2 have the unbound value, whereas d0 is bound */
Bind(ptd1, d0); *(ptd1) = d0;
DO_TRAIL(ptd1, d0);
continue; continue;
} }
@ -752,12 +755,13 @@ loop:
deref_head(d1, unifiable_comp_var_unk); deref_head(d1, unifiable_comp_var_unk);
unifiable_comp_var_nvar: unifiable_comp_var_nvar:
/* pt2 is unbound and d1 is bound */ /* pt2 is unbound and d1 is bound */
Bind(ptd0, d1); *ptd0 = d1;
DO_TRAIL(ptd0, d1);
continue; continue;
derefa_body(d1, ptd1, unifiable_comp_var_unk, unifiable_comp_var_nvar); derefa_body(d1, ptd1, unifiable_comp_var_unk, unifiable_comp_var_nvar);
/* ptd0 and ptd1 are unbound */ /* ptd0 and ptd1 are unbound */
UnifiableGlobalCells(ptd0, ptd1); UnifyAndTrailGlobalCells(ptd0, ptd1);
} }
} }
/* Do we still have compound terms to visit */ /* Do we still have compound terms to visit */
@ -879,7 +883,8 @@ unifiable_nvar_nvar:
deref_body(d1, pt1, unifiable_nvar_unk, unifiable_nvar_nvar); deref_body(d1, pt1, unifiable_nvar_unk, unifiable_nvar_nvar);
/* d0 is bound and d1 is unbound */ /* d0 is bound and d1 is unbound */
Bind(pt1, d0); *(pt1) = d0;
DO_TRAIL(pt1, d0);
return (TRUE); return (TRUE);
deref_body(d0, pt0, unifiable_unk, unifiable_nvar); deref_body(d0, pt0, unifiable_unk, unifiable_nvar);
@ -887,18 +892,13 @@ unifiable_nvar_nvar:
deref_head(d1, unifiable_var_unk); deref_head(d1, unifiable_var_unk);
unifiable_var_nvar: unifiable_var_nvar:
/* pt0 is unbound and d1 is bound */ /* pt0 is unbound and d1 is bound */
Bind(pt0, d1); *pt0 = d1;
DO_TRAIL(pt0, d1);
return TRUE; return TRUE;
#if TRAILING_REQUIRES_BRANCH
unifiable_var_nvar_trail:
DO_TRAIL(pt0);
return TRUE;
#endif
deref_body(d1, pt1, unifiable_var_unk, unifiable_var_nvar); deref_body(d1, pt1, unifiable_var_unk, unifiable_var_nvar);
/* d0 and pt1 are unbound */ /* d0 and pt1 are unbound */
UnifyCells(pt0, pt1); UnifyAndTrailCells(pt0, pt1);
return (TRUE); return (TRUE);
#if THREADS #if THREADS
#undef Yap_REGS #undef Yap_REGS
@ -914,13 +914,13 @@ unifiable_var_nvar_trail:
static Int static Int
p_unifiable( USES_REGS1 ) p_unifiable( USES_REGS1 )
{ {
tr_fr_ptr trp; tr_fr_ptr trp, trp0 = TR;
Term tf = TermNil; Term tf = TermNil;
if (!unifiable(ARG1,ARG2)) { if (!unifiable(ARG1,ARG2)) {
return FALSE; return FALSE;
} }
trp = TR; trp = TR;
while (trp != B->cp_tr) { while (trp != trp0) {
Term t[2]; Term t[2];
--trp; --trp;
t[0] = TrailTerm(trp); t[0] = TrailTerm(trp);
@ -931,6 +931,26 @@ p_unifiable( USES_REGS1 )
return Yap_unify(ARG3, tf); return Yap_unify(ARG3, tf);
} }
int
Yap_unifiable( Term d0, Term d1 )
{
CACHE_REGS
tr_fr_ptr trp, trp0 = TR;
Term tf = TermNil;
if (!unifiable(d0,d1)) {
return FALSE;
}
trp = TR;
while (trp != trp0) {
Term t;
--trp;
t = TrailTerm(trp);
RESET_VARIABLE(t);
}
return TRUE;
}
void void
Yap_InitUnify(void) Yap_InitUnify(void)
{ {
@ -940,7 +960,7 @@ Yap_InitUnify(void)
Yap_InitCPred("acyclic_term", 1, p_acyclic, SafePredFlag|TestPredFlag); Yap_InitCPred("acyclic_term", 1, p_acyclic, SafePredFlag|TestPredFlag);
CurrentModule = TERMS_MODULE; CurrentModule = TERMS_MODULE;
Yap_InitCPred("cyclic_term", 1, p_cyclic, SafePredFlag|TestPredFlag); Yap_InitCPred("cyclic_term", 1, p_cyclic, SafePredFlag|TestPredFlag);
Yap_InitCPred("protected_unifiable", 3, p_unifiable, 0); Yap_InitCPred("unifiable", 3, p_unifiable, 0);
CurrentModule = cm; CurrentModule = cm;
} }

View File

@ -1583,3 +1583,16 @@ void SET_ASP__(CELL *yreg, Int sz USES_REGS) {
#define INITIALIZE_PERMVAR(PTR, V) *(PTR) = (V) #define INITIALIZE_PERMVAR(PTR, V) *(PTR) = (V)
#endif #endif
/* l1: bind a, l2 bind b, l3 no binding */
#define UnifyAndTrailCells(a, b) \
if((a) > (b)) { \
if ((a) < H) { *(a) = (CELL)(b); DO_TRAIL((a),(CELL)(b)); } \
else if ((b) <= H) { *(a) =(CELL)(b); DO_TRAIL((a),(CELL)(b));} \
else { *(b) = (CELL)(a); DO_TRAIL((b),(CELL)(a)); } \
} else if((a) < (b)){ \
if ((b) <= H) { *(b) = (CELL)(a); DO_TRAIL((b),(CELL)(a)); } \
else if ((a) <= H) { *(b) = (CELL) (a); DO_TRAIL((b),(CELL)(a));} \
else { *(a) = (CELL) (b); DO_TRAIL((a),(CELL)(b));} \
}

View File

@ -16182,6 +16182,27 @@ of non-variable terms:
YAP_Bool YAP_IsApplTerm(YAP_Term @var{t}) YAP_Bool YAP_IsApplTerm(YAP_Term @var{t})
@end example @end example
The next primitive gives the type of a Prolog term:
@example
YAP_tag_t YAP_TagOfTerm(YAP_Term @var{t})
@end example
The set of possible values is an enumerated type, with the following values:
@table @i
@item @code{YAP_TAG_ATT}: an attributed variable
@item @code{YAP_TAG_UNBOUND}: an unbound variable
@item @code{YAP_TAG_REF}: a reference to a term
@item @code{YAP_TAG_PAIR}: a list
@item @code{YAP_TAG_ATOM}: an atom
@item @code{YAP_TAG_INT}: a small integer
@item @code{YAP_TAG_LONG_INT}: a word sized integer
@item @code{YAP_TAG_BIG_INT}: a very large integer
@item @code{YAP_TAG_RATIONAL}: a rational number
@item @code{YAP_TAG_FLOAT}: a floating point number
@item @code{YAP_TAG_OPAQUE}: an opaque term
@item @code{YAP_TAG_APPL}: a compound term
@end table
Next, we mention the primitives that allow one to destruct and construct Next, we mention the primitives that allow one to destruct and construct
terms. All the above primitives ensure that their result is terms. All the above primitives ensure that their result is
@i{dereferenced}, i.e. that it is not a pointer to another term. @i{dereferenced}, i.e. that it is not a pointer to another term.
@ -16567,14 +16588,14 @@ lead to a crash.
The following functions are often required to compare terms. The following functions are often required to compare terms.
@findex YAP_ExactlyEqual (C-Interface function) @findex YAP_ExactlyEqual (C-Interface function)
The first function succeeds if two terms are actually the same term, as Succeed if two terms are actually the same term, as in
@code{==/2}: @code{==/2}:
@example @example
int YAP_ExactlyEqual(YAP_Term t1, YAP_Term t2) int YAP_ExactlyEqual(YAP_Term t1, YAP_Term t2)
@end example @end example
@noindent @noindent
The second function succeeds if two terms are variant terms, and returns The next function succeeds if two terms are variant terms, and returns
0 otherwise, as 0 otherwise, as
@code{=@=/2}: @code{=@=/2}:
@example @example
@ -16582,6 +16603,13 @@ The second function succeeds if two terms are variant terms, and returns
@end example @end example
@noindent @noindent
Last, this function succeeds if two terms are unifiable:
@code{=@=/2}:
@example
int YAP_Unifiable(YAP_Term t1, YAP_Term t2)
@end example
@noindent
The second function computes a hash function for a term, as in The second function computes a hash function for a term, as in
@code{term_hash/4}. @code{term_hash/4}.
@example @example

View File

@ -534,6 +534,7 @@ extern X_API int PROTO(YAP_Erase,(void *));
/* term utilities */ /* term utilities */
extern X_API int PROTO(YAP_Variant,(YAP_Term,YAP_Term)); extern X_API int PROTO(YAP_Variant,(YAP_Term,YAP_Term));
extern X_API int PROTO(YAP_Unifiable,(YAP_Term,YAP_Term));
extern X_API int PROTO(YAP_ExactlyEqual,(YAP_Term,YAP_Term)); extern X_API int PROTO(YAP_ExactlyEqual,(YAP_Term,YAP_Term));
extern X_API YAP_Int PROTO(YAP_TermHash,(YAP_Term, YAP_Int, YAP_Int, int)); extern X_API YAP_Int PROTO(YAP_TermHash,(YAP_Term, YAP_Int, YAP_Int, int));
@ -570,6 +571,8 @@ extern X_API void *PROTO(YAP_OpaqueObjectFromTerm,(YAP_Term));
extern X_API int *PROTO(YAP_Argv,(char ***)); extern X_API int *PROTO(YAP_Argv,(char ***));
extern X_API YAP_tag_t PROTO(YAP_TagOfTerm,(YAP_Term));
#define YAP_InitCPred(N,A,F) YAP_UserCPredicate(N,F,A) #define YAP_InitCPred(N,A,F) YAP_UserCPredicate(N,F,A)
__END_DECLS __END_DECLS