80WORD 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;
130VOID 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;
170 if ( *t > AN.IndDum ) {
171 if ( AN.NumFound >= AN.MaxRenumScratch ) AdjustRenumScratch(BHEAD0);
175 *AN.DumFunPlace++ = 0;
186 if ( *t < FUNCTION ) {
187 MLOCK(ErrorMessageLock);
188 MesPrint(
"Unexpected code in ReNumber");
189 MUNLOCK(ErrorMessageLock);
193 if ( *t >= FUNCTION && functions[*t-FUNCTION].spec
194 >= TENSORFUNCTION ) {
197 if ( *t > AN.IndDum ) {
198 if ( AN.NumFound >= AN.MaxRenumScratch ) AdjustRenumScratch(BHEAD0);
202 *AN.DumFunPlace++ = fun;
223 if ( *t == -INDEX ) {
225 if ( *t >= AN.IndDum ) {
226 if ( AN.NumFound >= AN.MaxRenumScratch ) AdjustRenumScratch(BHEAD0);
230 *AN.DumFunPlace++ = fun;
234 else if ( *t <= -FUNCTION ) t++;
241 }
while ( t < tstop );
252WORD DetCurDum(PHEAD WORD *t)
255 WORD maxval = AN.IndDum;
256 WORD maxtop = AM.IndDum + WILDOFFSET;
257 WORD *tstop, *m, *r, i;
259 tstop -= ABS(*tstop);
261 while ( t < tstop ) {
262 if ( *t == VECTOR ) {
266 if ( *m > maxval && *m < maxtop ) maxval = *m;
270 else if ( *t == DELTA || *t == INDEX ) {
275 if ( *m > maxval && *m < maxtop ) maxval = *m;
279 else if ( *t >= FUNCTION ) {
280 if ( functions[*t-FUNCTION].spec >= TENSORFUNCTION ) {
288 if ( *r <= -FUNCTION ) r++;
289 else if ( *r == -INDEX ) {
290 if ( r[1] > maxval && r[1] < maxtop ) maxval = r[1];
299 i = DetCurDum(BHEAD m);
300 if ( i > maxval && i < maxtop ) maxval = i;
324int FullRenumber(PHEAD WORD *term, WORD par)
327 WORD *d, **p, **f, *w, *t, *best, *stac, *perm, a, *termtry;
329 WORD *oldworkpointer = AT.WorkPointer;
330 n = ReNumber(BHEAD term) - AM.IndDum;
331 if ( n <= 1 )
return(0);
332 Normalize(BHEAD term);
333 if ( *term == 0 )
return(0);
334 n = ReNumber(BHEAD term) - AM.IndDum;
338 if ( AT.WorkPointer < term + *term ) AT.WorkPointer = term + *term;
340 best = w = AT.WorkPointer; t = term;
341 for ( i = *term; i > 0; i-- ) *w++ = *t++;
343 Normalize(BHEAD best);
344 AT.WorkPointer = w = best + *best;
347 termtry = perm + n + 1;
348 for ( i = 1; i <= n; i++ ) perm[i] = i + AM.IndDum;
349 for ( i = 1; i <= n; i++ ) stac[i] = i;
350 for ( i = 0; i < k; i++ ) d[i] = *(p[i]) - AM.IndDum;
352 for ( i = 1; i < n; i++ ) {
353 for ( j = i+1; j <= n; j++ ) {
354 a = perm[j]; perm[j] = perm[i]; perm[i] = a;
355 for ( ii = 0; ii < k; ii++ ) {
356 *(p[ii]) = perm[d[ii]];
357 if ( f[ii] ) *(f[ii]) |= DIRTYSYMFLAG;
359 t = term; w = termtry;
360 for ( ii = 0; ii < *term; ii++ ) *w++ = *t++;
362 if ( Normalize(BHEAD termtry) == 0 ) {
363 if ( *termtry == 0 )
goto Return0;
364 if ( ( ii = CompareTerms(termtry,best,0) ) > 0 ) {
365 t = termtry; w = best;
366 for ( ii = 0; ii < *termtry; ii++ ) *w++ = *t++;
369 else if ( ii == 0 &&
CompCoef(termtry,best) != 0 )
373 a = perm[j]; perm[j] = perm[i]; perm[i] = a;
377 else if ( par == 1 ) {
380 if ( stac[j] == n ) {
381 a = perm[j]; perm[j] = perm[n]; perm[n] = a;
387 if ( j != stac[j] ) {
388 a = perm[j]; perm[j] = perm[stac[j]]; perm[stac[j]] = a;
391 a = perm[j]; perm[j] = perm[stac[j]]; perm[stac[j]] = a;
393 for ( i = 0; i < k; i++ ) {
394 *(p[i]) = perm[d[i]];
395 if ( f[i] ) *(f[i]) |= DIRTYSYMFLAG;
397 t = term; w = termtry;
398 for ( i = 0; i < *term; i++ ) *w++ = *t++;
400 if ( Normalize(BHEAD termtry) == 0 ) {
401 if ( *termtry == 0 )
goto Return0;
402 if ( ( ii = CompareTerms(termtry,best,0) ) > 0 ) {
403 t = termtry; w = best;
404 for ( i = 0; i < *termtry; i++ ) *w++ = *t++;
406 else if ( ii == 0 &&
CompCoef(termtry,best) != 0 )
410 if ( j < n-1 ) { j = n-1; }
415 for ( i = 0; i < n; i++ ) *t++ = *w++;
416 AT.WorkPointer = oldworkpointer;
420 AT.WorkPointer = oldworkpointer;
436VOID MoveDummies(PHEAD WORD *term, WORD shift)
439 WORD maxval = AN.IndDum;
440 WORD maxtop = AM.IndDum + WILDOFFSET;
442 tstop = term + *term - 1;
443 tstop -= ABS(*tstop);
445 while ( term < tstop ) {
446 if ( *term == VECTOR ) {
450 if ( *m > maxval && *m < maxtop ) *m += shift;
454 else if ( *term == DELTA || *term == INDEX ) {
459 if ( *m > maxval && *m < maxtop ) *m += shift;
463 else if ( *term >= FUNCTION ) {
464 if ( functions[*term-FUNCTION].spec >= TENSORFUNCTION ) {
472 if ( *r <= -FUNCTION ) r++;
473 else if ( *r == -INDEX ) {
474 if ( r[1] > maxval && r[1] < maxtop ) r[1] += shift;
483 MoveDummies(BHEAD m,shift);
506void AdjustRenumScratch(PHEAD0)
511 WORD **newpoin, *newnum;
512 if ( AN.MaxRenumScratch == 0 ) newsize = 100;
513 else newsize = AN.MaxRenumScratch*2;
514 if ( newsize > MAXPOSITIVE/2 ) newsize = MAXPOSITIVE/2+1;
516 newpoin = (WORD **)Malloc1(newsize*
sizeof(WORD *),
"PoinScratch");
517 for ( i = 0; i < AN.NumFound; i++ ) newpoin[i] = AN.PoinScratch[i];
518 for ( ; i < newsize; i++ ) newpoin[i] = 0;
519 if ( AN.PoinScratch ) M_free(AN.PoinScratch,
"PoinScratch");
520 AN.PoinScratch = newpoin;
521 AN.DumPlace = newpoin + AN.NumFound;
523 newpoin = (WORD **)Malloc1(newsize*
sizeof(WORD *),
"FunScratch");
524 for ( i = 0; i < AN.NumFound; i++ ) newpoin[i] = AN.FunScratch[i];
525 for ( ; i < newsize; i++ ) newpoin[i] = 0;
526 if ( AN.FunScratch ) M_free(AN.FunScratch,
"FunScratch");
527 AN.FunScratch = newpoin;
528 AN.DumFunPlace = newpoin + AN.NumFound;
530 newnum = (WORD *)Malloc1(newsize*
sizeof(WORD),
"RenumScratch");
531 for ( i = 0; i < AN.NumFound; i++ ) newnum[i] = AN.RenumScratch[i];
532 for ( ; i < newsize; i++ ) newnum[i] = 0;
533 if ( AN.RenumScratch ) M_free(AN.RenumScratch,
"RenumScratch");
534 AN.RenumScratch = newnum;
535 AN.DumFound = newnum + AN.NumFound;
537 AN.MaxRenumScratch = newsize;
552WORD CountDo(WORD *term, WORD *instruct)
554 WORD *m, *r, i, j, count = 0;
555 WORD *stopper, *tstop, *r1 = 0, *r2 = 0;
559 tstop = term + *term; tstop -= ABS(tstop[-1]); term++;
560 while ( term < tstop ) {
567 while ( m < stopper ) {
568 if ( *m == SYMBOL && m[2] == *term ) {
569 count += m[3] * term[1];
582 while ( m < stopper ) {
583 if ( *m == DOTPRODUCT && (( m[2] == *term &&
584 m[3] == term[1]) || ( m[2] == term[1] &&
586 count += m[4] * term[2];
592 while ( m < stopper ) {
593 if ( *m == VECTOR && m[2] == *term &&
594 ( m[3] & DOTPBIT ) != 0 ) {
595 count += m[m[1]-1] * term[2];
600 while ( m < stopper ) {
601 if ( *m == VECTOR && m[2] == term[1] &&
602 ( m[3] & DOTPBIT ) != 0 ) {
603 count += m[m[1]-1] * term[2];
616VectInd: i = term[1] - 2;
620 while ( m < stopper ) {
621 if ( *m == VECTOR && m[2] == *term &&
622 ( m[3] & VECTBIT ) != 0 ) {
632 if ( *term >= FUNCTION ) {
635 while ( m < stopper ) {
636 if ( *m == FUNCTION && m[2] == i ) count += m[3];
639 if ( functions[i-FUNCTION].spec >= TENSORFUNCTION ) {
640 i = term[1] - FUNHEAD;
645 while ( m < stopper ) {
646 if ( *m == VECTOR && m[2] == *term &&
647 ( m[3] & FUNBIT ) != 0 ) {
661 if ( ( *term == -INDEX || *term == -VECTOR
662 || *term == -MINVECTOR ) && term[1] < MINSPEC ) {
664 while ( m < stopper ) {
665 if ( *m == VECTOR && term[1] == m[2]
666 && ( m[3] & SETBIT ) != 0 ) {
667 r1 = SetElements + Sets[m[4]].first;
668 r2 = SetElements + Sets[m[4]].last;
682 else { NEXTARG(term) }
706WORD CountFun(WORD *term, WORD *countfun)
708 WORD *m, *r, i, j, count = 0, *instruct, *stopper, *tstop;
711 instruct = countfun + FUNHEAD;
712 tstop = term + *term; tstop -= ABS(tstop[-1]); term++;
713 while ( term < tstop ) {
720 while ( m < stopper ) {
721 if ( *m == -SNUMBER ) { NEXTARG(m)
continue; }
722 if ( *m == -SYMBOL && m[1] == *term
723 && m[2] == -SNUMBER && ( m + 2 ) < stopper ) {
724 count += m[3] * term[1]; m += 4;
737 while ( m < stopper ) {
738 if ( *m == -SNUMBER ) { NEXTARG(m)
continue; }
739 if ( *m == 9+ARGHEAD && m[ARGHEAD] == 9
740 && m[ARGHEAD+1] == DOTPRODUCT
741 && m[ARGHEAD+9] == -SNUMBER && ( m + ARGHEAD+9 ) < stopper
742 && (( m[ARGHEAD+3] == *term &&
743 m[ARGHEAD+4] == term[1]) ||
744 ( m[ARGHEAD+3] == term[1] &&
745 m[ARGHEAD+4] == *term )) ) {
746 count += m[ARGHEAD+10] * term[2];
752 while ( m < stopper ) {
753 if ( *m == -SNUMBER ) { NEXTARG(m)
continue; }
754 if ( ( *m == -VECTOR || *m == -MINVECTOR )
756 m[2] == -SNUMBER && ( m+2 ) < stopper ) {
757 count += m[3] * term[2]; m += 4;
762 while ( m < stopper ) {
763 if ( *m == -SNUMBER ) { NEXTARG(m)
continue; }
764 if ( ( *m == -VECTOR || *m == -MINVECTOR )
765 && m[1] == term[1] &&
766 m[2] == -SNUMBER && ( m+2 ) < stopper ) {
767 count += m[3] * term[2];
781VectInd: i = term[1] - 2;
785 while ( m < stopper ) {
786 if ( *m == -SNUMBER ) { NEXTARG(m)
continue; }
787 if ( ( *m == -VECTOR || *m == -MINVECTOR )
789 m[2] == -SNUMBER && (m+2) < stopper ) {
790 count += m[3]; m += 4;
799 if ( *term >= FUNCTION ) {
802 while ( m < stopper ) {
803 if ( *m == -SNUMBER ) { NEXTARG(m)
continue; }
804 if ( *m == -i && m[1] == -SNUMBER && (m+1) < stopper ) {
805 count += m[2]; m += 3;
809 if ( functions[i-FUNCTION].spec >= TENSORFUNCTION ) {
810 i = term[1] - FUNHEAD;
815 while ( m < stopper ) {
816 if ( *m == -SNUMBER ) { NEXTARG(m)
continue; }
817 if ( ( *m == -VECTOR || *m == -INDEX
818 || *m == -MINVECTOR ) && m[1] == *term &&
819 m[2] == -SNUMBER && (m+2) < stopper ) {
820 count += m[3]; m += 4;
833 if ( ( *term == -INDEX || *term == -VECTOR
834 || *term == -MINVECTOR ) && term[1] < MINSPEC ) {
836 while ( m < stopper ) {
837 if ( *m == -SNUMBER ) { NEXTARG(m)
continue; }
838 if ( *m == -VECTOR && m[1] == term[1]
839 && m[2] == -SNUMBER && (m+2) < stopper ) {
847 else { NEXTARG(term) }
867WORD DimensionSubterm(WORD *subterm)
869 WORD *r, *rstop, dim, i;
871 rstop = subterm + subterm[1];
872 if ( *subterm == SYMBOL ) {
874 while ( r < rstop ) {
875 if ( *r <= NumSymbols && *r > -MAXPOWER ) {
876 dim = symbols[*r].dimension;
877 if ( dim == MAXPOSITIVE )
goto undefined;
879 if ( x >= MAXPOSITIVE || x <= -MAXPOSITIVE )
goto outofrange;
882 else if ( *r <= MAXVARIABLES ) {
886 i = MAXVARIABLES - *r;
887 dim = cbuf[AM.sbufnum].dimension[i];
888 if ( dim == MAXPOSITIVE )
goto undefined;
889 if ( dim == -MAXPOSITIVE )
goto outofrange;
891 if ( x >= MAXPOSITIVE || x <= -MAXPOSITIVE )
goto outofrange;
897 else if ( *subterm == DOTPRODUCT ) {
899 while ( r < rstop ) {
900 dim = vectors[*r-AM.OffsetVector].dimension;
901 if ( dim == MAXPOSITIVE )
goto undefined;
903 if ( x >= MAXPOSITIVE || x <= -MAXPOSITIVE )
goto outofrange;
904 dim = vectors[r[1]-AM.OffsetVector].dimension;
905 if ( dim == MAXPOSITIVE )
goto undefined;
907 if ( x >= MAXPOSITIVE || x <= -MAXPOSITIVE )
goto outofrange;
911 else if ( *subterm == VECTOR ) {
913 while ( r < rstop ) {
914 dim = vectors[*r-AM.OffsetVector].dimension;
915 if ( dim == MAXPOSITIVE )
goto undefined;
917 if ( x >= MAXPOSITIVE || x <= -MAXPOSITIVE )
goto outofrange;
921 else if ( *subterm == INDEX ) {
923 while ( r < rstop ) {
925 dim = vectors[*r-AM.OffsetVector].dimension;
926 if ( dim == MAXPOSITIVE )
goto undefined;
928 if ( x >= MAXPOSITIVE || x <= -MAXPOSITIVE )
goto outofrange;
933 else if ( *subterm >= FUNCTION ) {
934 dim = functions[*subterm-FUNCTION].dimension;
935 if ( dim == MAXPOSITIVE )
goto undefined;
937 if ( x >= MAXPOSITIVE || x <= -MAXPOSITIVE )
goto outofrange;
938 if ( functions[*subterm-FUNCTION].spec > 0 ) {
939 r = subterm + FUNHEAD;
940 while ( r < rstop ) {
941 if ( *r < MINSPEC ) {
942 dim = vectors[*r-AM.OffsetVector].dimension;
943 if ( dim == MAXPOSITIVE )
goto undefined;
945 if ( x >= MAXPOSITIVE || x <= -MAXPOSITIVE )
goto outofrange;
953 return((WORD)MAXPOSITIVE);
955 return(-(WORD)MAXPOSITIVE);
968WORD DimensionTerm(WORD *term)
970 WORD *t, *tstop, dim;
972 tstop = term + *term; tstop -= ABS(tstop[-1]);
974 while ( t < tstop ) {
975 dim = DimensionSubterm(t);
976 if ( dim == MAXPOSITIVE )
goto undefined;
977 if ( dim == -MAXPOSITIVE )
goto outofrange;
979 if ( x >= MAXPOSITIVE || x <= -MAXPOSITIVE )
goto outofrange;
984 return((WORD)MAXPOSITIVE);
986 return(-(WORD)MAXPOSITIVE);
1000WORD DimensionExpression(PHEAD WORD *expr)
1002 WORD dim, *term, *old, x = 0;
1006 dim = DimensionTerm(term);
1007 if ( dim == MAXPOSITIVE )
goto undefined;
1008 if ( dim == -MAXPOSITIVE )
goto outofrange;
1009 if ( first ) { x = dim; }
1010 else if ( x != dim ) {
1011 old = AN.currentTerm;
1012 MLOCK(ErrorMessageLock);
1013 MesPrint(
"Dimension is not the same in the terms of the expression");
1016 AN.currentTerm = term;
1019 MUNLOCK(ErrorMessageLock);
1020 AN.currentTerm = old;
1021 return(-(WORD)MAXPOSITIVE);
1027 return((WORD)MAXPOSITIVE);
1029 old = AN.currentTerm;
1030 AN.currentTerm = term;
1031 MLOCK(ErrorMessageLock);
1032 MesPrint(
"Dimension out of range in %t in subexpression");
1033 MUNLOCK(ErrorMessageLock);
1034 AN.currentTerm = old;
1035 return(-(WORD)MAXPOSITIVE);
1044WORD MultDo(PHEAD WORD *term, WORD *pattern)
1049 if ( pattern[2] > 0 ) {
1055 *term += SUBEXPSIZE;
1057 do { *--r = *--t; }
while ( --i > 0 );
1060 while ( --i >= 0 ) *t++ = *r++;
1061 AT.WorkPointer = term + *term;
1072WORD TryDo(PHEAD WORD *term, WORD *pattern, WORD level)
1075 WORD *t, *r, *m, i, j;
1076 ReNumber(BHEAD term);
1077 Normalize(BHEAD term);
1078 m = r = term + *term;
1088 if ( ( j = Normalize(BHEAD r) ) == 0 || j == 1 ) {
1089 if ( *r == 0 )
return(0);
1090 ReNumber(BHEAD r); Normalize(BHEAD r);
1091 if ( *r == 0 )
return(0);
1092 if ( ( i = CompareTerms(term,r,0) ) < 0 ) {
1097 if ( i == 0 &&
CompCoef(term,r) != 0 ) {
return(0); }
1119WORD DoDistrib(PHEAD WORD *term, WORD level)
1122 WORD *t, *m, *r = 0, *stop, *tstop, *termout, *endhead, *starttail, *parms;
1123 WORD i, j, k, n, nn, ntype, fun1 = 0, fun2 = 0, typ1 = 0, typ2 = 0;
1124 WORD *arg, *oldwork, *mf, ktype = 0, atype = 0;
1125 WORD sgn, dirtyflag;
1126 AN.TeInFun = AR.TePos = 0;
1129 stop = tstop - ABS(tstop[-1]);
1131 while ( t < stop ) {
1133 if ( *t == DISTRIBUTION && t[FUNHEAD] == -SNUMBER
1134 && t[FUNHEAD+1] >= -2 && t[FUNHEAD+1] <= 2
1135 && t[FUNHEAD+2] == -SNUMBER
1136 && t[FUNHEAD+4] <= -FUNCTION
1137 && t[FUNHEAD+5] <= -FUNCTION ) {
1138 WORD *ttt = t+FUNHEAD+6, *tttstop = t+t[1];
1139 while ( ttt < tttstop ) {
1140 if ( *ttt == -DOLLAREXPRESSION )
break;
1143 if ( ttt >= tttstop ) {
1144 fun1 = -t[FUNHEAD+4];
1145 fun2 = -t[FUNHEAD+5];
1146 typ1 = functions[fun1-FUNCTION].spec;
1147 typ2 = functions[fun2-FUNCTION].spec;
1148 if ( typ1 > 0 || typ2 > 0 ) {
1152 if ( *m != -INDEX && *m != -VECTOR && *m != -MINVECTOR )
1157 MLOCK(ErrorMessageLock);
1158 MesPrint(
"Incompatible function types and arguments in distrib_");
1159 MUNLOCK(ErrorMessageLock);
1169 ntype = t[FUNHEAD+1];
1198 parms = m = t + FUNHEAD+6;
1204 oldwork = AT.WorkPointer;
1205 arg = AT.WorkPointer + 1;
1209 case 0: ktype = 1; atype = n < 0 ? 1: 0; n = 0;
break;
1210 case 1: ktype = 1; atype = 0;
break;
1211 case 2: ktype = 0; atype = 0;
break;
1212 case -1: ktype = 1; atype = 1;
break;
1213 case -2: ktype = 0; atype = 1;
break;
1220 if ( n > i )
return(0);
1222 for ( j = 0; j < n; j++ ) arg[j] = 1;
1223 for ( j = n; j < i; j++ ) arg[j] = 0;
1228 while ( t < endhead ) *m++ = *t++;
1235 while ( k-- > 0 ) *m++ = 0;
1238 for ( k = 0; k < i; k++ ) {
1239 if ( arg[k] == ktype ) {
1240 if ( *r <= -FUNCTION ) *m++ = *r++;
1241 else if ( *r < 0 ) {
1243 if ( *r == -MINVECTOR ) sgn ^= 1;
1247 else { *m++ = *r++; *m++ = *r++; }
1256 mf[1] = WORDDIF(m,mf);
1263 while ( k-- > 0 ) *m++ = 0;
1266 for ( k = 0; k < i; k++ ) {
1267 if ( arg[k] != ktype ) {
1268 if ( *r <= -FUNCTION ) *m++ = *r++;
1269 else if ( *r < 0 ) {
1271 if ( *r == -MINVECTOR ) sgn ^= 1;
1275 else { *m++ = *r++; *m++ = *r++; }
1284 mf[1] = WORDDIF(m,mf);
1288 for ( k = 0; k < i-1; k++ ) {
1289 if ( arg[k] == 0 )
continue;
1291 while ( k < i-1 && EqualArg(parms,k,k+1) ) { k++; k1++; }
1292 while ( k2 <= k && arg[k2] == 1 ) k2++;
1297 if ( k2 != k1 && k2 != 0 ) {
1298 if ( GetBinom((UWORD *)m+3,m+2,k1,k2) ) {
1299 MLOCK(ErrorMessageLock);
1300 MesCall(
"DoDistrib");
1301 MUNLOCK(ErrorMessageLock);
1304 m[1] = ( m[2] < 0 ? -m[2]: m[2] ) + 3;
1312 while ( r < tstop ) *m++ = *r++;
1317 for ( j = 0; j < i && k > 0; j++ ) {
1318 if ( arg[j] == 1 ) k--;
1324 if ( sgn ) m[-1] = -m[-1];
1325 *termout = WORDDIF(m,termout);
1327 if ( AT.WorkPointer > AT.WorkTop ) {
1328 MLOCK(ErrorMessageLock);
1330 MUNLOCK(ErrorMessageLock);
1335 if (
Generator(BHEAD termout,level) ) Terminate(-1);
1341redok:
while ( arg[j] == 1 && j >= 0 ) { j--; k++; }
1342 while ( arg[j] == 0 && j >= 0 ) j--;
1346 while ( !atype && EqualArg(parms,j,j+1) ) {
1348 if ( j >= i - k - 1 ) { j = k1; k++;
goto redok; }
1351 while ( k >= 0 ) { j++; arg[j] = 1; k--; }
1353 while ( j < i ) { arg[j] = 0; j++; }
1358 while ( arg[j] == 1 && j >= 0 ) { j--; k++; }
1359 while ( arg[j] == 0 && j >= 0 ) j--;
1362 while ( k >= 0 ) { j++; arg[j] = 1; k--; }
1364 while ( j < i ) { arg[j] = 0; j++; }
1367 }
while ( ntype == 0 && ++n <= i );
1368 AT.WorkPointer = oldwork;
1379WORD EqualArg(WORD *parms, WORD num1, WORD num2)
1384 while ( --num1 >= 0 ) { NEXTARG(t1); }
1386 while ( --num2 >= 0 ) { NEXTARG(t2); }
1387 if ( *t1 != *t2 )
return(0);
1389 if ( *t1 <= -FUNCTION || t1[1] == t2[1] )
return(1);
1393 while ( --i >= 0 ) {
1394 if ( *t1 != *t2 )
return(0);
1405WORD DoDelta3(PHEAD WORD *term, WORD level)
1408 WORD *t, *m, *m1, *m2, *stopper, *tstop, *termout, *dels, *taken;
1409 WORD *ic, *jc, *factors;
1410 WORD num, num2, i, j, k, knum, a;
1411 AN.TeInFun = AR.TePos = 0;
1412 tstop = term + *term;
1413 stopper = tstop - ABS(tstop[-1]);
1415 while ( ( *t != DELTA3 || ((t[1]-FUNHEAD) & 1 ) != 0 ) && t < stopper )
1417 if ( t >= stopper ) {
1418 MLOCK(ErrorMessageLock);
1419 MesPrint(
"Internal error with dd_ function");
1420 MUNLOCK(ErrorMessageLock);
1423 m1 = t; m2 = t + t[1];
1424 num = t[1] - FUNHEAD;
1426 termout = t = AT.WorkPointer;
1428 while ( m < m1 ) *t++ = *m++;
1429 m = m2;
while ( m < tstop ) *t++ = *m++;
1430 *termout = WORDDIF(t,termout);
1435 MLOCK(ErrorMessageLock);
1437 MUNLOCK(ErrorMessageLock);
1440 AT.WorkPointer = termout;
1447 for ( i = 1; i < num; i++ ) {
1448 if ( t[i] < t[i-1] ) {
1449 a = t[i]; t[i] = t[i-1]; t[i-1] = a;
1452 if ( t[j] >= t[j-1] )
break;
1453 a = t[j]; t[j] = t[j-1]; t[j-1] = a;
1463 m = taken = AT.WorkPointer;
1464 for ( i = 0; i < num; i++ ) *m++ = 0;
1466 for ( i = 0; i < num; knum++ ) {
1467 *m++ = t[i]; i++; taken[knum] = 1;
1469 if ( t[i] != t[i-1] )
break;
1470 i++; (taken[knum])++;
1473 for ( i = 0; i < knum; i++ ) *m++ = taken[i];
1474 ic = m; num2 = num/2;
1476 factors = jc + num2;
1477 termout = factors + num2;
1484 t = termout; m = term;
1485 while ( m < m1 ) *t++ = *m++;
1486 *t++ = DELTA; *t++ = num+2;
1487 for ( i = 0; i < num2; i++ ) {
1488 *t++ = dels[ic[i]]; *t++ = dels[jc[i]];
1490 for ( i = 0; i < num2; i++ ) {
1491 if ( ic[i] == jc[i] ) {
1493 while ( i < num2-1 && ic[i] == ic[i+1] && ic[i] == jc[i+1] )
1495 for ( a = 1; a < j; a++ ) {
1496 *t++ = SNUMBER; *t++ = 4; *t++ = 2*a+1; *t++ = 1;
1498 for ( a = 0; a+1+i < num2; a++ ) {
1499 if ( ic[a+i] != ic[a+i+1] )
break;
1502 if ( GetBinom((UWORD *)(t+3),t+2,2*j+a,a) ) {
1503 MLOCK(ErrorMessageLock);
1505 MUNLOCK(ErrorMessageLock);
1508 t[1] = ( t[2] < 0 ? -t[2]: t[2] ) + 3;
1513 else if ( factors[i] != 1 ) {
1514 *t++ = SNUMBER; *t++ = 4; *t++ = factors[i]; *t++ = 1;
1517 for ( i = 0; i < num2-1; i++ ) {
1518 if ( ic[i] == jc[i] )
continue;
1520 while ( i < num2-1 && jc[i] == jc[i+1] && ic[i] == ic[i+1] ) {
1523 for ( a = 0; a+i < num2-1; a++ ) {
1524 if ( ic[i+a] != ic[i+a+1] )
break;
1527 if ( GetBinom((UWORD *)(t+3),t+2,j+a,a) ) {
1528 MLOCK(ErrorMessageLock);
1530 MUNLOCK(ErrorMessageLock);
1533 t[1] = ( t[2] < 0 ? -t[2]: t[2] ) + 3;
1539 while ( m < tstop ) *t++ = *m++;
1540 *termout = WORDDIF(t,termout);
1545 MLOCK(ErrorMessageLock);
1547 MUNLOCK(ErrorMessageLock);
1551 if ( k >= 0 )
goto nextj;
1554 for ( ic[k] = 0; ic[k] < knum; ic[k]++ ) {
1555 if ( taken[ic[k]] > 0 )
break;
1557 if ( k > 0 && ic[k-1] == ic[k] ) jc[k] = jc[k-1];
1559 for ( ; jc[k] < knum; jc[k]++ ) {
1560 if ( taken[jc[k]] <= 0 )
continue;
1561 if ( ic[k] == jc[k] ) {
1562 if ( taken[jc[k]] <= 1 )
continue;
1570 factors[k] = taken[jc[k]];
1571 (taken[ic[k]])--; (taken[jc[k]])--;
1576 (taken[ic[k]])++; (taken[jc[k]])++;
1579 if ( k >= 0 )
goto nextj;
1582 AT.WorkPointer = taken;
1607WORD TestPartitions(WORD *tfun,
PARTI *parti)
1609 WORD *tnext = tfun + tfun[1];
1611 WORD argcount = 0, sum = 0, i, ipart, argremain;
1612 WORD tensorflag = 0;
1613 parti->psize = parti->nfun = parti->args = parti->nargs = 0;
1614 parti->numargs = parti->numpart = parti->where = 0;
1615 tt = t = tfun + FUNHEAD;
1616 while ( t < tnext ) { argcount++; NEXTARG(t); }
1617 if ( argcount < 1 )
goto No;
1619 if ( *t != -SNUMBER )
goto No;
1622 if ( *t <= -FUNCTION && t[1] == -SNUMBER && t[2] > 0 ) {
1623 if ( functions[-*t-FUNCTION].spec > 0 ) tensorflag = 1;
1624 if ( argcount-3 < 0 )
goto No;
1625 if ( ( (argcount-3) % t[2] ) != 0 )
goto No;
1628 parti->numpart = (argcount-3)/t[2];
1629 parti->numargs = argcount - 3;
1630 parti->psize = (WORD *)Malloc1((parti->numpart*2+parti->numargs*2+2)
1631 *
sizeof(WORD),
"partitions");
1632 parti->nfun = parti->psize + parti->numpart;
1633 parti->args = parti->nfun + parti->numpart;
1634 parti->nargs = parti->args + parti->numargs;
1635 for ( i = 0; i < parti->numpart; i++ ) {
1636 parti->psize[i] = t[2];
1637 parti->nfun[i] = -t[0];
1641 else if ( t[1] > 0 ) {
1650 parti->numpart = t[1]; t += 2;
1651 ipart = sum = 0; argremain = argcount - 1;
1656 parti->psize = (WORD *)Malloc1((argcount*4+2)*
sizeof(WORD),
"partitions");
1657 parti->nfun = parti->psize+argcount;
1658 parti->args = parti->nfun+argcount;
1659 parti->nargs = parti->args+argcount;
1660 while ( ipart < parti->numpart ) {
1661 if ( *t <= -FUNCTION && t[1] == -SNUMBER && t[2] >= 0 ) {
1662 if ( functions[-*t-FUNCTION].spec > 0 ) tensorflag = 1;
1664 if ( ipart+1 != parti->numpart )
goto WhatAPity;
1666 parti->nfun[ipart] = -*t;
1667 parti->psize[ipart++] = argremain-sum;
1672 parti->nfun[ipart] = -*t;
1673 parti->psize[ipart++] = t[2];
1679 else if ( *t == -SNUMBER && t[1] > 0 && ipart+t[1] <= parti->numpart
1680 && t[2] <= -FUNCTION && t[3] == -SNUMBER && t[4] > 0 ) {
1681 if ( functions[-t[2]-FUNCTION].spec > 0 ) tensorflag = 1;
1683 for ( i = 0; i < t[1]; i++ ) {
1684 parti->nfun[ipart] = -t[2];
1685 parti->psize[ipart++] = t[4];
1688 if ( sum > argremain )
goto WhatAPity;
1691 else goto WhatAPity;
1693 if ( sum != argremain )
goto WhatAPity;
1694 parti->numargs = argremain;
1700 for ( i = 0; i < parti->numargs; i++ ) {
1701 parti->args[i] = t - tfun;
1702 if ( tensorflag && ( *t != -VECTOR && *t != -INDEX ) )
goto WhatAPity;
1707 M_free(parti->psize,
"partitions");
1708 parti->psize = parti->nfun = parti->args = parti->nargs = 0;
1709 parti->numargs = parti->numpart = parti->where = 0;
1722WORD DoPartitions(PHEAD WORD *term, WORD level)
1724 WORD x, i, j, im, *fun, ndiff, siz, tensorflag = 0;
1725 PARTI part = AT.partitions;
1726 WORD *array, **j3, **j3fill, **j3where;
1727 WORD a, pfill, *j2, *j2fill, j3size, ncoeff, ncoeffnum, nfac, ncoeff2, ncoeff3, n;
1728 UWORD *coeff, *coeffnum, *cfac, *coeff2, *coeff3, *c;
1730 AT.partitions.psize = AT.partitions.nfun = AT.partitions.args = AT.partitions.nargs = 0;
1731 AT.partitions.numargs = AT.partitions.numpart = AT.partitions.where = 0;
1735 fun = term + part.where;
1736 if ( functions[*fun-FUNCTION].spec ) tensorflag = 1;
1737 for ( i = 1; i < part.numargs; i++ ) {
1738 for ( j = i-1; j >= 0; j-- ) {
1739 if ( CompArg(fun+part.args[j+1],fun+part.args[j]) >= 0 )
break;
1740 x = part.args[j+1]; part.args[j+1] = part.args[j]; part.args[j] = x;
1743 for ( i = 1; i < part.numpart; i++ ) {
1744 for ( j = i-1; j >= 0; j-- ) {
1745 if ( part.psize[j+1] < part.psize[j] )
break;
1746 if ( part.psize[j+1] == part.psize[j] && part.nfun[j+1] <= part.nfun[j] )
break;
1747 x = part.psize[j+1]; part.psize[j+1] = part.psize[j]; part.psize[j] = x;
1748 x = part.nfun[j+1]; part.nfun[j+1] = part.nfun[j]; part.nfun[j] = x;
1757 ndiff = 1; part.nargs[0] = ndiff;
1758 for ( i = 1; i < part.numargs; i++ ) {
1759 if ( CompArg(fun+part.args[i],fun+part.args[i-1]) != 0 ) ndiff++;
1760 part.nargs[i] = ndiff;
1762 part.nargs[part.numargs] = 0;
1763 coeffnum = NumberMalloc(
"partitionsn");
1764 coeff = NumberMalloc(
"partitions");
1765 coeff2 = NumberMalloc(
"partitions2");
1766 coeff3 = NumberMalloc(
"partitions3");
1767 cfac = NumberMalloc(
"partitions!");
1768 ncoeffnum = 1; coeffnum[0] = 1;
1774 for ( i = 1; i <= ndiff; i++ ) {
1776 while ( part.nargs[j] == i ) { n++; j++; }
1778 if ( Factorial(BHEAD n, cfac, &nfac) ) Terminate(-1);
1779 if ( MulLong(coeffnum,ncoeffnum,cfac,nfac,coeff2,&ncoeff2) ) Terminate(-1);
1780 c = coeffnum; coeffnum = coeff2; coeff2 = c;
1781 n = ncoeffnum; ncoeffnum = ncoeff2; ncoeff2 = n;
1802 siz = part.psize[0];
1803 j3size = 2*(part.numpart+1)+2*(part.numargs+1);
1804 array = (WORD *)Malloc1((part.numpart+1)*siz*
sizeof(WORD),
"parts");
1805 j3 = (WORD **)Malloc1(j3size*
sizeof(WORD *),
"parts3");
1806 j2 = (WORD *)Malloc1((part.numpart+part.numargs+2)*
sizeof(WORD),
"parts2");
1807 j3fill = j3+(part.numpart+1);
1808 j3where = j3fill+(part.numpart+1);
1809 for ( i = 0; i < j3size; i++ ) j3[i] = 0;
1810 j2fill = j2+(part.numpart+1);
1811 for ( i = 0; i < part.numargs; i++ ) j2fill[i] = 0;
1812 for ( i = 0; i < part.numpart; i++ ) {
1813 j3[i] = array+i*siz;
1814 for ( j = 0; j < siz; j++ ) j3[i][j] = 0;
1815 j3fill[i] = j3[i]+(siz-part.psize[i]);
1816 j2[i] = part.psize[i];
1818 j3[part.numpart] = array+part.numpart*siz;
1819 j2[part.numpart] = 0;
1829 while ( a < part.numargs ) {
1830 while ( j2[pfill] <= 0 ) {
1832 while ( pfill >= part.numpart ) {
1834 if ( a >= part.numargs )
goto Done;
1842 j3where[a] = j3fill[pfill];
1843 *(j3fill[pfill])++ = part.nargs[a];
1844 j2[pfill]--; j2fill[a] = pfill;
1848 if ( pfill > 0 && part.psize[pfill] == part.psize[pfill-1]
1849 && part.nfun[pfill] == part.nfun[pfill-1] ) {
1850 for ( im = 0; im < siz; im++ ) {
1851 if ( j3[pfill-1][im] < j3[pfill][im] )
break;
1852 if ( j3[pfill-1][im] > j3[pfill][im] ) im = siz;
1873 WORD *t, *to, *twhere = term+part.where, *t2, *tend = term+*term, *termout;
1874 WORD num, jj, *targ, *tfun;
1875 t2 = twhere+twhere[1];
1876 to = termout = AT.WorkPointer;
1877 if ( termout + *term + part.numpart*FUNHEAD + AM.MaxTal >= AT.WorkTop ) {
1880 for ( i = 0; i < ncoeffnum; i++ ) coeff[i] = coeffnum[i];
1882 t = term;
while ( t < twhere ) *to++ = *t++;
1886 for ( i = 0; i < part.numpart; i++ ) {
1888 *to++ = part.nfun[i]; to++; FILLFUN(to);
1889 for ( j = 1; j <= part.psize[i]; j++ ) {
1891 for ( jj = num-1; jj < part.numargs; jj++ ) {
1892 if ( part.nargs[jj] == num )
break;
1894 targ = part.args[jj]+twhere;
1896 if ( tensorflag ) targ++;
1897 else if ( *targ > -FUNCTION ) *to++ = *targ++;
1900 else { jj = *targ; NCOPY(to,targ,jj); }
1902 tfun[1] = to - tfun;
1909 while ( j < part.numpart ) {
1910 for ( im = 0; im < siz; im++ ) {
1911 if ( part.nfun[j-1] != part.nfun[j] )
break;
1912 if ( j3[j-1][im] < j3[j][im] )
break;
1913 if ( j3[j-1][im] > j3[j][im] ) im = 2*siz+2;
1915 if ( im == siz ) { n++; j++;
continue; }
1917div1:
if ( Factorial(BHEAD n, cfac, &nfac) ) Terminate(-1);
1918 if ( DivLong(coeff,ncoeff,cfac,nfac,coeff2,&ncoeff2,coeff3,&ncoeff3) ) Terminate(-1);
1919 c = coeff; coeff = coeff2; coeff2 = c;
1920 n = ncoeff; ncoeff = ncoeff2; ncoeff2 = n;
1924 if ( n > 1 )
goto div1;
1928 for ( i = 0; i < part.numpart; i++ ) {
1929 j = 0;
while ( j3[i][j] == 0 ) j++;
1932 if ( j3[i][j-1] == j3[i][j] ) { n++; j++; }
1935div2:
if ( Factorial(BHEAD n, cfac, &nfac) ) Terminate(-1);
1936 if ( DivLong(coeff,ncoeff,cfac,nfac,coeff2,&ncoeff2,coeff3,&ncoeff3) ) Terminate(-1);
1937 c = coeff; coeff = coeff2; coeff2 = c;
1938 n = ncoeff; ncoeff = ncoeff2; ncoeff2 = n;
1943 if ( n > 1 )
goto div2;
1948 if ( ncoeff != 1 || coeff[0] > 1 ) {
1949 if ( ncoeff == 1 && coeff[0] <= MAXPOSITIVE ) {
1950 *to++ = SNUMBER; *to++ = 4; *to++ = (WORD)(coeff[0]); *to++ = 1;
1953 *to++ = LNUMBER; *to++ = ncoeff+3; *to++ = ncoeff;
1954 for ( i = 0; i < ncoeff; i++ ) *to++ = ((WORD *)coeff)[i];
1960 while ( t2 < tend ) *to++ = *t2++;
1961 *termout = to-termout;
1962 AT.WorkPointer = to;
1963 if (
Generator(BHEAD termout,level) ) Terminate(-1);
1964 AT.WorkPointer = termout;
1971 while ( part.nargs[a] == 1 ) {
1972 pfill = j2fill[a]; j2[pfill]++; j3where[a][0] = 0; j3fill[pfill]--; a++;
1974 if ( a < part.numargs ) {
1975 pfill = j2fill[a]; j2[pfill]++; j3where[a][0] = 0; j3fill[pfill]--; a++;
1980 else if ( part.nargs[a] == part.nargs[a+1] ) {}
1984 M_free(j2,
"parts2");
1985 M_free(j3,
"parts3");
1986 M_free(array,
"parts");
1987 NumberFree(cfac,
"partitions!");
1988 NumberFree(coeff3,
"partitions3");
1989 NumberFree(coeff2,
"partitions2");
1990 NumberFree(coeff,
"partitions");
1991 NumberFree(coeffnum,
"partitionsn");
1992 M_free(part.psize,
"partitions");
1993 part.psize = part.nfun = part.args = part.nargs = 0;
1994 part.numargs = part.numpart = part.where = 0;
2007WORD DoPermutations(PHEAD WORD *term, WORD level)
2010 WORD *oldworkpointer = AT.WorkPointer, *termout = AT.WorkPointer;
2011 WORD *t, *tstop, *tt, *ttstop, odd = 0;
2012 WORD *args[MAXMATCH], nargs, i, first, skip, *to, *from;
2016 tstop = term+*term; tstop -= ABS(tstop[-1]);
2018 while ( t < tstop ) {
2019 if ( *t == PERMUTATIONS ) {
2020 if ( t[1] >= FUNHEAD+1 && t[FUNHEAD] <= -FUNCTION ) {
2023 else if ( t[1] >= FUNHEAD+3 && t[FUNHEAD] == -SNUMBER && t[FUNHEAD+2] <= -FUNCTION ) {
2024 if ( t[FUNHEAD+1] % 2 == 1 ) odd = -1;
2028 else { t += t[1];
continue; }
2029 tt = t+FUNHEAD+skip; ttstop = t + t[1];
2031 while ( tt < ttstop ) { NEXTARG(tt); nargs++; }
2032 tt = t+FUNHEAD+skip;
2033 if ( nargs > MAXMATCH ) {
2034 MLOCK(ErrorMessageLock);
2035 MesPrint(
"Too many arguments in function perm_. %d! is way too big",(WORD)MAXMATCH);
2036 MUNLOCK(ErrorMessageLock);
2040 while ( tt < ttstop ) { args[i++] = tt; NEXTARG(tt); }
2043 perm.objects = args;
2045 while ( (first = PermuteP(&perm,first) ) == 0 ) {
2049 to = termout; from = term;
2050 while ( from < t ) *to++ = *from++;
2051 *to++ = -t[FUNHEAD+skip-1];
2052 *to++ = t[1] - skip;
2053 for ( i = 2; i < FUNHEAD; i++ ) *to++ = t[i];
2054 for ( i = 0; i < nargs; i++ ) {
2059 tstop = term + *term;
2060 while ( from < tstop ) *to++ = *from++;
2061 if ( odd && ( ( perm.sign & 1 ) != 0 ) ) to[-1] = -to[-1];
2062 *termout = to - termout;
2063 AT.WorkPointer = to;
2064 if (
Generator(BHEAD termout,level) ) Terminate(-1);
2065 AT.WorkPointer = oldworkpointer;
2095WORD DoShuffle(WORD *term, WORD level, WORD fun, WORD option)
2099 WORD *t1, *t2, *tstop, ncoef, n = fun, *to, *from;
2105 if ( ( n = DolToFunction(BHEAD -n) ) == 0 ) {
2106 MLOCK(ErrorMessageLock);
2107 MesPrint(
"$-variable in merge statement did not evaluate to a function.");
2108 MUNLOCK(ErrorMessageLock);
2112 if ( AT.WorkPointer + 3*(*term) + AM.MaxTal > AT.WorkTop ) {
2113 MLOCK(ErrorMessageLock);
2115 MUNLOCK(ErrorMessageLock);
2119 tstop = term + *term;
2121 tstop -= ABS(ncoef);
2123 while ( t1 < tstop ) {
2124 if ( ( *t1 == n ) && ( t1+t1[1] < tstop ) && ( t1[1] > FUNHEAD ) ) {
2126 if ( t2 >= tstop ) {
2129 while ( t2 < tstop ) {
2130 if ( ( *t2 == n ) && ( t2[1] > FUNHEAD ) )
break;
2133 if ( t2 < tstop )
break;
2137 if ( t1 >= tstop ) {
2147 SH->finishuf = &FinishShuffle;
2148 SH->do_uffle = &DoShuffle;
2149 SH->outterm = AT.WorkPointer;
2150 AT.WorkPointer += *term;
2151 SH->stop1 = t1 + t1[1];
2152 SH->stop2 = t2 + t2[1];
2153 SH->thefunction = n;
2154 SH->option = option;
2157 SH->nincoef = ncoef;
2159 if ( AN.SHcombi == 0 || AN.SHcombisize == 0 ) {
2160 AN.SHcombisize = 200;
2161 AN.SHcombi = (UWORD *)Malloc1(AN.SHcombisize*
sizeof(UWORD),
"AN.SHcombi");
2163 SHback.combilast = 0;
2166 SH->combilast += AN.SHcombi[SH->combilast]+1;
2167 if ( SH->combilast >= AN.SHcombisize - 100 ) {
2168 newcombi = (UWORD *)Malloc1(2*AN.SHcombisize*
sizeof(UWORD),
"AN.SHcombi");
2169 for ( k = 0; k < AN.SHcombisize; k++ ) newcombi[k] = AN.SHcombi[k];
2170 M_free(AN.SHcombi,
"AN.SHcombi");
2171 AN.SHcombi = newcombi;
2172 AN.SHcombisize *= 2;
2175 AN.SHcombi[SH->combilast] = 1;
2176 AN.SHcombi[SH->combilast+1] = 1;
2178 i = t1-term; to = SH->outterm; from = term;
2181 for ( i = 0; i < FUNHEAD; i++ ) { *to++ = t1[i]; }
2183 error = Shuffle(t1+FUNHEAD,t2+FUNHEAD,to);
2185 AT.WorkPointer = SH->outterm;
2188 MesCall(
"DoShuffle");
2229int Shuffle(WORD *from1, WORD *from2, WORD *to)
2232 WORD *t, *fr, *next1, *next2, na, *fn1, *fn2, *tt;
2233 int i, n, n1, n2, j;
2236 if ( from1 == SH->stop1 && from2 == SH->stop2 ) {
2237 return(FiniShuffle(to));
2239 else if ( from1 == SH->stop1 ) {
2240 i = SH->stop2 - from2; t = to; tt = from2; NCOPY(t,tt,i)
2241 return(FiniShuffle(t));
2243 else if ( from2 == SH->stop2 ) {
2244 i = SH->stop1 - from1; t = to; tt = from1; NCOPY(t,tt,i)
2245 return(FiniShuffle(t));
2250 if ( AreArgsEqual(from1,from2) ) {
2254 next1 = from1; n1 = 1; NEXTARG(next1)
2255 while ( ( next1 < SH->stop1 ) && AreArgsEqual(from1,next1) ) {
2256 n1++; NEXTARG(next1)
2258 next2 = from2; n2 = 1; NEXTARG(next2)
2259 while ( ( next2 < SH->stop2 ) && AreArgsEqual(from2,next2) ) {
2260 n2++; NEXTARG(next2)
2262 combilast = SH->combilast;
2268 while ( --n >= 0 ) { fr = from1; CopyArg(t,fr) }
2269 if ( GetBinom((UWORD *)(t),&na,n1+n2,n1) )
goto shuffcall;
2270 if ( combilast + AN.SHcombi[combilast] + na + 2 >= AN.SHcombisize ) {
2278 UWORD *combi = (UWORD *)Malloc1(2*AN.SHcombisize*2,
"AN.SHcombi");
2280 for ( jj = 0; jj < AN.SHcombisize; jj++ ) combi[jj] = AN.SHcombi[jj];
2281 AN.SHcombisize *= 2;
2282 M_free(AN.SHcombi,
"AN.SHcombi");
2285 if ( MulLong((UWORD *)(AN.SHcombi+combilast+1),AN.SHcombi[combilast],
2287 (UWORD *)(AN.SHcombi+combilast+AN.SHcombi[combilast]+2),
2288 (WORD *)(AN.SHcombi+combilast+AN.SHcombi[combilast]+1)) )
goto shuffcall;
2289 SH->combilast = combilast + AN.SHcombi[combilast] + 1;
2290 if ( next1 >= SH->stop1 ) {
2291 fr = next2; i = SH->stop2 - fr;
2293 if ( FiniShuffle(t) )
goto shuffcall;
2295 else if ( next2 >= SH->stop2 ) {
2296 fr = next1; i = SH->stop1 - fr;
2298 if ( FiniShuffle(t) )
goto shuffcall;
2301 if ( Shuffle(next1,next2,t) )
goto shuffcall;
2303 SH->combilast = combilast;
2308 if ( next2 < SH->stop2 ) {
2311 while ( --n >= 0 ) { fr = from1; CopyArg(t,fr) }
2312 for ( j = 0; j < n1; j++ ) {
2313 if ( GetBinom((UWORD *)(t),&na,n2+j,j) )
goto shuffcall;
2314 if ( MulLong((UWORD *)(AN.SHcombi+combilast+1),AN.SHcombi[combilast],
2316 (UWORD *)(AN.SHcombi+combilast+AN.SHcombi[combilast]+2),
2317 (WORD *)(AN.SHcombi+combilast+AN.SHcombi[combilast]+1)) )
goto shuffcall;
2318 SH->combilast = combilast + AN.SHcombi[combilast] + 1;
2319 if ( j > 0 ) { fr = from1; CopyArg(t,fr) }
2320 fn2 = next2; tt = t;
2323 if ( fn2 >= SH->stop2 ) {
2325 while ( --n >= 0 ) { fr = from1; CopyArg(tt,fr) }
2326 fr = next1; i = SH->stop1 - fr;
2328 if ( FiniShuffle(tt) )
goto shuffcall;
2331 n = j; fn1 = from1;
while ( --n >= 0 ) { NEXTARG(fn1) }
2332 if ( Shuffle(fn1,fn2,tt) )
goto shuffcall;
2334 SH->combilast = combilast;
2341 if ( next1 < SH->stop1 ) {
2344 while ( --n >= 0 ) { fr = from1; CopyArg(t,fr) }
2345 for ( j = 0; j < n2; j++ ) {
2346 if ( GetBinom((UWORD *)(t),&na,n1+j,j) )
goto shuffcall;
2347 if ( MulLong((UWORD *)(AN.SHcombi+combilast+1),AN.SHcombi[combilast],
2349 (UWORD *)(AN.SHcombi+combilast+AN.SHcombi[combilast]+2),
2350 (WORD *)(AN.SHcombi+combilast+AN.SHcombi[combilast]+1)) )
goto shuffcall;
2351 SH->combilast = combilast + AN.SHcombi[combilast] + 1;
2352 if ( j > 0 ) { fr = from1; CopyArg(t,fr) }
2353 fn1 = next1; tt = t;
2356 if ( fn1 >= SH->stop1 ) {
2358 while ( --n >= 0 ) { fr = from1; CopyArg(tt,fr) }
2359 fr = next2; i = SH->stop2 - fr;
2361 if ( FiniShuffle(tt) )
goto shuffcall;
2364 n = j; fn2 = from2;
while ( --n >= 0 ) { NEXTARG(fn2) }
2365 if ( Shuffle(fn1,fn2,tt) )
goto shuffcall;
2367 SH->combilast = combilast;
2378 if ( fr >= SH->stop1 ) {
2379 fr = from2; i = SH->stop2 - fr;
2381 if ( FiniShuffle(t) )
goto shuffcall;
2384 if ( Shuffle(fr,from2,t) )
goto shuffcall;
2392 if ( fr >= SH->stop2 ) {
2393 fr = from1; i = SH->stop1 - fr;
2395 if ( FiniShuffle(t) )
goto shuffcall;
2398 if ( Shuffle(from1,fr,t) )
goto shuffcall;
2421int FinishShuffle(WORD *fini)
2424 WORD *t, *t1, *oldworkpointer = AT.WorkPointer, *tcoef, ntcoef, *out;
2427 SH->outfun[1] = fini - SH->outfun;
2428 if ( functions[SH->outfun[0]-FUNCTION].symmetric != 0 )
2429 SH->outfun[2] |= DIRTYSYMFLAG;
2430 out = fini; i = fini - SH->outterm; t = SH->outterm;
2434 while ( t1 < SH->stop2 ) { t = t1; t1 = t + t[1]; }
2436 while ( t1 < t ) *fini++ = *t1++;
2438 while ( t < SH->incoef ) *fini++ = *t++;
2440 ntcoef = SH->nincoef;
2443 ntcoef = REDLENG(ntcoef);
2444 Mully(BHEAD (UWORD *)tcoef,&ntcoef,
2445 (UWORD *)(AN.SHcombi+SH->combilast+1),AN.SHcombi[SH->combilast]);
2446 ntcoef = INCLENG(ntcoef);
2447 fini = tcoef + ABS(ntcoef);
2448 if ( ( ( SH->option & 2 ) != 0 ) && ( ( SH->option & 256 ) != 0 ) ) ntcoef = -ntcoef;
2450 i = *out = fini - out;
2454 AT.WorkPointer = out + *out;
2455 if ( ( SH->option & 1 ) == 1 ) {
2456 if (
Generator(BHEAD out,SH->level) )
goto Finicall;
2459 if ( DoShtuffle(out,SH->level,SH->thefunction,SH->option) )
goto Finicall;
2461 AT.WorkPointer = oldworkpointer;
2464 AT.WorkPointer = oldworkpointer;
2465 MesCall(
"FinishShuffle");
2487WORD DoStuffle(WORD *term, WORD level, WORD fun, WORD option)
2491 WORD *t1, *t2, *tstop, *t1stop, *t2stop, ncoef, n = fun, *to, *from;
2497 WORD *rr1, *rr2, i1, i2;
2500 if ( ( n = DolToFunction(BHEAD -n) ) == 0 ) {
2501 MLOCK(ErrorMessageLock);
2502 MesPrint(
"$-variable in merge statement did not evaluate to a function.");
2503 MUNLOCK(ErrorMessageLock);
2507 if ( AT.WorkPointer + 3*(*term) + AM.MaxTal > AT.WorkTop ) {
2508 MLOCK(ErrorMessageLock);
2510 MUNLOCK(ErrorMessageLock);
2514 tstop = term + *term;
2516 tstop -= ABS(ncoef);
2519 while ( t1 < tstop ) {
2520 if ( ( *t1 == n ) && ( t1+t1[1] < tstop ) && ( t1[1] > FUNHEAD ) ) {
2522 if ( t2 >= tstop ) {
2526 while ( t2 < tstop ) {
2527 if ( ( *t2 == n ) && ( t2[1] > FUNHEAD ) )
break;
2530 if ( t2 < tstop )
break;
2534 if ( t1 >= tstop ) {
2542 t1stop = t1 + t1[1];
2544 while ( r1 < t1stop ) {
2545 if ( *r1 != -SNUMBER )
break;
2546 if ( r1[1] == 0 )
break;
2549 if ( r1 < t1stop ) { t1 = t2;
goto retry1; }
2550 t2stop = t2 + t2[1];
2552 while ( r2 < t2stop ) {
2553 if ( *r2 != -SNUMBER )
break;
2554 if ( r2[1] == 0 )
break;
2557 if ( r2 < t2stop ) { t2 = t2 + t2[1];
goto retry2; }
2559 t1stop = t1 + t1[1];
2561 while ( r1 < t1stop ) {
2562 if ( *r1 == -SNUMBER ) {
2563 if ( r1[1] == 0 )
break;
2566 else if ( *r1 == -SYMBOL ) {
2567 if ( ( symbols[r1[1]].complex & VARTYPEROOTOFUNITY ) != VARTYPEROOTOFUNITY )
2571 if ( *r1 > 0 && *r1 == r1[ARGHEAD]+ARGHEAD ) {
2572 if ( ABS(r1[r1[0]-1]) == r1[0]-ARGHEAD-1 ) {}
2573 else if ( r1[ARGHEAD+1] == SYMBOL ) {
2574 rr1 = r1 + ARGHEAD + 3;
2577 if ( ( symbols[*rr1].complex & VARTYPEROOTOFUNITY ) != VARTYPEROOTOFUNITY )
2581 if ( i1 > 0 )
break;
2585 i1 = (ABS(*rr1)-1)/2;
2587 if ( rr1[-1] )
break;
2590 if ( i1 > 1 || rr1[-1] != 1 )
break;
2595 if ( r1 < t1stop ) { t1 = t2;
goto retry1; }
2596 t2stop = t2 + t2[1];
2599 while ( r2 < t2stop ) {
2600 if ( *r2 == -SNUMBER ) {
2601 if ( r2[1] == 0 )
break;
2604 else if ( *r2 == -SYMBOL ) {
2605 if ( ( symbols[r2[1]].complex & VARTYPEROOTOFUNITY ) != VARTYPEROOTOFUNITY )
2609 if ( *r2 > 0 && *r2 == r2[ARGHEAD]+ARGHEAD ) {
2610 if ( ABS(r2[r2[0]-1]) == r2[0]-ARGHEAD-1 ) {}
2611 else if ( r2[ARGHEAD+1] == SYMBOL ) {
2612 rr2 = r2 + ARGHEAD + 3;
2615 if ( ( symbols[*rr2].complex & VARTYPEROOTOFUNITY ) != VARTYPEROOTOFUNITY )
2619 if ( i2 > 0 )
break;
2623 i2 = (ABS(*rr2)-1)/2;
2625 if ( rr2[-1] )
break;
2628 if ( i2 > 1 || rr2[-1] != 1 )
break;
2633 if ( r2 < t2stop ) { t2 = t2 + t2[1];
goto retry2; }
2641 SH->finishuf = &FinishStuffle;
2642 SH->do_uffle = &DoStuffle;
2643 SH->outterm = AT.WorkPointer;
2644 AT.WorkPointer += *term;
2645 SH->ststop1 = t1 + t1[1];
2646 SH->ststop2 = t2 + t2[1];
2647 SH->thefunction = n;
2648 SH->option = option;
2651 SH->nincoef = ncoef;
2652 if ( AN.SHcombi == 0 || AN.SHcombisize == 0 ) {
2653 AN.SHcombisize = 200;
2654 AN.SHcombi = (UWORD *)Malloc1(AN.SHcombisize*
sizeof(UWORD),
"AN.SHcombi");
2656 SHback.combilast = 0;
2659 SH->combilast += AN.SHcombi[SH->combilast]+1;
2660 if ( SH->combilast >= AN.SHcombisize - 100 ) {
2661 newcombi = (UWORD *)Malloc1(2*AN.SHcombisize*
sizeof(UWORD),
"AN.SHcombi");
2662 for ( k = 0; k < AN.SHcombisize; k++ ) newcombi[k] = AN.SHcombi[k];
2663 M_free(AN.SHcombi,
"AN.SHcombi");
2664 AN.SHcombi = newcombi;
2665 AN.SHcombisize *= 2;
2668 AN.SHcombi[SH->combilast] = 1;
2669 AN.SHcombi[SH->combilast+1] = 1;
2671 i = t1-term; to = SH->outterm; from = term;
2674 for ( i = 0; i < FUNHEAD; i++ ) { *to++ = t1[i]; }
2676 error = Stuffle(t1+FUNHEAD,t2+FUNHEAD,to);
2678 AT.WorkPointer = SH->outterm;
2681 MesCall(
"DoStuffle");
2702int Stuffle(WORD *from1, WORD *from2, WORD *to)
2705 WORD *t, *tf, *next1, *next2, *st1, *st2, *save1, *save2;
2711 save1 = SH->stop1; save2 = SH->stop2;
2712 if ( from1 >= SH->ststop1 && from2 == SH->ststop2 ) {
2713 SH->stop1 = SH->ststop1;
2714 SH->stop2 = SH->ststop2;
2715 retval = FinishShuffle(to);
2716 SH->stop1 = save1; SH->stop2 = save2;
2719 else if ( from1 >= SH->ststop1 ) {
2720 i = SH->ststop2 - from2; t = to; tf = from2; NCOPY(t,tf,i)
2721 SH->stop1 = SH->ststop1;
2722 SH->stop2 = SH->ststop2;
2723 retval = FinishShuffle(t);
2724 SH->stop1 = save1; SH->stop2 = save2;
2727 else if ( from2 >= SH->ststop2 ) {
2728 i = SH->ststop1 - from1; t = to; tf = from1; NCOPY(t,tf,i)
2729 SH->stop1 = SH->ststop1;
2730 SH->stop2 = SH->ststop2;
2731 retval = FinishShuffle(t);
2732 SH->stop1 = save1; SH->stop2 = save2;
2738 SH->stop1 = SH->ststop1;
2739 SH->stop2 = SH->ststop2;
2740 SH->finishuf = &FinishShuffle;
2741 if ( Shuffle(from1,from2,to) )
goto stuffcall;
2742 SH->finishuf = &FinishStuffle;
2747 st1 = from1; next1 = st1+2;
2749 st1 = next1 = from1;
2752 while ( next1 <= SH->ststop1 ) {
2754 st2 = from2; next2 = st2+2;
2756 next2 = st2 = from2;
2759 while ( next2 <= SH->ststop2 ) {
2762 if ( st1 == from1 && st2 == from2 ) {
2765 *t++ = -SNUMBER; *t++ = StuffAdd(st1[1],st2[1]);
2767 t = StuffRootAdd(st1,st2,t);
2770 if ( Stuffle(next1,next2,t) )
goto stuffcall;
2773 else if ( st1 == from1 ) {
2775 t = to; tf = from2; NCOPY(t,tf,i)
2777 *t++ = -SNUMBER; *t++ = StuffAdd(st1[1],st2[1]);
2779 t = StuffRootAdd(st1,st2,t);
2782 if ( Stuffle(next1,next2,t) )
goto stuffcall;
2785 else if ( st2 == from2 ) {
2787 t = to; tf = from1; NCOPY(t,tf,i)
2789 *t++ = -SNUMBER; *t++ = StuffAdd(st1[1],st2[1]);
2791 t = StuffRootAdd(st1,st2,t);
2794 if ( Stuffle(next1,next2,t) )
goto stuffcall;
2798 if ( Shuffle(from1,from2,to) )
goto stuffcall;
2801 st2 = next2; next2 += 2;
2808 st1 = next1; next1 += 2;
2814 SH->stop1 = save1; SH->stop2 = save2;
2829int FinishStuffle(WORD *fini)
2834 WORD *next1 = SH->stop1, *next2 = SH->stop2;
2835 fini = StuffRootAdd(next1,next2,fini);
2837 *fini++ = -SNUMBER; *fini++ = StuffAdd(SH->stop1[1],SH->stop2[1]);
2843 if ( Stuffle(next1,next2,fini) )
goto stuffcall;
2845 if ( Stuffle(SH->stop1+2,SH->stop2+2,fini) )
goto stuffcall;
2850 MesCall(
"FinishStuffle");
2876WORD *StuffRootAdd(WORD *t1, WORD *t2, WORD *to)
2878 int type1, type2, type3, sgn, sgn1, sgn2, sgn3, pow, root, nosymbols, i;
2879 WORD *tt1, *tt2, it1, it2, *t3, *r, size1, size2, size3;
2882 if ( *t1 == -SNUMBER ) { type1 = 1;
if ( t1[1] < 0 ) sgn1 = -1;
else sgn1 = 1; }
2883 else if ( *t1 == -SYMBOL ) { type1 = 2; sgn1 = 1; }
2884 else if ( ABS(t1[*t1-1]) == *t1-ARGHEAD-1 ) {
2885 type1 = 3;
if ( t1[*t1-1] < 0 ) sgn1 = -1;
else sgn1 = 1; }
2886 else { type1 = 4;
if ( t1[*t1-1] < 0 ) sgn1 = -1;
else sgn1 = 1; }
2887 if ( *t2 == -SNUMBER ) { type2 = 1;
if ( t2[1] < 0 ) sgn2 = -1;
else sgn2 = 1; }
2888 else if ( *t2 == -SYMBOL ) { type2 = 2; sgn2 = 1; }
2889 else if ( ABS(t2[*t2-1]) == *t2-ARGHEAD-1 ) {
2890 type2 = 3;
if ( t2[*t2-1] < 0 ) sgn2 = -1;
else sgn2 = 1; }
2891 else { type2 = 4;
if ( t2[*t2-1] < 0 ) sgn2 = -1;
else sgn2 = 1; }
2892 if ( type1 > type2 ) {
2893 t3 = t1; t1 = t2; t2 = t3;
2894 type3 = type1; type1 = type2; type2 = type3;
2895 sgn3 = sgn1; sgn1 = sgn2; sgn2 = sgn3;
2897 nosymbols = 1; sgn3 = 1;
2903 if ( x > MAXPOSITIVE || x < -(MAXPOSITIVE+1) ) {
2904 if ( x < 0 ) { sgn1 = -3; x = -x; }
2909 *to++ = 4; *to++ = (UWORD)x; *to++ = 1; *to++ = sgn1;
2911 else { *to++ = -SNUMBER; *to++ = (WORD)x; }
2913 else if ( type2 == 2 ) {
2914 *to++ = ARGHEAD+8; *to++ = 0; FILLARG(to)
2915 *to++ = 8; *to++ = SYMBOL; *to++ = 4; *to++ = t2[1]; *to++ = 1;
2916 *to++ = ABS(t1[1])+1;
2920 else if ( type2 == 3 ) {
2921 tt1 = (WORD *)scratch; tt1[0] = ABS(t1[1]); size1 = 1;
2922 tt2 = t2+ARGHEAD+1; size2 = (ABS(t2[*t2-1])-1)/2;
2924 *to++ = 0; *to++ = 0; FILLARG(to) *to++ = 0;
2931 tt1 = (WORD *)scratch; tt1[0] = ABS(t1[1]); size1 = 1;
2932 tt2 = t2+ARGHEAD+1; tt2 += tt2[1]; size2 = (ABS(t2[*t2-1])-1)/2;
2933 t3 = to; i = tt2 - t2; r = t2;
2941 if ( t1[1] == t2[1] ) {
2942 if ( ( symbols[t1[1]].maxpower == 4 )
2943 && ( ( symbols[t1[1]].complex & VARTYPEMINUS ) == VARTYPEMINUS ) ) {
2944 *to++ = -SNUMBER; *to++ = -2;
2946 else if ( symbols[t1[1]].maxpower == 2 ) {
2947 *to++ = -SNUMBER; *to++ = 2;
2950 *to++ = ARGHEAD+8; *to++ = 0; FILLARG(to)
2951 *to++ = 8; *to++ = SYMBOL; *to++ = 4;
2952 *to++ = t1[1]; *to++ = 2;
2953 *to++ = 2; *to++ = 1; *to++ = 3;
2957 *to++ = ARGHEAD+10; *to++ = 0; FILLARG(to)
2958 *to++ = 10; *to++ = SYMBOL; *to++ = 6;
2959 if ( t1[1] < t2[1] ) {
2960 *to++ = t1[1]; *to++ = 1; *to++ = t2[1]; *to++ = 1;
2963 *to++ = t2[1]; *to++ = 1; *to++ = t1[1]; *to++ = 1;
2965 *to++ = 2; *to++ = 1; *to++ = 3;
2968 else if ( type2 == 3 ) {
2970 *to++ = 0; *to++ = 0; FILLARG(to) *to++ = 0;
2971 *to++ = SYMBOL; *to++ = 4; *to++ = t1[1]; *to++ = 1;
2972 tt1 = scratch; tt1[1] = 1; size1 = 1;
2973 tt2 = t2+ARGHEAD+1; size2 = (ABS(t2[*t2-1])-1)/2;
2978 tt1 = scratch; tt1[0] = 1; size1 = 1;
2980 *to++ = 0; *to++ = 0; FILLARG(to) *to++ = 0;
2981 *to++ = SYMBOL; *to++ = 0;
2982 tt2 = t2 + ARGHEAD+3; it2 = tt2[-1]-2;
2984 if ( *tt2 == t1[1] ) {
2986 root = symbols[*tt2].maxpower;
2987 if ( pow >= root ) pow -= root;
2988 if ( ( symbols[*tt2].complex & VARTYPEMINUS ) == VARTYPEMINUS ) {
2989 if ( ( root & 1 ) == 0 && pow >= root/2 ) {
2990 pow -= root/2; sgn3 = -sgn3;
2994 *to++ = *tt2; *to++ = pow;
2999 else if ( t1[1] < *tt2 ) {
3000 *to++ = t1[1]; *to++ = 1;
break;
3003 *to++ = *tt2++; *to++ = *tt2++; it2 -= 2;
3004 if ( it2 <= 0 ) { *to++ = t1[1]; *to++ = 1; }
3007 while ( it2 > 0 ) { *to++ = *tt2++; *to++ = *tt2++; it2 -= 2; }
3008 if ( (to - t3) > ARGHEAD+3 ) {
3009 t3[ARGHEAD+2] = (to-t3)-ARGHEAD-1;
3015 size2 = (ABS(t2[*t2-1])-1)/2;
3024 tt1 = t1+ARGHEAD+1; size1 = (ABS(t1[*t1-1])-1)/2;
3025 tt2 = t2+ARGHEAD+1; size2 = (ABS(t2[*t2-1])-1)/2;
3027 *to++ = 0; *to++ = 0; FILLARG(to) *to++ = 0;
3034 tt1 = t1+ARGHEAD+1; size1 = (ABS(t1[*t1-1])-1)/2;
3035 tt2 = t2+ARGHEAD+1; tt2 += tt2[1]; size2 = (ABS(t2[*t2-1])-1)/2;
3036 t3 = to; i = tt2 - t2; r = t2;
3047 tt1 = t1+ARGHEAD+3; it1 = tt1[-1]-2;
3048 tt2 = t2+ARGHEAD+3; it2 = tt2[-1]-2;
3050 *to++ = 0; *to++ = 0; FILLARG(to)
3051 *to++ = 0; *to++ = SYMBOL; *to++ = 0;
3052 while ( it1 > 0 && it2 > 0 ) {
3053 if ( *tt1 == *tt2 ) {
3054 pow = tt1[1]+tt2[1];
3055 root = symbols[*tt1].maxpower;
3056 if ( pow >= root ) pow -= root;
3057 if ( ( symbols[*tt1].complex & VARTYPEMINUS ) == VARTYPEMINUS ) {
3058 if ( ( root & 1 ) == 0 && pow >= root/2 ) {
3059 pow -= root/2; sgn3 = -sgn3;
3063 *to++ = *tt1; *to++ = pow;
3065 tt1 += 2; tt2 += 2; it1 -= 2; it2 -= 2;
3067 else if ( *tt1 < *tt2 ) {
3068 *to++ = *tt1++; *to++ = *tt1++; it1 -= 2;
3071 *to++ = *tt2++; *to++ = *tt2++; it2 -= 2;
3074 while ( it1 > 0 ) { *to++ = *tt1++; *to++ = *tt1++; it1 -= 2; }
3075 while ( it2 > 0 ) { *to++ = *tt2++; *to++ = *tt2++; it2 -= 2; }
3076 if ( (to - t3) > ARGHEAD+3 ) {
3077 t3[ARGHEAD+2] = (to-t3)-ARGHEAD-1;
3083 size1 = (ABS(t1[*t1-1])-1)/2;
3084 size2 = (ABS(t2[*t2-1])-1)/2;
3091 if ( AddLong((UWORD *)tt1,size1,(UWORD *)tt2,size2,(UWORD *)to,&size3) ) {
3092 MLOCK(ErrorMessageLock);
3093 MesPrint(
"Called from StuffRootAdd");
3094 MUNLOCK(ErrorMessageLock);
3097 sgn = sgn1*sgn2*sgn3;
3098 if ( nosymbols && size3 == 1 ) {
3099 if ( (UWORD)(to[0]) <= MAXPOSITIVE && sgn > 0 ) {
3101 to = t3; *to++ = -SNUMBER; *to++ = sgn1;
3103 else if ( (UWORD)(to[0]) <= (MAXPOSITIVE+1) && sgn < 0 ) {
3105 to = t3; *to++ = -SNUMBER; *to++ = -sgn1;
3107 else goto genericcoef;
3112 sgn = sgn*(2*size3+1);
3114 while ( size3 > 1 ) { *to++ = 0; size3--; }
3117 t3[ARGHEAD] = t3[0] - ARGHEAD;
WORD CompCoef(WORD *, WORD *)
WORD Generator(PHEAD WORD *, WORD)