80 WORD ReNumber(
PHEAD WORD *term)
83 WORD *d, *e, **p, **f;
85 AN.DumFound = AN.RenumScratch;
86 AN.DumPlace = AN.PoinScratch;
87 AN.DumFunPlace = AN.FunScratch;
102 if ( *f ) **f |= DIRTYSYMFLAG;
105 for ( j = 1; j <= n; j++ ) {
106 if ( *e && *(p[j]) == old ) {
108 if ( f[j] ) *(f[j]) |= DIRTYSYMFLAG;
130 VOID FunLevel(
PHEAD WORD *term)
133 WORD *t, *tstop, *r, *fun;
137 tstop = r - ABS(r[-1]);
139 if ( t < tstop )
do {
148 if ( *t > AN.IndDum ) {
149 if ( AN.NumFound >= AN.MaxRenumScratch ) AdjustRenumScratch(BHEAD0);
153 *AN.DumFunPlace++ = 0;
169 if ( *t > AN.IndDum ) {
170 if ( AN.NumFound >= AN.MaxRenumScratch ) AdjustRenumScratch(BHEAD0);
174 *AN.DumFunPlace++ = 0;
185 if ( *t < FUNCTION ) {
186 MLOCK(ErrorMessageLock);
187 MesPrint(
"Unexpected code in ReNumber");
188 MUNLOCK(ErrorMessageLock);
192 if ( *t >= FUNCTION && functions[*t-FUNCTION].spec
193 >= TENSORFUNCTION ) {
196 if ( *t > AN.IndDum ) {
197 if ( AN.NumFound >= AN.MaxRenumScratch ) AdjustRenumScratch(BHEAD0);
201 *AN.DumFunPlace++ = fun;
222 if ( *t == -INDEX ) {
224 if ( *t >= AN.IndDum ) {
225 if ( AN.NumFound >= AN.MaxRenumScratch ) AdjustRenumScratch(BHEAD0);
229 *AN.DumFunPlace++ = fun;
233 else if ( *t <= -FUNCTION ) t++;
240 }
while ( t < tstop );
251 WORD DetCurDum(
PHEAD WORD *t)
254 WORD maxval = AN.IndDum;
255 WORD maxtop = AM.IndDum + WILDOFFSET;
256 WORD *tstop, *m, *r, i;
258 tstop -= ABS(*tstop);
260 while ( t < tstop ) {
261 if ( *t == VECTOR ) {
265 if ( *m > maxval && *m < maxtop ) maxval = *m;
269 else if ( *t == DELTA || *t == INDEX ) {
274 if ( *m > maxval && *m < maxtop ) maxval = *m;
278 else if ( *t >= FUNCTION ) {
279 if ( functions[*t-FUNCTION].spec >= TENSORFUNCTION ) {
287 if ( *r <= -FUNCTION ) r++;
288 else if ( *r == -INDEX ) {
289 if ( r[1] > maxval && r[1] < maxtop ) maxval = r[1];
298 i = DetCurDum(BHEAD m);
299 if ( i > maxval && i < maxtop ) maxval = i;
323 int FullRenumber(
PHEAD WORD *term, WORD par)
326 WORD *d, **p, **f, *w, *t, *best, *stac, *perm, a, *termtry;
328 WORD *oldworkpointer = AT.WorkPointer;
329 n = ReNumber(BHEAD term) - AM.IndDum;
330 if ( n <= 1 )
return(0);
331 Normalize(BHEAD term);
332 if ( *term == 0 )
return(0);
333 n = ReNumber(BHEAD term) - AM.IndDum;
337 if ( AT.WorkPointer < term + *term ) AT.WorkPointer = term + *term;
339 best = w = AT.WorkPointer; t = term;
340 for ( i = *term; i > 0; i-- ) *w++ = *t++;
342 Normalize(BHEAD best);
343 AT.WorkPointer = w = best + *best;
346 termtry = perm + n + 1;
347 for ( i = 1; i <= n; i++ ) perm[i] = i + AM.IndDum;
348 for ( i = 1; i <= n; i++ ) stac[i] = i;
349 for ( i = 0; i < k; i++ ) d[i] = *(p[i]) - AM.IndDum;
351 for ( i = 1; i < n; i++ ) {
352 for ( j = i+1; j <= n; j++ ) {
353 a = perm[j]; perm[j] = perm[i]; perm[i] = a;
354 for ( ii = 0; ii < k; ii++ ) {
355 *(p[ii]) = perm[d[ii]];
356 if ( f[ii] ) *(f[ii]) |= DIRTYSYMFLAG;
358 t = term; w = termtry;
359 for ( ii = 0; ii < *term; ii++ ) *w++ = *t++;
361 if ( Normalize(BHEAD termtry) == 0 ) {
362 if ( *termtry == 0 )
goto Return0;
363 if ( ( ii = CompareTerms(BHEAD termtry,best,0) ) > 0 ) {
364 t = termtry; w = best;
365 for ( ii = 0; ii < *termtry; ii++ ) *w++ = *t++;
368 else if ( ii == 0 &&
CompCoef(termtry,best) != 0 )
372 a = perm[j]; perm[j] = perm[i]; perm[i] = a;
376 else if ( par == 1 ) {
379 if ( stac[j] == n ) {
380 a = perm[j]; perm[j] = perm[n]; perm[n] = a;
386 if ( j != stac[j] ) {
387 a = perm[j]; perm[j] = perm[stac[j]]; perm[stac[j]] = a;
390 a = perm[j]; perm[j] = perm[stac[j]]; perm[stac[j]] = a;
392 for ( i = 0; i < k; i++ ) {
393 *(p[i]) = perm[d[i]];
394 if ( f[i] ) *(f[i]) |= DIRTYSYMFLAG;
396 t = term; w = termtry;
397 for ( i = 0; i < *term; i++ ) *w++ = *t++;
399 if ( Normalize(BHEAD termtry) == 0 ) {
400 if ( *termtry == 0 )
goto Return0;
401 if ( ( ii = CompareTerms(BHEAD termtry,best,0) ) > 0 ) {
402 t = termtry; w = best;
403 for ( i = 0; i < *termtry; i++ ) *w++ = *t++;
405 else if ( ii == 0 &&
CompCoef(termtry,best) != 0 )
409 if ( j < n-1 ) { j = n-1; }
414 for ( i = 0; i < n; i++ ) *t++ = *w++;
415 AT.WorkPointer = oldworkpointer;
419 AT.WorkPointer = oldworkpointer;
435 VOID MoveDummies(
PHEAD WORD *term, WORD shift)
438 WORD maxval = AN.IndDum;
439 WORD maxtop = AM.IndDum + WILDOFFSET;
441 tstop = term + *term - 1;
442 tstop -= ABS(*tstop);
444 while ( term < tstop ) {
445 if ( *term == VECTOR ) {
449 if ( *m > maxval && *m < maxtop ) *m += shift;
453 else if ( *term == DELTA || *term == INDEX ) {
458 if ( *m > maxval && *m < maxtop ) *m += shift;
462 else if ( *term >= FUNCTION ) {
463 if ( functions[*term-FUNCTION].spec >= TENSORFUNCTION ) {
471 if ( *r <= -FUNCTION ) r++;
472 else if ( *r == -INDEX ) {
473 if ( r[1] > maxval && r[1] < maxtop ) r[1] += shift;
482 MoveDummies(BHEAD m,shift);
505 void AdjustRenumScratch(PHEAD0)
510 WORD **newpoin, *newnum;
511 if ( AN.MaxRenumScratch == 0 ) newsize = 100;
512 else newsize = AN.MaxRenumScratch*2;
513 if ( newsize > MAXPOSITIVE/2 ) newsize = MAXPOSITIVE/2+1;
515 newpoin = (WORD **)Malloc1(newsize*
sizeof(WORD *),
"PoinScratch");
516 for ( i = 0; i < AN.NumFound; i++ ) newpoin[i] = AN.PoinScratch[i];
517 for ( ; i < newsize; i++ ) newpoin[i] = 0;
518 if ( AN.PoinScratch ) M_free(AN.PoinScratch,
"PoinScratch");
519 AN.PoinScratch = newpoin;
520 AN.DumPlace = newpoin + AN.NumFound;
522 newpoin = (WORD **)Malloc1(newsize*
sizeof(WORD *),
"FunScratch");
523 for ( i = 0; i < AN.NumFound; i++ ) newpoin[i] = AN.FunScratch[i];
524 for ( ; i < newsize; i++ ) newpoin[i] = 0;
525 if ( AN.FunScratch ) M_free(AN.FunScratch,
"FunScratch");
526 AN.FunScratch = newpoin;
527 AN.DumFunPlace = newpoin + AN.NumFound;
529 newnum = (WORD *)Malloc1(newsize*
sizeof(WORD),
"RenumScratch");
530 for ( i = 0; i < AN.NumFound; i++ ) newnum[i] = AN.RenumScratch[i];
531 for ( ; i < newsize; i++ ) newnum[i] = 0;
532 if ( AN.RenumScratch ) M_free(AN.RenumScratch,
"RenumScratch");
533 AN.RenumScratch = newnum;
534 AN.DumFound = newnum + AN.NumFound;
536 AN.MaxRenumScratch = newsize;
551 WORD CountDo(WORD *term, WORD *instruct)
553 WORD *m, *r, i, j, count = 0;
554 WORD *stopper, *tstop, *r1 = 0, *r2 = 0;
558 tstop = term + *term; tstop -= ABS(tstop[-1]); term++;
559 while ( term < tstop ) {
566 while ( m < stopper ) {
567 if ( *m == SYMBOL && m[2] == *term ) {
568 count += m[3] * term[1];
581 while ( m < stopper ) {
582 if ( *m == DOTPRODUCT && (( m[2] == *term &&
583 m[3] == term[1]) || ( m[2] == term[1] &&
585 count += m[4] * term[2];
591 while ( m < stopper ) {
592 if ( *m == VECTOR && m[2] == *term &&
593 ( m[3] & DOTPBIT ) != 0 ) {
594 count += m[m[1]-1] * term[2];
599 while ( m < stopper ) {
600 if ( *m == VECTOR && m[2] == term[1] &&
601 ( m[3] & DOTPBIT ) != 0 ) {
602 count += m[m[1]-1] * term[2];
615 VectInd: i = term[1] - 2;
619 while ( m < stopper ) {
620 if ( *m == VECTOR && m[2] == *term &&
621 ( m[3] & VECTBIT ) != 0 ) {
631 if ( *term >= FUNCTION ) {
634 while ( m < stopper ) {
635 if ( *m == FUNCTION && m[2] == i ) count += m[3];
638 if ( functions[i-FUNCTION].spec >= TENSORFUNCTION ) {
639 i = term[1] - FUNHEAD;
644 while ( m < stopper ) {
645 if ( *m == VECTOR && m[2] == *term &&
646 ( m[3] & FUNBIT ) != 0 ) {
660 if ( ( *term == -INDEX || *term == -VECTOR
661 || *term == -MINVECTOR ) && term[1] < MINSPEC ) {
663 while ( m < stopper ) {
664 if ( *m == VECTOR && term[1] == m[2]
665 && ( m[3] & SETBIT ) != 0 ) {
666 r1 = SetElements + Sets[m[4]].first;
667 r2 = SetElements + Sets[m[4]].last;
681 else { NEXTARG(term) }
705 WORD CountFun(WORD *term, WORD *countfun)
707 WORD *m, *r, i, j, count = 0, *instruct, *stopper, *tstop;
710 instruct = countfun + FUNHEAD;
711 tstop = term + *term; tstop -= ABS(tstop[-1]); term++;
712 while ( term < tstop ) {
719 while ( m < stopper ) {
720 if ( *m == -SNUMBER ) { NEXTARG(m)
continue; }
721 if ( *m == -SYMBOL && m[1] == *term
722 && m[2] == -SNUMBER && ( m + 2 ) < stopper ) {
723 count += m[3] * term[1]; m += 4;
736 while ( m < stopper ) {
737 if ( *m == -SNUMBER ) { NEXTARG(m)
continue; }
738 if ( *m == 9+ARGHEAD && m[ARGHEAD] == 9
739 && m[ARGHEAD+1] == DOTPRODUCT
740 && m[ARGHEAD+9] == -SNUMBER && ( m + ARGHEAD+9 ) < stopper
741 && (( m[ARGHEAD+3] == *term &&
742 m[ARGHEAD+4] == term[1]) ||
743 ( m[ARGHEAD+3] == term[1] &&
744 m[ARGHEAD+4] == *term )) ) {
745 count += m[ARGHEAD+10] * term[2];
751 while ( m < stopper ) {
752 if ( *m == -SNUMBER ) { NEXTARG(m)
continue; }
753 if ( ( *m == -VECTOR || *m == -MINVECTOR )
755 m[2] == -SNUMBER && ( m+2 ) < stopper ) {
756 count += m[3] * term[2]; m += 4;
761 while ( m < stopper ) {
762 if ( *m == -SNUMBER ) { NEXTARG(m)
continue; }
763 if ( ( *m == -VECTOR || *m == -MINVECTOR )
764 && m[1] == term[1] &&
765 m[2] == -SNUMBER && ( m+2 ) < stopper ) {
766 count += m[3] * term[2];
780 VectInd: i = term[1] - 2;
784 while ( m < stopper ) {
785 if ( *m == -SNUMBER ) { NEXTARG(m)
continue; }
786 if ( ( *m == -VECTOR || *m == -MINVECTOR )
788 m[2] == -SNUMBER && (m+2) < stopper ) {
789 count += m[3]; m += 4;
798 if ( *term >= FUNCTION ) {
801 while ( m < stopper ) {
802 if ( *m == -SNUMBER ) { NEXTARG(m)
continue; }
803 if ( *m == -i && m[1] == -SNUMBER && (m+1) < stopper ) {
804 count += m[2]; m += 3;
808 if ( functions[i-FUNCTION].spec >= TENSORFUNCTION ) {
809 i = term[1] - FUNHEAD;
814 while ( m < stopper ) {
815 if ( *m == -SNUMBER ) { NEXTARG(m)
continue; }
816 if ( ( *m == -VECTOR || *m == -INDEX
817 || *m == -MINVECTOR ) && m[1] == *term &&
818 m[2] == -SNUMBER && (m+2) < stopper ) {
819 count += m[3]; m += 4;
832 if ( ( *term == -INDEX || *term == -VECTOR
833 || *term == -MINVECTOR ) && term[1] < MINSPEC ) {
835 while ( m < stopper ) {
836 if ( *m == -SNUMBER ) { NEXTARG(m)
continue; }
837 if ( *m == -VECTOR && m[1] == term[1]
838 && m[2] == -SNUMBER && (m+2) < stopper ) {
846 else { NEXTARG(term) }
866 WORD DimensionSubterm(WORD *subterm)
868 WORD *r, *rstop, dim, i;
870 rstop = subterm + subterm[1];
871 if ( *subterm == SYMBOL ) {
873 while ( r < rstop ) {
874 if ( *r <= NumSymbols && *r > -MAXPOWER ) {
875 dim = symbols[*r].dimension;
876 if ( dim == MAXPOSITIVE )
goto undefined;
878 if ( x >= MAXPOSITIVE || x <= -MAXPOSITIVE )
goto outofrange;
881 else if ( *r <= MAXVARIABLES ) {
885 i = MAXVARIABLES - *r;
886 dim = cbuf[AM.sbufnum].dimension[i];
887 if ( dim == MAXPOSITIVE )
goto undefined;
888 if ( dim == -MAXPOSITIVE )
goto outofrange;
890 if ( x >= MAXPOSITIVE || x <= -MAXPOSITIVE )
goto outofrange;
896 else if ( *subterm == DOTPRODUCT ) {
898 while ( r < rstop ) {
899 dim = vectors[*r-AM.OffsetVector].dimension;
900 if ( dim == MAXPOSITIVE )
goto undefined;
902 if ( x >= MAXPOSITIVE || x <= -MAXPOSITIVE )
goto outofrange;
903 dim = vectors[r[1]-AM.OffsetVector].dimension;
904 if ( dim == MAXPOSITIVE )
goto undefined;
906 if ( x >= MAXPOSITIVE || x <= -MAXPOSITIVE )
goto outofrange;
910 else if ( *subterm == VECTOR ) {
912 while ( r < rstop ) {
913 dim = vectors[*r-AM.OffsetVector].dimension;
914 if ( dim == MAXPOSITIVE )
goto undefined;
916 if ( x >= MAXPOSITIVE || x <= -MAXPOSITIVE )
goto outofrange;
920 else if ( *subterm == INDEX ) {
922 while ( r < rstop ) {
924 dim = vectors[*r-AM.OffsetVector].dimension;
925 if ( dim == MAXPOSITIVE )
goto undefined;
927 if ( x >= MAXPOSITIVE || x <= -MAXPOSITIVE )
goto outofrange;
932 else if ( *subterm >= FUNCTION ) {
933 dim = functions[*subterm-FUNCTION].dimension;
934 if ( dim == MAXPOSITIVE )
goto undefined;
936 if ( x >= MAXPOSITIVE || x <= -MAXPOSITIVE )
goto outofrange;
937 if ( functions[*subterm-FUNCTION].spec > 0 ) {
938 r = subterm + FUNHEAD;
939 while ( r < rstop ) {
941 dim = vectors[*r-AM.OffsetVector].dimension;
942 if ( dim == MAXPOSITIVE )
goto undefined;
944 if ( x >= MAXPOSITIVE || x <= -MAXPOSITIVE )
goto outofrange;
952 return((WORD)MAXPOSITIVE);
954 return(-(WORD)MAXPOSITIVE);
967 WORD DimensionTerm(WORD *term)
969 WORD *t, *tstop, dim;
971 tstop = term + *term; tstop -= ABS(tstop[-1]);
973 while ( t < tstop ) {
974 dim = DimensionSubterm(t);
975 if ( dim == MAXPOSITIVE )
goto undefined;
976 if ( dim == -MAXPOSITIVE )
goto outofrange;
978 if ( x >= MAXPOSITIVE || x <= -MAXPOSITIVE )
goto outofrange;
983 return((WORD)MAXPOSITIVE);
985 return(-(WORD)MAXPOSITIVE);
999 WORD DimensionExpression(
PHEAD WORD *expr)
1001 WORD dim, *term, *old, x = 0;
1005 dim = DimensionTerm(term);
1006 if ( dim == MAXPOSITIVE )
goto undefined;
1007 if ( dim == -MAXPOSITIVE )
goto outofrange;
1008 if ( first ) { x = dim; }
1009 else if ( x != dim ) {
1010 old = AN.currentTerm;
1011 MLOCK(ErrorMessageLock);
1012 MesPrint(
"Dimension is not the same in the terms of the expression");
1015 AN.currentTerm = term;
1018 MUNLOCK(ErrorMessageLock);
1019 AN.currentTerm = old;
1020 return(-(WORD)MAXPOSITIVE);
1026 return((WORD)MAXPOSITIVE);
1028 old = AN.currentTerm;
1029 AN.currentTerm = term;
1030 MLOCK(ErrorMessageLock);
1031 MesPrint(
"Dimension out of range in %t in subexpression");
1032 MUNLOCK(ErrorMessageLock);
1033 AN.currentTerm = old;
1034 return(-(WORD)MAXPOSITIVE);
1043 WORD MultDo(
PHEAD WORD *term, WORD *pattern)
1048 if ( pattern[2] > 0 ) {
1054 *term += SUBEXPSIZE;
1056 do { *--r = *--t; }
while ( --i > 0 );
1059 while ( --i >= 0 ) *t++ = *r++;
1060 AT.WorkPointer = term + *term;
1071 WORD TryDo(
PHEAD WORD *term, WORD *pattern, WORD level)
1074 WORD *t, *r, *m, i, j;
1075 ReNumber(BHEAD term);
1076 Normalize(BHEAD term);
1077 m = r = term + *term;
1087 if ( ( j = Normalize(BHEAD r) ) == 0 || j == 1 ) {
1088 if ( *r == 0 )
return(0);
1089 ReNumber(BHEAD r); Normalize(BHEAD r);
1090 if ( *r == 0 )
return(0);
1091 if ( ( i = CompareTerms(BHEAD term,r,0) ) < 0 ) {
1096 if ( i == 0 &&
CompCoef(term,r) != 0 ) {
return(0); }
1118 WORD DoDistrib(
PHEAD WORD *term, WORD level)
1121 WORD *t, *m, *r = 0, *stop, *tstop, *termout, *endhead, *starttail, *parms;
1122 WORD i, j, k, n, nn, ntype, fun1 = 0, fun2 = 0, typ1 = 0, typ2 = 0;
1123 WORD *arg, *oldwork, *mf, ktype = 0, atype = 0;
1124 WORD sgn, dirtyflag;
1125 AN.TeInFun = AR.TePos = 0;
1128 stop = tstop - ABS(tstop[-1]);
1130 while ( t < stop ) {
1132 if ( *t == DISTRIBUTION && t[FUNHEAD] == -SNUMBER
1133 && t[FUNHEAD+1] >= -2 && t[FUNHEAD+1] <= 2
1134 && t[FUNHEAD+2] == -SNUMBER
1135 && t[FUNHEAD+4] <= -FUNCTION
1136 && t[FUNHEAD+5] <= -FUNCTION ) {
1137 WORD *ttt = t+FUNHEAD+6, *tttstop = t+t[1];
1138 while ( ttt < tttstop ) {
1139 if ( *ttt == -DOLLAREXPRESSION )
break;
1142 if ( ttt >= tttstop ) {
1143 fun1 = -t[FUNHEAD+4];
1144 fun2 = -t[FUNHEAD+5];
1145 typ1 = functions[fun1-FUNCTION].spec;
1146 typ2 = functions[fun2-FUNCTION].spec;
1147 if ( typ1 > 0 || typ2 > 0 ) {
1151 if ( *m != -INDEX && *m != -VECTOR && *m != -MINVECTOR )
1156 MLOCK(ErrorMessageLock);
1157 MesPrint(
"Incompatible function types and arguments in distrib_");
1158 MUNLOCK(ErrorMessageLock);
1168 ntype = t[FUNHEAD+1];
1197 parms = m = t + FUNHEAD+6;
1203 oldwork = AT.WorkPointer;
1204 arg = AT.WorkPointer + 1;
1208 case 0: ktype = 1; atype = n < 0 ? 1: 0; n = 0;
break;
1209 case 1: ktype = 1; atype = 0;
break;
1210 case 2: ktype = 0; atype = 0;
break;
1211 case -1: ktype = 1; atype = 1;
break;
1212 case -2: ktype = 0; atype = 1;
break;
1219 if ( n > i )
return(0);
1221 for ( j = 0; j < n; j++ ) arg[j] = 1;
1222 for ( j = n; j < i; j++ ) arg[j] = 0;
1227 while ( t < endhead ) *m++ = *t++;
1234 while ( k-- > 0 ) *m++ = 0;
1237 for ( k = 0; k < i; k++ ) {
1238 if ( arg[k] == ktype ) {
1239 if ( *r <= -FUNCTION ) *m++ = *r++;
1240 else if ( *r < 0 ) {
1242 if ( *r == -MINVECTOR ) sgn ^= 1;
1246 else { *m++ = *r++; *m++ = *r++; }
1255 mf[1] = WORDDIF(m,mf);
1262 while ( k-- > 0 ) *m++ = 0;
1265 for ( k = 0; k < i; k++ ) {
1266 if ( arg[k] != ktype ) {
1267 if ( *r <= -FUNCTION ) *m++ = *r++;
1268 else if ( *r < 0 ) {
1270 if ( *r == -MINVECTOR ) sgn ^= 1;
1274 else { *m++ = *r++; *m++ = *r++; }
1283 mf[1] = WORDDIF(m,mf);
1287 for ( k = 0; k < i-1; k++ ) {
1288 if ( arg[k] == 0 )
continue;
1290 while ( k < i-1 && EqualArg(parms,k,k+1) ) { k++; k1++; }
1291 while ( k2 <= k && arg[k2] == 1 ) k2++;
1296 if ( k2 != k1 && k2 != 0 ) {
1297 if ( GetBinom((UWORD *)m+3,m+2,k1,k2) ) {
1298 MLOCK(ErrorMessageLock);
1299 MesCall(
"DoDistrib");
1300 MUNLOCK(ErrorMessageLock);
1303 m[1] = ( m[2] < 0 ? -m[2]: m[2] ) + 3;
1311 while ( r < tstop ) *m++ = *r++;
1316 for ( j = 0; j < i && k > 0; j++ ) {
1317 if ( arg[j] == 1 ) k--;
1323 if ( sgn ) m[-1] = -m[-1];
1324 *termout = WORDDIF(m,termout);
1326 if ( AT.WorkPointer > AT.WorkTop ) {
1327 MLOCK(ErrorMessageLock);
1329 MUNLOCK(ErrorMessageLock);
1334 if (
Generator(BHEAD termout,level) ) Terminate(-1);
1340 redok:
while ( arg[j] == 1 && j >= 0 ) { j--; k++; }
1341 while ( arg[j] == 0 && j >= 0 ) j--;
1345 while ( !atype && EqualArg(parms,j,j+1) ) {
1347 if ( j >= i - k - 1 ) { j = k1; k++;
goto redok; }
1350 while ( k >= 0 ) { j++; arg[j] = 1; k--; }
1352 while ( j < i ) { arg[j] = 0; j++; }
1357 while ( arg[j] == 1 && j >= 0 ) { j--; k++; }
1358 while ( arg[j] == 0 && j >= 0 ) j--;
1361 while ( k >= 0 ) { j++; arg[j] = 1; k--; }
1363 while ( j < i ) { arg[j] = 0; j++; }
1366 }
while ( ntype == 0 && ++n <= i );
1367 AT.WorkPointer = oldwork;
1378 WORD EqualArg(WORD *parms, WORD num1, WORD num2)
1383 while ( --num1 >= 0 ) { NEXTARG(t1); }
1385 while ( --num2 >= 0 ) { NEXTARG(t2); }
1386 if ( *t1 != *t2 )
return(0);
1388 if ( *t1 <= -FUNCTION || t1[1] == t2[1] )
return(1);
1392 while ( --i >= 0 ) {
1393 if ( *t1 != *t2 )
return(0);
1404 WORD DoDelta3(
PHEAD WORD *term, WORD level)
1407 WORD *t, *m, *m1, *m2, *stopper, *tstop, *termout, *dels, *taken;
1408 WORD *ic, *jc, *factors;
1409 WORD num, num2, i, j, k, knum, a;
1410 AN.TeInFun = AR.TePos = 0;
1411 tstop = term + *term;
1412 stopper = tstop - ABS(tstop[-1]);
1414 while ( ( *t != DELTA3 || ((t[1]-FUNHEAD) & 1 ) != 0 ) && t < stopper )
1416 if ( t >= stopper ) {
1417 MLOCK(ErrorMessageLock);
1418 MesPrint(
"Internal error with dd_ function");
1419 MUNLOCK(ErrorMessageLock);
1422 m1 = t; m2 = t + t[1];
1423 num = t[1] - FUNHEAD;
1425 termout = t = AT.WorkPointer;
1427 while ( m < m1 ) *t++ = *m++;
1428 m = m2;
while ( m < tstop ) *t++ = *m++;
1429 *termout = WORDDIF(t,termout);
1434 MLOCK(ErrorMessageLock);
1436 MUNLOCK(ErrorMessageLock);
1439 AT.WorkPointer = termout;
1446 for ( i = 1; i < num; i++ ) {
1447 if ( t[i] < t[i-1] ) {
1448 a = t[i]; t[i] = t[i-1]; t[i-1] = a;
1451 if ( t[j] >= t[j-1] )
break;
1452 a = t[j]; t[j] = t[j-1]; t[j-1] = a;
1462 m = taken = AT.WorkPointer;
1463 for ( i = 0; i < num; i++ ) *m++ = 0;
1465 for ( i = 0; i < num; knum++ ) {
1466 *m++ = t[i]; i++; taken[knum] = 1;
1468 if ( t[i] != t[i-1] )
break;
1469 i++; (taken[knum])++;
1472 for ( i = 0; i < knum; i++ ) *m++ = taken[i];
1473 ic = m; num2 = num/2;
1475 factors = jc + num2;
1476 termout = factors + num2;
1483 t = termout; m = term;
1484 while ( m < m1 ) *t++ = *m++;
1485 *t++ = DELTA; *t++ = num+2;
1486 for ( i = 0; i < num2; i++ ) {
1487 *t++ = dels[ic[i]]; *t++ = dels[jc[i]];
1489 for ( i = 0; i < num2; i++ ) {
1490 if ( ic[i] == jc[i] ) {
1492 while ( i < num2-1 && ic[i] == ic[i+1] && ic[i] == jc[i+1] )
1494 for ( a = 1; a < j; a++ ) {
1495 *t++ = SNUMBER; *t++ = 4; *t++ = 2*a+1; *t++ = 1;
1497 for ( a = 0; a+1+i < num2; a++ ) {
1498 if ( ic[a+i] != ic[a+i+1] )
break;
1501 if ( GetBinom((UWORD *)(t+3),t+2,2*j+a,a) ) {
1502 MLOCK(ErrorMessageLock);
1504 MUNLOCK(ErrorMessageLock);
1507 t[1] = ( t[2] < 0 ? -t[2]: t[2] ) + 3;
1512 else if ( factors[i] != 1 ) {
1513 *t++ = SNUMBER; *t++ = 4; *t++ = factors[i]; *t++ = 1;
1516 for ( i = 0; i < num2-1; i++ ) {
1517 if ( ic[i] == jc[i] )
continue;
1519 while ( i < num2-1 && jc[i] == jc[i+1] && ic[i] == ic[i+1] ) {
1522 for ( a = 0; a+i < num2-1; a++ ) {
1523 if ( ic[i+a] != ic[i+a+1] )
break;
1526 if ( GetBinom((UWORD *)(t+3),t+2,j+a,a) ) {
1527 MLOCK(ErrorMessageLock);
1529 MUNLOCK(ErrorMessageLock);
1532 t[1] = ( t[2] < 0 ? -t[2]: t[2] ) + 3;
1538 while ( m < tstop ) *t++ = *m++;
1539 *termout = WORDDIF(t,termout);
1544 MLOCK(ErrorMessageLock);
1546 MUNLOCK(ErrorMessageLock);
1550 if ( k >= 0 )
goto nextj;
1553 for ( ic[k] = 0; ic[k] < knum; ic[k]++ ) {
1554 if ( taken[ic[k]] > 0 )
break;
1556 if ( k > 0 && ic[k-1] == ic[k] ) jc[k] = jc[k-1];
1558 for ( ; jc[k] < knum; jc[k]++ ) {
1559 if ( taken[jc[k]] <= 0 )
continue;
1560 if ( ic[k] == jc[k] ) {
1561 if ( taken[jc[k]] <= 1 )
continue;
1569 factors[k] = taken[jc[k]];
1570 (taken[ic[k]])--; (taken[jc[k]])--;
1575 (taken[ic[k]])++; (taken[jc[k]])++;
1578 if ( k >= 0 )
goto nextj;
1581 AT.WorkPointer = taken;
1606 WORD TestPartitions(
PHEAD WORD *tfun,
PARTI *parti)
1608 WORD *tnext = tfun + tfun[1];
1610 WORD argcount = 0, sum = 0, i, ipart, argremain;
1611 WORD tensorflag = 0;
1612 parti->psize = parti->nfun = parti->args = parti->nargs = 0;
1613 parti->numargs = parti->numpart = parti->where = 0;
1614 tt = t = tfun + FUNHEAD;
1615 while ( t < tnext ) { argcount++; NEXTARG(t); }
1616 if ( argcount < 1 )
goto No;
1618 if ( *t != -SNUMBER )
goto No;
1621 if ( *t <= -FUNCTION && t[1] == -SNUMBER && t[2] > 0 ) {
1622 if ( functions[-*t-FUNCTION].spec > 0 ) tensorflag = 1;
1623 if ( argcount-3 < 0 )
goto No;
1624 if ( ( (argcount-3) % t[2] ) != 0 )
goto No;
1627 parti->numpart = (argcount-3)/t[2];
1628 parti->numargs = argcount - 3;
1629 parti->psize = (WORD *)Malloc1((parti->numpart*2+parti->numargs*2+2)
1630 *
sizeof(WORD),
"partitions");
1631 parti->nfun = parti->psize + parti->numpart;
1632 parti->args = parti->nfun + parti->numpart;
1633 parti->nargs = parti->args + parti->numargs;
1634 for ( i = 0; i < parti->numpart; i++ ) {
1635 parti->psize[i] = t[2];
1636 parti->nfun[i] = -t[0];
1640 else if ( t[1] > 0 ) {
1649 parti->numpart = t[1]; t += 2;
1650 ipart = sum = 0; argremain = argcount - 1;
1655 parti->psize = (WORD *)Malloc1((argcount*4+2)*
sizeof(WORD),
"partitions");
1656 parti->nfun = parti->psize+argcount;
1657 parti->args = parti->nfun+argcount;
1658 parti->nargs = parti->args+argcount;
1659 while ( ipart < parti->numpart ) {
1660 if ( *t <= -FUNCTION && t[1] == -SNUMBER && t[2] >= 0 ) {
1661 if ( functions[-*t-FUNCTION].spec > 0 ) tensorflag = 1;
1663 if ( ipart+1 != parti->numpart )
goto WhatAPity;
1665 parti->nfun[ipart] = -*t;
1666 parti->psize[ipart++] = argremain-sum;
1671 parti->nfun[ipart] = -*t;
1672 parti->psize[ipart++] = t[2];
1678 else if ( *t == -SNUMBER && t[1] > 0 && ipart+t[1] <= parti->numpart
1679 && t[2] <= -FUNCTION && t[3] == -SNUMBER && t[4] > 0 ) {
1680 if ( functions[-t[2]-FUNCTION].spec > 0 ) tensorflag = 1;
1682 for ( i = 0; i < t[1]; i++ ) {
1683 parti->nfun[ipart] = -t[2];
1684 parti->psize[ipart++] = t[4];
1687 if ( sum > argremain )
goto WhatAPity;
1690 else goto WhatAPity;
1692 if ( sum != argremain )
goto WhatAPity;
1693 parti->numargs = argremain;
1699 for ( i = 0; i < parti->numargs; i++ ) {
1700 parti->args[i] = t - tfun;
1701 if ( tensorflag && ( *t != -VECTOR && *t != -INDEX ) )
goto WhatAPity;
1706 M_free(parti->psize,
"partitions");
1707 parti->psize = parti->nfun = parti->args = parti->nargs = 0;
1708 parti->numargs = parti->numpart = parti->where = 0;
1721 WORD DoPartitions(
PHEAD WORD *term, WORD level)
1723 WORD x, i, j, im, *fun, ndiff, siz, tensorflag = 0;
1724 PARTI part = AT.partitions;
1725 WORD *array, **j3, **j3fill, **j3where;
1726 WORD a, pfill, *j2, *j2fill, j3size, ncoeff, ncoeffnum, nfac, ncoeff2, ncoeff3, n;
1727 UWORD *coeff, *coeffnum, *cfac, *coeff2, *coeff3, *c;
1729 AT.partitions.psize = AT.partitions.nfun = AT.partitions.args = AT.partitions.nargs = 0;
1730 AT.partitions.numargs = AT.partitions.numpart = AT.partitions.where = 0;
1734 fun = term + part.where;
1735 if ( functions[*fun-FUNCTION].spec ) tensorflag = 1;
1736 for ( i = 1; i < part.numargs; i++ ) {
1737 for ( j = i-1; j >= 0; j-- ) {
1738 if ( CompArg(fun+part.args[j+1],fun+part.args[j]) >= 0 )
break;
1739 x = part.args[j+1]; part.args[j+1] = part.args[j]; part.args[j] = x;
1742 for ( i = 1; i < part.numpart; i++ ) {
1743 for ( j = i-1; j >= 0; j-- ) {
1744 if ( part.psize[j+1] < part.psize[j] )
break;
1745 if ( part.psize[j+1] == part.psize[j] && part.nfun[j+1] <= part.nfun[j] )
break;
1746 x = part.psize[j+1]; part.psize[j+1] = part.psize[j]; part.psize[j] = x;
1747 x = part.nfun[j+1]; part.nfun[j+1] = part.nfun[j]; part.nfun[j] = x;
1756 ndiff = 1; part.nargs[0] = ndiff;
1757 for ( i = 1; i < part.numargs; i++ ) {
1758 if ( CompArg(fun+part.args[i],fun+part.args[i-1]) != 0 ) ndiff++;
1759 part.nargs[i] = ndiff;
1761 part.nargs[part.numargs] = 0;
1762 coeffnum = NumberMalloc(
"partitionsn");
1763 coeff = NumberMalloc(
"partitions");
1764 coeff2 = NumberMalloc(
"partitions2");
1765 coeff3 = NumberMalloc(
"partitions3");
1766 cfac = NumberMalloc(
"partitions!");
1767 ncoeffnum = 1; coeffnum[0] = 1;
1773 for ( i = 1; i <= ndiff; i++ ) {
1775 while ( part.nargs[j] == i ) { n++; j++; }
1777 if ( Factorial(BHEAD n, cfac, &nfac) ) Terminate(-1);
1778 if ( MulLong(coeffnum,ncoeffnum,cfac,nfac,coeff2,&ncoeff2) ) Terminate(-1);
1779 c = coeffnum; coeffnum = coeff2; coeff2 = c;
1780 n = ncoeffnum; ncoeffnum = ncoeff2; ncoeff2 = n;
1801 siz = part.psize[0];
1802 j3size = 2*(part.numpart+1)+2*(part.numargs+1);
1803 array = (WORD *)Malloc1((part.numpart+1)*siz*
sizeof(WORD),
"parts");
1804 j3 = (WORD **)Malloc1(j3size*
sizeof(WORD *),
"parts3");
1805 j2 = (WORD *)Malloc1((part.numpart+part.numargs+2)*
sizeof(WORD),
"parts2");
1806 j3fill = j3+(part.numpart+1);
1807 j3where = j3fill+(part.numpart+1);
1808 for ( i = 0; i < j3size; i++ ) j3[i] = 0;
1809 j2fill = j2+(part.numpart+1);
1810 for ( i = 0; i < part.numargs; i++ ) j2fill[i] = 0;
1811 for ( i = 0; i < part.numpart; i++ ) {
1812 j3[i] = array+i*siz;
1813 for ( j = 0; j < siz; j++ ) j3[i][j] = 0;
1814 j3fill[i] = j3[i]+(siz-part.psize[i]);
1815 j2[i] = part.psize[i];
1817 j3[part.numpart] = array+part.numpart*siz;
1818 j2[part.numpart] = 0;
1828 while ( a < part.numargs ) {
1829 while ( j2[pfill] <= 0 ) {
1831 while ( pfill >= part.numpart ) {
1833 if ( a >= part.numargs )
goto Done;
1841 j3where[a] = j3fill[pfill];
1842 *(j3fill[pfill])++ = part.nargs[a];
1843 j2[pfill]--; j2fill[a] = pfill;
1847 if ( pfill > 0 && part.psize[pfill] == part.psize[pfill-1]
1848 && part.nfun[pfill] == part.nfun[pfill-1] ) {
1849 for ( im = 0; im < siz; im++ ) {
1850 if ( j3[pfill-1][im] < j3[pfill][im] )
break;
1851 if ( j3[pfill-1][im] > j3[pfill][im] ) im = siz;
1872 WORD *t, *to, *twhere = term+part.where, *t2, *tend = term+*term, *termout;
1873 WORD num, jj, *targ, *tfun;
1874 t2 = twhere+twhere[1];
1875 to = termout = AT.WorkPointer;
1876 if ( termout + *term + part.numpart*FUNHEAD + AM.MaxTal >= AT.WorkTop ) {
1879 for ( i = 0; i < ncoeffnum; i++ ) coeff[i] = coeffnum[i];
1881 t = term;
while ( t < twhere ) *to++ = *t++;
1885 for ( i = 0; i < part.numpart; i++ ) {
1887 *to++ = part.nfun[i]; to++; FILLFUN(to);
1888 for ( j = 1; j <= part.psize[i]; j++ ) {
1890 for ( jj = num-1; jj < part.numargs; jj++ ) {
1891 if ( part.nargs[jj] == num )
break;
1893 targ = part.args[jj]+twhere;
1895 if ( tensorflag ) targ++;
1896 else if ( *targ > -FUNCTION ) *to++ = *targ++;
1899 else { jj = *targ; NCOPY(to,targ,jj); }
1901 tfun[1] = to - tfun;
1908 while ( j < part.numpart ) {
1909 for ( im = 0; im < siz; im++ ) {
1910 if ( part.nfun[j-1] != part.nfun[j] )
break;
1911 if ( j3[j-1][im] < j3[j][im] )
break;
1912 if ( j3[j-1][im] > j3[j][im] ) im = 2*siz+2;
1914 if ( im == siz ) { n++; j++;
continue; }
1916 div1:
if ( Factorial(BHEAD n, cfac, &nfac) ) Terminate(-1);
1917 if ( DivLong(coeff,ncoeff,cfac,nfac,coeff2,&ncoeff2,coeff3,&ncoeff3) ) Terminate(-1);
1918 c = coeff; coeff = coeff2; coeff2 = c;
1919 n = ncoeff; ncoeff = ncoeff2; ncoeff2 = n;
1923 if ( n > 1 )
goto div1;
1927 for ( i = 0; i < part.numpart; i++ ) {
1928 j = 0;
while ( j3[i][j] == 0 ) j++;
1931 if ( j3[i][j-1] == j3[i][j] ) { n++; j++; }
1934 div2:
if ( Factorial(BHEAD n, cfac, &nfac) ) Terminate(-1);
1935 if ( DivLong(coeff,ncoeff,cfac,nfac,coeff2,&ncoeff2,coeff3,&ncoeff3) ) Terminate(-1);
1936 c = coeff; coeff = coeff2; coeff2 = c;
1937 n = ncoeff; ncoeff = ncoeff2; ncoeff2 = n;
1942 if ( n > 1 )
goto div2;
1947 if ( ncoeff != 1 || coeff[0] > 1 ) {
1948 if ( ncoeff == 1 && coeff[0] <= MAXPOSITIVE ) {
1949 *to++ = SNUMBER; *to++ = 4; *to++ = (WORD)(coeff[0]); *to++ = 1;
1952 *to++ = LNUMBER; *to++ = ncoeff+3; *to++ = ncoeff;
1953 for ( i = 0; i < ncoeff; i++ ) *to++ = ((WORD *)coeff)[i];
1959 while ( t2 < tend ) *to++ = *t2++;
1960 *termout = to-termout;
1961 AT.WorkPointer = to;
1962 if (
Generator(BHEAD termout,level) ) Terminate(-1);
1963 AT.WorkPointer = termout;
1970 while ( part.nargs[a] == 1 ) {
1971 pfill = j2fill[a]; j2[pfill]++; j3where[a][0] = 0; j3fill[pfill]--; a++;
1973 if ( a < part.numargs ) {
1974 pfill = j2fill[a]; j2[pfill]++; j3where[a][0] = 0; j3fill[pfill]--; a++;
1979 else if ( part.nargs[a] == part.nargs[a+1] ) {}
1983 M_free(j2,
"parts2");
1984 M_free(j3,
"parts3");
1985 M_free(array,
"parts");
1986 NumberFree(cfac,
"partitions!");
1987 NumberFree(coeff3,
"partitions3");
1988 NumberFree(coeff2,
"partitions2");
1989 NumberFree(coeff,
"partitions");
1990 NumberFree(coeffnum,
"partitionsn");
1991 M_free(part.psize,
"partitions");
1992 part.psize = part.nfun = part.args = part.nargs = 0;
1993 part.numargs = part.numpart = part.where = 0;
2006 WORD DoPermutations(
PHEAD WORD *term, WORD level)
2009 WORD *oldworkpointer = AT.WorkPointer, *termout = AT.WorkPointer;
2010 WORD *t, *tstop, *tt, *ttstop, odd = 0;
2011 WORD *args[MAXMATCH], nargs, i, first, skip, *to, *from;
2015 tstop = term+*term; tstop -= ABS(tstop[-1]);
2017 while ( t < tstop ) {
2018 if ( *t == PERMUTATIONS ) {
2019 if ( t[1] >= FUNHEAD+1 && t[FUNHEAD] <= -FUNCTION ) {
2022 else if ( t[1] >= FUNHEAD+3 && t[FUNHEAD] == -SNUMBER && t[FUNHEAD+2] <= -FUNCTION ) {
2023 if ( t[FUNHEAD+1] % 2 == 1 ) odd = -1;
2027 else { t += t[1];
continue; }
2028 tt = t+FUNHEAD+skip; ttstop = t + t[1];
2030 while ( tt < ttstop ) { NEXTARG(tt); nargs++; }
2031 tt = t+FUNHEAD+skip;
2032 if ( nargs > MAXMATCH ) {
2033 MLOCK(ErrorMessageLock);
2034 MesPrint(
"Too many arguments in function perm_. %d! is way too big",(WORD)MAXMATCH);
2035 MUNLOCK(ErrorMessageLock);
2039 while ( tt < ttstop ) { args[i++] = tt; NEXTARG(tt); }
2042 perm.objects = args;
2044 while ( (first = PermuteP(&perm,first) ) == 0 ) {
2048 to = termout; from = term;
2049 while ( from < t ) *to++ = *from++;
2050 *to++ = -t[FUNHEAD+skip-1];
2051 *to++ = t[1] - skip;
2052 for ( i = 2; i < FUNHEAD; i++ ) *to++ = t[i];
2053 for ( i = 0; i < nargs; i++ ) {
2058 tstop = term + *term;
2059 while ( from < tstop ) *to++ = *from++;
2060 if ( odd && ( ( perm.sign & 1 ) != 0 ) ) to[-1] = -to[-1];
2061 *termout = to - termout;
2062 AT.WorkPointer = to;
2063 if (
Generator(BHEAD termout,level) ) Terminate(-1);
2064 AT.WorkPointer = oldworkpointer;
2094 WORD DoShuffle(
PHEAD WORD *term, WORD level, WORD fun, WORD option)
2098 WORD *t1, *t2, *tstop, ncoef, n = fun, *to, *from;
2104 if ( ( n = DolToFunction(BHEAD -n) ) == 0 ) {
2105 MLOCK(ErrorMessageLock);
2106 MesPrint(
"$-variable in merge statement did not evaluate to a function.");
2107 MUNLOCK(ErrorMessageLock);
2111 if ( AT.WorkPointer + 3*(*term) + AM.MaxTal > AT.WorkTop ) {
2112 MLOCK(ErrorMessageLock);
2114 MUNLOCK(ErrorMessageLock);
2118 tstop = term + *term;
2120 tstop -= ABS(ncoef);
2122 while ( t1 < tstop ) {
2123 if ( ( *t1 == n ) && ( t1+t1[1] < tstop ) && ( t1[1] > FUNHEAD ) ) {
2125 if ( t2 >= tstop ) {
2128 while ( t2 < tstop ) {
2129 if ( ( *t2 == n ) && ( t2[1] > FUNHEAD ) )
break;
2132 if ( t2 < tstop )
break;
2136 if ( t1 >= tstop ) {
2146 SH->finishuf = &FinishShuffle;
2147 SH->do_uffle = &DoShuffle;
2148 SH->outterm = AT.WorkPointer;
2149 AT.WorkPointer += *term;
2150 SH->stop1 = t1 + t1[1];
2151 SH->stop2 = t2 + t2[1];
2152 SH->thefunction = n;
2153 SH->option = option;
2156 SH->nincoef = ncoef;
2158 if ( AN.SHcombi == 0 || AN.SHcombisize == 0 ) {
2159 AN.SHcombisize = 200;
2160 AN.SHcombi = (UWORD *)Malloc1(AN.SHcombisize*
sizeof(UWORD),
"AN.SHcombi");
2162 SHback.combilast = 0;
2165 SH->combilast += AN.SHcombi[SH->combilast]+1;
2166 if ( SH->combilast >= AN.SHcombisize - 100 ) {
2167 newcombi = (UWORD *)Malloc1(2*AN.SHcombisize*
sizeof(UWORD),
"AN.SHcombi");
2168 for ( k = 0; k < AN.SHcombisize; k++ ) newcombi[k] = AN.SHcombi[k];
2169 M_free(AN.SHcombi,
"AN.SHcombi");
2170 AN.SHcombi = newcombi;
2171 AN.SHcombisize *= 2;
2174 AN.SHcombi[SH->combilast] = 1;
2175 AN.SHcombi[SH->combilast+1] = 1;
2177 i = t1-term; to = SH->outterm; from = term;
2180 for ( i = 0; i < FUNHEAD; i++ ) { *to++ = t1[i]; }
2182 error = Shuffle(BHEAD t1+FUNHEAD,t2+FUNHEAD,to);
2184 AT.WorkPointer = SH->outterm;
2187 MesCall(
"DoShuffle");
2228 int Shuffle(
PHEAD WORD *from1, WORD *from2, WORD *to)
2230 WORD *t, *fr, *next1, *next2, na, *fn1, *fn2, *tt;
2231 int i, n, n1, n2, j;
2234 if ( from1 == SH->stop1 && from2 == SH->stop2 ) {
2235 return(FiniShuffle(BHEAD to));
2237 else if ( from1 == SH->stop1 ) {
2238 i = SH->stop2 - from2; t = to; tt = from2; NCOPY(t,tt,i)
2239 return(FiniShuffle(BHEAD t));
2241 else if ( from2 == SH->stop2 ) {
2242 i = SH->stop1 - from1; t = to; tt = from1; NCOPY(t,tt,i)
2243 return(FiniShuffle(BHEAD t));
2248 if ( AreArgsEqual(from1,from2) ) {
2252 next1 = from1; n1 = 1; NEXTARG(next1)
2253 while ( ( next1 < SH->stop1 ) && AreArgsEqual(from1,next1) ) {
2254 n1++; NEXTARG(next1)
2256 next2 = from2; n2 = 1; NEXTARG(next2)
2257 while ( ( next2 < SH->stop2 ) && AreArgsEqual(from2,next2) ) {
2258 n2++; NEXTARG(next2)
2260 combilast = SH->combilast;
2266 while ( --n >= 0 ) { fr = from1; CopyArg(t,fr) }
2267 if ( GetBinom((UWORD *)(t),&na,n1+n2,n1) )
goto shuffcall;
2268 if ( combilast + AN.SHcombi[combilast] + na + 2 >= AN.SHcombisize ) {
2276 UWORD *combi = (UWORD *)Malloc1(2*AN.SHcombisize*2,
"AN.SHcombi");
2278 for ( jj = 0; jj < AN.SHcombisize; jj++ ) combi[jj] = AN.SHcombi[jj];
2279 AN.SHcombisize *= 2;
2280 M_free(AN.SHcombi,
"AN.SHcombi");
2283 if ( MulLong((UWORD *)(AN.SHcombi+combilast+1),AN.SHcombi[combilast],
2285 (UWORD *)(AN.SHcombi+combilast+AN.SHcombi[combilast]+2),
2286 (WORD *)(AN.SHcombi+combilast+AN.SHcombi[combilast]+1)) )
goto shuffcall;
2287 SH->combilast = combilast + AN.SHcombi[combilast] + 1;
2288 if ( next1 >= SH->stop1 ) {
2289 fr = next2; i = SH->stop2 - fr;
2291 if ( FiniShuffle(BHEAD t) )
goto shuffcall;
2293 else if ( next2 >= SH->stop2 ) {
2294 fr = next1; i = SH->stop1 - fr;
2296 if ( FiniShuffle(BHEAD t) )
goto shuffcall;
2299 if ( Shuffle(BHEAD next1,next2,t) )
goto shuffcall;
2301 SH->combilast = combilast;
2306 if ( next2 < SH->stop2 ) {
2309 while ( --n >= 0 ) { fr = from1; CopyArg(t,fr) }
2310 for ( j = 0; j < n1; j++ ) {
2311 if ( GetBinom((UWORD *)(t),&na,n2+j,j) )
goto shuffcall;
2312 if ( MulLong((UWORD *)(AN.SHcombi+combilast+1),AN.SHcombi[combilast],
2314 (UWORD *)(AN.SHcombi+combilast+AN.SHcombi[combilast]+2),
2315 (WORD *)(AN.SHcombi+combilast+AN.SHcombi[combilast]+1)) )
goto shuffcall;
2316 SH->combilast = combilast + AN.SHcombi[combilast] + 1;
2317 if ( j > 0 ) { fr = from1; CopyArg(t,fr) }
2318 fn2 = next2; tt = t;
2321 if ( fn2 >= SH->stop2 ) {
2323 while ( --n >= 0 ) { fr = from1; CopyArg(tt,fr) }
2324 fr = next1; i = SH->stop1 - fr;
2326 if ( FiniShuffle(BHEAD tt) )
goto shuffcall;
2329 n = j; fn1 = from1;
while ( --n >= 0 ) { NEXTARG(fn1) }
2330 if ( Shuffle(BHEAD fn1,fn2,tt) )
goto shuffcall;
2332 SH->combilast = combilast;
2339 if ( next1 < SH->stop1 ) {
2342 while ( --n >= 0 ) { fr = from1; CopyArg(t,fr) }
2343 for ( j = 0; j < n2; j++ ) {
2344 if ( GetBinom((UWORD *)(t),&na,n1+j,j) )
goto shuffcall;
2345 if ( MulLong((UWORD *)(AN.SHcombi+combilast+1),AN.SHcombi[combilast],
2347 (UWORD *)(AN.SHcombi+combilast+AN.SHcombi[combilast]+2),
2348 (WORD *)(AN.SHcombi+combilast+AN.SHcombi[combilast]+1)) )
goto shuffcall;
2349 SH->combilast = combilast + AN.SHcombi[combilast] + 1;
2350 if ( j > 0 ) { fr = from1; CopyArg(t,fr) }
2351 fn1 = next1; tt = t;
2354 if ( fn1 >= SH->stop1 ) {
2356 while ( --n >= 0 ) { fr = from1; CopyArg(tt,fr) }
2357 fr = next2; i = SH->stop2 - fr;
2359 if ( FiniShuffle(BHEAD tt) )
goto shuffcall;
2362 n = j; fn2 = from2;
while ( --n >= 0 ) { NEXTARG(fn2) }
2363 if ( Shuffle(BHEAD fn1,fn2,tt) )
goto shuffcall;
2365 SH->combilast = combilast;
2376 if ( fr >= SH->stop1 ) {
2377 fr = from2; i = SH->stop2 - fr;
2379 if ( FiniShuffle(BHEAD t) )
goto shuffcall;
2382 if ( Shuffle(BHEAD fr,from2,t) )
goto shuffcall;
2390 if ( fr >= SH->stop2 ) {
2391 fr = from1; i = SH->stop1 - fr;
2393 if ( FiniShuffle(BHEAD t) )
goto shuffcall;
2396 if ( Shuffle(BHEAD from1,fr,t) )
goto shuffcall;
2419 int FinishShuffle(
PHEAD WORD *fini)
2421 WORD *t, *t1, *oldworkpointer = AT.WorkPointer, *tcoef, ntcoef, *out;
2424 SH->outfun[1] = fini - SH->outfun;
2425 if ( functions[SH->outfun[0]-FUNCTION].symmetric != 0 )
2426 SH->outfun[2] |= DIRTYSYMFLAG;
2427 out = fini; i = fini - SH->outterm; t = SH->outterm;
2431 while ( t1 < SH->stop2 ) { t = t1; t1 = t + t[1]; }
2433 while ( t1 < t ) *fini++ = *t1++;
2435 while ( t < SH->incoef ) *fini++ = *t++;
2437 ntcoef = SH->nincoef;
2440 ntcoef = REDLENG(ntcoef);
2441 Mully(BHEAD (UWORD *)tcoef,&ntcoef,
2442 (UWORD *)(AN.SHcombi+SH->combilast+1),AN.SHcombi[SH->combilast]);
2443 ntcoef = INCLENG(ntcoef);
2444 fini = tcoef + ABS(ntcoef);
2445 if ( ( ( SH->option & 2 ) != 0 ) && ( ( SH->option & 256 ) != 0 ) ) ntcoef = -ntcoef;
2447 i = *out = fini - out;
2451 AT.WorkPointer = out + *out;
2452 if ( ( SH->option & 1 ) == 1 ) {
2453 if (
Generator(BHEAD out,SH->level) )
goto Finicall;
2456 if ( DoShtuffle(BHEAD out,SH->level,SH->thefunction,SH->option) )
goto Finicall;
2458 AT.WorkPointer = oldworkpointer;
2461 AT.WorkPointer = oldworkpointer;
2462 MesCall(
"FinishShuffle");
2484 WORD DoStuffle(
PHEAD WORD *term, WORD level, WORD fun, WORD option)
2488 WORD *t1, *t2, *tstop, *t1stop, *t2stop, ncoef, n = fun, *to, *from;
2494 WORD *rr1, *rr2, i1, i2;
2497 if ( ( n = DolToFunction(BHEAD -n) ) == 0 ) {
2498 MLOCK(ErrorMessageLock);
2499 MesPrint(
"$-variable in merge statement did not evaluate to a function.");
2500 MUNLOCK(ErrorMessageLock);
2504 if ( AT.WorkPointer + 3*(*term) + AM.MaxTal > AT.WorkTop ) {
2505 MLOCK(ErrorMessageLock);
2507 MUNLOCK(ErrorMessageLock);
2511 tstop = term + *term;
2513 tstop -= ABS(ncoef);
2516 while ( t1 < tstop ) {
2517 if ( ( *t1 == n ) && ( t1+t1[1] < tstop ) && ( t1[1] > FUNHEAD ) ) {
2519 if ( t2 >= tstop ) {
2523 while ( t2 < tstop ) {
2524 if ( ( *t2 == n ) && ( t2[1] > FUNHEAD ) )
break;
2527 if ( t2 < tstop )
break;
2531 if ( t1 >= tstop ) {
2539 t1stop = t1 + t1[1];
2541 while ( r1 < t1stop ) {
2542 if ( *r1 != -SNUMBER )
break;
2543 if ( r1[1] == 0 )
break;
2546 if ( r1 < t1stop ) { t1 = t2;
goto retry1; }
2547 t2stop = t2 + t2[1];
2549 while ( r2 < t2stop ) {
2550 if ( *r2 != -SNUMBER )
break;
2551 if ( r2[1] == 0 )
break;
2554 if ( r2 < t2stop ) { t2 = t2 + t2[1];
goto retry2; }
2556 t1stop = t1 + t1[1];
2558 while ( r1 < t1stop ) {
2559 if ( *r1 == -SNUMBER ) {
2560 if ( r1[1] == 0 )
break;
2563 else if ( *r1 == -SYMBOL ) {
2564 if ( ( symbols[r1[1]].complex & VARTYPEROOTOFUNITY ) != VARTYPEROOTOFUNITY )
2568 if ( *r1 > 0 && *r1 == r1[ARGHEAD]+ARGHEAD ) {
2569 if ( ABS(r1[r1[0]-1]) == r1[0]-ARGHEAD-1 ) {}
2570 else if ( r1[ARGHEAD+1] == SYMBOL ) {
2571 rr1 = r1 + ARGHEAD + 3;
2574 if ( ( symbols[*rr1].complex & VARTYPEROOTOFUNITY ) != VARTYPEROOTOFUNITY )
2578 if ( i1 > 0 )
break;
2582 i1 = (ABS(*rr1)-1)/2;
2584 if ( rr1[-1] )
break;
2587 if ( i1 > 1 || rr1[-1] != 1 )
break;
2592 if ( r1 < t1stop ) { t1 = t2;
goto retry1; }
2593 t2stop = t2 + t2[1];
2596 while ( r2 < t2stop ) {
2597 if ( *r2 == -SNUMBER ) {
2598 if ( r2[1] == 0 )
break;
2601 else if ( *r2 == -SYMBOL ) {
2602 if ( ( symbols[r2[1]].complex & VARTYPEROOTOFUNITY ) != VARTYPEROOTOFUNITY )
2606 if ( *r2 > 0 && *r2 == r2[ARGHEAD]+ARGHEAD ) {
2607 if ( ABS(r2[r2[0]-1]) == r2[0]-ARGHEAD-1 ) {}
2608 else if ( r2[ARGHEAD+1] == SYMBOL ) {
2609 rr2 = r2 + ARGHEAD + 3;
2612 if ( ( symbols[*rr2].complex & VARTYPEROOTOFUNITY ) != VARTYPEROOTOFUNITY )
2616 if ( i2 > 0 )
break;
2620 i2 = (ABS(*rr2)-1)/2;
2622 if ( rr2[-1] )
break;
2625 if ( i2 > 1 || rr2[-1] != 1 )
break;
2630 if ( r2 < t2stop ) { t2 = t2 + t2[1];
goto retry2; }
2638 SH->finishuf = &FinishStuffle;
2639 SH->do_uffle = &DoStuffle;
2640 SH->outterm = AT.WorkPointer;
2641 AT.WorkPointer += *term;
2642 SH->ststop1 = t1 + t1[1];
2643 SH->ststop2 = t2 + t2[1];
2644 SH->thefunction = n;
2645 SH->option = option;
2648 SH->nincoef = ncoef;
2649 if ( AN.SHcombi == 0 || AN.SHcombisize == 0 ) {
2650 AN.SHcombisize = 200;
2651 AN.SHcombi = (UWORD *)Malloc1(AN.SHcombisize*
sizeof(UWORD),
"AN.SHcombi");
2653 SHback.combilast = 0;
2656 SH->combilast += AN.SHcombi[SH->combilast]+1;
2657 if ( SH->combilast >= AN.SHcombisize - 100 ) {
2658 newcombi = (UWORD *)Malloc1(2*AN.SHcombisize*
sizeof(UWORD),
"AN.SHcombi");
2659 for ( k = 0; k < AN.SHcombisize; k++ ) newcombi[k] = AN.SHcombi[k];
2660 M_free(AN.SHcombi,
"AN.SHcombi");
2661 AN.SHcombi = newcombi;
2662 AN.SHcombisize *= 2;
2665 AN.SHcombi[SH->combilast] = 1;
2666 AN.SHcombi[SH->combilast+1] = 1;
2668 i = t1-term; to = SH->outterm; from = term;
2671 for ( i = 0; i < FUNHEAD; i++ ) { *to++ = t1[i]; }
2673 error = Stuffle(BHEAD t1+FUNHEAD,t2+FUNHEAD,to);
2675 AT.WorkPointer = SH->outterm;
2678 MesCall(
"DoStuffle");
2699 int Stuffle(
PHEAD WORD *from1, WORD *from2, WORD *to)
2702 WORD *t, *tf, *next1, *next2, *st1, *st2, *save1, *save2;
2708 save1 = SH->stop1; save2 = SH->stop2;
2709 if ( from1 >= SH->ststop1 && from2 == SH->ststop2 ) {
2710 SH->stop1 = SH->ststop1;
2711 SH->stop2 = SH->ststop2;
2712 retval = FinishShuffle(BHEAD to);
2713 SH->stop1 = save1; SH->stop2 = save2;
2716 else if ( from1 >= SH->ststop1 ) {
2717 i = SH->ststop2 - from2; t = to; tf = from2; NCOPY(t,tf,i)
2718 SH->stop1 = SH->ststop1;
2719 SH->stop2 = SH->ststop2;
2720 retval = FinishShuffle(BHEAD t);
2721 SH->stop1 = save1; SH->stop2 = save2;
2724 else if ( from2 >= SH->ststop2 ) {
2725 i = SH->ststop1 - from1; t = to; tf = from1; NCOPY(t,tf,i)
2726 SH->stop1 = SH->ststop1;
2727 SH->stop2 = SH->ststop2;
2728 retval = FinishShuffle(BHEAD t);
2729 SH->stop1 = save1; SH->stop2 = save2;
2735 SH->stop1 = SH->ststop1;
2736 SH->stop2 = SH->ststop2;
2737 SH->finishuf = &FinishShuffle;
2738 if ( Shuffle(BHEAD from1,from2,to) )
goto stuffcall;
2739 SH->finishuf = &FinishStuffle;
2744 st1 = from1; next1 = st1+2;
2746 st1 = next1 = from1;
2749 while ( next1 <= SH->ststop1 ) {
2751 st2 = from2; next2 = st2+2;
2753 next2 = st2 = from2;
2756 while ( next2 <= SH->ststop2 ) {
2759 if ( st1 == from1 && st2 == from2 ) {
2762 *t++ = -SNUMBER; *t++ = StuffAdd(st1[1],st2[1]);
2764 t = StuffRootAdd(st1,st2,t);
2767 if ( Stuffle(BHEAD next1,next2,t) )
goto stuffcall;
2770 else if ( st1 == from1 ) {
2772 t = to; tf = from2; NCOPY(t,tf,i)
2774 *t++ = -SNUMBER; *t++ = StuffAdd(st1[1],st2[1]);
2776 t = StuffRootAdd(st1,st2,t);
2779 if ( Stuffle(BHEAD next1,next2,t) )
goto stuffcall;
2782 else if ( st2 == from2 ) {
2784 t = to; tf = from1; NCOPY(t,tf,i)
2786 *t++ = -SNUMBER; *t++ = StuffAdd(st1[1],st2[1]);
2788 t = StuffRootAdd(st1,st2,t);
2791 if ( Stuffle(BHEAD next1,next2,t) )
goto stuffcall;
2795 if ( Shuffle(BHEAD from1,from2,to) )
goto stuffcall;
2798 st2 = next2; next2 += 2;
2805 st1 = next1; next1 += 2;
2811 SH->stop1 = save1; SH->stop2 = save2;
2826 int FinishStuffle(
PHEAD WORD *fini)
2831 WORD *next1 = SH->stop1, *next2 = SH->stop2;
2832 fini = StuffRootAdd(next1,next2,fini);
2834 *fini++ = -SNUMBER; *fini++ = StuffAdd(SH->stop1[1],SH->stop2[1]);
2840 if ( Stuffle(BHEAD next1,next2,fini) )
goto stuffcall;
2842 if ( Stuffle(BHEAD SH->stop1+2,SH->stop2+2,fini) )
goto stuffcall;
2847 MesCall(
"FinishStuffle");
2873 WORD *StuffRootAdd(WORD *t1, WORD *t2, WORD *to)
2875 int type1, type2, type3, sgn, sgn1, sgn2, sgn3, pow, root, nosymbols, i;
2876 WORD *tt1, *tt2, it1, it2, *t3, *r, size1, size2, size3;
2879 if ( *t1 == -SNUMBER ) { type1 = 1;
if ( t1[1] < 0 ) sgn1 = -1;
else sgn1 = 1; }
2880 else if ( *t1 == -SYMBOL ) { type1 = 2; sgn1 = 1; }
2881 else if ( ABS(t1[*t1-1]) == *t1-ARGHEAD-1 ) {
2882 type1 = 3;
if ( t1[*t1-1] < 0 ) sgn1 = -1;
else sgn1 = 1; }
2883 else { type1 = 4;
if ( t1[*t1-1] < 0 ) sgn1 = -1;
else sgn1 = 1; }
2884 if ( *t2 == -SNUMBER ) { type2 = 1;
if ( t2[1] < 0 ) sgn2 = -1;
else sgn2 = 1; }
2885 else if ( *t2 == -SYMBOL ) { type2 = 2; sgn2 = 1; }
2886 else if ( ABS(t2[*t2-1]) == *t2-ARGHEAD-1 ) {
2887 type2 = 3;
if ( t2[*t2-1] < 0 ) sgn2 = -1;
else sgn2 = 1; }
2888 else { type2 = 4;
if ( t2[*t2-1] < 0 ) sgn2 = -1;
else sgn2 = 1; }
2889 if ( type1 > type2 ) {
2890 t3 = t1; t1 = t2; t2 = t3;
2891 type3 = type1; type1 = type2; type2 = type3;
2892 sgn3 = sgn1; sgn1 = sgn2; sgn2 = sgn3;
2894 nosymbols = 1; sgn3 = 1;
2900 if ( x > MAXPOSITIVE || x < -(MAXPOSITIVE+1) ) {
2901 if ( x < 0 ) { sgn1 = -3; x = -x; }
2906 *to++ = 4; *to++ = (UWORD)x; *to++ = 1; *to++ = sgn1;
2908 else { *to++ = -SNUMBER; *to++ = (WORD)x; }
2910 else if ( type2 == 2 ) {
2911 *to++ = ARGHEAD+8; *to++ = 0; FILLARG(to)
2912 *to++ = 8; *to++ = SYMBOL; *to++ = 4; *to++ = t2[1]; *to++ = 1;
2913 *to++ = ABS(t1[1])+1;
2917 else if ( type2 == 3 ) {
2918 tt1 = (WORD *)scratch; tt1[0] = ABS(t1[1]); size1 = 1;
2919 tt2 = t2+ARGHEAD+1; size2 = (ABS(t2[*t2-1])-1)/2;
2921 *to++ = 0; *to++ = 0; FILLARG(to) *to++ = 0;
2928 tt1 = (WORD *)scratch; tt1[0] = ABS(t1[1]); size1 = 1;
2929 tt2 = t2+ARGHEAD+1; tt2 += tt2[1]; size2 = (ABS(t2[*t2-1])-1)/2;
2930 t3 = to; i = tt2 - t2; r = t2;
2938 if ( t1[1] == t2[1] ) {
2939 if ( ( symbols[t1[1]].maxpower == 4 )
2940 && ( ( symbols[t1[1]].complex & VARTYPEMINUS ) == VARTYPEMINUS ) ) {
2941 *to++ = -SNUMBER; *to++ = -2;
2943 else if ( symbols[t1[1]].maxpower == 2 ) {
2944 *to++ = -SNUMBER; *to++ = 2;
2947 *to++ = ARGHEAD+8; *to++ = 0; FILLARG(to)
2948 *to++ = 8; *to++ = SYMBOL; *to++ = 4;
2949 *to++ = t1[1]; *to++ = 2;
2950 *to++ = 2; *to++ = 1; *to++ = 3;
2954 *to++ = ARGHEAD+10; *to++ = 0; FILLARG(to)
2955 *to++ = 10; *to++ = SYMBOL; *to++ = 6;
2956 if ( t1[1] < t2[1] ) {
2957 *to++ = t1[1]; *to++ = 1; *to++ = t2[1]; *to++ = 1;
2960 *to++ = t2[1]; *to++ = 1; *to++ = t1[1]; *to++ = 1;
2962 *to++ = 2; *to++ = 1; *to++ = 3;
2965 else if ( type2 == 3 ) {
2967 *to++ = 0; *to++ = 0; FILLARG(to) *to++ = 0;
2968 *to++ = SYMBOL; *to++ = 4; *to++ = t1[1]; *to++ = 1;
2969 tt1 = scratch; tt1[1] = 1; size1 = 1;
2970 tt2 = t2+ARGHEAD+1; size2 = (ABS(t2[*t2-1])-1)/2;
2975 tt1 = scratch; tt1[0] = 1; size1 = 1;
2977 *to++ = 0; *to++ = 0; FILLARG(to) *to++ = 0;
2978 *to++ = SYMBOL; *to++ = 0;
2979 tt2 = t2 + ARGHEAD+3; it2 = tt2[-1]-2;
2981 if ( *tt2 == t1[1] ) {
2983 root = symbols[*tt2].maxpower;
2984 if ( pow >= root ) pow -= root;
2985 if ( ( symbols[*tt2].complex & VARTYPEMINUS ) == VARTYPEMINUS ) {
2986 if ( ( root & 1 ) == 0 && pow >= root/2 ) {
2987 pow -= root/2; sgn3 = -sgn3;
2991 *to++ = *tt2; *to++ = pow;
2996 else if ( t1[1] < *tt2 ) {
2997 *to++ = t1[1]; *to++ = 1;
break;
3000 *to++ = *tt2++; *to++ = *tt2++; it2 -= 2;
3001 if ( it2 <= 0 ) { *to++ = t1[1]; *to++ = 1; }
3004 while ( it2 > 0 ) { *to++ = *tt2++; *to++ = *tt2++; it2 -= 2; }
3005 if ( (to - t3) > ARGHEAD+3 ) {
3006 t3[ARGHEAD+2] = (to-t3)-ARGHEAD-1;
3012 size2 = (ABS(t2[*t2-1])-1)/2;
3021 tt1 = t1+ARGHEAD+1; size1 = (ABS(t1[*t1-1])-1)/2;
3022 tt2 = t2+ARGHEAD+1; size2 = (ABS(t2[*t2-1])-1)/2;
3024 *to++ = 0; *to++ = 0; FILLARG(to) *to++ = 0;
3031 tt1 = t1+ARGHEAD+1; size1 = (ABS(t1[*t1-1])-1)/2;
3032 tt2 = t2+ARGHEAD+1; tt2 += tt2[1]; size2 = (ABS(t2[*t2-1])-1)/2;
3033 t3 = to; i = tt2 - t2; r = t2;
3044 tt1 = t1+ARGHEAD+3; it1 = tt1[-1]-2;
3045 tt2 = t2+ARGHEAD+3; it2 = tt2[-1]-2;
3047 *to++ = 0; *to++ = 0; FILLARG(to)
3048 *to++ = 0; *to++ = SYMBOL; *to++ = 0;
3049 while ( it1 > 0 && it2 > 0 ) {
3050 if ( *tt1 == *tt2 ) {
3051 pow = tt1[1]+tt2[1];
3052 root = symbols[*tt1].maxpower;
3053 if ( pow >= root ) pow -= root;
3054 if ( ( symbols[*tt1].complex & VARTYPEMINUS ) == VARTYPEMINUS ) {
3055 if ( ( root & 1 ) == 0 && pow >= root/2 ) {
3056 pow -= root/2; sgn3 = -sgn3;
3060 *to++ = *tt1; *to++ = pow;
3062 tt1 += 2; tt2 += 2; it1 -= 2; it2 -= 2;
3064 else if ( *tt1 < *tt2 ) {
3065 *to++ = *tt1++; *to++ = *tt1++; it1 -= 2;
3068 *to++ = *tt2++; *to++ = *tt2++; it2 -= 2;
3071 while ( it1 > 0 ) { *to++ = *tt1++; *to++ = *tt1++; it1 -= 2; }
3072 while ( it2 > 0 ) { *to++ = *tt2++; *to++ = *tt2++; it2 -= 2; }
3073 if ( (to - t3) > ARGHEAD+3 ) {
3074 t3[ARGHEAD+2] = (to-t3)-ARGHEAD-1;
3080 size1 = (ABS(t1[*t1-1])-1)/2;
3081 size2 = (ABS(t2[*t2-1])-1)/2;
3088 if ( AddLong((UWORD *)tt1,size1,(UWORD *)tt2,size2,(UWORD *)to,&size3) ) {
3089 MLOCK(ErrorMessageLock);
3090 MesPrint(
"Called from StuffRootAdd");
3091 MUNLOCK(ErrorMessageLock);
3094 sgn = sgn1*sgn2*sgn3;
3095 if ( nosymbols && size3 == 1 ) {
3096 if ( (UWORD)(to[0]) <= MAXPOSITIVE && sgn > 0 ) {
3098 to = t3; *to++ = -SNUMBER; *to++ = sgn1;
3100 else if ( (UWORD)(to[0]) <= (MAXPOSITIVE+1) && sgn < 0 ) {
3102 to = t3; *to++ = -SNUMBER; *to++ = -sgn1;
3104 else goto genericcoef;
3109 sgn = sgn*(2*size3+1);
3111 while ( size3 > 1 ) { *to++ = 0; size3--; }
3114 t3[ARGHEAD] = t3[0] - ARGHEAD;
WORD Generator(PHEAD WORD *, WORD)
WORD CompCoef(WORD *, WORD *)