diff --git a/sources/ftypes.h b/sources/ftypes.h index f700a562..b1d6dc0a 100644 --- a/sources/ftypes.h +++ b/sources/ftypes.h @@ -357,6 +357,7 @@ typedef int (*TFUN1)(); #define HAAKJE0 9 #define FUNCTION 20 +#define TMPPOLYFUN 14 #define ARGFIELD 15 #define SNUMBER 16 #define LNUMBER 17 diff --git a/sources/normal.c b/sources/normal.c index 9bfcabaa..109e7d2f 100644 --- a/sources/normal.c +++ b/sources/normal.c @@ -213,7 +213,7 @@ WORD Normalize(PHEAD WORD *term) WORD *ReplaceSub; WORD *fillsetexp; CBUF *C = cbuf+AT.ebufnum; - WORD *ANsc = 0, *ANsm = 0, *ANsr = 0; + WORD *ANsc = 0, *ANsm = 0, *ANsr = 0, PolyFunMode; LONG oldcpointer = 0; n_coef = TermMalloc("NormCoef"); n_llnum = TermMalloc("n_llnum"); @@ -243,7 +243,7 @@ PrintTerm(term,"Normalize"); termout = AT.WorkPointer; AT.WorkPointer = (WORD *)(((UBYTE *)(AT.WorkPointer)) + AM.MaxTer); fillsetexp = termout+1; - AN.PolyNormFlag = 0; + AN.PolyNormFlag = 0; PolyFunMode = AN.PolyFunTodo; /* termflag = 0; */ @@ -3116,7 +3116,12 @@ NextI:; if ( AR.PolyFunType == 1 ) { /* Regular PolyFun with one argument */ if ( t[FUNHEAD+1] == 0 && AR.Eside != LHSIDE && t[1] == FUNHEAD + 2 && t[FUNHEAD] == -SNUMBER ) goto NormZero; - if ( i > 0 && pcom[i-1][0] == AR.PolyFun ) AN.PolyNormFlag = 1; + if ( i > 0 && pcom[i-1][0] == AR.PolyFun ) { + if ( AN.PolyNormFlag == 0 ) { + AN.PolyNormFlag = 1; + AN.PolyFunTodo = 0; + } + } k = t[1]; NCOPY(m,t,k); } @@ -3147,23 +3152,59 @@ regularratfun:; if ( *u == -SNUMBER && u[1] == 0 ) goto NormInf; } if ( i > 0 && pcom[i-1][0] == AR.PolyFun ) AN.PolyNormFlag = 1; + else if ( i < ncom-1 && pcom[i+1][0] == AR.PolyFun ) AN.PolyNormFlag = 1; k = t[1]; - if ( AR.PolyFunExp == 0 ) { - NCOPY(m,t,k); - } - else if ( AR.PolyFunExp == 1 ) { /* get highest divergence */ - WORD *mmm = m; - NCOPY(m,t,k); - if ( TreatPolyRatFun(BHEAD mmm) != 0 ) - goto FromNorm; - m = mmm+mmm[1]; + if ( AN.PolyNormFlag ) { + if ( AR.PolyFunExp == 0 ) { + AN.PolyFunTodo = 0; + NCOPY(m,t,k); + } + else if ( AR.PolyFunExp == 1 ) { /* get highest divergence */ + if ( PolyFunMode == 0 ) { + NCOPY(m,t,k); + AN.PolyFunTodo = 1; + } + else { + WORD *mmm = m; + NCOPY(m,t,k); + if ( TreatPolyRatFun(BHEAD mmm) != 0 ) + goto FromNorm; + m = mmm+mmm[1]; + } + } + else { + if ( PolyFunMode == 0 ) { + NCOPY(m,t,k); + AN.PolyFunTodo = 1; + } + else { + WORD *mmm = m; + NCOPY(m,t,k); + if ( ExpandRat(BHEAD mmm) != 0 ) + goto FromNorm; + m = mmm+mmm[1]; + } + } } else { - WORD *mmm = m; - NCOPY(m,t,k); - if ( ExpandRat(BHEAD mmm) != 0 ) - goto FromNorm; - m = mmm+mmm[1]; + if ( AR.PolyFunExp == 0 ) { + AN.PolyFunTodo = 0; + NCOPY(m,t,k); + } + else if ( AR.PolyFunExp == 1 ) { /* get highest divergence */ + WORD *mmm = m; + NCOPY(m,t,k); + if ( TreatPolyRatFun(BHEAD mmm) != 0 ) + goto FromNorm; + m = mmm+mmm[1]; + } + else { + WORD *mmm = m; + NCOPY(m,t,k); + if ( ExpandRat(BHEAD mmm) != 0 ) + goto FromNorm; + m = mmm+mmm[1]; + } } } } @@ -3777,227 +3818,6 @@ regularratfun:; m += m[1]; } } -/* - #[ normalize replacements : - - At this point we have the problem that we may have to treat functions - with a dirtyflag. In the original setting DIRTYFLAG is replaced - in the redo by DIRTYSYMFLAG but that doesn't take care of things - like f(y*x) -> f(x*y) etc. This is why we need to redo the arguments - in the style that TestSub uses for dirty arguments, But this again - involves calls to Normalize itself (and to the sorting system). - This is the reason why Normalize has to be reentrant. - - To do things 100% right we have to call TestSub and potentially - invoke Generator, because there could be Table elements that - suddenly can be substituted! - - It seems best to get the term through Generator again, but that means - we have to catch the output via the sort mechanism. It may be a bit - wasteful, but it is definitely the most correct. -*/ -#ifdef OLDNORMREPLACE - { - WORD oldpolynorm = AN.PolyNormFlag; - WORD *oldcterm = AN.cTerm, *tstop, *argstop, *rnext, *tt, *wt; - WORD *oldwork, olddefer; - LONG newspace, oldspace, numterms; - AT.WorkPointer = termout; - if ( AT.WorkPointer < term + *term && term >= AT.WorkSpace - && term < AT.WorkTop ) AT.WorkPointer = term + *term; -/* - To do things 100% right we have to call TestSub and potentially - invoke Generator, because there could be Table elements that - suddenly can be substituted! - That last possibility we will omit! -*/ - tstop = term + *term; tstop -= ABS(tstop[-1]); - t = term +1; - while ( t < tstop ) { - if ( *t >= FUNCTION && ( ( t[2] & DIRTYFLAG ) != 0 ) - && ( functions[*t-FUNCTION].spec == 0 ) ) { - VOID *oldcompareroutine = AR.CompareRoutine; - r = t + FUNHEAD; argstop = t + t[1]; - while ( r < argstop ) { - if ( *r > 0 && ( r[1] != 0 ) ) { - m = r + ARGHEAD; rnext = r + *r; - oldwork = AT.WorkPointer; - olddefer = AR.DeferFlag; - AR.DeferFlag = 0; - if ( *t == AR.PolyFun && AR.PolyFunType == 2 ) { - AR.CompareRoutine = &CompareSymbols; - } - NewSort(BHEAD0); - m = r + ARGHEAD; rnext = r + *r; - while ( m < rnext ) { - i = *m; tt = m; wt = oldwork; - NCOPY(wt,tt,i); - AT.WorkPointer = wt; - if ( Generator(BHEAD oldwork,AR.Cnumlhs) ) { - LowerSortLevel(); goto FromNorm; - } - m += *m; - } - AT.WorkPointer = (WORD *)(((UBYTE *)(oldwork)) + AM.MaxTer); - if ( AT.WorkPointer > AT.WorkTop ) goto OverWork; - m = AT.WorkPointer; - if ( EndSort(BHEAD m,1) < 0 ) goto FromNorm; - if ( *t == AR.PolyFun && AR.PolyFunType == 2 ) { - AR.CompareRoutine = oldcompareroutine; - } -/* - Now we have to analyse the output - Count terms and space -*/ - AR.DeferFlag = olddefer; - numterms = 0; wt = m; - while ( *wt ) { numterms++; wt += *wt; } - newspace = wt - m; - oldspace = *r - ARGHEAD; -/* - Now the special cases -*/ - if ( numterms == 0 ) { - m[0] = -SNUMBER; m[1] = 0; - newspace = 2; - } - else if ( numterms == 1 ) { - if ( *m == 4+FUNHEAD && m[3+FUNHEAD] == 3 - && m[2+FUNHEAD] == 1 && m[1+FUNHEAD] == 1 - && m[1] >= FUNCTION ) { - m[0] = -m[1]; - newspace = 1; - } - else if ( *m == 8 && m[7] == 3 - && m[6] == 1 && m[5] == 1 - && m[1] == SYMBOL && m[4] == 1 ) { - m[0] = -SYMBOL; m[1] = m[3]; - newspace = 2; - } - else if ( *m == 7 && m[6] == 3 - && m[5] == 1 && m[4] == 1 - && m[1] == INDEX ) { - if ( m[3] >= 0 ) { - m[0] = -INDEX; m[1] = m[3]; - } - else { - m[0] = -VECTOR; m[1] = m[3]; - } - newspace = 2; - } - else if ( *m == 7 && m[6] == -3 - && m[5] == 1 && m[4] == 1 - && m[1] == INDEX && m[3] < 0 ) { - m[0] = -MINVECTOR; m[1] = m[3]; - newspace = 2; - } - else if ( *m == 4 - && m[2] == 1 && (UWORD)(m[1]) <= MAXPOSITIVE ) { - m[0] = -SNUMBER; - if ( m[3] < 0 ) m[1] = -m[1]; - newspace = 2; - } - } -/* - Now the old argument takes oldspace spaces. - The new argument takes newspace places. - The new argument sits at m. There should be enough - space in the term to accept it, but we may have to - move the tail of the term -*/ - if ( newspace <= 2 ) { - oldspace = *r; - i = oldspace - newspace; - *r = *m; - if ( newspace > 1 ) r[1] = m[1]; - m = r + newspace; - wt = rnext; - tt = term + *term; - while ( wt < tt ) *m++ = *wt++; - *term -= i; - t[1] -= i; - tstop -= i; - argstop -= i; - } - else if ( oldspace == newspace ) { - i = newspace; tt = r+ARGHEAD; wt = m; - NCOPY(tt,wt,i); - r[1] = 0; - } - else if ( oldspace > newspace ) { - i = newspace; tt = r+ARGHEAD; wt = m; - NCOPY(tt,wt,i); - wt = rnext; m = term + *term; - while ( wt < m ) *tt++ = *wt++; - i = oldspace - newspace; - *term -= i; - t[1] -= i; - tstop -= i; - argstop -= i; - *r -= i; - r[1] = 0; - } - else if ( (*term+newspace-oldspace)*sizeof(WORD) > AM.MaxTer ) { - MLOCK(ErrorMessageLock); - MesPrint("Term too complex. Maybe increasing MaxTermSize can help"); - MesCall("Norm"); - MUNLOCK(ErrorMessageLock); - TermFree(n_llnum,"n_llnum"); - TermFree(n_coef,"NormCoef"); - return(-1); - } - else { - i = newspace - oldspace; - tt = term + *term; wt = rnext; - while ( tt > rnext ) { tt--; tt[i] = tt[0]; } - *term += i; - t[1] += i; - tstop += i; - argstop += i; - *r += i; - i = newspace; tt = r+ARGHEAD; wt = m; - NCOPY(tt,wt,i); - r[1] = 0; - } - AT.WorkPointer = oldwork; - } - NEXTARG(r) - } - } - if ( *t >= FUNCTION && ( t[2] & DIRTYFLAG ) != 0 ) { - t[2] &= ~DIRTYFLAG; - if ( functions[*t-FUNCTION].symmetric ) t[2] |= DIRTYSYMFLAG; - } - t += t[1]; - } - - AN.PolyNormFlag = oldpolynorm; - AN.cTerm = oldcterm; - } - { - WORD *oldwork = AT.WorkPointer; - WORD olddefer = AR.DeferFlag; - AR.DeferFlag = 0; - NewSort(BHEAD0); - if ( Generator(BHEAD term,AR.Cnumlhs) ) { - LowerSortLevel(); goto FromNorm; - } - AT.WorkPointer = oldwork; - if ( EndSort(BHEAD term,1) < 0 ) goto FromNorm; - if ( *term == 0 ) goto NormZero; - AR.DeferFlag = olddefer; - } -#endif -/* - #] normalize replacements : -*/ -#ifdef OLDNORMREPLACE - AT.WorkPointer = termout; - if ( ReplaceType == 0 ) { - regval = 1; - goto Restart; - } -#endif /* The next 'reset' cannot be done. We still need the expression in the buffer. Note though that this may cause a runaway pointer @@ -4075,17 +3895,6 @@ regularratfun:; TermFree(n_coef,"NormCoef"); return(-1); -#ifdef OLDNORMREPLACE -OverWork: - MLOCK(ErrorMessageLock); - MesWork(); - MesCall("Norm"); - MUNLOCK(ErrorMessageLock); - TermFree(n_llnum,"n_llnum"); - TermFree(n_coef,"NormCoef"); - return(-1); -#endif - /* #] Errors and Finish : */ @@ -4954,6 +4763,7 @@ int TreatPolyRatFun(PHEAD WORD *prf) we never can have arguments that consist of just a function. */ exp1 = exp1-exp2; +/* if ( exp1 > 0 ) exp1 = 0; */ t = prf+FUNHEAD; if ( exp1 == 0 ) { *t++ = -SNUMBER; *t++ = 1; diff --git a/sources/polywrap.cc b/sources/polywrap.cc index 6c1a5cfd..cc0d13a0 100644 --- a/sources/polywrap.cc +++ b/sources/polywrap.cc @@ -656,17 +656,26 @@ int poly_ratfun_normalize (PHEAD WORD *term) { } if (num_polyratfun <= 1) return 0; +/* + When there are polyratfun's with only one variable: rename them + temporarily to TMPPOLYFUN. +*/ + for (WORD *t=term+1; t e; - for (WORD *t=term+1; t 1 ) { + if ( PolyFunMul(BHEAD term) ) goto GenCall; + AN.PolyNormFlag = 0; + if ( !*term ) goto Return0; + } +*/ Renormalize: + AN.PolyNormFlag = 0; if ( ( retnorm = Normalize(BHEAD term) ) != 0 ) { if ( retnorm > 0 ) { if ( AT.WorkPointer < term + *term ) AT.WorkPointer = term + *term; @@ -2925,10 +2934,26 @@ WORD Generator(PHEAD WORD *term, WORD level) } goto GenCall; } - if ( !*term ) goto Return0; + if ( !*term ) { AN.PolyNormFlag = 0; goto Return0; } if ( AN.PolyNormFlag ) { - if ( PolyFunMul(BHEAD term) ) goto GenCall; - if ( !*term ) goto Return0; + if ( AN.PolyFunTodo == 0 ) { + if ( PolyFunMul(BHEAD term) ) goto GenCall; + if ( !*term ) { AN.PolyNormFlag = 0; goto Return0; } + } + else { + WORD oldPolyFunExp = AR.PolyFunExp; + AR.PolyFunExp = 0; + if ( PolyFunMul(BHEAD term) ) goto GenCall; + AR.PolyFunExp = oldPolyFunExp; + if ( !*term ) { AN.PolyNormFlag = 0; goto Return0; } + if ( Normalize(BHEAD term) < 0 ) goto GenCall; + if ( !*term ) { AN.PolyNormFlag = 0; goto Return0; } + if ( AN.PolyNormFlag ) { + if ( PolyFunMul(BHEAD term) ) goto GenCall; + if ( !*term ) { AN.PolyNormFlag = 0; goto Return0; } + } + AN.PolyFunTodo = 0; + } } if ( AT.WorkPointer < (WORD *)(((UBYTE *)(term)) + AM.MaxTer) ) AT.WorkPointer = (WORD *)(((UBYTE *)(term)) + AM.MaxTer); @@ -4726,6 +4751,7 @@ WORD PrepPoly(PHEAD WORD *term) we call poly_ratfun_normalize */ if ( m[-1] == 3 && m[-2] == 1 && m[-3] == 1 ) return(0); + if ( AR.PolyFunExp != 1 ) { if ( m[-1] < 0 ) { sign = -1; size = -m[-1]; } else { sign = 1; size = m[-1]; } num = m - size; size = (size-1)/2; den = num + size; sizenum = size; while ( num[sizenum-1] == 0 ) sizenum--; @@ -4754,6 +4780,10 @@ WORD PrepPoly(PHEAD WORD *term) w = num; i = v - m; NCOPY(w,m,i); + } + else { + w = m-ABS(m[-1]); + } *w++ = 1; *w++ = 1; *w++ = 3; *term = w - term; { WORD oldtype = AR.SortType; @@ -4766,7 +4796,7 @@ WORD PrepPoly(PHEAD WORD *term) } goto endofit; /* - #] Two arguments : + #] Two arguments : */ } else { @@ -4787,7 +4817,7 @@ endofit:; } /* - #] PrepPoly : + #] PrepPoly : #[ PolyFunMul : WORD PolyFunMul(term) */ /** @@ -4807,8 +4837,82 @@ WORD PolyFunMul(PHEAD WORD *term) WORD *t, *fun1, *fun2, *t1, *t2, *m, *w, *ww, *tt1, *tt2, *tt4, *arg1, *arg2; WORD *tstop, i, dirty = 0; WORD n1, n2, i1, i2, l1, l2, l3, l4, action = 0, noac = 0; + if ( AR.PolyFunType == 2 && AR.PolyFunExp == 1 ) { + WORD pow = 0, pow1; + t = term + 1; t1 = term + *term; t1 -= ABS(t1[-1]); + w = t; + while ( t < t1 ) { + if ( *t != AR.PolyFun ) { +SkipFun: + if ( t == w ) { t += t[1]; w = t; } + else { i = t[1]; NCOPY(w,t,i) } + continue; + } + pow1 = 0; + t2 = t + t[1]; t += FUNHEAD; + if ( *t < 0 ) { + if ( *t == -SYMBOL && t[1] == AR.PolyFunVar ) pow1++; + else if ( *t != -SNUMBER ) goto NoLegal; + t += 2; + } + else if ( t[0] == ARGHEAD+8 && t[ARGHEAD] == 8 + && t[ARGHEAD+1] == SYMBOL && t[ARGHEAD+3] == AR.PolyFunVar + && t[ARGHEAD+5] == 1 && t[ARGHEAD+6] == 1 && t[ARGHEAD+7] == 3 ) { + pow1 += t[ARGHEAD+4]; + t += *t; + } + else { +NoLegal: + MLOCK(ErrorMessageLock); + MesPrint("Illegal term with divergence in PolyRatFun"); + MesCall("PolyFunMul"); + MUNLOCK(ErrorMessageLock); + Terminate(-1); + } + if ( *t < 0 ) { + if ( *t == -SYMBOL && t[1] == AR.PolyFunVar ) pow1--; + else if ( *t != -SNUMBER ) goto NoLegal; + t += 2; + } + else if ( t[0] == ARGHEAD+8 && t[ARGHEAD] == 8 + && t[ARGHEAD+1] == SYMBOL && t[ARGHEAD+3] == AR.PolyFunVar + && t[ARGHEAD+5] == 1 && t[ARGHEAD+6] == 1 && t[ARGHEAD+7] == 3 ) { + pow1 -= t[ARGHEAD+4]; + t += *t; + } + else goto NoLegal; + if ( t == t2 ) pow += pow1; + else goto SkipFun; + } + m = w; + *w++ = AR.PolyFun; *w++ = 0; FILLFUN(w); + if ( pow > 1 ) { + *w++ = 8+ARGHEAD; *w++ = 0; FILLARG(w); + *w++ = 8; *w++ = SYMBOL; *w++ = 4; *w++ = AR.PolyFunVar; *w++ = pow; + *w++ = 1; *w++ = 1; *w++ = 3; *w++ = -SNUMBER; *w++ = 1; + } + else if ( pow == 1 ) { + *w++ = -SYMBOL; *w++ = AR.PolyFunVar; *w++ = -SNUMBER; *w++ = 1; + } + else if ( pow < -1 ) { + *w++ = -SNUMBER; *w++ = 1; *w++ = 8+ARGHEAD; *w++ = 0; FILLARG(w); + *w++ = 8; *w++ = SYMBOL; *w++ = 4; *w++ = AR.PolyFunVar; *w++ = -pow; + *w++ = 1; *w++ = 1; *w++ = 3; + } + else if ( pow == -1 ) { + *w++ = -SNUMBER; *w++ = 1; *w++ = -SYMBOL; *w++ = AR.PolyFunVar; + } + else { + *w++ = -SNUMBER; *w++ = 1; *w++ = -SNUMBER; *w++ = 1; + } + m[1] = w - m; + *w++ = 1; *w++ = 1; *w++ = 3; + *term = w - term; + return(0); + } ReStart: - if ( AR.PolyFunType == 2 && AR.PolyFunExp != 2 ) { + if ( AR.PolyFunType == 2 && ( ( AR.PolyFunExp != 2 ) + || ( AR.PolyFunExp == 2 && AN.PolyNormFlag > 1 ) ) ) { WORD retval, count1 = 0, count2 = 0, count3; WORD oldtype = AR.SortType; t = term + 1; t1 = term + *term; t1 -= ABS(t1[-1]); @@ -4818,6 +4922,7 @@ WORD PolyFunMul(PHEAD WORD *term) dirty = 1; ReadPolyRatFun(BHEAD term); /* poly_ratfun_normalize(BHEAD term); */ + if ( term[0] == 0 ) return(0); goto ReStart; } t2 = t + t[1]; tt2 = t+FUNHEAD; count3 = 0; @@ -4873,10 +4978,15 @@ WORD PolyFunMul(PHEAD WORD *term) t += t[1]; } if ( count1 <= 1 ) return(0); + if ( AR.PolyFunExp == 1 ) { + t = term + *term; t -= ABS(t[-1]); + *t++ = 1; *t++ = 1; *t++ = 3; *term = t - term; + } { AR.SortType = SORTHIGHFIRST; /* retval = ReadPolyRatFun(BHEAD term); */ retval = poly_ratfun_normalize(BHEAD term); + if ( *term == 0 ) return(retval); AR.SortType = oldtype; } diff --git a/sources/ratio.c b/sources/ratio.c index c2e74593..5bda67f0 100644 --- a/sources/ratio.c +++ b/sources/ratio.c @@ -2224,7 +2224,10 @@ int ReadPolyRatFun(PHEAD WORD *term) if ( ( t[2] & CLEANPRF ) == 0 ) { t += t[1]; continue; } fun = t; nextt = t + t[1]; + if ( fun[1] > FUNHEAD && fun[FUNHEAD] == -SNUMBER && fun[FUNHEAD+1] == 0 ) + { *term = 0; break; } if ( FromPolyRatFun(BHEAD fun, &num, &den) > 0 ) { t = nextt; continue; } + if ( *num == ARGHEAD ) { *term = 0; break; } /* Now we have num and den. Both are in general argument notation, but can also be used as expressions as in num+ARGHEAD, den+ARGHEAD. @@ -2255,25 +2258,23 @@ int ReadPolyRatFun(PHEAD WORD *term) for the header of the argument. Fortutately there are only two types of fast arguments. */ - if ( num1[0] == 4 && num1[2] == 1 && num1[1] > 0 ) { + if ( num1[0] == 4 && num1[4] == 0 && num1[2] == 1 && num1[1] > 0 ) { numsize = 2; num1[0] = -SNUMBER; if ( num1[3] < 0 ) num1[1] = -num1[1]; } - else if ( num1[0] == 8 && num1[7] == 3 && num1[6] == 1 && num1[5] == 1 - && num1[1] == SYMBOL && num1[4] == 1 ) { + else if ( num1[0] == 8 && num1[8] == 0 && num1[7] == 3 && num1[6] == 1 + && num1[5] == 1 && num1[1] == SYMBOL && num1[4] == 1 ) { numsize = 2; num1[0] = -SYMBOL; num1[1] = num1[3]; } -/* if ( ToFast(num1,num1) ) { numsize = 2; } */ else { m1 = num1; while ( *m1 ) m1 += *m1; numsize = (m1-num1)+ARGHEAD; } - if ( den1[0] == 4 && den1[2] == 1 && den1[1] > 0 ) { + if ( den1[0] == 4 && den1[4] == 0 && den1[2] == 1 && den1[1] > 0 ) { densize = 2; den1[0] = -SNUMBER; if ( den1[3] < 0 ) den1[1] = -den1[1]; } - else if ( den1[0] == 8 && den1[7] == 3 && den1[6] == 1 && den1[5] == 1 - && den1[1] == SYMBOL && den1[4] == 1 ) { + else if ( den1[0] == 8 && den1[8] == 0 && den1[7] == 3 && den1[6] == 1 + && den1[5] == 1 && den1[1] == SYMBOL && den1[4] == 1 ) { densize = 2; den1[0] = -SYMBOL; den1[1] = den1[3]; } -/* if ( ToFast(den1,den1) ) { densize = 2; } */ else { m2 = den1; while ( *m2 ) m2 += *m2; densize = (m2-den1)+ARGHEAD; } size = FUNHEAD+numsize+densize; @@ -2307,6 +2308,7 @@ int ReadPolyRatFun(PHEAD WORD *term) TermFree(den1,"MULfunc"); t = nextt; } + if ( flag ) AT.WorkPointer = term +*term; else AT.WorkPointer = oldworkpointer; AR.CompareRoutine = oldcompareroutine; @@ -2579,7 +2581,6 @@ void GCDclean(PHEAD WORD *num, WORD *den) WORD *out2 = TermMalloc("GCDclean"); WORD *t1, *t2, *r1, *r2, *t1stop, *t2stop, csize1, csize2, csize3, pow, sign; int i; - t1stop = num+*num; sign = ( t1stop[-1] < 0 ) ? -1 : 1; csize1 = ABS(t1stop[-1]); t1stop -= csize1; t2stop = den+*den; if ( t2stop[-1] < 0 ) sign = -sign; @@ -3034,6 +3035,7 @@ int ExpandRat(PHEAD WORD *fun) */ NormArg:; if ( outarg == 0 ) outarg = TermMalloc("ExpandRat")+ARGHEAD; + AT.TrimPower = 1; NewSort(BHEAD0); r = fun+FUNHEAD+ARGHEAD; while ( r < tnext ) { @@ -3044,6 +3046,7 @@ NormArg:; } r = fun+FUNHEAD+ARGHEAD; EndSort(BHEAD r,1); + AT.TrimPower = 0; if ( *r == 0 ) { fun[FUNHEAD] = -SNUMBER; fun[FUNHEAD+1] = 0; fun[1] = FUNHEAD+2; diff --git a/sources/structs.h b/sources/structs.h index bf7e0f95..d77929d3 100644 --- a/sources/structs.h +++ b/sources/structs.h @@ -2136,6 +2136,7 @@ struct N_const { WORD WildArgs; /* (R) */ WORD WildEat; /* (R) */ WORD PolyNormFlag; /* (R) For polynomial arithmetic */ + WORD PolyFunTodo; /* deals with expansions and multiplications */ WORD sizeselecttermundo; /* () Used in pattern.c */ WORD patternbuffersize; /* () Used in pattern.c */ WORD numlistinprint; /* () Used in process.c */ @@ -2151,29 +2152,29 @@ struct N_const { #ifdef WITHPTHREADS #ifdef WHICHSUBEXPRESSION #ifdef WITHZLIB - PADPOSITION(54,11,23,24,sizeof(SHvariables)); + PADPOSITION(54,11,23,25,sizeof(SHvariables)); #else - PADPOSITION(52,11,23,24,sizeof(SHvariables)); + PADPOSITION(52,11,23,25,sizeof(SHvariables)); #endif #else #ifdef WITHZLIB - PADPOSITION(53,9,23,22,sizeof(SHvariables)); + PADPOSITION(53,9,23,23,sizeof(SHvariables)); #else - PADPOSITION(51,9,23,22,sizeof(SHvariables)); + PADPOSITION(51,9,23,23,sizeof(SHvariables)); #endif #endif #else #ifdef WHICHSUBEXPRESSION #ifdef WITHZLIB - PADPOSITION(52,9,23,24,sizeof(SHvariables)); + PADPOSITION(52,9,23,25,sizeof(SHvariables)); #else - PADPOSITION(50,9,23,24,sizeof(SHvariables)); + PADPOSITION(50,9,23,25,sizeof(SHvariables)); #endif #else #ifdef WITHZLIB - PADPOSITION(51,7,23,22,sizeof(SHvariables)); + PADPOSITION(51,7,23,23,sizeof(SHvariables)); #else - PADPOSITION(49,7,23,22,sizeof(SHvariables)); + PADPOSITION(49,7,23,23,sizeof(SHvariables)); #endif #endif #endif diff --git a/sources/threads.c b/sources/threads.c index 33e91605..47712bbe 100644 --- a/sources/threads.c +++ b/sources/threads.c @@ -1092,6 +1092,7 @@ int LoadOneThread(int from, int identity, THREADBUCKET *thr, int par) AN.ncmod = AC.ncmod; AT.BrackBuf = AT0.BrackBuf; AT.bracketindexflag = AT0.bracketindexflag; + AN.PolyFunTodo = 0; /* The relevant variables and the term are in their place. There is nothing more to do.