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 ) {
188 MLOCK(ErrorMessageLock);
189 MesPrint(
"!>Unexpected code in ReNumber");
190 MUNLOCK(ErrorMessageLock);
195 if ( *t >= FUNCTION && functions[*t-FUNCTION].spec
196 >= TENSORFUNCTION ) {
199 if ( *t > AN.IndDum ) {
200 if ( AN.NumFound >= AN.MaxRenumScratch ) AdjustRenumScratch(BHEAD0);
204 *AN.DumFunPlace++ = fun;
225 if ( *t == -INDEX ) {
227 if ( *t > AN.IndDum ) {
228 if ( AN.NumFound >= AN.MaxRenumScratch ) AdjustRenumScratch(BHEAD0);
232 *AN.DumFunPlace++ = fun;
236 else if ( *t <= -FUNCTION ) t++;
243 }
while ( t < tstop );
254WORD DetCurDum(PHEAD WORD *t)
257 WORD maxval = AN.IndDum;
258 WORD maxtop = AM.IndDum + WILDOFFSET;
259 WORD *tstop, *m, *r, i;
261 tstop -= ABS(*tstop);
263 while ( t < tstop ) {
264 if ( *t == VECTOR ) {
268 if ( *m > maxval && *m < maxtop ) maxval = *m;
272 else if ( *t == DELTA || *t == INDEX ) {
277 if ( *m > maxval && *m < maxtop ) maxval = *m;
281 else if ( *t >= FUNCTION ) {
282 if ( functions[*t-FUNCTION].spec >= TENSORFUNCTION ) {
290 if ( *r <= -FUNCTION ) r++;
291 else if ( *r == -INDEX ) {
292 if ( r[1] > maxval && r[1] < maxtop ) maxval = r[1];
301 i = DetCurDum(BHEAD m);
302 if ( i > maxval && i < maxtop ) maxval = i;
326int FullRenumber(PHEAD WORD *term, WORD par)
329 WORD *d, **p, **f, *w, *t, *best, *stac, *perm, a, *termtry;
331 WORD *oldworkpointer = AT.WorkPointer;
332 n = ReNumber(BHEAD term) - AM.IndDum;
333 if ( n <= 1 )
return(0);
334 Normalize(BHEAD term);
335 if ( *term == 0 )
return(0);
336 n = ReNumber(BHEAD term) - AM.IndDum;
340 if ( AT.WorkPointer < term + *term ) AT.WorkPointer = term + *term;
342 best = w = AT.WorkPointer; t = term;
343 for ( i = *term; i > 0; i-- ) *w++ = *t++;
345 Normalize(BHEAD best);
346 AT.WorkPointer = w = best + *best;
349 termtry = perm + n + 1;
350 for ( i = 1; i <= n; i++ ) perm[i] = i + AM.IndDum;
351 for ( i = 1; i <= n; i++ ) stac[i] = i;
352 for ( i = 0; i < k; i++ ) d[i] = *(p[i]) - AM.IndDum;
354 for ( i = 1; i < n; i++ ) {
355 for ( j = i+1; j <= n; j++ ) {
356 a = perm[j]; perm[j] = perm[i]; perm[i] = a;
357 for ( ii = 0; ii < k; ii++ ) {
358 *(p[ii]) = perm[d[ii]];
359 if ( f[ii] ) *(f[ii]) |= DIRTYSYMFLAG;
361 t = term; w = termtry;
362 for ( ii = 0; ii < *term; ii++ ) *w++ = *t++;
364 if ( Normalize(BHEAD termtry) == 0 ) {
365 if ( *termtry == 0 )
goto Return0;
366 if ( ( ii = CompareTerms(BHEAD termtry,best,0) ) > 0 ) {
367 t = termtry; w = best;
368 for ( ii = 0; ii < *termtry; ii++ ) *w++ = *t++;
371 else if ( ii == 0 &&
CompCoef(termtry,best) != 0 )
375 a = perm[j]; perm[j] = perm[i]; perm[i] = a;
379 else if ( par == 1 ) {
382 if ( stac[j] == n ) {
383 a = perm[j]; perm[j] = perm[n]; perm[n] = a;
389 if ( j != stac[j] ) {
390 a = perm[j]; perm[j] = perm[stac[j]]; perm[stac[j]] = a;
393 a = perm[j]; perm[j] = perm[stac[j]]; perm[stac[j]] = a;
395 for ( i = 0; i < k; i++ ) {
396 *(p[i]) = perm[d[i]];
397 if ( f[i] ) *(f[i]) |= DIRTYSYMFLAG;
399 t = term; w = termtry;
400 for ( i = 0; i < *term; i++ ) *w++ = *t++;
402 if ( Normalize(BHEAD termtry) == 0 ) {
403 if ( *termtry == 0 )
goto Return0;
404 if ( ( ii = CompareTerms(BHEAD termtry,best,0) ) > 0 ) {
405 t = termtry; w = best;
406 for ( i = 0; i < *termtry; i++ ) *w++ = *t++;
408 else if ( ii == 0 &&
CompCoef(termtry,best) != 0 )
412 if ( j < n-1 ) { j = n-1; }
417 for ( i = 0; i < n; i++ ) *t++ = *w++;
418 AT.WorkPointer = oldworkpointer;
422 AT.WorkPointer = oldworkpointer;
438void MoveDummies(PHEAD WORD *term, WORD shift)
441 WORD maxval = AN.IndDum;
442 WORD maxtop = AM.IndDum + WILDOFFSET;
444 tstop = term + *term - 1;
445 tstop -= ABS(*tstop);
447 while ( term < tstop ) {
448 if ( *term == VECTOR ) {
452 if ( *m > maxval && *m < maxtop ) *m += shift;
456 else if ( *term == DELTA || *term == INDEX ) {
461 if ( *m > maxval && *m < maxtop ) *m += shift;
465 else if ( *term >= FUNCTION ) {
466 if ( functions[*term-FUNCTION].spec >= TENSORFUNCTION ) {
474 if ( *r <= -FUNCTION ) r++;
475 else if ( *r == -INDEX ) {
476 if ( r[1] > maxval && r[1] < maxtop ) r[1] += shift;
485 MoveDummies(BHEAD m,shift);
508void AdjustRenumScratch(PHEAD0)
513 WORD **newpoin, *newnum;
514 if ( AN.MaxRenumScratch == 0 ) newsize = 100;
515 else newsize = AN.MaxRenumScratch*2;
516 if ( newsize > MAXPOSITIVE/2 ) newsize = MAXPOSITIVE/2+1;
518 newpoin = (WORD **)Malloc1(newsize*
sizeof(WORD *),
"PoinScratch");
519 for ( i = 0; i < AN.NumFound; i++ ) newpoin[i] = AN.PoinScratch[i];
520 for ( ; i < newsize; i++ ) newpoin[i] = 0;
521 if ( AN.PoinScratch ) M_free(AN.PoinScratch,
"PoinScratch");
522 AN.PoinScratch = newpoin;
523 AN.DumPlace = newpoin + AN.NumFound;
525 newpoin = (WORD **)Malloc1(newsize*
sizeof(WORD *),
"FunScratch");
526 for ( i = 0; i < AN.NumFound; i++ ) newpoin[i] = AN.FunScratch[i];
527 for ( ; i < newsize; i++ ) newpoin[i] = 0;
528 if ( AN.FunScratch ) M_free(AN.FunScratch,
"FunScratch");
529 AN.FunScratch = newpoin;
530 AN.DumFunPlace = newpoin + AN.NumFound;
532 newnum = (WORD *)Malloc1(newsize*
sizeof(WORD),
"RenumScratch");
533 for ( i = 0; i < AN.NumFound; i++ ) newnum[i] = AN.RenumScratch[i];
534 for ( ; i < newsize; i++ ) newnum[i] = 0;
535 if ( AN.RenumScratch ) M_free(AN.RenumScratch,
"RenumScratch");
536 AN.RenumScratch = newnum;
537 AN.DumFound = newnum + AN.NumFound;
539 AN.MaxRenumScratch = newsize;
554WORD CountDo(WORD *term, WORD *instruct)
556 WORD *m, *r, i, j, count = 0;
557 WORD *stopper, *tstop, *r1 = 0, *r2 = 0;
561 tstop = term + *term; tstop -= ABS(tstop[-1]); term++;
562 while ( term < tstop ) {
569 while ( m < stopper ) {
570 if ( *m == SYMBOL && m[2] == *term ) {
571 count += m[3] * term[1];
584 while ( m < stopper ) {
585 if ( *m == DOTPRODUCT && (( m[2] == *term &&
586 m[3] == term[1]) || ( m[2] == term[1] &&
588 count += m[4] * term[2];
594 while ( m < stopper ) {
595 if ( *m == VECTOR && m[2] == *term &&
596 ( m[3] & DOTPBIT ) != 0 ) {
597 count += m[m[1]-1] * term[2];
602 while ( m < stopper ) {
603 if ( *m == VECTOR && m[2] == term[1] &&
604 ( m[3] & DOTPBIT ) != 0 ) {
605 count += m[m[1]-1] * term[2];
618VectInd: i = term[1] - 2;
622 while ( m < stopper ) {
623 if ( *m == VECTOR && m[2] == *term &&
624 ( m[3] & VECTBIT ) != 0 ) {
634 if ( *term >= FUNCTION ) {
637 while ( m < stopper ) {
638 if ( *m == FUNCTION && m[2] == i ) count += m[3];
641 if ( functions[i-FUNCTION].spec >= TENSORFUNCTION ) {
642 i = term[1] - FUNHEAD;
647 while ( m < stopper ) {
648 if ( *m == VECTOR && m[2] == *term &&
649 ( m[3] & FUNBIT ) != 0 ) {
663 if ( ( *term == -INDEX || *term == -VECTOR
664 || *term == -MINVECTOR ) && term[1] < MINSPEC ) {
666 while ( m < stopper ) {
667 if ( *m == VECTOR && term[1] == m[2]
668 && ( m[3] & SETBIT ) != 0 ) {
669 r1 = SetElements + Sets[m[4]].first;
670 r2 = SetElements + Sets[m[4]].last;
684 else { NEXTARG(term) }
708WORD CountFun(WORD *term, WORD *countfun)
710 WORD *m, *r, i, j, count = 0, *instruct, *stopper, *tstop;
713 instruct = countfun + FUNHEAD;
714 tstop = term + *term; tstop -= ABS(tstop[-1]); term++;
715 while ( term < tstop ) {
722 while ( m < stopper ) {
723 if ( *m == -SNUMBER ) { NEXTARG(m)
continue; }
724 if ( *m == -SYMBOL && m[1] == *term
725 && m[2] == -SNUMBER && ( m + 2 ) < stopper ) {
726 count += m[3] * term[1]; m += 4;
739 while ( m < stopper ) {
740 if ( *m == -SNUMBER ) { NEXTARG(m)
continue; }
741 if ( *m == 9+ARGHEAD && m[ARGHEAD] == 9
742 && m[ARGHEAD+1] == DOTPRODUCT
743 && m[ARGHEAD+9] == -SNUMBER && ( m + ARGHEAD+9 ) < stopper
744 && (( m[ARGHEAD+3] == *term &&
745 m[ARGHEAD+4] == term[1]) ||
746 ( m[ARGHEAD+3] == term[1] &&
747 m[ARGHEAD+4] == *term )) ) {
748 count += m[ARGHEAD+10] * term[2];
754 while ( m < stopper ) {
755 if ( *m == -SNUMBER ) { NEXTARG(m)
continue; }
756 if ( ( *m == -VECTOR || *m == -MINVECTOR )
758 m[2] == -SNUMBER && ( m+2 ) < stopper ) {
759 count += m[3] * term[2]; m += 4;
764 while ( m < stopper ) {
765 if ( *m == -SNUMBER ) { NEXTARG(m)
continue; }
766 if ( ( *m == -VECTOR || *m == -MINVECTOR )
767 && m[1] == term[1] &&
768 m[2] == -SNUMBER && ( m+2 ) < stopper ) {
769 count += m[3] * term[2];
783VectInd: i = term[1] - 2;
787 while ( m < stopper ) {
788 if ( *m == -SNUMBER ) { NEXTARG(m)
continue; }
789 if ( ( *m == -VECTOR || *m == -MINVECTOR )
791 m[2] == -SNUMBER && (m+2) < stopper ) {
792 count += m[3]; m += 4;
801 if ( *term >= FUNCTION ) {
804 while ( m < stopper ) {
805 if ( *m == -SNUMBER ) { NEXTARG(m)
continue; }
806 if ( *m == -i && m[1] == -SNUMBER && (m+1) < stopper ) {
807 count += m[2]; m += 3;
811 if ( functions[i-FUNCTION].spec >= TENSORFUNCTION ) {
812 i = term[1] - FUNHEAD;
817 while ( m < stopper ) {
818 if ( *m == -SNUMBER ) { NEXTARG(m)
continue; }
819 if ( ( *m == -VECTOR || *m == -INDEX
820 || *m == -MINVECTOR ) && m[1] == *term &&
821 m[2] == -SNUMBER && (m+2) < stopper ) {
822 count += m[3]; m += 4;
835 if ( ( *term == -INDEX || *term == -VECTOR
836 || *term == -MINVECTOR ) && term[1] < MINSPEC ) {
838 while ( m < stopper ) {
839 if ( *m == -SNUMBER ) { NEXTARG(m)
continue; }
840 if ( *m == -VECTOR && m[1] == term[1]
841 && m[2] == -SNUMBER && (m+2) < stopper ) {
849 else { NEXTARG(term) }
869WORD DimensionSubterm(WORD *subterm)
871 WORD *r, *rstop, dim, i;
873 rstop = subterm + subterm[1];
874 if ( *subterm == SYMBOL ) {
876 while ( r < rstop ) {
877 if ( *r <= NumSymbols && *r > -MAXPOWER ) {
878 dim = symbols[*r].dimension;
879 if ( dim == MAXPOSITIVE )
goto undefined;
881 if ( x >= MAXPOSITIVE || x <= -MAXPOSITIVE )
goto outofrange;
884 else if ( *r <= MAXVARIABLES ) {
888 i = MAXVARIABLES - *r;
889 dim = cbuf[AM.sbufnum].dimension[i];
890 if ( dim == MAXPOSITIVE )
goto undefined;
891 if ( dim == -MAXPOSITIVE )
goto outofrange;
893 if ( x >= MAXPOSITIVE || x <= -MAXPOSITIVE )
goto outofrange;
899 else if ( *subterm == DOTPRODUCT ) {
901 while ( r < rstop ) {
902 dim = vectors[*r-AM.OffsetVector].dimension;
903 if ( dim == MAXPOSITIVE )
goto undefined;
905 if ( x >= MAXPOSITIVE || x <= -MAXPOSITIVE )
goto outofrange;
906 dim = vectors[r[1]-AM.OffsetVector].dimension;
907 if ( dim == MAXPOSITIVE )
goto undefined;
909 if ( x >= MAXPOSITIVE || x <= -MAXPOSITIVE )
goto outofrange;
913 else if ( *subterm == VECTOR ) {
915 while ( r < rstop ) {
916 dim = vectors[*r-AM.OffsetVector].dimension;
917 if ( dim == MAXPOSITIVE )
goto undefined;
919 if ( x >= MAXPOSITIVE || x <= -MAXPOSITIVE )
goto outofrange;
923 else if ( *subterm == INDEX ) {
925 while ( r < rstop ) {
927 dim = vectors[*r-AM.OffsetVector].dimension;
928 if ( dim == MAXPOSITIVE )
goto undefined;
930 if ( x >= MAXPOSITIVE || x <= -MAXPOSITIVE )
goto outofrange;
935 else if ( *subterm >= FUNCTION ) {
936 dim = functions[*subterm-FUNCTION].dimension;
937 if ( dim == MAXPOSITIVE )
goto undefined;
939 if ( x >= MAXPOSITIVE || x <= -MAXPOSITIVE )
goto outofrange;
940 if ( functions[*subterm-FUNCTION].spec > 0 ) {
941 r = subterm + FUNHEAD;
942 while ( r < rstop ) {
943 if ( *r < MINSPEC ) {
944 dim = vectors[*r-AM.OffsetVector].dimension;
945 if ( dim == MAXPOSITIVE )
goto undefined;
947 if ( x >= MAXPOSITIVE || x <= -MAXPOSITIVE )
goto outofrange;
955 return((WORD)MAXPOSITIVE);
957 return(-(WORD)MAXPOSITIVE);
970WORD DimensionTerm(WORD *term)
972 WORD *t, *tstop, dim;
974 tstop = term + *term; tstop -= ABS(tstop[-1]);
976 while ( t < tstop ) {
977 dim = DimensionSubterm(t);
978 if ( dim == MAXPOSITIVE )
goto undefined;
979 if ( dim == -MAXPOSITIVE )
goto outofrange;
981 if ( x >= MAXPOSITIVE || x <= -MAXPOSITIVE )
goto outofrange;
986 return((WORD)MAXPOSITIVE);
988 return(-(WORD)MAXPOSITIVE);
1002WORD DimensionExpression(PHEAD WORD *expr)
1004 WORD dim, *term, *old, x = 0;
1008 dim = DimensionTerm(term);
1009 if ( dim == MAXPOSITIVE )
goto undefined;
1010 if ( dim == -MAXPOSITIVE )
goto outofrange;
1011 if ( first ) { x = dim; }
1012 else if ( x != dim ) {
1013 old = AN.currentTerm;
1014 MLOCK(ErrorMessageLock);
1015 MesPrint(
"Dimension is not the same in the terms of the expression");
1018 AN.currentTerm = term;
1021 MUNLOCK(ErrorMessageLock);
1022 AN.currentTerm = old;
1023 return(-(WORD)MAXPOSITIVE);
1029 return((WORD)MAXPOSITIVE);
1031 old = AN.currentTerm;
1032 AN.currentTerm = term;
1033 MLOCK(ErrorMessageLock);
1034 MesPrint(
"Dimension out of range in %t in subexpression");
1035 MUNLOCK(ErrorMessageLock);
1036 AN.currentTerm = old;
1037 return(-(WORD)MAXPOSITIVE);
1046int MultDo(PHEAD WORD *term, WORD *pattern)
1051 if ( pattern[2] > 0 ) {
1057 *term += SUBEXPSIZE;
1059 do { *--r = *--t; }
while ( --i > 0 );
1062 while ( --i >= 0 ) *t++ = *r++;
1063 AT.WorkPointer = term + *term;
1074int TryDo(PHEAD WORD *term, WORD *pattern, WORD level)
1077 WORD *t, *r, *m, i, j;
1078 ReNumber(BHEAD term);
1079 Normalize(BHEAD term);
1080 m = r = term + *term;
1090 if ( ( j = Normalize(BHEAD r) ) == 0 || j == 1 ) {
1091 if ( *r == 0 )
return(0);
1092 ReNumber(BHEAD r); Normalize(BHEAD r);
1093 if ( *r == 0 )
return(0);
1094 if ( ( i = CompareTerms(BHEAD term,r,0) ) < 0 ) {
1099 if ( i == 0 &&
CompCoef(term,r) != 0 ) {
return(0); }
1121int DoDistrib(PHEAD WORD *term, WORD level)
1124 WORD *t, *m, *r = 0, *stop, *tstop, *termout, *endhead, *starttail, *parms;
1125 WORD i, j, k, n, nn, ntype, fun1 = 0, fun2 = 0, typ1 = 0, typ2 = 0;
1126 WORD *arg, *oldwork, *mf, ktype = 0, atype = 0;
1127 WORD sgn, dirtyflag;
1128 AN.TeInFun = AR.TePos = 0;
1131 stop = tstop - ABS(tstop[-1]);
1133 while ( t < stop ) {
1135 if ( *t == DISTRIBUTION && t[FUNHEAD] == -SNUMBER
1136 && t[FUNHEAD+1] >= -2 && t[FUNHEAD+1] <= 2
1137 && t[FUNHEAD+2] == -SNUMBER
1138 && t[FUNHEAD+4] <= -FUNCTION
1139 && t[FUNHEAD+5] <= -FUNCTION ) {
1140 WORD *ttt = t+FUNHEAD+6, *tttstop = t+t[1];
1141 while ( ttt < tttstop ) {
1142 if ( *ttt == -DOLLAREXPRESSION )
break;
1145 if ( ttt >= tttstop ) {
1146 fun1 = -t[FUNHEAD+4];
1147 fun2 = -t[FUNHEAD+5];
1148 typ1 = functions[fun1-FUNCTION].spec;
1149 typ2 = functions[fun2-FUNCTION].spec;
1150 if ( typ1 > 0 || typ2 > 0 ) {
1154 if ( *m != -INDEX && *m != -VECTOR && *m != -MINVECTOR )
1159 MLOCK(ErrorMessageLock);
1160 MesPrint(
"Incompatible function types and arguments in distrib_");
1161 MUNLOCK(ErrorMessageLock);
1171 ntype = t[FUNHEAD+1];
1200 parms = m = t + FUNHEAD+6;
1206 oldwork = AT.WorkPointer;
1207 arg = AT.WorkPointer + 1;
1211 case 0: ktype = 1; atype = n < 0 ? 1: 0; n = 0;
break;
1212 case 1: ktype = 1; atype = 0;
break;
1213 case 2: ktype = 0; atype = 0;
break;
1214 case -1: ktype = 1; atype = 1;
break;
1215 case -2: ktype = 0; atype = 1;
break;
1222 if ( n > i )
return(0);
1224 for ( j = 0; j < n; j++ ) arg[j] = 1;
1225 for ( j = n; j < i; j++ ) arg[j] = 0;
1230 while ( t < endhead ) *m++ = *t++;
1237 while ( k-- > 0 ) *m++ = 0;
1240 for ( k = 0; k < i; k++ ) {
1241 if ( arg[k] == ktype ) {
1242 if ( *r <= -FUNCTION ) *m++ = *r++;
1243 else if ( *r < 0 ) {
1245 if ( *r == -MINVECTOR ) sgn ^= 1;
1249 else { *m++ = *r++; *m++ = *r++; }
1258 mf[1] = WORDDIF(m,mf);
1265 while ( k-- > 0 ) *m++ = 0;
1268 for ( k = 0; k < i; k++ ) {
1269 if ( arg[k] != ktype ) {
1270 if ( *r <= -FUNCTION ) *m++ = *r++;
1271 else if ( *r < 0 ) {
1273 if ( *r == -MINVECTOR ) sgn ^= 1;
1277 else { *m++ = *r++; *m++ = *r++; }
1286 mf[1] = WORDDIF(m,mf);
1290 for ( k = 0; k < i-1; k++ ) {
1291 if ( arg[k] == 0 )
continue;
1293 while ( k < i-1 && EqualArg(parms,k,k+1) ) { k++; k1++; }
1294 while ( k2 <= k && arg[k2] == 1 ) k2++;
1299 if ( k2 != k1 && k2 != 0 ) {
1300 if ( GetBinom((UWORD *)m+3,m+2,k1,k2) ) {
1301 MLOCK(ErrorMessageLock);
1302 MesCall(
"DoDistrib");
1303 MUNLOCK(ErrorMessageLock);
1306 m[1] = ( m[2] < 0 ? -m[2]: m[2] ) + 3;
1314 while ( r < tstop ) *m++ = *r++;
1319 for ( j = 0; j < i && k > 0; j++ ) {
1320 if ( arg[j] == 1 ) k--;
1326 if ( sgn ) m[-1] = -m[-1];
1327 *termout = WORDDIF(m,termout);
1329 if ( AT.WorkPointer > AT.WorkTop ) {
1330 MLOCK(ErrorMessageLock);
1332 MUNLOCK(ErrorMessageLock);
1337 if (
Generator(BHEAD termout,level) ) Terminate(-1);
1343redok:
while ( arg[j] == 1 && j >= 0 ) { j--; k++; }
1344 while ( arg[j] == 0 && j >= 0 ) j--;
1348 while ( !atype && EqualArg(parms,j,j+1) ) {
1350 if ( j >= i - k - 1 ) { j = k1; k++;
goto redok; }
1353 while ( k >= 0 ) { j++; arg[j] = 1; k--; }
1355 while ( j < i ) { arg[j] = 0; j++; }
1360 while ( arg[j] == 1 && j >= 0 ) { j--; k++; }
1361 while ( arg[j] == 0 && j >= 0 ) j--;
1364 while ( k >= 0 ) { j++; arg[j] = 1; k--; }
1366 while ( j < i ) { arg[j] = 0; j++; }
1369 }
while ( ntype == 0 && ++n <= i );
1370 AT.WorkPointer = oldwork;
1381int EqualArg(WORD *parms, WORD num1, WORD num2)
1386 while ( --num1 >= 0 ) { NEXTARG(t1); }
1388 while ( --num2 >= 0 ) { NEXTARG(t2); }
1389 if ( *t1 != *t2 )
return(0);
1391 if ( *t1 <= -FUNCTION || t1[1] == t2[1] )
return(1);
1395 while ( --i >= 0 ) {
1396 if ( *t1 != *t2 )
return(0);
1407int DoDelta3(PHEAD WORD *term, WORD level)
1410 WORD *t, *m, *m1, *m2, *stopper, *tstop, *termout, *dels, *taken;
1411 WORD *ic, *jc, *factors;
1412 WORD num, num2, i, j, k, knum, a;
1413 AN.TeInFun = AR.TePos = 0;
1414 tstop = term + *term;
1415 stopper = tstop - ABS(tstop[-1]);
1417 while ( ( *t != DELTA3 || ((t[1]-FUNHEAD) & 1 ) != 0 ) && t < stopper )
1419 if ( t >= stopper ) {
1421 MLOCK(ErrorMessageLock);
1422 MesPrint(
"!>Internal error with dd_ function");
1423 MUNLOCK(ErrorMessageLock);
1427 m1 = t; m2 = t + t[1];
1428 num = t[1] - FUNHEAD;
1430 termout = t = AT.WorkPointer;
1432 while ( m < m1 ) *t++ = *m++;
1433 m = m2;
while ( m < tstop ) *t++ = *m++;
1434 *termout = WORDDIF(t,termout);
1439 MLOCK(ErrorMessageLock);
1441 MUNLOCK(ErrorMessageLock);
1444 AT.WorkPointer = termout;
1451 for ( i = 1; i < num; i++ ) {
1452 if ( t[i] < t[i-1] ) {
1453 a = t[i]; t[i] = t[i-1]; t[i-1] = a;
1456 if ( t[j] >= t[j-1] )
break;
1457 a = t[j]; t[j] = t[j-1]; t[j-1] = a;
1467 m = taken = AT.WorkPointer;
1468 for ( i = 0; i < num; i++ ) *m++ = 0;
1470 for ( i = 0; i < num; knum++ ) {
1471 *m++ = t[i]; i++; taken[knum] = 1;
1473 if ( t[i] != t[i-1] )
break;
1474 i++; (taken[knum])++;
1477 for ( i = 0; i < knum; i++ ) *m++ = taken[i];
1478 ic = m; num2 = num/2;
1480 factors = jc + num2;
1481 termout = factors + num2;
1488 t = termout; m = term;
1489 while ( m < m1 ) *t++ = *m++;
1490 *t++ = DELTA; *t++ = num+2;
1491 for ( i = 0; i < num2; i++ ) {
1492 *t++ = dels[ic[i]]; *t++ = dels[jc[i]];
1494 for ( i = 0; i < num2; i++ ) {
1495 if ( ic[i] == jc[i] ) {
1497 while ( i < num2-1 && ic[i] == ic[i+1] && ic[i] == jc[i+1] )
1499 for ( a = 1; a < j; a++ ) {
1500 *t++ = SNUMBER; *t++ = 4; *t++ = 2*a+1; *t++ = 1;
1502 for ( a = 0; a+1+i < num2; a++ ) {
1503 if ( ic[a+i] != ic[a+i+1] )
break;
1506 if ( GetBinom((UWORD *)(t+3),t+2,2*j+a,a) ) {
1507 MLOCK(ErrorMessageLock);
1509 MUNLOCK(ErrorMessageLock);
1512 t[1] = ( t[2] < 0 ? -t[2]: t[2] ) + 3;
1517 else if ( factors[i] != 1 ) {
1518 *t++ = SNUMBER; *t++ = 4; *t++ = factors[i]; *t++ = 1;
1521 for ( i = 0; i < num2-1; i++ ) {
1522 if ( ic[i] == jc[i] )
continue;
1524 while ( i < num2-1 && jc[i] == jc[i+1] && ic[i] == ic[i+1] ) {
1527 for ( a = 0; a+i < num2-1; a++ ) {
1528 if ( ic[i+a] != ic[i+a+1] )
break;
1531 if ( GetBinom((UWORD *)(t+3),t+2,j+a,a) ) {
1532 MLOCK(ErrorMessageLock);
1534 MUNLOCK(ErrorMessageLock);
1537 t[1] = ( t[2] < 0 ? -t[2]: t[2] ) + 3;
1543 while ( m < tstop ) *t++ = *m++;
1544 *termout = WORDDIF(t,termout);
1549 MLOCK(ErrorMessageLock);
1551 MUNLOCK(ErrorMessageLock);
1555 if ( k >= 0 )
goto nextj;
1558 for ( ic[k] = 0; ic[k] < knum; ic[k]++ ) {
1559 if ( taken[ic[k]] > 0 )
break;
1561 if ( k > 0 && ic[k-1] == ic[k] ) jc[k] = jc[k-1];
1563 for ( ; jc[k] < knum; jc[k]++ ) {
1564 if ( taken[jc[k]] <= 0 )
continue;
1565 if ( ic[k] == jc[k] ) {
1566 if ( taken[jc[k]] <= 1 )
continue;
1574 factors[k] = taken[jc[k]];
1575 (taken[ic[k]])--; (taken[jc[k]])--;
1580 (taken[ic[k]])++; (taken[jc[k]])++;
1583 if ( k >= 0 )
goto nextj;
1586 AT.WorkPointer = taken;
1611int TestPartitions(WORD *tfun,
PARTI *parti)
1613 WORD *tnext = tfun + tfun[1];
1615 WORD argcount = 0, sum = 0, i, ipart, argremain;
1616 WORD tensorflag = 0;
1617 parti->psize = parti->nfun = parti->args = parti->nargs = 0;
1618 parti->numargs = parti->numpart = parti->where = 0;
1619 tt = t = tfun + FUNHEAD;
1620 while ( t < tnext ) { argcount++; NEXTARG(t); }
1621 if ( argcount < 1 )
goto No;
1623 if ( *t != -SNUMBER )
goto No;
1626 if ( *t <= -FUNCTION && t[1] == -SNUMBER && t[2] > 0 ) {
1627 if ( functions[-*t-FUNCTION].spec > 0 ) tensorflag = 1;
1628 if ( argcount-3 < 0 )
goto No;
1629 if ( ( (argcount-3) % t[2] ) != 0 )
goto No;
1632 parti->numpart = (argcount-3)/t[2];
1633 parti->numargs = argcount - 3;
1634 parti->psize = (WORD *)Malloc1((parti->numpart*2+parti->numargs*2+2)
1635 *
sizeof(WORD),
"partitions");
1636 parti->nfun = parti->psize + parti->numpart;
1637 parti->args = parti->nfun + parti->numpart;
1638 parti->nargs = parti->args + parti->numargs;
1639 for ( i = 0; i < parti->numpart; i++ ) {
1640 parti->psize[i] = t[2];
1641 parti->nfun[i] = -t[0];
1645 else if ( t[1] > 0 ) {
1654 parti->numpart = t[1]; t += 2;
1655 ipart = sum = 0; argremain = argcount - 1;
1660 parti->psize = (WORD *)Malloc1((argcount*4+2)*
sizeof(WORD),
"partitions");
1661 parti->nfun = parti->psize+argcount;
1662 parti->args = parti->nfun+argcount;
1663 parti->nargs = parti->args+argcount;
1664 while ( ipart < parti->numpart ) {
1665 if ( *t <= -FUNCTION && t[1] == -SNUMBER && t[2] >= 0 ) {
1666 if ( functions[-*t-FUNCTION].spec > 0 ) tensorflag = 1;
1668 if ( ipart+1 != parti->numpart )
goto WhatAPity;
1670 parti->nfun[ipart] = -*t;
1671 parti->psize[ipart++] = argremain-sum;
1676 parti->nfun[ipart] = -*t;
1677 parti->psize[ipart++] = t[2];
1683 else if ( *t == -SNUMBER && t[1] > 0 && ipart+t[1] <= parti->numpart
1684 && t[2] <= -FUNCTION && t[3] == -SNUMBER && t[4] > 0 ) {
1685 if ( functions[-t[2]-FUNCTION].spec > 0 ) tensorflag = 1;
1687 for ( i = 0; i < t[1]; i++ ) {
1688 parti->nfun[ipart] = -t[2];
1689 parti->psize[ipart++] = t[4];
1692 if ( sum > argremain )
goto WhatAPity;
1695 else goto WhatAPity;
1697 if ( sum != argremain )
goto WhatAPity;
1698 parti->numargs = argremain;
1704 for ( i = 0; i < parti->numargs; i++ ) {
1705 parti->args[i] = t - tfun;
1706 if ( tensorflag && ( *t != -VECTOR && *t != -INDEX ) )
goto WhatAPity;
1711 M_free(parti->psize,
"partitions");
1712 parti->psize = parti->nfun = parti->args = parti->nargs = 0;
1713 parti->numargs = parti->numpart = parti->where = 0;
1726int DoPartitions(PHEAD WORD *term, WORD level)
1728 WORD x, i, j, im, *fun, ndiff, siz, tensorflag = 0;
1729 PARTI part = AT.partitions;
1730 WORD *array, **j3, **j3fill, **j3where;
1731 WORD a, pfill, *j2, *j2fill, j3size, ncoeff, ncoeffnum, nfac, ncoeff2, ncoeff3, n;
1732 UWORD *coeff, *coeffnum, *cfac, *coeff2, *coeff3, *c;
1734 AT.partitions.psize = AT.partitions.nfun = AT.partitions.args = AT.partitions.nargs = 0;
1735 AT.partitions.numargs = AT.partitions.numpart = AT.partitions.where = 0;
1739 fun = term + part.where;
1740 if ( functions[*fun-FUNCTION].spec > 0 ) tensorflag = 1;
1741 for ( i = 1; i < part.numargs; i++ ) {
1742 for ( j = i-1; j >= 0; j-- ) {
1743 if ( CompArg(fun+part.args[j+1],fun+part.args[j]) >= 0 )
break;
1744 x = part.args[j+1]; part.args[j+1] = part.args[j]; part.args[j] = x;
1747 for ( i = 1; i < part.numpart; i++ ) {
1748 for ( j = i-1; j >= 0; j-- ) {
1749 if ( part.psize[j+1] < part.psize[j] )
break;
1750 if ( part.psize[j+1] == part.psize[j] && part.nfun[j+1] <= part.nfun[j] )
break;
1751 x = part.psize[j+1]; part.psize[j+1] = part.psize[j]; part.psize[j] = x;
1752 x = part.nfun[j+1]; part.nfun[j+1] = part.nfun[j]; part.nfun[j] = x;
1761 ndiff = 1; part.nargs[0] = ndiff;
1762 for ( i = 1; i < part.numargs; i++ ) {
1763 if ( CompArg(fun+part.args[i],fun+part.args[i-1]) != 0 ) ndiff++;
1764 part.nargs[i] = ndiff;
1766 part.nargs[part.numargs] = 0;
1767 coeffnum = NumberMalloc(
"partitionsn");
1768 coeff = NumberMalloc(
"partitions");
1769 coeff2 = NumberMalloc(
"partitions2");
1770 coeff3 = NumberMalloc(
"partitions3");
1771 cfac = NumberMalloc(
"partitions!");
1772 ncoeffnum = 1; coeffnum[0] = 1;
1778 for ( i = 1; i <= ndiff; i++ ) {
1780 while ( part.nargs[j] == i ) { n++; j++; }
1782 if ( Factorial(BHEAD n, cfac, &nfac) ) Terminate(-1);
1783 if ( MulLong(coeffnum,ncoeffnum,cfac,nfac,coeff2,&ncoeff2) ) Terminate(-1);
1784 c = coeffnum; coeffnum = coeff2; coeff2 = c;
1785 n = ncoeffnum; ncoeffnum = ncoeff2; ncoeff2 = n;
1806 siz = part.psize[0];
1807 j3size = 2*(part.numpart+1)+2*(part.numargs+1);
1808 array = (WORD *)Malloc1((part.numpart+1)*siz*
sizeof(WORD),
"parts");
1809 j3 = (WORD **)Malloc1(j3size*
sizeof(WORD *),
"parts3");
1810 j2 = (WORD *)Malloc1((part.numpart+part.numargs+2)*
sizeof(WORD),
"parts2");
1811 j3fill = j3+(part.numpart+1);
1812 j3where = j3fill+(part.numpart+1);
1813 for ( i = 0; i < j3size; i++ ) j3[i] = 0;
1814 j2fill = j2+(part.numpart+1);
1815 for ( i = 0; i < part.numargs; i++ ) j2fill[i] = 0;
1816 for ( i = 0; i < part.numpart; i++ ) {
1817 j3[i] = array+i*siz;
1818 for ( j = 0; j < siz; j++ ) j3[i][j] = 0;
1819 j3fill[i] = j3[i]+(siz-part.psize[i]);
1820 j2[i] = part.psize[i];
1822 j3[part.numpart] = array+part.numpart*siz;
1823 j2[part.numpart] = 0;
1833 while ( a < part.numargs ) {
1834 while ( j2[pfill] <= 0 ) {
1836 while ( pfill >= part.numpart ) {
1838 if ( a >= part.numargs )
goto Done;
1846 j3where[a] = j3fill[pfill];
1847 *(j3fill[pfill])++ = part.nargs[a];
1848 j2[pfill]--; j2fill[a] = pfill;
1852 if ( pfill > 0 && part.psize[pfill] == part.psize[pfill-1]
1853 && part.nfun[pfill] == part.nfun[pfill-1] ) {
1854 for ( im = 0; im < siz; im++ ) {
1855 if ( j3[pfill-1][im] < j3[pfill][im] )
break;
1856 if ( j3[pfill-1][im] > j3[pfill][im] ) im = siz;
1877 WORD *t, *to, *twhere = term+part.where, *t2, *tend = term+*term, *termout;
1878 WORD num, jj, *targ, *tfun;
1879 t2 = twhere+twhere[1];
1880 to = termout = AT.WorkPointer;
1881 if ( termout + *term + part.numpart*FUNHEAD + AM.MaxTal >= AT.WorkTop ) {
1884 for ( i = 0; i < ncoeffnum; i++ ) coeff[i] = coeffnum[i];
1886 t = term;
while ( t < twhere ) *to++ = *t++;
1890 for ( i = 0; i < part.numpart; i++ ) {
1892 *to++ = part.nfun[i]; to++; FILLFUN(to);
1893 for ( j = 1; j <= part.psize[i]; j++ ) {
1895 for ( jj = num-1; jj < part.numargs; jj++ ) {
1896 if ( part.nargs[jj] == num )
break;
1898 targ = part.args[jj]+twhere;
1900 if ( tensorflag ) targ++;
1901 else if ( *targ > -FUNCTION ) *to++ = *targ++;
1904 else { jj = *targ; NCOPY(to,targ,jj); }
1906 tfun[1] = to - tfun;
1913 while ( j < part.numpart ) {
1914 for ( im = 0; im < siz; im++ ) {
1915 if ( part.nfun[j-1] != part.nfun[j] )
break;
1916 if ( j3[j-1][im] < j3[j][im] )
break;
1917 if ( j3[j-1][im] > j3[j][im] ) im = 2*siz+2;
1919 if ( im == siz ) { n++; j++;
continue; }
1921div1:
if ( Factorial(BHEAD n, cfac, &nfac) ) Terminate(-1);
1922 if ( DivLong(coeff,ncoeff,cfac,nfac,coeff2,&ncoeff2,coeff3,&ncoeff3) ) Terminate(-1);
1923 c = coeff; coeff = coeff2; coeff2 = c;
1924 n = ncoeff; ncoeff = ncoeff2; ncoeff2 = n;
1928 if ( n > 1 )
goto div1;
1932 for ( i = 0; i < part.numpart; i++ ) {
1933 j = 0;
while ( j3[i][j] == 0 ) j++;
1936 if ( j3[i][j-1] == j3[i][j] ) { n++; j++; }
1939div2:
if ( Factorial(BHEAD n, cfac, &nfac) ) Terminate(-1);
1940 if ( DivLong(coeff,ncoeff,cfac,nfac,coeff2,&ncoeff2,coeff3,&ncoeff3) ) Terminate(-1);
1941 c = coeff; coeff = coeff2; coeff2 = c;
1942 n = ncoeff; ncoeff = ncoeff2; ncoeff2 = n;
1947 if ( n > 1 )
goto div2;
1952 if ( ncoeff != 1 || coeff[0] > 1 ) {
1953 if ( ncoeff == 1 && coeff[0] <= MAXPOSITIVE ) {
1954 *to++ = SNUMBER; *to++ = 4; *to++ = (WORD)(coeff[0]); *to++ = 1;
1957 *to++ = LNUMBER; *to++ = ncoeff+3; *to++ = ncoeff;
1958 for ( i = 0; i < ncoeff; i++ ) *to++ = ((WORD *)coeff)[i];
1964 while ( t2 < tend ) *to++ = *t2++;
1965 *termout = to-termout;
1966 AT.WorkPointer = to;
1967 if (
Generator(BHEAD termout,level) ) Terminate(-1);
1968 AT.WorkPointer = termout;
1975 while ( part.nargs[a] == 1 ) {
1976 pfill = j2fill[a]; j2[pfill]++; j3where[a][0] = 0; j3fill[pfill]--; a++;
1978 if ( a < part.numargs ) {
1979 pfill = j2fill[a]; j2[pfill]++; j3where[a][0] = 0; j3fill[pfill]--; a++;
1984 else if ( part.nargs[a] == part.nargs[a+1] ) {}
1988 M_free(j2,
"parts2");
1989 M_free(j3,
"parts3");
1990 M_free(array,
"parts");
1991 NumberFree(cfac,
"partitions!");
1992 NumberFree(coeff3,
"partitions3");
1993 NumberFree(coeff2,
"partitions2");
1994 NumberFree(coeff,
"partitions");
1995 NumberFree(coeffnum,
"partitionsn");
1996 M_free(part.psize,
"partitions");
1997 part.psize = part.nfun = part.args = part.nargs = 0;
1998 part.numargs = part.numpart = part.where = 0;
2011int DoPermutations(PHEAD WORD *term, WORD level)
2014 WORD *oldworkpointer = AT.WorkPointer, *termout = AT.WorkPointer;
2015 WORD *t, *tstop, *tt, *ttstop, odd = 0;
2016 WORD *args[MAXMATCH], nargs, i, first, skip, *to, *from;
2020 tstop = term+*term; tstop -= ABS(tstop[-1]);
2022 while ( t < tstop ) {
2023 if ( *t == PERMUTATIONS ) {
2024 if ( t[1] >= FUNHEAD+1 && t[FUNHEAD] <= -FUNCTION ) {
2027 else if ( t[1] >= FUNHEAD+3 && t[FUNHEAD] == -SNUMBER && t[FUNHEAD+2] <= -FUNCTION ) {
2028 if ( t[FUNHEAD+1] % 2 == 1 ) odd = -1;
2032 else { t += t[1];
continue; }
2033 tt = t+FUNHEAD+skip; ttstop = t + t[1];
2035 while ( tt < ttstop ) { NEXTARG(tt); nargs++; }
2036 tt = t+FUNHEAD+skip;
2037 if ( nargs > MAXMATCH ) {
2038 MLOCK(ErrorMessageLock);
2039 MesPrint(
"Too many arguments in function perm_. %d! is way too big",(WORD)MAXMATCH);
2040 MUNLOCK(ErrorMessageLock);
2044 while ( tt < ttstop ) { args[i++] = tt; NEXTARG(tt); }
2047 perm.objects = args;
2049 while ( (first = PermuteP(&perm,first) ) == 0 ) {
2053 to = termout; from = term;
2054 while ( from < t ) *to++ = *from++;
2055 *to++ = -t[FUNHEAD+skip-1];
2056 *to++ = t[1] - skip;
2057 for ( i = 2; i < FUNHEAD; i++ ) *to++ = t[i];
2058 for ( i = 0; i < nargs; i++ ) {
2063 tstop = term + *term;
2064 while ( from < tstop ) *to++ = *from++;
2065 if ( odd && ( ( perm.sign & 1 ) != 0 ) ) to[-1] = -to[-1];
2066 *termout = to - termout;
2067 AT.WorkPointer = to;
2068 if (
Generator(BHEAD termout,level) ) Terminate(-1);
2069 AT.WorkPointer = oldworkpointer;
2099int DoShuffle(WORD *term, WORD level, WORD fun, WORD option)
2103 WORD *t1, *t2, *tstop, ncoef, n = fun, *to, *from;
2109 if ( ( n = DolToFunction(BHEAD -n) ) == 0 ) {
2110 MLOCK(ErrorMessageLock);
2111 MesPrint(
"$-variable in merge statement did not evaluate to a function.");
2112 MUNLOCK(ErrorMessageLock);
2116 if ( AT.WorkPointer + 3*(*term) + AM.MaxTal > AT.WorkTop ) {
2117 MLOCK(ErrorMessageLock);
2119 MUNLOCK(ErrorMessageLock);
2123 tstop = term + *term;
2125 tstop -= ABS(ncoef);
2127 while ( t1 < tstop ) {
2128 if ( ( *t1 == n ) && ( t1+t1[1] < tstop ) && ( t1[1] > FUNHEAD ) ) {
2130 if ( t2 >= tstop ) {
2133 while ( t2 < tstop ) {
2134 if ( ( *t2 == n ) && ( t2[1] > FUNHEAD ) )
break;
2137 if ( t2 < tstop )
break;
2141 if ( t1 >= tstop ) {
2151 SH->finishuf = &FinishShuffle;
2152 SH->do_uffle = &DoShuffle;
2153 SH->outterm = AT.WorkPointer;
2154 AT.WorkPointer += *term;
2155 SH->stop1 = t1 + t1[1];
2156 SH->stop2 = t2 + t2[1];
2157 SH->thefunction = n;
2158 SH->option = option;
2161 SH->nincoef = ncoef;
2163 if ( AN.SHcombi == 0 || AN.SHcombisize == 0 ) {
2164 AN.SHcombisize = 200;
2165 AN.SHcombi = (UWORD *)Malloc1(AN.SHcombisize*
sizeof(UWORD),
"AN.SHcombi");
2167 SHback.combilast = 0;
2170 SH->combilast += AN.SHcombi[SH->combilast]+1;
2171 if ( SH->combilast >= AN.SHcombisize - 100 ) {
2172 newcombi = (UWORD *)Malloc1(2*AN.SHcombisize*
sizeof(UWORD),
"AN.SHcombi");
2173 for ( k = 0; k < AN.SHcombisize; k++ ) newcombi[k] = AN.SHcombi[k];
2174 M_free(AN.SHcombi,
"AN.SHcombi");
2175 AN.SHcombi = newcombi;
2176 AN.SHcombisize *= 2;
2179 AN.SHcombi[SH->combilast] = 1;
2180 AN.SHcombi[SH->combilast+1] = 1;
2182 i = t1-term; to = SH->outterm; from = term;
2185 for ( i = 0; i < FUNHEAD; i++ ) { *to++ = t1[i]; }
2187 error = Shuffle(t1+FUNHEAD,t2+FUNHEAD,to);
2189 AT.WorkPointer = SH->outterm;
2192 MesCall(
"DoShuffle");
2233int Shuffle(WORD *from1, WORD *from2, WORD *to)
2236 WORD *t, *fr, *next1, *next2, na, *fn1, *fn2, *tt;
2237 int i, n, n1, n2, j;
2240 if ( from1 == SH->stop1 && from2 == SH->stop2 ) {
2241 return(FiniShuffle(to));
2243 else if ( from1 == SH->stop1 ) {
2244 i = SH->stop2 - from2; t = to; tt = from2; NCOPY(t,tt,i)
2245 return(FiniShuffle(t));
2247 else if ( from2 == SH->stop2 ) {
2248 i = SH->stop1 - from1; t = to; tt = from1; NCOPY(t,tt,i)
2249 return(FiniShuffle(t));
2254 if ( AreArgsEqual(from1,from2) ) {
2258 next1 = from1; n1 = 1; NEXTARG(next1)
2259 while ( ( next1 < SH->stop1 ) && AreArgsEqual(from1,next1) ) {
2260 n1++; NEXTARG(next1)
2262 next2 = from2; n2 = 1; NEXTARG(next2)
2263 while ( ( next2 < SH->stop2 ) && AreArgsEqual(from2,next2) ) {
2264 n2++; NEXTARG(next2)
2266 combilast = SH->combilast;
2272 while ( --n >= 0 ) { fr = from1; CopyArg(t,fr) }
2273 if ( GetBinom((UWORD *)(t),&na,n1+n2,n1) )
goto shuffcall;
2274 if ( combilast + AN.SHcombi[combilast] + na + 2 >= AN.SHcombisize ) {
2282 UWORD *combi = (UWORD *)Malloc1(2*AN.SHcombisize*2,
"AN.SHcombi");
2284 for ( jj = 0; jj < AN.SHcombisize; jj++ ) combi[jj] = AN.SHcombi[jj];
2285 AN.SHcombisize *= 2;
2286 M_free(AN.SHcombi,
"AN.SHcombi");
2289 if ( MulLong((UWORD *)(AN.SHcombi+combilast+1),AN.SHcombi[combilast],
2291 (UWORD *)(AN.SHcombi+combilast+AN.SHcombi[combilast]+2),
2292 (WORD *)(AN.SHcombi+combilast+AN.SHcombi[combilast]+1)) )
goto shuffcall;
2293 SH->combilast = combilast + AN.SHcombi[combilast] + 1;
2294 if ( next1 >= SH->stop1 ) {
2295 fr = next2; i = SH->stop2 - fr;
2297 if ( FiniShuffle(t) )
goto shuffcall;
2299 else if ( next2 >= SH->stop2 ) {
2300 fr = next1; i = SH->stop1 - fr;
2302 if ( FiniShuffle(t) )
goto shuffcall;
2305 if ( Shuffle(next1,next2,t) )
goto shuffcall;
2307 SH->combilast = combilast;
2312 if ( next2 < SH->stop2 ) {
2315 while ( --n >= 0 ) { fr = from1; CopyArg(t,fr) }
2316 for ( j = 0; j < n1; j++ ) {
2317 if ( GetBinom((UWORD *)(t),&na,n2+j,j) )
goto shuffcall;
2318 if ( MulLong((UWORD *)(AN.SHcombi+combilast+1),AN.SHcombi[combilast],
2320 (UWORD *)(AN.SHcombi+combilast+AN.SHcombi[combilast]+2),
2321 (WORD *)(AN.SHcombi+combilast+AN.SHcombi[combilast]+1)) )
goto shuffcall;
2322 SH->combilast = combilast + AN.SHcombi[combilast] + 1;
2323 if ( j > 0 ) { fr = from1; CopyArg(t,fr) }
2324 fn2 = next2; tt = t;
2327 if ( fn2 >= SH->stop2 ) {
2329 while ( --n >= 0 ) { fr = from1; CopyArg(tt,fr) }
2330 fr = next1; i = SH->stop1 - fr;
2332 if ( FiniShuffle(tt) )
goto shuffcall;
2335 n = j; fn1 = from1;
while ( --n >= 0 ) { NEXTARG(fn1) }
2336 if ( Shuffle(fn1,fn2,tt) )
goto shuffcall;
2338 SH->combilast = combilast;
2345 if ( next1 < SH->stop1 ) {
2348 while ( --n >= 0 ) { fr = from1; CopyArg(t,fr) }
2349 for ( j = 0; j < n2; j++ ) {
2350 if ( GetBinom((UWORD *)(t),&na,n1+j,j) )
goto shuffcall;
2351 if ( MulLong((UWORD *)(AN.SHcombi+combilast+1),AN.SHcombi[combilast],
2353 (UWORD *)(AN.SHcombi+combilast+AN.SHcombi[combilast]+2),
2354 (WORD *)(AN.SHcombi+combilast+AN.SHcombi[combilast]+1)) )
goto shuffcall;
2355 SH->combilast = combilast + AN.SHcombi[combilast] + 1;
2356 if ( j > 0 ) { fr = from1; CopyArg(t,fr) }
2357 fn1 = next1; tt = t;
2360 if ( fn1 >= SH->stop1 ) {
2362 while ( --n >= 0 ) { fr = from1; CopyArg(tt,fr) }
2363 fr = next2; i = SH->stop2 - fr;
2365 if ( FiniShuffle(tt) )
goto shuffcall;
2368 n = j; fn2 = from2;
while ( --n >= 0 ) { NEXTARG(fn2) }
2369 if ( Shuffle(fn1,fn2,tt) )
goto shuffcall;
2371 SH->combilast = combilast;
2382 if ( fr >= SH->stop1 ) {
2383 fr = from2; i = SH->stop2 - fr;
2385 if ( FiniShuffle(t) )
goto shuffcall;
2388 if ( Shuffle(fr,from2,t) )
goto shuffcall;
2396 if ( fr >= SH->stop2 ) {
2397 fr = from1; i = SH->stop1 - fr;
2399 if ( FiniShuffle(t) )
goto shuffcall;
2402 if ( Shuffle(from1,fr,t) )
goto shuffcall;
2425int FinishShuffle(WORD *fini)
2428 WORD *t, *t1, *oldworkpointer = AT.WorkPointer, *tcoef, ntcoef, *out;
2431 SH->outfun[1] = fini - SH->outfun;
2432 if ( functions[SH->outfun[0]-FUNCTION].symmetric != 0 )
2433 SH->outfun[2] |= DIRTYSYMFLAG;
2434 out = fini; i = fini - SH->outterm; t = SH->outterm;
2438 while ( t1 < SH->stop2 ) { t = t1; t1 = t + t[1]; }
2440 while ( t1 < t ) *fini++ = *t1++;
2442 while ( t < SH->incoef ) *fini++ = *t++;
2444 ntcoef = SH->nincoef;
2447 ntcoef = REDLENG(ntcoef);
2448 Mully(BHEAD (UWORD *)tcoef,&ntcoef,
2449 (UWORD *)(AN.SHcombi+SH->combilast+1),AN.SHcombi[SH->combilast]);
2450 ntcoef = INCLENG(ntcoef);
2451 fini = tcoef + ABS(ntcoef);
2452 if ( ( ( SH->option & 2 ) != 0 ) && ( ( SH->option & 256 ) != 0 ) ) ntcoef = -ntcoef;
2454 i = *out = fini - out;
2458 AT.WorkPointer = out + *out;
2459 if ( ( SH->option & 1 ) == 1 ) {
2460 if (
Generator(BHEAD out,SH->level) )
goto Finicall;
2463 if ( DoShtuffle(out,SH->level,SH->thefunction,SH->option) )
goto Finicall;
2465 AT.WorkPointer = oldworkpointer;
2468 AT.WorkPointer = oldworkpointer;
2469 MesCall(
"FinishShuffle");
2491int DoStuffle(WORD *term, WORD level, WORD fun, WORD option)
2495 WORD *t1, *t2, *tstop, *t1stop, *t2stop, ncoef, n = fun, *to, *from;
2501 WORD *rr1, *rr2, i1, i2;
2504 if ( ( n = DolToFunction(BHEAD -n) ) == 0 ) {
2505 MLOCK(ErrorMessageLock);
2506 MesPrint(
"$-variable in merge statement did not evaluate to a function.");
2507 MUNLOCK(ErrorMessageLock);
2511 if ( AT.WorkPointer + 3*(*term) + AM.MaxTal > AT.WorkTop ) {
2512 MLOCK(ErrorMessageLock);
2514 MUNLOCK(ErrorMessageLock);
2518 tstop = term + *term;
2520 tstop -= ABS(ncoef);
2523 while ( t1 < tstop ) {
2524 if ( ( *t1 == n ) && ( t1+t1[1] < tstop ) && ( t1[1] > FUNHEAD ) ) {
2526 if ( t2 >= tstop ) {
2530 while ( t2 < tstop ) {
2531 if ( ( *t2 == n ) && ( t2[1] > FUNHEAD ) )
break;
2534 if ( t2 < tstop )
break;
2538 if ( t1 >= tstop ) {
2546 t1stop = t1 + t1[1];
2548 while ( r1 < t1stop ) {
2549 if ( *r1 != -SNUMBER )
break;
2550 if ( r1[1] == 0 )
break;
2553 if ( r1 < t1stop ) { t1 = t2;
goto retry1; }
2554 t2stop = t2 + t2[1];
2556 while ( r2 < t2stop ) {
2557 if ( *r2 != -SNUMBER )
break;
2558 if ( r2[1] == 0 )
break;
2561 if ( r2 < t2stop ) { t2 = t2 + t2[1];
goto retry2; }
2563 t1stop = t1 + t1[1];
2565 while ( r1 < t1stop ) {
2566 if ( *r1 == -SNUMBER ) {
2567 if ( r1[1] == 0 )
break;
2570 else if ( *r1 == -SYMBOL ) {
2571 if ( ( symbols[r1[1]].complex & VARTYPEROOTOFUNITY ) != VARTYPEROOTOFUNITY )
2575 if ( *r1 > 0 && *r1 == r1[ARGHEAD]+ARGHEAD ) {
2576 if ( ABS(r1[r1[0]-1]) == r1[0]-ARGHEAD-1 ) {}
2577 else if ( r1[ARGHEAD+1] == SYMBOL ) {
2578 rr1 = r1 + ARGHEAD + 3;
2581 if ( ( symbols[*rr1].complex & VARTYPEROOTOFUNITY ) != VARTYPEROOTOFUNITY )
2585 if ( i1 > 0 )
break;
2589 i1 = (ABS(*rr1)-1)/2;
2591 if ( rr1[-1] )
break;
2594 if ( i1 > 1 || rr1[-1] != 1 )
break;
2599 if ( r1 < t1stop ) { t1 = t2;
goto retry1; }
2600 t2stop = t2 + t2[1];
2603 while ( r2 < t2stop ) {
2604 if ( *r2 == -SNUMBER ) {
2605 if ( r2[1] == 0 )
break;
2608 else if ( *r2 == -SYMBOL ) {
2609 if ( ( symbols[r2[1]].complex & VARTYPEROOTOFUNITY ) != VARTYPEROOTOFUNITY )
2613 if ( *r2 > 0 && *r2 == r2[ARGHEAD]+ARGHEAD ) {
2614 if ( ABS(r2[r2[0]-1]) == r2[0]-ARGHEAD-1 ) {}
2615 else if ( r2[ARGHEAD+1] == SYMBOL ) {
2616 rr2 = r2 + ARGHEAD + 3;
2619 if ( ( symbols[*rr2].complex & VARTYPEROOTOFUNITY ) != VARTYPEROOTOFUNITY )
2623 if ( i2 > 0 )
break;
2627 i2 = (ABS(*rr2)-1)/2;
2629 if ( rr2[-1] )
break;
2632 if ( i2 > 1 || rr2[-1] != 1 )
break;
2637 if ( r2 < t2stop ) { t2 = t2 + t2[1];
goto retry2; }
2645 SH->finishuf = &FinishStuffle;
2646 SH->do_uffle = &DoStuffle;
2647 SH->outterm = AT.WorkPointer;
2648 AT.WorkPointer += *term;
2649 SH->ststop1 = t1 + t1[1];
2650 SH->ststop2 = t2 + t2[1];
2651 SH->thefunction = n;
2652 SH->option = option;
2655 SH->nincoef = ncoef;
2656 if ( AN.SHcombi == 0 || AN.SHcombisize == 0 ) {
2657 AN.SHcombisize = 200;
2658 AN.SHcombi = (UWORD *)Malloc1(AN.SHcombisize*
sizeof(UWORD),
"AN.SHcombi");
2660 SHback.combilast = 0;
2663 SH->combilast += AN.SHcombi[SH->combilast]+1;
2664 if ( SH->combilast >= AN.SHcombisize - 100 ) {
2665 newcombi = (UWORD *)Malloc1(2*AN.SHcombisize*
sizeof(UWORD),
"AN.SHcombi");
2666 for ( k = 0; k < AN.SHcombisize; k++ ) newcombi[k] = AN.SHcombi[k];
2667 M_free(AN.SHcombi,
"AN.SHcombi");
2668 AN.SHcombi = newcombi;
2669 AN.SHcombisize *= 2;
2672 AN.SHcombi[SH->combilast] = 1;
2673 AN.SHcombi[SH->combilast+1] = 1;
2675 i = t1-term; to = SH->outterm; from = term;
2678 for ( i = 0; i < FUNHEAD; i++ ) { *to++ = t1[i]; }
2680 error = Stuffle(t1+FUNHEAD,t2+FUNHEAD,to);
2682 AT.WorkPointer = SH->outterm;
2685 MesCall(
"DoStuffle");
2706int Stuffle(WORD *from1, WORD *from2, WORD *to)
2709 WORD *t, *tf, *next1, *next2, *st1, *st2, *save1, *save2;
2715 save1 = SH->stop1; save2 = SH->stop2;
2716 if ( from1 >= SH->ststop1 && from2 == SH->ststop2 ) {
2717 SH->stop1 = SH->ststop1;
2718 SH->stop2 = SH->ststop2;
2719 retval = FinishShuffle(to);
2720 SH->stop1 = save1; SH->stop2 = save2;
2723 else if ( from1 >= SH->ststop1 ) {
2724 i = SH->ststop2 - from2; t = to; tf = from2; NCOPY(t,tf,i)
2725 SH->stop1 = SH->ststop1;
2726 SH->stop2 = SH->ststop2;
2727 retval = FinishShuffle(t);
2728 SH->stop1 = save1; SH->stop2 = save2;
2731 else if ( from2 >= SH->ststop2 ) {
2732 i = SH->ststop1 - from1; t = to; tf = from1; NCOPY(t,tf,i)
2733 SH->stop1 = SH->ststop1;
2734 SH->stop2 = SH->ststop2;
2735 retval = FinishShuffle(t);
2736 SH->stop1 = save1; SH->stop2 = save2;
2742 SH->stop1 = SH->ststop1;
2743 SH->stop2 = SH->ststop2;
2744 SH->finishuf = &FinishShuffle;
2745 if ( Shuffle(from1,from2,to) )
goto stuffcall;
2746 SH->finishuf = &FinishStuffle;
2751 st1 = from1; next1 = st1+2;
2753 st1 = next1 = from1;
2756 while ( next1 <= SH->ststop1 ) {
2758 st2 = from2; next2 = st2+2;
2760 next2 = st2 = from2;
2763 while ( next2 <= SH->ststop2 ) {
2766 if ( st1 == from1 && st2 == from2 ) {
2769 *t++ = -SNUMBER; *t++ = StuffAdd(st1[1],st2[1]);
2771 t = StuffRootAdd(st1,st2,t);
2774 if ( Stuffle(next1,next2,t) )
goto stuffcall;
2777 else if ( st1 == from1 ) {
2779 t = to; tf = from2; NCOPY(t,tf,i)
2781 *t++ = -SNUMBER; *t++ = StuffAdd(st1[1],st2[1]);
2783 t = StuffRootAdd(st1,st2,t);
2786 if ( Stuffle(next1,next2,t) )
goto stuffcall;
2789 else if ( st2 == from2 ) {
2791 t = to; tf = from1; NCOPY(t,tf,i)
2793 *t++ = -SNUMBER; *t++ = StuffAdd(st1[1],st2[1]);
2795 t = StuffRootAdd(st1,st2,t);
2798 if ( Stuffle(next1,next2,t) )
goto stuffcall;
2802 if ( Shuffle(from1,from2,to) )
goto stuffcall;
2805 st2 = next2; next2 += 2;
2812 st1 = next1; next1 += 2;
2818 SH->stop1 = save1; SH->stop2 = save2;
2833int FinishStuffle(WORD *fini)
2838 WORD *next1 = SH->stop1, *next2 = SH->stop2;
2839 fini = StuffRootAdd(next1,next2,fini);
2841 *fini++ = -SNUMBER; *fini++ = StuffAdd(SH->stop1[1],SH->stop2[1]);
2847 if ( Stuffle(next1,next2,fini) )
goto stuffcall;
2849 if ( Stuffle(SH->stop1+2,SH->stop2+2,fini) )
goto stuffcall;
2854 MesCall(
"FinishStuffle");
2880WORD *StuffRootAdd(WORD *t1, WORD *t2, WORD *to)
2882 int type1, type2, type3, sgn, sgn1, sgn2, sgn3, pow, root, nosymbols, i;
2883 WORD *tt1, *tt2, it1, it2, *t3, *r, size1, size2, size3;
2886 if ( *t1 == -SNUMBER ) { type1 = 1;
if ( t1[1] < 0 ) sgn1 = -1;
else sgn1 = 1; }
2887 else if ( *t1 == -SYMBOL ) { type1 = 2; sgn1 = 1; }
2888 else if ( ABS(t1[*t1-1]) == *t1-ARGHEAD-1 ) {
2889 type1 = 3;
if ( t1[*t1-1] < 0 ) sgn1 = -1;
else sgn1 = 1; }
2890 else { type1 = 4;
if ( t1[*t1-1] < 0 ) sgn1 = -1;
else sgn1 = 1; }
2891 if ( *t2 == -SNUMBER ) { type2 = 1;
if ( t2[1] < 0 ) sgn2 = -1;
else sgn2 = 1; }
2892 else if ( *t2 == -SYMBOL ) { type2 = 2; sgn2 = 1; }
2893 else if ( ABS(t2[*t2-1]) == *t2-ARGHEAD-1 ) {
2894 type2 = 3;
if ( t2[*t2-1] < 0 ) sgn2 = -1;
else sgn2 = 1; }
2895 else { type2 = 4;
if ( t2[*t2-1] < 0 ) sgn2 = -1;
else sgn2 = 1; }
2896 if ( type1 > type2 ) {
2897 t3 = t1; t1 = t2; t2 = t3;
2898 type3 = type1; type1 = type2; type2 = type3;
2899 sgn3 = sgn1; sgn1 = sgn2; sgn2 = sgn3;
2901 nosymbols = 1; sgn3 = 1;
2907 if ( x > MAXPOSITIVE || x < -(MAXPOSITIVE+1) ) {
2908 if ( x < 0 ) { sgn1 = -3; x = -x; }
2913 *to++ = 4; *to++ = (UWORD)x; *to++ = 1; *to++ = sgn1;
2915 else { *to++ = -SNUMBER; *to++ = (WORD)x; }
2917 else if ( type2 == 2 ) {
2918 *to++ = ARGHEAD+8; *to++ = 0; FILLARG(to)
2919 *to++ = 8; *to++ = SYMBOL; *to++ = 4; *to++ = t2[1]; *to++ = 1;
2920 *to++ = ABS(t1[1])+1;
2924 else if ( type2 == 3 ) {
2925 tt1 = (WORD *)scratch; tt1[0] = ABS(t1[1]); size1 = 1;
2926 tt2 = t2+ARGHEAD+1; size2 = (ABS(t2[*t2-1])-1)/2;
2928 *to++ = 0; *to++ = 0; FILLARG(to) *to++ = 0;
2935 tt1 = (WORD *)scratch; tt1[0] = ABS(t1[1]); size1 = 1;
2936 tt2 = t2+ARGHEAD+1; tt2 += tt2[1]; size2 = (ABS(t2[*t2-1])-1)/2;
2937 t3 = to; i = tt2 - t2; r = t2;
2945 if ( t1[1] == t2[1] ) {
2946 if ( ( symbols[t1[1]].maxpower == 4 )
2947 && ( ( symbols[t1[1]].complex & VARTYPEMINUS ) == VARTYPEMINUS ) ) {
2948 *to++ = -SNUMBER; *to++ = -2;
2950 else if ( symbols[t1[1]].maxpower == 2 ) {
2951 *to++ = -SNUMBER; *to++ = 2;
2954 *to++ = ARGHEAD+8; *to++ = 0; FILLARG(to)
2955 *to++ = 8; *to++ = SYMBOL; *to++ = 4;
2956 *to++ = t1[1]; *to++ = 2;
2957 *to++ = 2; *to++ = 1; *to++ = 3;
2961 *to++ = ARGHEAD+10; *to++ = 0; FILLARG(to)
2962 *to++ = 10; *to++ = SYMBOL; *to++ = 6;
2963 if ( t1[1] < t2[1] ) {
2964 *to++ = t1[1]; *to++ = 1; *to++ = t2[1]; *to++ = 1;
2967 *to++ = t2[1]; *to++ = 1; *to++ = t1[1]; *to++ = 1;
2969 *to++ = 2; *to++ = 1; *to++ = 3;
2972 else if ( type2 == 3 ) {
2974 *to++ = 0; *to++ = 0; FILLARG(to) *to++ = 0;
2975 *to++ = SYMBOL; *to++ = 4; *to++ = t1[1]; *to++ = 1;
2976 tt1 = scratch; tt1[1] = 1; size1 = 1;
2977 tt2 = t2+ARGHEAD+1; size2 = (ABS(t2[*t2-1])-1)/2;
2982 tt1 = scratch; tt1[0] = 1; size1 = 1;
2984 *to++ = 0; *to++ = 0; FILLARG(to) *to++ = 0;
2985 *to++ = SYMBOL; *to++ = 0;
2986 tt2 = t2 + ARGHEAD+3; it2 = tt2[-1]-2;
2988 if ( *tt2 == t1[1] ) {
2990 root = symbols[*tt2].maxpower;
2991 if ( pow >= root ) pow -= root;
2992 if ( ( symbols[*tt2].complex & VARTYPEMINUS ) == VARTYPEMINUS ) {
2993 if ( ( root & 1 ) == 0 && pow >= root/2 ) {
2994 pow -= root/2; sgn3 = -sgn3;
2998 *to++ = *tt2; *to++ = pow;
3003 else if ( t1[1] < *tt2 ) {
3004 *to++ = t1[1]; *to++ = 1;
break;
3007 *to++ = *tt2++; *to++ = *tt2++; it2 -= 2;
3008 if ( it2 <= 0 ) { *to++ = t1[1]; *to++ = 1; }
3011 while ( it2 > 0 ) { *to++ = *tt2++; *to++ = *tt2++; it2 -= 2; }
3012 if ( (to - t3) > ARGHEAD+3 ) {
3013 t3[ARGHEAD+2] = (to-t3)-ARGHEAD-1;
3019 size2 = (ABS(t2[*t2-1])-1)/2;
3028 tt1 = t1+ARGHEAD+1; size1 = (ABS(t1[*t1-1])-1)/2;
3029 tt2 = t2+ARGHEAD+1; size2 = (ABS(t2[*t2-1])-1)/2;
3031 *to++ = 0; *to++ = 0; FILLARG(to) *to++ = 0;
3038 tt1 = t1+ARGHEAD+1; size1 = (ABS(t1[*t1-1])-1)/2;
3039 tt2 = t2+ARGHEAD+1; tt2 += tt2[1]; size2 = (ABS(t2[*t2-1])-1)/2;
3040 t3 = to; i = tt2 - t2; r = t2;
3051 tt1 = t1+ARGHEAD+3; it1 = tt1[-1]-2;
3052 tt2 = t2+ARGHEAD+3; it2 = tt2[-1]-2;
3054 *to++ = 0; *to++ = 0; FILLARG(to)
3055 *to++ = 0; *to++ = SYMBOL; *to++ = 0;
3056 while ( it1 > 0 && it2 > 0 ) {
3057 if ( *tt1 == *tt2 ) {
3058 pow = tt1[1]+tt2[1];
3059 root = symbols[*tt1].maxpower;
3060 if ( pow >= root ) pow -= root;
3061 if ( ( symbols[*tt1].complex & VARTYPEMINUS ) == VARTYPEMINUS ) {
3062 if ( ( root & 1 ) == 0 && pow >= root/2 ) {
3063 pow -= root/2; sgn3 = -sgn3;
3067 *to++ = *tt1; *to++ = pow;
3069 tt1 += 2; tt2 += 2; it1 -= 2; it2 -= 2;
3071 else if ( *tt1 < *tt2 ) {
3072 *to++ = *tt1++; *to++ = *tt1++; it1 -= 2;
3075 *to++ = *tt2++; *to++ = *tt2++; it2 -= 2;
3078 while ( it1 > 0 ) { *to++ = *tt1++; *to++ = *tt1++; it1 -= 2; }
3079 while ( it2 > 0 ) { *to++ = *tt2++; *to++ = *tt2++; it2 -= 2; }
3080 if ( (to - t3) > ARGHEAD+3 ) {
3081 t3[ARGHEAD+2] = (to-t3)-ARGHEAD-1;
3087 size1 = (ABS(t1[*t1-1])-1)/2;
3088 size2 = (ABS(t2[*t2-1])-1)/2;
3095 if ( AddLong((UWORD *)tt1,size1,(UWORD *)tt2,size2,(UWORD *)to,&size3) ) {
3097 MLOCK(ErrorMessageLock);
3098 MesPrint(
"!>Called from StuffRootAdd");
3099 MUNLOCK(ErrorMessageLock);
3103 sgn = sgn1*sgn2*sgn3;
3104 if ( nosymbols && size3 == 1 ) {
3105 if ( (UWORD)(to[0]) <= MAXPOSITIVE && sgn > 0 ) {
3107 to = t3; *to++ = -SNUMBER; *to++ = sgn1;
3109 else if ( (UWORD)(to[0]) <= (MAXPOSITIVE+1) && sgn < 0 ) {
3111 to = t3; *to++ = -SNUMBER; *to++ = -sgn1;
3113 else goto genericcoef;
3118 sgn = sgn*(2*size3+1);
3120 while ( size3 > 1 ) { *to++ = 0; size3--; }
3123 t3[ARGHEAD] = t3[0] - ARGHEAD;
WORD CompCoef(WORD *, WORD *)
int Generator(PHEAD WORD *, WORD)