CompareResult LPO4CompareCopy(OCB_p ocb, Term_p s, Term_p t, DerefType deref_s, DerefType deref_t) { CompareResult res; Term_p s1, t1; /* printf("LPO4CompareCopy()...\n"); */ if(deref_s == DEREF_NEVER) { s1 = s; } else { s1 = TermCopyKeepVars(s, deref_s); } if(deref_t == DEREF_NEVER) { t1 = t; } else { t1 = TermCopyKeepVars(t, deref_t); } if(TermStructEqualNoDerefHardVars(s1,t1)) { res = to_equal; } else if(lpo4_copy_greater(ocb, s1,t1)) { res = to_greater; } else if(lpo4_copy_greater(ocb, t1,s1)) { res = to_lesser; } else { res = to_uncomparable; } if(deref_s != DEREF_NEVER) { TermFree(s1); } if(deref_t != DEREF_NEVER) { TermFree(t1); } /* printf("...LPO4CompareCopy()=%d\n", res);*/ assert(res == LPOCompare(ocb, s, t, deref_s, deref_t)); return res; }
bool LPOGreaterCopy(OCB_p ocb, Term_p s, Term_p t, DerefType deref_s, DerefType deref_t) { bool res; Term_p s1, t1; /* printf("LPOGreaterCopy()...\n"); */ if(deref_s == DEREF_NEVER) { s1 = s; } else { s1 = TermCopyKeepVars(s, deref_s); } if(deref_t == DEREF_NEVER) { t1 = t; } else { t1 = TermCopyKeepVars(t, deref_t); } res = LPOGreater(ocb, s1,t1,DEREF_NEVER,DEREF_NEVER); if(deref_s != DEREF_NEVER) { TermFree(s1); } if(deref_t != DEREF_NEVER) { TermFree(t1); } /* printf("...LPOGreaterCopy()\n"); */ assert(res == LPOGreater(ocb, s, t, deref_s, deref_t)); return res; }
CompareResult LPOCompareCopy(OCB_p ocb, Term_p s, Term_p t, DerefType deref_s, DerefType deref_t) { CompareResult res; Term_p s1, t1; /* printf("LPOCompareCopy()...\n"); */ if(deref_s == DEREF_NEVER) { s1 = s; } else { s1 = TermCopyKeepVars(s, deref_s); } if(deref_t == DEREF_NEVER) { t1 = t; } else { t1 = TermCopyKeepVars(t, deref_t); } res = LPOCompare(ocb, s1, t1, DEREF_NEVER, DEREF_NEVER); if(deref_s != DEREF_NEVER) { TermFree(s1); } if(deref_t != DEREF_NEVER) { TermFree(t1); } /* printf("...LPOCompareCopy()=%d\n", res); */ assert(res == LPOCompare(ocb, s, t, deref_s, deref_t)); return res; }
void TermFree(Term_p junk) { assert(junk); if(!TermIsVar(junk)) { assert(!TermCellQueryProp(junk, TPIsShared)); if(junk->arity) { int i; assert(junk->args); for(i=0; i<junk->arity; i++) { TermFree(junk->args[i]); } } else { assert(!junk->args); } TermTopFree(junk); } }
WORD DoIfStatement(PHEAD WORD *ifcode, WORD *term) { GETBIDENTITY WORD *ifstop, *ifp; UWORD *coef1 = 0, *coef2, *coef3, *cc; WORD ncoef1, ncoef2, ncoef3, i = 0, first, *r, acoef, ismul1, ismul2, j; UWORD *Spac1, *Spac2; ifstop = ifcode + ifcode[1]; ifp = ifcode + 3; if ( ifp >= ifstop ) return(1); if ( ( ifp + ifp[1] ) >= ifstop ) { switch ( *ifp ) { case LONGNUMBER: if ( ifp[2] ) return(1); else return(0); case MATCH: case TYPEIF: if ( HowMany(BHEAD ifp,term) ) return(1); else return(0); case TYPEFINDLOOP: if ( Lus(term,ifp[3],ifp[4],ifp[5],ifp[6],ifp[2]) ) return(1); else return(0); case TYPECOUNT: if ( CountDo(term,ifp) ) return(1); else return(0); case COEFFI: case MULTIPLEOF: return(1); case IFDOLLAR: { DOLLARS d = Dollars + ifp[2]; #ifdef WITHPTHREADS int nummodopt, dtype = -1; if ( AS.MultiThreaded ) { for ( nummodopt = 0; nummodopt < NumModOptdollars; nummodopt++ ) { if ( ifp[2] == ModOptdollars[nummodopt].number ) break; } if ( nummodopt < NumModOptdollars ) { dtype = ModOptdollars[nummodopt].type; if ( dtype == MODLOCAL ) { d = ModOptdollars[nummodopt].dstruct+AT.identity; } } } dtype = d->type; #else int dtype = d->type; /* We use dtype to make the operation atomic */ #endif if ( dtype == DOLZERO ) return(0); if ( dtype == DOLUNDEFINED ) { if ( AC.UnsureDollarMode == 0 ) { MesPrint("$%s is undefined",AC.dollarnames->namebuffer+d->name); Terminate(-1); } } } return(1); case IFEXPRESSION: r = ifp+2; j = ifp[1] - 2; while ( --j >= 0 ) { if ( *r == AR.CurExpr ) return(1); r++; } return(0); case IFISFACTORIZED: r = ifp+2; j = ifp[1] - 2; if ( j == 0 ) { if ( ( Expressions[AR.CurExpr].vflags & ISFACTORIZED ) != 0 ) return(1); else return(0); } while ( --j >= 0 ) { if ( ( Expressions[*r].vflags & ISFACTORIZED ) == 0 ) return(0); r++; } return(1); case IFOCCURS: { WORD *OccStop = ifp + ifp[1]; ifp += 2; while ( ifp < OccStop ) { if ( FindVar(ifp,term) == 1 ) return(1); if ( *ifp == DOTPRODUCT ) ifp += 3; else ifp += 2; } } return(0); default: /* Now we have a subexpression. Test first for one with a single item. */ if ( ifp[3] == ( ifp[1] + 3 ) ) return(DoIfStatement(BHEAD ifp,term)); ifstop = ifp + ifp[1]; ifp += 3; break; } } /* Here is the composite condition. */ coef3 = NumberMalloc("DoIfStatement"); Spac1 = NumberMalloc("DoIfStatement"); Spac2 = (UWORD *)(TermMalloc("DoIfStatement")); ncoef1 = 0; first = 1; ismul1 = 0; do { if ( !first ) { ifp += 2; if ( ifp[-2] == ORCOND && ncoef1 ) { coef1 = Spac1; ncoef1 = 1; coef1[0] = coef1[1] = 1; goto SkipCond; } if ( ifp[-2] == ANDCOND && !ncoef1 ) goto SkipCond; } coef2 = Spac2; ncoef2 = 1; ismul2 = 0; switch ( *ifp ) { case LONGNUMBER: ncoef2 = ifp[2]; j = 2*(ABS(ncoef2)); cc = (UWORD *)(ifp + 3); for ( i = 0; i < j; i++ ) coef2[i] = cc[i]; break; case MATCH: case TYPEIF: coef2[0] = HowMany(BHEAD ifp,term); coef2[1] = 1; if ( coef2[0] == 0 ) ncoef2 = 0; break; case TYPECOUNT: acoef = CountDo(term,ifp); coef2[0] = ABS(acoef); coef2[1] = 1; if ( acoef == 0 ) ncoef2 = 0; else if ( acoef < 0 ) ncoef2 = -1; break; case TYPEFINDLOOP: acoef = Lus(term,ifp[3],ifp[4],ifp[5],ifp[6],ifp[2]); coef2[0] = ABS(acoef); coef2[1] = 1; if ( acoef == 0 ) ncoef2 = 0; else if ( acoef < 0 ) ncoef2 = -1; break; case COEFFI: r = term + *term; ncoef2 = r[-1]; i = ABS(ncoef2); cc = (UWORD *)(r - i); if ( ncoef2 < 0 ) ncoef2 = (ncoef2+1)>>1; else ncoef2 = (ncoef2-1)>>1; i--; for ( j = 0; j < i; j++ ) coef2[j] = cc[j]; break; case SUBEXPR: ncoef2 = coef2[0] = DoIfStatement(BHEAD ifp,term); coef2[1] = 1; break; case MULTIPLEOF: ncoef2 = 1; coef2[0] = ifp[2]; coef2[1] = 1; ismul2 = 1; break; case IFDOLLAREXTRA: break; case IFDOLLAR: { /* We need to abstract a long rational in coef2 with length ncoef2. What if that cannot be done? */ DOLLARS d = Dollars + ifp[2]; #ifdef WITHPTHREADS int nummodopt, dtype = -1; if ( AS.MultiThreaded ) { for ( nummodopt = 0; nummodopt < NumModOptdollars; nummodopt++ ) { if ( ifp[2] == ModOptdollars[nummodopt].number ) break; } if ( nummodopt < NumModOptdollars ) { dtype = ModOptdollars[nummodopt].type; if ( dtype == MODLOCAL ) { d = ModOptdollars[nummodopt].dstruct+AT.identity; } else { LOCK(d->pthreadslockread); } } } #endif /* We have to pick up the IFDOLLAREXTRA pieces for [1], [$y] etc. */ if ( ifp+3 < ifstop && ifp[3] == IFDOLLAREXTRA ) { if ( d->nfactors == 0 ) { MLOCK(ErrorMessageLock); MesPrint("Attempt to use a factor of an unfactored $-variable"); MUNLOCK(ErrorMessageLock); Terminate(-1); } { WORD num = GetIfDollarNum(ifp+3,ifstop); WORD *w; while ( ifp+3 < ifstop && ifp[3] == IFDOLLAREXTRA ) ifp += 3; if ( num > d->nfactors ) { MLOCK(ErrorMessageLock); MesPrint("Dollar factor number %s out of range",num); MUNLOCK(ErrorMessageLock); Terminate(-1); } if ( num == 0 ) { ncoef2 = 1; coef2[0] = d->nfactors; coef2[1] = 1; break; } w = d->factors[num-1].where; if ( w == 0 ) { if ( d->factors[num-1].value < 0 ) { ncoef2 = -1; coef2[0] = -d->factors[num-1].value; coef2[1] = 1; } else { ncoef2 = 1; coef2[0] = d->factors[num-1].value; coef2[1] = 1; } break; } if ( w[*w] == 0 ) { r = w + *w - 1; i = ABS(*r); if ( i == ( *w-1 ) ) { ncoef2 = (i-1)/2; if ( *r < 0 ) ncoef2 = -ncoef2; i--; cc = coef2; r = w + 1; while ( --i >= 0 ) *cc++ = (UWORD)(*r++); break; } } goto generic; } } else { switch ( d->type ) { case DOLUNDEFINED: if ( AC.UnsureDollarMode == 0 ) { #ifdef WITHPTHREADS if ( dtype > 0 && dtype != MODLOCAL ) { UNLOCK(d->pthreadslockread); } #endif MLOCK(ErrorMessageLock); MesPrint("$%s is undefined",AC.dollarnames->namebuffer+d->name); MUNLOCK(ErrorMessageLock); Terminate(-1); } ncoef2 = 0; coef2[0] = 0; coef2[1] = 1; break; case DOLZERO: ncoef2 = coef2[0] = 0; coef2[1] = 1; break; case DOLSUBTERM: if ( d->where[0] != INDEX || d->where[1] != 3 || d->where[2] < 0 || d->where[2] >= AM.OffsetIndex ) { if ( AC.UnsureDollarMode == 0 ) { #ifdef WITHPTHREADS if ( dtype > 0 && dtype != MODLOCAL ) { UNLOCK(d->pthreadslockread); } #endif MLOCK(ErrorMessageLock); MesPrint("$%s is of wrong type",AC.dollarnames->namebuffer+d->name); MUNLOCK(ErrorMessageLock); Terminate(-1); } ncoef2 = 0; coef2[0] = 0; coef2[1] = 1; break; } d->index = d->where[2]; case DOLINDEX: if ( d->index == 0 ) { ncoef2 = coef2[0] = 0; coef2[1] = 1; } else if ( d->index > 0 && d->index < AM.OffsetIndex ) { ncoef2 = 1; coef2[0] = d->index; coef2[1] = 1; } else if ( AC.UnsureDollarMode == 0 ) { #ifdef WITHPTHREADS if ( dtype > 0 && dtype != MODLOCAL ) { UNLOCK(d->pthreadslockread); } #endif MLOCK(ErrorMessageLock); MesPrint("$%s is of wrong type",AC.dollarnames->namebuffer+d->name); MUNLOCK(ErrorMessageLock); Terminate(-1); } ncoef2 = coef2[0] = 0; coef2[1] = 1; break; case DOLWILDARGS: if ( d->where[0] <= -FUNCTION || ( d->where[0] < 0 && d->where[2] != 0 ) || ( d->where[0] > 0 && d->where[d->where[0]] != 0 ) ) { if ( AC.UnsureDollarMode == 0 ) { #ifdef WITHPTHREADS if ( dtype > 0 && dtype != MODLOCAL ) { UNLOCK(d->pthreadslockread); } #endif MLOCK(ErrorMessageLock); MesPrint("$%s is of wrong type",AC.dollarnames->namebuffer+d->name); MUNLOCK(ErrorMessageLock); Terminate(-1); } ncoef2 = coef2[0] = 0; coef2[1] = 1; break; } case DOLARGUMENT: if ( d->where[0] == -SNUMBER ) { if ( d->where[1] == 0 ) { ncoef2 = coef2[0] = 0; } else if ( d->where[1] < 0 ) { ncoef2 = -1; coef2[0] = -d->where[1]; } else { ncoef2 = 1; coef2[0] = d->where[1]; } coef2[1] = 1; } else if ( d->where[0] == -INDEX && d->where[1] >= 0 && d->where[1] < AM.OffsetIndex ) { if ( d->where[1] == 0 ) { ncoef2 = coef2[0] = 0; coef2[1] = 1; } else { ncoef2 = 1; coef2[0] = d->where[1]; coef2[1] = 1; } } else if ( d->where[0] > 0 && d->where[ARGHEAD] == (d->where[0]-ARGHEAD) && ABS(d->where[d->where[0]-1]) == (d->where[0] - ARGHEAD-1) ) { i = d->where[d->where[0]-1]; ncoef2 = (ABS(i)-1)/2; if ( i < 0 ) { ncoef2 = -ncoef2; i = -i; } i--; cc = coef2; r = d->where + ARGHEAD+1; while ( --i >= 0 ) *cc++ = (UWORD)(*r++); } else { if ( AC.UnsureDollarMode == 0 ) { #ifdef WITHPTHREADS if ( dtype > 0 && dtype != MODLOCAL ) { UNLOCK(d->pthreadslockread); } #endif MLOCK(ErrorMessageLock); MesPrint("$%s is of wrong type",AC.dollarnames->namebuffer+d->name); MUNLOCK(ErrorMessageLock); Terminate(-1); } ncoef2 = 0; coef2[0] = 0; coef2[1] = 1; } break; case DOLNUMBER: case DOLTERMS: if ( d->where[d->where[0]] == 0 ) { r = d->where + d->where[0]-1; i = ABS(*r); if ( i == ( d->where[0]-1 ) ) { ncoef2 = (i-1)/2; if ( *r < 0 ) ncoef2 = -ncoef2; i--; cc = coef2; r = d->where + 1; while ( --i >= 0 ) *cc++ = (UWORD)(*r++); break; } } generic:; if ( AC.UnsureDollarMode == 0 ) { #ifdef WITHPTHREADS if ( dtype > 0 && dtype != MODLOCAL ) { UNLOCK(d->pthreadslockread); } #endif MLOCK(ErrorMessageLock); MesPrint("$%s is of wrong type",AC.dollarnames->namebuffer+d->name); MUNLOCK(ErrorMessageLock); Terminate(-1); } ncoef2 = 0; coef2[0] = 0; coef2[1] = 1; break; } } #ifdef WITHPTHREADS if ( dtype > 0 && dtype != MODLOCAL ) { UNLOCK(d->pthreadslockread); } #endif } break; case IFEXPRESSION: r = ifp+2; j = ifp[1] - 2; ncoef2 = 0; while ( --j >= 0 ) { if ( *r == AR.CurExpr ) { ncoef2 = 1; break; } r++; } coef2[0] = ncoef2; coef2[1] = 1; break; case IFISFACTORIZED: r = ifp+2; j = ifp[1] - 2; if ( j == 0 ) { ncoef2 = 0; if ( ( Expressions[AR.CurExpr].vflags & ISFACTORIZED ) != 0 ) { ncoef2 = 1; } } else { ncoef2 = 1; while ( --j >= 0 ) { if ( ( Expressions[*r].vflags & ISFACTORIZED ) == 0 ) { ncoef2 = 0; break; } r++; } } coef2[0] = ncoef2; coef2[1] = 1; break; case IFOCCURS: { WORD *OccStop = ifp + ifp[1], *ifpp = ifp+2; ncoef2 = 0; while ( ifpp < OccStop ) { if ( FindVar(ifpp,term) == 1 ) { ncoef2 = 1; break; } if ( *ifpp == DOTPRODUCT ) ifp += 3; else ifpp += 2; } coef2[0] = ncoef2; coef2[1] = 1; } break; default: break; } if ( !first ) { if ( ifp[-2] != ORCOND && ifp[-2] != ANDCOND ) { if ( ( ifp[-2] == EQUAL || ifp[-2] == NOTEQUAL ) && ( ismul2 || ismul1 ) ) { if ( ismul1 && ismul2 ) { if ( coef1[0] == coef2[0] ) i = 1; else i = 0; } else { if ( ismul1 ) { if ( ncoef2 ) Divvy(BHEAD coef2,&ncoef2,coef1,ncoef1); cc = coef2; ncoef3 = ncoef2; } else { if ( ncoef1 ) Divvy(BHEAD coef1,&ncoef1,coef2,ncoef2); cc = coef1; ncoef3 = ncoef1; } if ( ncoef3 < 0 ) ncoef3 = -ncoef3; if ( ncoef3 == 0 ) { if ( ifp[-2] == EQUAL ) i = 1; else i = 0; } else if ( cc[ncoef3] != 1 ) { if ( ifp[-2] == EQUAL ) i = 0; else i = 1; } else { for ( j = 1; j < ncoef3; j++ ) { if ( cc[ncoef3+j] != 0 ) break; } if ( j < ncoef3 ) { if ( ifp[-2] == EQUAL ) i = 0; else i = 1; } else if ( ifp[-2] == EQUAL ) i = 1; else i = 0; } } goto donemul; } else if ( AddRat(BHEAD coef1,ncoef1,coef2,-ncoef2,coef3,&ncoef3) ) { NumberFree(coef3,"DoIfStatement"); NumberFree(Spac1,"DoIfStatement"); TermFree(Spac2,"DoIfStatement"); MesCall("DoIfStatement"); return(-1); } switch ( ifp[-2] ) { case GREATER: if ( ncoef3 > 0 ) i = 1; else i = 0; break; case GREATEREQUAL: if ( ncoef3 >= 0 ) i = 1; else i = 0; break; case LESS: if ( ncoef3 < 0 ) i = 1; else i = 0; break; case LESSEQUAL: if ( ncoef3 <= 0 ) i = 1; else i = 0; break; case EQUAL: if ( ncoef3 == 0 ) i = 1; else i = 0; break; case NOTEQUAL: if ( ncoef3 != 0 ) i = 1; else i = 0; break; } donemul: if ( i ) { ncoef2 = 1; coef2 = Spac2; coef2[0] = coef2[1] = 1; } else ncoef2 = 0; ismul1 = ismul2 = 0; } } else { first = 0; } coef1 = Spac1; i = 2*ABS(ncoef2); for ( j = 0; j < i; j++ ) coef1[j] = coef2[j]; ncoef1 = ncoef2; SkipCond: ifp += ifp[1]; } while ( ifp < ifstop );