48#define HAS_CACHE_REGS 1
52int Yap_rational_tree_loop(CELL *, CELL *, CELL **, CELL **);
54static int OCUnify_complex(CELL *, CELL *, CELL *);
55static int OCUnify(
register CELL,
register CELL);
56static Int p_ocunify( USES_REGS1 );
60#define tovisit_base ((struct v_record *)AuxSp)
63Yap_rational_tree_loop(CELL *pt0, CELL *pt0_end, CELL **tovisit, CELL **tovisit_max)
65 CELL ** base = tovisit;
67 while (pt0 < pt0_end) {
74 deref_head(d0, rtree_loop_unk);
77 if (d0 == TermFoundVar)
81 if (tovisit < tovisit_max) {
82 tovisit = Yap_shift_visit(tovisit, &tovisit_max, &base);
86 tovisit[2] = (CELL *)*pt0;
88 pt0_end = (pt0 = RepPair(d0) - 1) + 2;
99 if (IsExtensionFunctor(f)) {
103 if (tovisit < tovisit_max) {
104 tovisit = Yap_shift_visit(tovisit, &tovisit_max, &base);
107 tovisit[1] = pt0_end;
108 tovisit[2] = (CELL *)*pt0;
110 d0 = ArityOfFunctor(f);
118 derefa_body(d0, ptd0, rtree_loop_unk, rtree_loop_nvar);
121 if (tovisit < base) {
123 pt0_end = tovisit[1];
124 *pt0 = (CELL)tovisit[2];
132 while (tovisit < (CELL **)base) {
135 *pt0 = (CELL)tovisit[2];
142rational_tree(Term d0) {
144 CELL **tovisit_max = (CELL **)AuxBase, **tovisit = (CELL **)AuxSp;
146 if (IsPairTerm(d0)) {
147 CELL *pt0 = RepPair(d0);
149 return Yap_rational_tree_loop(pt0-1, pt0+1, tovisit, tovisit_max);
150 }
else if (IsApplTerm(d0)) {
151 CELL *pt0 = RepAppl(d0);
154 if (IsExtensionFunctor(f))
156 return Yap_rational_tree_loop(pt0, pt0+ArityOfFunctor(f), tovisit, tovisit_max);
162OCUnify_complex(CELL *pt0, CELL *pt0_end, CELL *pt1)
168#define Yap_REGS (*regp)
169#elif defined(SHADOW_REGS)
170#if defined(B) || defined(TR)
171 register REGSTORE *regp = &Yap_REGS;
173#define Yap_REGS (*regp)
178 register CELL *HBREG = HB;
183#define unif_base ((struct unif_record *)AuxBase)
186 while (pt0 < pt0_end) {
187 register CELL *ptd0 = pt0+1;
193 deref_head(d0, unify_comp_unk);
196 register CELL *ptd1 = pt1;
197 register CELL d1 = *ptd1;
199 deref_head(d1, unify_comp_nvar_unk);
200 unify_comp_nvar_nvar:
202 if (Yap_rational_tree_loop(pt0-1, pt0, (CELL **)tovisit, (CELL **)unif))
206 if (IsPairTerm(d0)) {
207 if (!IsPairTerm(d1)) {
213 if (RATIONAL_TREES || pt0 < pt0_end) {
218 if ((
void *)tovisit < (
void *)unif) {
219 CELL **urec = (CELL **)unif;
220 tovisit = (
struct v_record *)Yap_shift_visit((CELL **)tovisit, &urec, NULL);
223 tovisit->start0 = pt0;
224 tovisit->end0 = pt0_end;
225 tovisit->start1 = pt1;
232 pt0_end = (pt0 = RepPair(d0) - 1) + 2;
233 pt1 = RepPair(d1) - 1;
236 if (IsApplTerm(d0)) {
238 register CELL *ap2, *ap3;
240 if (!IsApplTerm(d1)) {
250 if (IsExtensionFunctor(f)) {
251 if (unify_extension(f, d0, ap2, d1))
258 if (RATIONAL_TREES || pt0 < pt0_end) {
263 if ((
void *)tovisit < (
void *)unif) {
264 CELL **urec = (CELL **)unif;
265 tovisit = (
struct v_record *)Yap_shift_visit((CELL **)tovisit, &urec, NULL);
268 tovisit->start0 = pt0;
269 tovisit->end0 = pt0_end;
270 tovisit->start1 = pt1;
277 d0 = ArityOfFunctor(f);
285 derefa_body(d1, ptd1, unify_comp_nvar_unk, unify_comp_nvar_nvar);
287 Bind_Global(ptd1, d0);
288 if (Yap_rational_tree_loop(ptd1-1, ptd1, (CELL **)tovisit, (CELL **)unif))
293 derefa_body(d0, ptd0, unify_comp_unk, unify_comp_nvar);
302 deref_head(d1, unify_comp_var_unk);
305 Bind_Global(ptd0, d1);
306 if (Yap_rational_tree_loop(ptd0-1, ptd0, (CELL **)tovisit, (CELL **)unif))
310 derefa_body(d1, ptd1, unify_comp_var_unk, unify_comp_var_nvar);
312 UnifyGlobalCells(ptd0, ptd1);
316 if (tovisit < tovisit_base) {
317 pt0 = tovisit->start0;
318 pt0_end = tovisit->end0;
319 pt1 = tovisit->start1;
325 while (unif-- != unif_base) {
337 while (unif-- != unif_base) {
347#define Yap_REGS (*Yap_regp)
348#elif defined(SHADOW_REGS)
349#if defined(B) || defined(TR)
358OCUnify(
register CELL d0,
register CELL d1)
361 register CELL *pt0, *pt1;
364 register CELL *HBREG = HB;
367 deref_head(d0, oc_unify_unk);
371 deref_head(d1, oc_unify_nvar_unk);
375 return (!rational_tree(d0));
378 if (IsPairTerm(d0)) {
379 if (!IsPairTerm(d1)) {
384 return (OCUnify_complex(pt0 - 1, pt0 + 1, pt1 - 1));
386 else if (IsApplTerm(d0)) {
396 if (IsExtensionFunctor((
Functor)d0)) {
398 case (CELL)FunctorDBRef:
400 case (CELL)FunctorLongInt:
401 return(pt0[1] == pt1[1]);
402 case (CELL)FunctorDouble:
403 return(FloatOfTerm(AbsAppl(pt0)) == FloatOfTerm(AbsAppl(pt1)));
404 case (CELL)FunctorString:
405 return(strcmp( (
const char *)(pt0+2), (
const char *)(pt1+2)) == 0);
407 case (CELL)FunctorBigInt:
408 return(Yap_gmp_tcmp_big_big(AbsAppl(pt0),AbsAppl(pt0)) == 0);
414 return (OCUnify_complex(pt0, pt0 + ArityOfFunctor((
Functor) d0),
421 deref_body(d1, pt1, oc_unify_nvar_unk, oc_unify_nvar_nvar);
425 if (pt1 > HR && pt1 < LCL0)
427 if (rational_tree(d0))
431 deref_body(d0, pt0, oc_unify_unk, oc_unify_nvar);
433 deref_head(d1, oc_unify_var_unk);
438 if (pt0 > HR && pt0 < LCL0)
440 if (rational_tree(d1))
444 deref_body(d1, pt1, oc_unify_var_unk, oc_unify_var_nvar);
446 UnifyCells(pt0, pt1);
452p_ocunify( USES_REGS1 )
454 return(OCUnify(ARG1,ARG2));
458p_cyclic( USES_REGS1 )
460 Term t = Deref(ARG1);
463 return rational_tree(t);
466bool Yap_IsAcyclicTerm(Term t)
468 return !rational_tree(t);
472p_acyclic( USES_REGS1 )
474 Term t = Deref(ARG1);
477 return !rational_tree(t);
481Yap_IUnify(
register CELL d0,
register CELL d1)
487#define Yap_REGS (*regp)
489#if defined(B) || defined(TR)
490 register REGSTORE *regp = &Yap_REGS;
492#define Yap_REGS (*regp)
497 register CELL *HBREG = HB;
500 register CELL *pt0, *pt1;
502 deref_head(d0, unify_unk);
506 deref_head(d1, unify_nvar_unk);
511 if (IsPairTerm(d0)) {
512 if (!IsPairTerm(d1)) {
517 return (IUnify_complex(pt0 - 1, pt0 + 1, pt1 - 1));
519 else if (IsApplTerm(d0)) {
529 if (IsExtensionFunctor((
Functor)d0)) {
531 case (CELL)FunctorDBRef:
533 case (CELL)FunctorLongInt:
534 return(pt0[1] == pt1[1]);
535 case (CELL)FunctorString:
536 return(strcmp( (
const char *)(pt0+2), (
const char *)(pt1+2)) == 0);
537 case (CELL)FunctorDouble:
538 return(FloatOfTerm(AbsAppl(pt0)) == FloatOfTerm(AbsAppl(pt1)));
540 case (CELL)FunctorBigInt:
541 return(Yap_gmp_tcmp_big_big(AbsAppl(pt0),AbsAppl(pt0)) == 0);
547 return (IUnify_complex(pt0, pt0 + ArityOfFunctor((
Functor) d0),
554 deref_body(d1, pt1, unify_nvar_unk, unify_nvar_nvar);
559 deref_body(d0, pt0, unify_unk, unify_nvar);
561 deref_head(d1, unify_var_unk);
567#if TRAILING_REQUIRES_BRANCH
573 deref_body(d1, pt1, unify_var_unk, unify_var_nvar);
575 UnifyCells(pt0, pt1);
580#define Yap_REGS (*Yap_regp)
582#if defined(B) || defined(TR)
599InitReverseLookupOpcode(
void)
604 int hash_size_mask = OP_HASH_SIZE-1;
605 UInt sz = OP_HASH_SIZE*
sizeof(
struct opcode_optab_entry);
607 while (OP_RTABLE == NULL) {
608 if ((OP_RTABLE = (op_entry *)Yap_AllocCodeSpace(sz)) == NULL) {
609 if (!Yap_growheap(FALSE, sz, NULL)) {
610 Yap_Error(SYSTEM_ERROR_INTERNAL, TermNil,
611 "Couldn't obtain space for the reverse translation opcode table");
615 memset(OP_RTABLE, 0, sz);
620 for (j=0; j<OP_HASH_SIZE; j++) {
622 opeptr[j].opnum = _Ystop;
626 opeptr[rtable_hash_op(Yap_opcode(_Ystop),hash_size_mask)].opc
627 = Yap_opcode(_Ystop);
629 for (i = _std_top; i > _Ystop; i--) {
630 OPCODE opc = Yap_opcode(i);
631 int j = rtable_hash_op(opc,hash_size_mask);
632 while (opeptr[j].opc) {
633 if (++j > hash_size_mask)
643#define UnifyAndTrailGlobalCells(a, b) \
646 DO_TRAIL((a), (CELL)(b)); \
647 } else if((a) < (b)){ \
649 DO_TRAIL((b), (CELL)(a)); \
653unifiable_complex(CELL *pt0, CELL *pt0_end, CELL *pt1)
659#define Yap_REGS (*regp)
660#elif defined(SHADOW_REGS)
661#if defined(B) || defined(TR)
662 register REGSTORE *regp = &Yap_REGS;
664#define Yap_REGS (*regp)
669 register CELL *HBREG = HB;
674#define unif_base ((struct unif_record *)AuxBase)
675#define tovisit_base ((struct v_record *)AuxSp)
678 while (pt0 < pt0_end) {
679 register CELL *ptd0 = pt0+1;
685 deref_head(d0, unifiable_comp_unk);
688 register CELL *ptd1 = pt1;
689 register CELL d1 = *ptd1;
691 deref_head(d1, unifiable_comp_nvar_unk);
692 unifiable_comp_nvar_nvar:
695 if (IsPairTerm(d0)) {
696 if (!IsPairTerm(d1)) {
702 if (RATIONAL_TREES || pt0 < pt0_end) {
707 if ((
void *)tovisit < (
void *)unif) {
708 CELL **urec = (CELL **)unif;
709 tovisit = (
struct v_record *)Yap_shift_visit((CELL **)tovisit, &urec, NULL);
712 tovisit->start0 = pt0;
713 tovisit->end0 = pt0_end;
714 tovisit->start1 = pt1;
721 pt0_end = (pt0 = RepPair(d0) - 1) + 2;
722 pt1 = RepPair(d1) - 1;
725 if (IsApplTerm(d0)) {
727 register CELL *ap2, *ap3;
729 if (!IsApplTerm(d1)) {
739 if (IsExtensionFunctor(f)) {
740 if (unify_extension(f, d0, ap2, d1))
747 if (RATIONAL_TREES || pt0 < pt0_end) {
752 if ((
void *)tovisit < (
void *)unif) {
753 CELL **urec = (CELL **)unif;
754 tovisit = (
struct v_record *)Yap_shift_visit((CELL **)tovisit, &urec, NULL);
757 tovisit->start0 = pt0;
758 tovisit->end0 = pt0_end;
759 tovisit->start1 = pt1;
766 d0 = ArityOfFunctor(f);
774 derefa_body(d1, ptd1, unifiable_comp_nvar_unk, unifiable_comp_nvar_nvar);
781 derefa_body(d0, ptd0, unifiable_comp_unk, unifiable_comp_nvar);
790 deref_head(d1, unifiable_comp_var_unk);
791 unifiable_comp_var_nvar:
797 derefa_body(d1, ptd1, unifiable_comp_var_unk, unifiable_comp_var_nvar);
799 UnifyAndTrailGlobalCells(ptd0, ptd1);
803 if (tovisit < tovisit_base) {
804 pt0 = tovisit->start0;
805 pt0_end = tovisit->end0;
806 pt1 = tovisit->start1;
812 while (unif-- != unif_base) {
824 while (unif-- != unif_base) {
834#define Yap_REGS (*Yap_regp)
835#elif defined(SHADOW_REGS)
836#if defined(B) || defined(TR)
848unifiable(CELL d0, CELL d1)
854#define Yap_REGS (*regp)
856#if defined(B) || defined(TR)
857 register REGSTORE *regp = &Yap_REGS;
859#define Yap_REGS (*regp)
864 register CELL *HBREG = HB;
867 register CELL *pt0, *pt1;
869 deref_head(d0, unifiable_unk);
873 deref_head(d1, unifiable_nvar_unk);
878 if (IsPairTerm(d0)) {
879 if (!IsPairTerm(d1)) {
884 return (unifiable_complex(pt0 - 1, pt0 + 1, pt1 - 1));
886 else if (IsApplTerm(d0)) {
896 if (IsExtensionFunctor((
Functor)d0)) {
898 case (CELL)FunctorDBRef:
900 case (CELL)FunctorLongInt:
901 return(pt0[1] == pt1[1]);
902 case (CELL)FunctorString:
903 return(strcmp( (
const char *)(pt0+2), (
const char *)(pt1+2)) == 0);
904 case (CELL)FunctorDouble:
905 return(FloatOfTerm(AbsAppl(pt0)) == FloatOfTerm(AbsAppl(pt1)));
907 case (CELL)FunctorBigInt:
908 return(Yap_gmp_tcmp_big_big(AbsAppl(pt0),AbsAppl(pt0)) == 0);
914 return (unifiable_complex(pt0, pt0 + ArityOfFunctor((
Functor) d0),
921 deref_body(d1, pt1, unifiable_nvar_unk, unifiable_nvar_nvar);
927 deref_body(d0, pt0, unifiable_unk, unifiable_nvar);
929 deref_head(d1, unifiable_var_unk);
936 deref_body(d1, pt1, unifiable_var_unk, unifiable_var_nvar);
938 UnifyAndTrailCells(pt0, pt1);
942#define Yap_REGS (*Yap_regp)
944#if defined(B) || defined(TR)
952p_unifiable( USES_REGS1 )
954 tr_fr_ptr trp, trp0 = TR;
956 if (!unifiable(ARG1,ARG2)) {
960 while (trp != trp0) {
963 t[0] = TrailTerm(trp);
964 t[1] = *(CELL *)t[0];
965 tf = MkPairTerm(Yap_MkApplTerm(FunctorEq,2,t),tf);
966 RESET_VARIABLE(t[0]);
968 return Yap_unify(ARG3, tf);
972Yap_Unifiable( Term d0, Term d1 )
975 tr_fr_ptr trp, trp0 = TR;
977 if (!unifiable(d0,d1)) {
981 while (trp != trp0) {
995 Term cm = CurrentModule;
996 Yap_InitCPred(
"unify_with_occurs_check", 2, p_ocunify, SafePredFlag);
1020 Yap_InitCPred(
"acyclic_term", 1, p_acyclic, SafePredFlag|TestPredFlag);
1028 CurrentModule = TERMS_MODULE;
1029 Yap_InitCPred(
"cyclic_term", 1, p_cyclic, SafePredFlag|TestPredFlag);
1030 Yap_InitCPred(
"unifiable", 3, p_unifiable, 0);
1039#if USE_THREADED_CODE
1041 InitReverseLookupOpcode();
1058 register CELL *HBREG = HB;
1061#include "trim_trail.h"