51int MakeDirty(WORD *term, WORD *x, WORD par)
55 next = term; next += *term;
56 next -= ABS(next[-1]);
58 if ( x < term )
return(0);
59 if ( x >= next )
return(0);
60 while ( term < next ) {
68 next = term + term[1];
69 if ( x < term || x >= next )
return(0);
71 if ( *term < FUNCTION )
return(0);
72 if ( functions[*term-FUNCTION].spec >= TENSORFUNCTION )
return(0);
74 if ( x < term )
return(0);
75 next = term; NEXTARG(next)
76 while ( x >= next ) { term = next; NEXTARG(next) }
77 if ( *term < 0 )
return(0);
80 if ( x < term )
return(1);
82 while ( x >= next ) { term = next; next += *next; }
97void MarkDirty(WORD *term, WORD flags)
99 WORD *t, *r, *m, *tstop;
102 while ( t < tstop ) {
103 if ( *t < FUNCTION ) { t += t[1];
continue; }
105 if ( *t < FUNCTION+WILDOFFSET && functions[*t-FUNCTION].spec > 0 ) {
108 if ( *t >= FUNCTION+WILDOFFSET && functions[*t-FUNCTION-WILDOFFSET].spec > 0 ) {
115 if ( *r <= -FUNCTION ) r++;
139void PolyFunDirty(PHEAD WORD *term)
142 WORD *t, *tstop, *endarg;
143 tstop = term + *term;
144 tstop -= ABS(tstop[-1]);
146 while ( t < tstop ) {
147 if ( *t == AR.PolyFun ) {
148 if ( AR.PolyFunType == 2 ) t[2] |= MUSTCLEANPRF;
152 while ( t < endarg ) {
174void PolyFunClean(PHEAD WORD *term)
178 tstop = term + *term;
179 tstop -= ABS(tstop[-1]);
181 while ( t < tstop ) {
182 if ( *t == AR.PolyFun ) {
183 t[2] &= ~MUSTCLEANPRF;
213WORD Symmetrize(PHEAD WORD *func, WORD *Lijst, WORD ngroups, WORD gsize,
217 WORD **args,**arg,nargs;
218 WORD *to, *r, *fstop;
219 WORD i, j, k, ff, exch, nexch, neq;
222 if ( ( type & REVERSEORDER ) != 0 ) reverseorder = -1;
223 else reverseorder = 1;
224 type &= ~REVERSEORDER;
226 ff = ( *func > FUNCTION ) ? functions[*func-FUNCTION].spec: 0;
228 if ( 2*func[1] > AN.arglistsize ) {
229 if ( AN.arglist ) M_free(AN.arglist,
"Symmetrize");
230 AN.arglistsize = 2*func[1] + 8;
231 AN.arglist = (WORD **)Malloc1(AN.arglistsize*
sizeof(WORD *),
"Symmetrize");
233 arg = args = AN.arglist;
239 while ( r < fstop ) {
243 if ( *r == FUNNYWILD ) r++;
252 if ( type == SYMMETRIC || type == ANTISYMMETRIC ) {
253 for ( i = 1; i < ngroups; i++ ) {
254 a3 = a2 = a1 + gsize;
255 k = reverseorder*CompGroup(BHEAD ff,args,a1,a2,gsize);
259 for ( k = 0; k < gsize; k++ ) {
260 r = args[a1[k]]; args[a1[k]] = args[a2[k]]; args[a2[k]] = r;
267 k = reverseorder*CompGroup(BHEAD ff,args,a1,a2,gsize);
268 if ( k == 0 ) neq = 2;
273 else if ( k == 0 ) neq = 2;
277 else if ( type == CYCLESYMMETRIC || type == RCYCLESYMMETRIC ) {
278 WORD rev = 0, jmin = 0, ii, iimin;
280 for ( j = 1; j < ngroups; j++ ) {
281 for ( i = 0; i < ngroups; i++ ) {
283 if ( iimin >= ngroups ) iimin -= ngroups;
285 if ( ii >= ngroups ) ii -= ngroups;
286 k = reverseorder*CompGroup(BHEAD ff,args,Lijst+gsize*iimin,Lijst+gsize*ii,gsize);
288 if ( k < 0 ) { jmin = j; nexch = 4;
break; }
291 if ( type == RCYCLESYMMETRIC && rev == 0 && ngroups > 1 ) {
292 for ( j = 0; j < ngroups; j++ ) {
293 for ( i = 0; i < ngroups; i++ ) {
295 if ( iimin >= ngroups ) iimin -= ngroups;
297 if ( ii < 0 ) ii += ngroups;
298 k = reverseorder*CompGroup(BHEAD ff,args,Lijst+gsize*iimin,Lijst+gsize*ii,gsize);
304 a2 = Lijst + gsize * (ngroups-1);
306 for ( k = 0; k < gsize; k++ ) {
308 args[a1[k]] = args[a2[k]];
311 a1 += gsize; a2 -= gsize;
320 arg = AN.arglist + func[1];
321 a1 = Lijst + gsize * jmin;
324 for ( i = 0; i < k; i++ ) {
325 if ( a1 >= a2 ) a1 = Lijst;
326 *arg++ = args[*a1++];
328 arg = AN.arglist + func[1];
330 for ( i = 0; i < k; i++ ) args[*a1++] = *arg++;
336 for ( i = 0; i < nargs; i++ ) {
338 if ( *(args[i]) == FUNNYWILD ) {
342 else *to++ = *(args[i]);
344 else if ( ( j = *args[i] ) < 0 ) {
346 if ( j > -FUNCTION ) *to++ = args[i][1];
357 return ( exch | nexch | neq );
373int CompGroup(PHEAD WORD type, WORD **args, WORD *a1, WORD *a2, WORD num)
376 WORD *t1, *t2, i1, i2, n, k;
378 for ( n = 0; n < num; n++ ) {
379 t1 = args[a1[n]]; t2 = args[a2[n]];
380 if ( type >= TENSORFUNCTION ) {
381 if ( AR.Eside == LHSIDE || AR.Eside == LHSIDEX ) {
382 if ( *t1 == FUNNYWILD ) {
383 if ( *t2 == FUNNYWILD ) {
384 if ( t1[1] < t2[1] )
return(1);
385 if ( t1[1] > t2[1] )
return(-1);
389 else if ( *t2 == FUNNYWILD ) {
393 if ( *t1 < *t2 )
return(1);
394 if ( *t1 > *t2 )
return(-1);
398 if ( *t1 < *t2 )
return(1);
399 if ( *t1 > *t2 )
return(-1);
402 else if ( type == 0 ) {
403 if ( AC.properorderflag ) {
405 if ( k < 0 )
return(1);
406 if ( k > 0 )
return(-1);
412 i1 = *t1 - ARGHEAD - 1;
415 i2 = *t2 - ARGHEAD - 1;
417 while ( i1 > 0 && i2 > 0 ) {
418 if ( *t1 > *t2 )
return(-1);
419 else if ( *t1 < *t2 )
return(1);
420 i1--; i2--; t1++; t2++;
422 if ( i1 > 0 )
return(-1);
423 else if ( i2 > 0 )
return(1);
431 else if ( *t2 > 0 )
return(1);
434 if ( *t1 <= -FUNCTION && *t2 <= -FUNCTION ) {
435 if ( *t1 < *t2 )
return(-1);
439 if ( *t1 < *t2 )
return(1);
443 if ( *t1 > -FUNCTION ) {
444 if ( t1[1] != t2[1] ) {
445 if ( t1[1] < t2[1] )
return(1);
473int FullSymmetrize(PHEAD WORD *fun,
int type)
476 WORD *Lijst, count = 0;
477 WORD *t, *funstop, i;
480 if ( functions[*fun-FUNCTION].spec > 0 ) {
481 count = fun[1] - FUNHEAD;
482 for ( i = fun[1]-1; i >= FUNHEAD; i-- ) {
483 if ( fun[i] == FUNNYWILD ) count--;
487 funstop = fun + fun[1];
489 while ( t < funstop ) { count++; NEXTARG(t) }
492 fun[2] &= ~DIRTYSYMFLAG;
495 Lijst = AT.WorkPointer;
496 for ( i = 0; i < count; i++ ) Lijst[i] = i;
497 AT.WorkPointer += count;
498 retval = Symmetrize(BHEAD fun,Lijst,count,1,type);
499 fun[2] &= ~DIRTYSYMFLAG;
500 AT.WorkPointer = Lijst;
518int SymGen(PHEAD WORD *term, WORD *params, WORD num, WORD level)
522 WORD i, j, k, c1, c2, ngroup;
523 WORD *rstop, Nlist, *inLijst, *Lijst, sign = 1, sumch = 0, count;
526 c2 = FUNCTION + WILDOFFSET;
528 if ( Nlist < 0 ) Nlist = 0;
529 else Nlist = params[0] - 7;
535 if ( *t == c1 || c1 > c2 ) {
536 if ( *t >= FUNCTION && functions[*t-FUNCTION].spec
537 >= TENSORFUNCTION ) {
538 count = t[1] - FUNHEAD;
545 while ( r < rstop ) { count++; NEXTARG(r) }
547 if ( ( j = params[4] ) > 0 && j != count )
goto NextFun;
550 for ( i = 0; i < Nlist; i++ )
551 if ( inLijst[i] > count-1 )
goto NextFun;
554 if ( Nlist > (params[0] - 7) ) Nlist = params[0] - 7;
555 Lijst = AT.WorkPointer;
556 inLijst = params + 7;
558 if ( Nlist > 0 && j < 0 ) {
560 for ( i = 0; i < ngroup; i++ ) {
561 for ( j = 0; j < params[6]; j++ ) {
562 if ( inLijst[j] > count+1 ) {
563 inLijst += params[6];
568 NCOPY(Lijst,inLijst,j);
572 if ( k <= 1 )
goto NextFun;
574 inLijst = AT.WorkPointer;
575 AT.WorkPointer = Lijst;
578 else if ( Nlist == 0 ) {
579 for ( i = 0; i < count; i++ ) Lijst[i] = i;
580 AT.WorkPointer += count;
584 for ( i = 0; i < Nlist; i++ ) Lijst[i] = inLijst[i];
585 AT.WorkPointer += Nlist;
587 j = Symmetrize(BHEAD t,Lijst,ngroup,params[6],params[2]);
588 AT.WorkPointer = Lijst;
589 if ( params[2] == 4 ) {
590 if ( ( j & 1 ) != 0 ) sign = -sign;
591 if ( ( j & 2 ) != 0 )
return(0);
593 if ( ( j & 4 ) != 0 ) sumch++;
594 t[2] &= ~DIRTYSYMFLAG;
605 if ( Normalize(BHEAD term) ) {
606 MLOCK(ErrorMessageLock);
608 MUNLOCK(ErrorMessageLock);
611 if ( !*term )
return(0);
614 if ( AR.CurDum > AM.IndDum && AR.sLevel <= 0 ) ReNumber(BHEAD term);
633int SymFind(PHEAD WORD *term, WORD *params)
637 WORD j, c1, c2, count;
640 c2 = FUNCTION + WILDOFFSET;
646 if ( *t == c1 || c1 > c2 ) {
647 if ( *t >= FUNCTION && functions[*t-FUNCTION].spec
648 >= TENSORFUNCTION ) { count = t[1] - FUNHEAD; }
654 while ( r < rstop ) { count++; NEXTARG(r) }
656 if ( ( j = params[5] ) > 0 && j != count )
goto NextFun;
659 rstop = params + params[1];
660 while ( r < rstop ) {
661 if ( *r > count + 1 )
goto NextFun;
691int ChainIn(PHEAD WORD *term, WORD funnum)
694 WORD *t, *tend, *m, *tt, *ts;
695 int action, normFlag = 0;
697 funnum = DolToFunction(BHEAD -funnum);
698 if ( AN.ErrorInDollar || funnum <= 0 ) {
699 MLOCK(ErrorMessageLock);
700 MesPrint(
"Dollar variable does not evaluate to function in ChainIn statement");
701 MUNLOCK(ErrorMessageLock);
708 tend -= ABS(tend[-1]);
711 if ( *t != funnum ) { t += t[1];
continue; }
715 if ( t >= tend || *t != funnum )
continue;
718 while ( t < tend && *t == funnum ) {
721 while ( t < ts ) *tt++ = *t++;
725 while ( t < ts ) *tt++ = *t++;
733 MarkDirty(term, DIRTYSYMFLAG);
734 AT.WorkPointer = term + *term;
735 Normalize(BHEAD term);
748int ChainOut(PHEAD WORD *term, WORD funnum)
751 WORD *t, *tend, *tt, *ts, *w, *ws;
754 funnum = DolToFunction(BHEAD -funnum);
755 if ( AN.ErrorInDollar || funnum <= 0 ) {
756 MLOCK(ErrorMessageLock);
757 MesPrint(
"Dollar variable does not evaluate to function in ChainOut statement");
758 MUNLOCK(ErrorMessageLock);
763 if ( AT.WorkPointer < tend ) AT.WorkPointer = tend;
764 tend -= ABS(tend[-1]);
765 t = term+1; tt = term; w = AT.WorkPointer;
767 if ( *t != funnum || t[1] == FUNHEAD ) { t += t[1];
continue; }
769 while ( tt < t ) *w++ = *tt++;
774 for ( i = 0; i < FUNHEAD; i++ ) *w++ = tt[i];
775 if ( functions[*tt-FUNCTION].spec >= TENSORFUNCTION ) {
779 if ( *t <= -FUNCTION ) *w++ = *t++;
780 else { *w++ = *t++; *w++ = *t++; }
783 i = *t; NCOPY(w,t,i);
791 while ( tt < ts ) *w++ = *tt++;
792 *AT.WorkPointer = w - AT.WorkPointer;
793 t = term; w = AT.WorkPointer; i = *w;
795 AT.WorkPointer = term + *term;
796 Normalize(BHEAD term);
826int MatchFunction(PHEAD WORD *pattern, WORD *interm, WORD *wilds)
830 WORD *mstop = 0, *tstop = 0;
831 WORD *argmstop, *argtstop;
832 WORD *mtrmstop, *ttrmstop;
833 WORD *msubstop, *mnextsub;
834 WORD msizcoef, mcount, tcount, newvalue, j;
836 WORD *OldWork, numofwildarg;
837 WORD nwstore, tobeeaten, reservevalue = 0, resernum = 0, withwild;
839 CBUF *C = cbuf+AT.ebufnum;
840 int ntwa = AN.NumTotWildArgs;
846 if ( *interm == FLOATFUN )
return(0);
851 AN.RepFunList[AN.RepFunNum+1] = 0;
853 m = pattern; t = interm;
856 if ( *m < (FUNCTION + WILDOFFSET) )
return(0);
857 if ( *t < FUNCTION )
return(0);
858 if ( functions[*t-FUNCTION].spec !=
859 functions[*m-FUNCTION-WILDOFFSET].spec )
return(0);
862 if ( *m >= (FUNCTION + WILDOFFSET) ) { i--; m++; t++; }
863 do {
if ( *m++ != *t++ )
break; }
while ( --i > 0 );
865 if ( AN.SignCheck && AN.ExpectedSign )
return(0);
866 i = *pattern - WILDOFFSET;
867 if ( i >= FUNCTION ) {
868 if ( *interm != GAMMA
869 && !CheckWild(BHEAD i,FUNTOFUN,*interm,&newvalue) ) {
870 AddWild(BHEAD i,FUNTOFUN,newvalue);
881 t = wildargtaken = OldWork = AT.WorkPointer;
884 nwstore = i = (m[-SUBEXPSIZE+1]-SUBEXPSIZE)/4;
888 *t++ = *m++; *t++ = *m++; *t++ = *m++; *t++ = *m++; *t++ = *r++;
892 if ( t >= AT.WorkTop ) {
893 MLOCK(ErrorMessageLock);
895 MUNLOCK(ErrorMessageLock);
901 if ( *wilds == 1 )
goto endoloop;
904 m = pattern; t = interm;
921 if ( *m != GAMMA )
goto NoCaseB;
923 if ( m[1] == FUNHEAD+1 ) {
924 if ( i )
goto NoCaseB;
925 if ( m[FUNHEAD] < (AM.OffsetIndex+WILDOFFSET) ||
926 t[FUNHEAD] >= (AM.OffsetIndex+WILDOFFSET) )
goto NoCaseB;
928 if ( CheckWild(BHEAD m[FUNHEAD]-WILDOFFSET,INDTOIND,t[FUNHEAD],&newvalue) )
goto NoCaseB;
929 AddWild(BHEAD m[FUNHEAD]-WILDOFFSET,INDTOIND,newvalue);
931 AT.WorkPointer = OldWork;
932 if ( AN.SignCheck && AN.ExpectedSign )
return(0);
935 if ( i < 0 )
goto NoCaseB;
938 m += FUNHEAD; t += FUNHEAD;
939 if ( *m >= (AM.OffsetIndex+WILDOFFSET) && *t < (AM.OffsetIndex+WILDOFFSET) ) {
940 if ( CheckWild(BHEAD *m-WILDOFFSET,INDTOIND,*t,&newvalue) )
goto NoCaseB;
941 reservevalue = newvalue;
943 resernum = *m-WILDOFFSET;
944 AddWild(BHEAD *m-WILDOFFSET,INDTOIND,newvalue);
946 else if ( *m != *t )
goto NoCaseB;
949 oldm = m; argtstop = oldt = t;
955 if ( t < tstop && mstop < AN.patstop ) {
957 mnextsub = pattern + pattern[1];
959 while ( k == GAMMA && mnextsub[FUNHEAD]
960 != pattern[FUNHEAD] ) {
961 mnextsub += mnextsub[1];
962 if ( mnextsub >= AN.patstop )
goto FullOK;
965 if ( k >= FUNCTION ) {
966 if ( k > (FUNCTION + WILDOFFSET) ) k -= WILDOFFSET;
967 if ( functions[k-FUNCTION].commute )
goto NoGamma;
970FullOK:
if ( AN.SignCheck && AN.ExpectedSign )
goto NoGamma;
971 AN.RepFunList[AN.RepFunNum+1] = WORDDIF(oldt,argtstop);
974 if ( t >= tstop )
goto NoCaseB;
976 else if ( *m >= (AM.OffsetIndex+WILDOFFSET)
977 && *m < (AM.OffsetIndex + (WILDOFFSET<<1)) && ( *t >= 0 ||
979 if ( !CheckWild(BHEAD *m-WILDOFFSET,INDTOIND,*t,&newvalue) ) {
980 AddWild(BHEAD *m-WILDOFFSET,INDTOIND,newvalue);
986 else if ( *m < MINSPEC && *m >= (AM.OffsetVector+WILDOFFSET)
988 if ( !CheckWild(BHEAD *m-WILDOFFSET,VECTOVEC,*t,&newvalue) ) {
989 AddWild(BHEAD *m-WILDOFFSET,VECTOVEC,newvalue);
999 t = OldWork + AN.NumTotWildArgs; r = AT.WildMask; j = nwstore;
1002 *m++ = *t++; *m++ = *t++;
1003 *m++ = *t++; *m++ = *t++; *r++ = *t++;
1004 }
while ( --j > 0 );
1010 m = oldm; t = ++oldt; i--;
1012 AddWild(BHEAD resernum,INDTOIND,reservevalue);
1022 else if ( *t >= FUNCTION && functions[*t-FUNCTION].spec >= TENSORFUNCTION ) {
1029 tcount = WORDDIF(tstop,t);
1030 while ( m < mstop ) {
1031 if ( *m == FUNNYWILD ) { m++; AN.WildArgs++; }
1034 tobeeaten = tcount - mcount + AN.WildArgs;
1036 if ( tobeeaten < 0 || AN.WildArgs == 0 ) {
1037 AT.WorkPointer = OldWork;
1041 AT.WildArgTaken[0] = AN.WildEat = tobeeaten;
1042 for ( i = 1; i < AN.WildArgs; i++ ) AT.WildArgTaken[i] = 0;
1046 m = pattern; t = interm;
1049 i = *m - WILDOFFSET;
1050 if ( CheckWild(BHEAD i,FUNTOFUN,*t,&newvalue) )
goto NoCaseB;
1051 AddWild(BHEAD i,FUNTOFUN,newvalue);
1055 while ( m < mstop ) {
1059 if ( *m == *t ) { m++; t++;
continue; }
1064 if ( *m == FUNNYWILD ) {
1065 tobeeaten = AT.WildArgTaken[numofwildarg++];
1066 if ( CheckWild(BHEAD m[1],ARGTOARG|EATTENSOR,tobeeaten,t) )
goto endloop;
1067 AddWild(BHEAD m[1],ARGTOARG|EATTENSOR,tobeeaten);
1076 if ( i < MINSPEC ) {
1078 if ( *t >= MINSPEC )
goto endloop;
1080 if ( i < AM.OffsetVector )
goto endloop;
1081 if ( CheckWild(BHEAD i,VECTOVEC,*t,&newvalue) )
1083 AddWild(BHEAD i,VECTOVEC,newvalue);
1086 else if ( i >= AM.OffsetIndex ) {
1087 if ( i < ( AM.OffsetIndex + WILDOFFSET ) )
goto endloop;
1088 if ( i >= ( AM.OffsetIndex + (WILDOFFSET<<1) ) ) {
1093 if ( CheckWild(BHEAD i,INDTOIND,*t,&newvalue) )
1095 AddWild(BHEAD i,INDTOIND,newvalue);
1100 if ( AN.SignCheck && AN.ExpectedSign )
goto endloop;
1101 AT.WorkPointer = OldWork;
1102 if ( AN.WildArgs > 1 ) *wilds = 2;
1112 t = OldWork + ntwa; r = AT.WildMask;
1114 *m++ = *t++; *m++ = *t++; *m++ = *t++; *m++ = *t++; *r++ = *t++;
1115 }
while ( --i > 0 );
1120 i = AN.WildArgs - 1;
1122 AT.WorkPointer = OldWork;
1125 while ( --i >= 0 ) {
1126 if ( AT.WildArgTaken[i] == 0 ) {
1128 AT.WorkPointer = OldWork;
1134 (AT.WildArgTaken[i])--;
1136 for ( j = 0; j <= i; j++ ) {
1137 numofwildarg += AT.WildArgTaken[j];
1139 AT.WildArgTaken[j] = AN.WildEat-numofwildarg;
1140 for ( j++; j < AN.WildArgs; j++ ) AT.WildArgTaken[j] = 0;
1154 mcount = 0; tcount = 0;
1155 m += FUNHEAD; t += FUNHEAD;
1156 while ( t < tstop ) { tcount++; NEXTARG(t) }
1158 while ( m < mstop ) {
1160 if ( *m == -ARGWILD ) AN.WildArgs++;
1163 tobeeaten = tcount - mcount + AN.WildArgs;
1165 if ( tobeeaten < 0 || AN.WildArgs == 0 ) {
1166 AT.WorkPointer = OldWork;
1174 AT.WildArgTaken[0] = AN.WildEat = tobeeaten;
1175 for ( i = 1; i < AN.WildArgs; i++ ) AT.WildArgTaken[i] = 0;
1181 m = pattern; t = interm;
1183 i = *m - WILDOFFSET;
1184 if ( CheckWild(BHEAD i,FUNTOFUN,*t,&newvalue) )
goto NoCaseB;
1185 AddWild(BHEAD i,FUNTOFUN,newvalue);
1191 while ( m < mstop ) {
1192 argmstop = oldm = m;
1193 argtstop = oldt = t;
1197 if ( *m == -ARGWILD )
goto ArgAll;
1200 if ( *m < 0 && *t < 0 ) {
1201 if ( *t <= -FUNCTION ) {
1203 else if ( *m <= -FUNCTION-WILDOFFSET
1204 && functions[-*t-FUNCTION].spec
1205 == functions[-*m-FUNCTION-WILDOFFSET].spec ) {
1206 i = -*m - WILDOFFSET;
1207 if ( CheckWild(BHEAD i,FUNTOFUN,-*t,&newvalue) )
goto endofloop;
1208 AddWild(BHEAD i,FUNTOFUN,newvalue);
1210 else if ( *m == -SYMBOL && m[1] >= 2*MAXPOWER ) {
1211 i = m[1] - 2*MAXPOWER;
1212 AN.argaddress = AT.FunArg;
1213 AT.FunArg[ARGHEAD+1] = -*t;
1214 if ( CheckWild(BHEAD i,SYMTOSUB,1,AN.argaddress) )
goto endofloop;
1215 AddWild(BHEAD i,SYMTOSUB,0);
1217 else if ( *m == -ARGWILD ) {
1218ArgAll: i = AT.WildArgTaken[numofwildarg++];
1220 if ( CheckWild(BHEAD m[1],ARGTOARG,i,t) )
goto endofloop;
1221 AddWild(BHEAD m[1],ARGTOARG,i);
1223 while ( --i >= 0 ) { NEXTARG(t) }
1226 else goto endofloop;
1228 else if ( *t == *m ) {
1229 if ( t[1] == m[1] ) {}
1230 else if ( *t == -SYMBOL ) {
1233 if ( ( i = m[1] - 2*MAXPOWER ) < 0 )
goto endofloop;
1234 if ( CheckWild(BHEAD i,j,t[1],&newvalue) )
goto endofloop;
1235 AddWild(BHEAD i,j,newvalue);
1237 else if ( *t == -INDEX ) {
1238IndAll: i = m[1] - WILDOFFSET;
1239 if ( i < AM.OffsetIndex || i >= WILDOFFSET+AM.OffsetIndex )
1242 if ( CheckWild(BHEAD i,INDTOIND,t[1],&newvalue) )
goto endofloop;
1243 AddWild(BHEAD i,INDTOIND,newvalue);
1245 else if ( *t == -VECTOR || *t == -MINVECTOR ) {
1246 i = m[1] - WILDOFFSET;
1247 if ( i < AM.OffsetVector )
goto endofloop;
1248 if ( CheckWild(BHEAD i,VECTOVEC,t[1],&newvalue) )
goto endofloop;
1249 AddWild(BHEAD i,VECTOVEC,newvalue);
1251 else goto endofloop;
1253 else if ( *m == -ARGWILD )
goto ArgAll;
1254 else if ( *m == -INDEX && m[1] >= AM.OffsetIndex+WILDOFFSET
1255 && m[1] < AM.OffsetIndex+(WILDOFFSET<<1) ) {
1256 if ( *t == -VECTOR )
goto IndAll;
1257 if ( *t == -SNUMBER && t[1] >= 0 && t[1] < AM.OffsetIndex )
goto IndAll;
1258 if ( *t == -MINVECTOR ) {
1259 i = m[1] - WILDOFFSET;
1260 AN.argaddress = AT.MinVecArg;
1261 AT.MinVecArg[ARGHEAD+3] = t[1];
1262 if ( CheckWild(BHEAD i,INDTOSUB,1,AN.argaddress) )
goto endofloop;
1263 AddWild(BHEAD i,INDTOSUB,(WORD)0);
1265 else goto endofloop;
1267 else if ( *m == -SYMBOL && m[1] >= 2*MAXPOWER && *t == -SNUMBER ) {
1271 else if ( *m == -VECTOR && *t == -MINVECTOR &&
1272 ( i = m[1] - WILDOFFSET ) >= AM.OffsetVector ) {
1281 if ( CheckWild(BHEAD i,VECTOMIN,t[1],&newvalue) )
goto endofloop;
1282 AddWild(BHEAD i,VECTOMIN,newvalue);
1285 else if ( *m == -MINVECTOR && *t == -VECTOR &&
1286 ( i = m[1] - WILDOFFSET ) >= AM.OffsetVector ) {
1295 if ( CheckWild(BHEAD i,VECTOMIN,t[1],&newvalue) )
goto endofloop;
1296 AddWild(BHEAD i,VECTOMIN,newvalue);
1298 else goto endofloop;
1300 else if ( *t <= -FUNCTION && *m > 0 ) {
1301 if ( ( m[ARGHEAD]+ARGHEAD == *m ) && m[*m-1] == 3
1302 && m[*m-2] == 1 && m[*m-3] == 1 && m[ARGHEAD+1] >= FUNCTION
1303 && m[ARGHEAD+2] == *m-ARGHEAD-4 ) {
1305 if ( m[ARGHEAD+1] >= FUNCTION+WILDOFFSET ) {
1307 i = m[ARGHEAD+1] - WILDOFFSET;
1308 if ( CheckWild(BHEAD i,FUNTOFUN,-*t,&newvalue) )
goto endofloop;
1309 AddWild(BHEAD i,FUNTOFUN,newvalue);
1311 else if ( m[ARGHEAD+1] != -*t )
goto endofloop;
1316 mmm = m + ARGHEAD + FUNHEAD + 1;
1317 while ( mmm < mmmst ) {
1318 if ( *mmm != -ARGWILD )
goto endofloop;
1321 if ( CheckWild(BHEAD mmm[1],ARGTOARG,i,t) )
goto endofloop;
1322 AddWild(BHEAD mmm[1],ARGTOARG,i);
1326 else goto endofloop;
1328 else if ( *m < 0 && *t > 0 ) {
1329 if ( *m == -SYMBOL ) {
1330 if ( m[1] < 2*MAXPOWER )
goto endofloop;
1331 i = m[1] - 2*MAXPOWER;
1333 if ( CheckWild(BHEAD i,SYMTOSUB,1,AN.argaddress) )
goto endofloop;
1334 AddWild(BHEAD i,SYMTOSUB,0);
1336 else if ( *m == -VECTOR ) {
1337 if ( ( i = m[1] - WILDOFFSET ) < AM.OffsetVector )
1340 if ( CheckWild(BHEAD i,VECTOSUB,1,t) )
goto endofloop;
1341 AddWild(BHEAD i,VECTOSUB,(WORD)0);
1343 else if ( *m == -INDEX ) {
1344 if ( ( i = m[1] - WILDOFFSET ) < AM.OffsetIndex )
goto endofloop;
1345 if ( i >= AM.OffsetIndex + WILDOFFSET )
goto endofloop;
1347 if ( CheckWild(BHEAD i,INDTOSUB,1,AN.argaddress) )
goto endofloop;
1348 AddWild(BHEAD i,INDTOSUB,(WORD)0);
1350 else if ( *m == -ARGWILD )
goto ArgAll;
1351 else goto endofloop;
1353 else if ( *m > 0 && *t > 0 ) {
1356 do {
if ( *m++ != *t++ )
break; }
while ( --i > 0 );
1357 if ( i == 1 && ii == 0 ) {
1361 WORD *cto, *cfrom, *csav, ci;
1364 WORD *oterstart,*oterstop,*opatstop;
1366 WORD wildargs, wildeat;
1372 m += ARGHEAD; t += ARGHEAD;
1375 if ( mtrmstop < argmstop )
goto endofloop;
1376 msizcoef = mtrmstop[-1];
1377 if ( msizcoef < 0 ) msizcoef = -msizcoef;
1378 msubstop = mtrmstop - msizcoef;
1380 if ( m >= msubstop )
goto endofloop;
1394 if ( argtstop > ttrmstop )
goto endofloop;
1396 oterstart = AN.terstart;
1397 oterstop = AN.terstop;
1398 opatstop = AN.patstop;
1399 oRepFunList = AN.RepFunList;
1400 oRepFunNum = AN.RepFunNum;
1402 AN.RepFunList = AT.WorkPointer;
1403 AT.WorkPointer = (WORD *)(((UBYTE *)(AT.WorkPointer)) + AM.MaxTer);
1404 if ( AT.WorkPointer+*t+5 > AT.WorkTop ) {
1405 MLOCK(ErrorMessageLock);
1407 MUNLOCK(ErrorMessageLock);
1410 csav = cto = AT.WorkPointer;
1413 while ( --ci >= 0 ) *cto++ = *cfrom++;
1414 AT.WorkPointer = cto;
1418 if ( abs(*--cfrom) != abs(*--cto) ) {
1419 AT.WorkPointer = csav;
1420 AN.RepFunList = oRepFunList;
1421 AN.RepFunNum = oRepFunNum;
1422 AN.terstart = oterstart;
1423 AN.terstop = oterstop;
1424 AN.patstop = opatstop;
1427 i = (*cfrom != *cto) ? 1 : 0;
1428 while ( --ci >= 0 ) {
1429 if ( *--cfrom != *--cto ) {
1430 AT.WorkPointer = csav;
1431 AN.RepFunList = oRepFunList;
1432 AN.RepFunNum = oRepFunNum;
1433 AN.terstart = oterstart;
1434 AN.terstop = oterstop;
1435 AN.patstop = opatstop;
1439 oExpectedSign = AN.ExpectedSign;
1440 AN.ExpectedSign = i;
1442 wildargs = AN.WildArgs;
1443 wildeat = AN.WildEat;
1444 for ( i = 0; i < wildargs; i++ ) wildargtaken[i] = AT.WildArgTaken[i];
1445 AN.ForFindOnly = 0; AN.UseFindOnly = 1;
1447 if ( FindRest(BHEAD csav,m) && ( AN.UsedOtherFind || FindOnly(BHEAD csav,m) ) ) {}
1451 AT.WorkPointer = csav;
1452 AN.RepFunList = oRepFunList;
1453 AN.RepFunNum = oRepFunNum;
1454 AN.terstart = oterstart;
1455 AN.terstop = oterstop;
1456 AN.patstop = opatstop;
1457 AN.WildArgs = wildargs;
1458 AN.WildEat = wildeat;
1459 AN.ExpectedSign = oExpectedSign;
1461 for ( i = 0; i < wildargs; i++ ) AT.WildArgTaken[i] = wildargtaken[i];
1465 if ( *m == 1 || m[1] < FUNCTION ) {
1466 if ( AN.ExpectedSign )
goto nomatch;
1469 if ( m[1] > FUNCTION + WILDOFFSET ) {
1470 if ( functions[m[1]-FUNCTION-WILDOFFSET].spec >= TENSORFUNCTION ) {
1471 if ( AN.ExpectedSign != AN.RepFunList[AN.RepFunNum-1] )
goto nomatch;
1475 if ( AN.ExpectedSign != AN.RepFunList[AN.RepFunNum-1] )
goto nomatch;
1484 AN.ExpectedSign = oExpectedSign;
1485 AN.WildArgs = wildargs;
1486 AN.WildEat = wildeat;
1487 for ( i = 0; i < wildargs; i++ ) AT.WildArgTaken[i] = wildargtaken[i];
1488 Substitute(BHEAD csav,m,1);
1490 cfrom = cto + *cto - msizcoef;
1493 AT.WorkPointer = csav;
1494 AN.RepFunList = oRepFunList;
1495 AN.RepFunNum = oRepFunNum;
1496 AN.terstart = oterstart;
1497 AN.terstop = oterstop;
1498 AN.patstop = opatstop;
1499 if ( *cto != SUBEXPRESSION )
goto endofloop;
1501 if ( cto < cfrom )
goto endofloop;
1504 else goto endofloop;
1509 if ( AN.SignCheck && AN.ExpectedSign )
goto endofloop;
1510 AT.WorkPointer = OldWork;
1511 if ( AN.WildArgs > 1 ) *wilds = 1;
1512 if ( AN.SignCheck && AN.ExpectedSign )
return(0);
1522 t = OldWork + ntwa; r = AT.WildMask;
1524 *m++ = *t++; *m++ = *t++; *m++ = *t++; *m++ = *t++; *r++ = *t++;
1525 }
while ( --i > 0 );
1533 AT.WorkPointer = OldWork;
1536 while ( --i >= 0 ) {
1537 if ( AT.WildArgTaken[i] == 0 ) {
1539 AT.WorkPointer = OldWork;
1544 (AT.WildArgTaken[i])--;
1546 for ( j = 0; j <= i; j++ ) {
1547 numofwildarg += AT.WildArgTaken[j];
1549 AT.WildArgTaken[j] = AN.WildEat-numofwildarg;
1551 for ( j++; j < AN.WildArgs; j++ ) AT.WildArgTaken[j] = 0;
1563 t = OldWork + ntwa; r = AT.WildMask;
1565 *m++ = *t++; *m++ = *t++; *m++ = *t++; *m++ = *t++; *r++ = *t++;
1566 }
while ( --i > 0 );
1570 AT.WorkPointer = OldWork;
1618int ScanFunctions(PHEAD WORD *inpat, WORD *inter, WORD par)
1621 WORD i, *m, *t, *r, sym, psym;
1622 WORD *newpat, *newter, *instart, *oinpat = 0, *ointer = 0;
1623 WORD nwstore, offset, *OldWork, SetStop = 0, oRepFunNum = AN.RepFunNum;
1624 WORD wilds, wildargs = 0, wildeat = 0, *wildargtaken;
1625 WORD *Oterfirstcomm = AN.terfirstcomm;
1626 CBUF *C = cbuf+AT.ebufnum;
1627 int ntwa = AN.NumTotWildArgs;
1629 WORD oldSignCheck = AN.SignCheck;
1635 if ( AN.nogroundlevel ) {
1636 AN.SignCheck = ( inpat + inpat[1] >= AN.patstop ) ? 1 : 0;
1644 t = wildargtaken = OldWork = AT.WorkPointer;
1647 nwstore = i = (m[-SUBEXPSIZE+1]-SUBEXPSIZE)/4;
1651 *t++ = *m++; *t++ = *m++; *t++ = *m++; *t++ = *m++; *t++ = *r++;
1652 }
while ( --i > 0 );
1655 if ( t >= AT.WorkTop ) {
1656 MLOCK(ErrorMessageLock);
1658 MUNLOCK(ErrorMessageLock);
1667 if ( AN.RepFunNum > 0 ) {
1672 if ( *inter >= FUNCTION && functions[*inter-FUNCTION].commute ) {
1674 offset = WORDDIF(inter,AN.terstart);
1675 for ( i = 0; i < AN.RepFunNum; i += 2 ) {
1676 if ( AN.RepFunList[i] >= offset )
break;
1678 if ( i >= AN.RepFunNum )
break;
1680 }
while ( inter < AN.terfirstcomm );
1681 if ( inter < AN.terfirstcomm ) {
1682 for ( i = 0; i < AN.RepFunNum; i += 2 ) {
1683 if ( functions[AN.terstart[AN.RepFunList[i]]-FUNCTION].commute
1684 && AN.RepFunList[i]+AN.terstart[AN.RepFunList[i]+1] == offset )
break;
1686 if ( i < AN.RepFunNum )
goto trythis;
1688 inter = AN.terfirstcomm;
1693 while ( inter < AN.terstop ) {
1694 offset = WORDDIF(inter,AN.terstart);
1695 for ( i = 0; i < AN.RepFunNum; i += 2 ) {
1696 if ( AN.RepFunList[i] == offset )
break;
1698 if ( i >= AN.RepFunNum )
break;
1701 if ( inter >= AN.terstop )
goto Failure;
1708 offset = WORDDIF(inter,AN.terstart);
1713 offset = WORDDIF(inter,AN.terstart);
1714 for ( i = 0; i < AN.RepFunNum; i += 2 ) {
1715 if ( AN.RepFunList[i] == offset )
break;
1717 if ( i >= AN.RepFunNum )
break;
1719 }
while ( inter < AN.terstop );
1720 if ( inter >= AN.terstop )
goto Failure;
1724 if ( *inter >= FUNCTION && *inpat >= FUNCTION ) {
1725 if ( *inpat == *inter || *inpat >= FUNCTION + WILDOFFSET ) {
1729 if ( functions[*inter-FUNCTION].spec >= TENSORFUNCTION
1730 && ( *inter == *inpat ||
1731 functions[*inpat-FUNCTION-WILDOFFSET].spec >= TENSORFUNCTION ) ) {
1732 sym = functions[*inter-FUNCTION].symmetric & ~REVERSEORDER;
1733 if ( *inpat == *inter ) psym = sym;
1734 else psym = functions[*inpat-FUNCTION-WILDOFFSET].symmetric & ~REVERSEORDER;
1735 if ( sym == ANTISYMMETRIC || sym == SYMMETRIC
1736 || psym == SYMMETRIC || psym == ANTISYMMETRIC ) {
1737 if ( sym == ANTISYMMETRIC && psym == SYMMETRIC )
goto rewild;
1738 if ( sym == SYMMETRIC && psym == ANTISYMMETRIC )
goto rewild;
1742 if ( MatchE(BHEAD inpat,inter,instart,par) )
goto OnSuccess;
1744 else if ( sym == CYCLESYMMETRIC || sym == RCYCLESYMMETRIC
1745 || psym == CYCLESYMMETRIC || psym == RCYCLESYMMETRIC ) {
1749 if ( MatchCy(BHEAD inpat,inter,instart,par) )
goto OnSuccess;
1753 else if ( functions[*inter-FUNCTION].spec <= 0
1754 && ( *inter == *inpat ||
1755 functions[*inpat-FUNCTION-WILDOFFSET].spec <= 0 ) ) {
1756 sym = functions[*inter-FUNCTION].symmetric & ~REVERSEORDER;
1757 if ( *inpat == *inter ) psym = sym;
1758 else psym = functions[*inpat-FUNCTION-WILDOFFSET].symmetric & ~REVERSEORDER;
1759 if ( psym == SYMMETRIC || sym == SYMMETRIC
1765 || psym == ANTISYMMETRIC || sym == ANTISYMMETRIC
1767 if ( sym == ANTISYMMETRIC && psym == SYMMETRIC )
goto rewild;
1768 if ( sym == SYMMETRIC && psym == ANTISYMMETRIC )
goto rewild;
1769 if ( FunMatchSy(BHEAD inpat,inter,instart,par) )
goto OnSuccess;
1772 if ( sym == CYCLESYMMETRIC || sym == RCYCLESYMMETRIC
1773 || psym == CYCLESYMMETRIC || psym == RCYCLESYMMETRIC ) {
1774 if ( FunMatchCy(BHEAD inpat,inter,instart,par) )
goto OnSuccess;
1779 AN.terfirstcomm = Oterfirstcomm;
1781 else if ( par > 0 ) { SetStop = 1;
goto maybenext; }
1785 AN.terfirstcomm = Oterfirstcomm;
1786 if ( *inter != SUBEXPRESSION && MatchFunction(BHEAD inpat,inter,&wilds) ) {
1787 AN.terfirstcomm = Oterfirstcomm;
1793 wildargs = AN.WildArgs;
1794 wildeat = AN.WildEat;
1795 for ( i = 0; i < wildargs; i++ ) wildargtaken[i] = AT.WildArgTaken[i];
1796 oinpat = inpat; ointer = inter;
1798 if ( par && *inter == GAMMA && AN.RepFunList[AN.RepFunNum+1] ) {
1799 SetStop = 1;
goto NoMat;
1802 if ( *inter < FUNCTION || functions[*inter-FUNCTION].commute ) {
1807 AN.RepFunList[AN.RepFunNum] = offset;
1809 newpat = inpat + inpat[1];
1810 if ( newpat >= AN.patstop ) {
1811 if ( AN.UseFindOnly == 0 ) {
1812 if ( FindOnce(BHEAD AN.findTerm,AN.findPattern) ) {
1813 AN.UsedOtherFind = 1;
1821 if ( *inter < FUNCTION || functions[*inter-FUNCTION].commute ) {
1822 newter = inter + inter[1];
1823 if ( newter >= AN.terstop )
goto Failure;
1824 if ( *inter == GAMMA && inpat[1] <
1825 inter[1] - AN.RepFunList[AN.RepFunNum-1] ) {
1826 if ( ScanFunctions(BHEAD newpat,newter,2) )
goto OnSuccess;
1827 AN.terfirstcomm = Oterfirstcomm;
1829 else if ( *newter == SUBEXPRESSION ) {}
1830 else if ( functions[*inter-FUNCTION].commute ) {
1831 if ( ScanFunctions(BHEAD newpat,newter,1) )
goto OnSuccess;
1832 AN.terfirstcomm = Oterfirstcomm;
1833 if ( ( *newpat < (FUNCTION+WILDOFFSET)
1834 && ( functions[*newpat-FUNCTION].commute == 0 ) ) ||
1835 ( *newpat >= (FUNCTION+WILDOFFSET)
1836 && ( functions[*newpat-FUNCTION-WILDOFFSET].commute == 0 ) ) ) {
1837 newter = AN.terfirstcomm;
1838 if ( newter < AN.terstop && ScanFunctions(BHEAD newpat,newter,1) )
goto OnSuccess;
1842 if ( ScanFunctions(BHEAD newpat,instart,1) )
goto OnSuccess;
1843 AN.terfirstcomm = Oterfirstcomm;
1851 if ( par && inter > instart && ( ( *newpat < (FUNCTION+WILDOFFSET)
1852 && functions[*newpat-FUNCTION].commute ) ||
1853 ( *newpat >= (FUNCTION+WILDOFFSET)
1854 && functions[*newpat-FUNCTION-WILDOFFSET].commute ) ) ) {
1859 if ( ScanFunctions(BHEAD newpat,newter,par) )
goto OnSuccess;
1860 AN.terfirstcomm = Oterfirstcomm;
1870 t = OldWork + ntwa; r = AT.WildMask;
1872 *m++ = *t++; *m++ = *t++; *m++ = *t++; *m++ = *t++; *r++ = *t++;
1873 }
while ( --i > 0 );
1878 AN.RepFunNum = oRepFunNum;
1880 inter = ointer; inpat = oinpat;
1881 AN.WildArgs = wildargs;
1882 AN.WildEat = wildeat;
1883 for ( i = 0; i < wildargs; i++ ) AT.WildArgTaken[i] = wildargtaken[i];
1886 if ( SetStop )
break;
1890 if ( *inpat < (FUNCTION+WILDOFFSET) ) {
1891 if ( *inpat < FUNCTION ||
1892 functions[*inpat-FUNCTION].commute )
break;
1895 if ( functions[*inpat-FUNCTION-WILDOFFSET].commute )
break;
1899 }
while ( inter < AN.terstop );
1901 AN.SignCheck = oldSignCheck;
1902 AT.WorkPointer = OldWork;
1905 if ( AT.idallflag && AN.nogroundlevel <= 0 ) {
1906 if ( AT.idallmaxnum > 0 && AT.idallnum >= AT.idallmaxnum ) {
1907 AN.terfirstcomm = Oterfirstcomm;
1908 AN.SignCheck = oldSignCheck;
1909 AT.WorkPointer = OldWork;
1914 if ( AT.idallmaxnum == 0 || AT.idallnum < AT.idallmaxnum )
goto NoMat;
1916 AN.terfirstcomm = Oterfirstcomm;
1917 AN.SignCheck = oldSignCheck;
1921 if ( AN.DisOrderFlag && AN.RepFunNum >= 4 ) {
1923 for ( i = 2; i < AN.RepFunNum; i += 2 ) {
1927 m = AN.terstart + AN.RepFunList[i-2];
1928 t = AN.terstart + AN.RepFunList[i];
1930 if ( *m > *t )
continue;
1933 if ( *m >= FUNCTION && functions[*m-FUNCTION].spec >=
1936 kk = t[1] - FUNHEAD;
1942 kk = t[1] - FUNHEAD;
1946 while ( k > 0 && kk > 0 ) {
1947 if ( *m < *t )
goto NextFor;
1948 else if ( *m++ > *t++ )
goto doesmatch;
1951 if ( k > 0 )
goto doesmatch;
1958 AT.WorkPointer = OldWork;
int Generator(PHEAD WORD *, WORD)