51 WORD 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; }
97 void 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++;
139 void 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 ) {
151 while ( t < endarg ) {
173 void PolyFunClean(
PHEAD WORD *term)
177 tstop = term + *term;
178 tstop -= ABS(tstop[-1]);
180 while ( t < tstop ) {
181 if ( *t == AR.PolyFun ) {
212 WORD Symmetrize(
PHEAD WORD *func, WORD *Lijst, WORD ngroups, WORD gsize,
216 WORD **args,**arg,nargs;
217 WORD *to, *r, *fstop;
218 WORD i, j, k, ff, exch, nexch, neq;
221 if ( ( type & REVERSEORDER ) != 0 ) reverseorder = -1;
222 else reverseorder = 1;
223 type &= ~REVERSEORDER;
225 ff = ( *func > FUNCTION ) ? functions[*func-FUNCTION].spec: 0;
227 if ( 2*func[1] > AN.arglistsize ) {
228 if ( AN.arglist ) M_free(AN.arglist,
"Symmetrize");
229 AN.arglistsize = 2*func[1] + 8;
230 AN.arglist = (WORD **)Malloc1(AN.arglistsize*
sizeof(WORD *),
"Symmetrize");
232 arg = args = AN.arglist;
238 while ( r < fstop ) {
242 if ( *r == FUNNYWILD ) r++;
251 if ( type == SYMMETRIC || type == ANTISYMMETRIC ) {
252 for ( i = 1; i < ngroups; i++ ) {
253 a3 = a2 = a1 + gsize;
254 k = reverseorder*CompGroup(BHEAD ff,args,a1,a2,gsize);
258 for ( k = 0; k < gsize; k++ ) {
259 r = args[a1[k]]; args[a1[k]] = args[a2[k]]; args[a2[k]] = r;
266 k = reverseorder*CompGroup(BHEAD ff,args,a1,a2,gsize);
267 if ( k == 0 ) neq = 2;
272 else if ( k == 0 ) neq = 2;
276 else if ( type == CYCLESYMMETRIC || type == RCYCLESYMMETRIC ) {
277 WORD rev = 0, jmin = 0, ii, iimin;
279 for ( j = 1; j < ngroups; j++ ) {
280 for ( i = 0; i < ngroups; i++ ) {
282 if ( iimin >= ngroups ) iimin -= ngroups;
284 if ( ii >= ngroups ) ii -= ngroups;
285 k = reverseorder*CompGroup(BHEAD ff,args,Lijst+gsize*iimin,Lijst+gsize*ii,gsize);
287 if ( k < 0 ) { jmin = j; nexch = 4;
break; }
290 if ( type == RCYCLESYMMETRIC && rev == 0 && ngroups > 1 ) {
291 for ( j = 0; j < ngroups; j++ ) {
292 for ( i = 0; i < ngroups; i++ ) {
294 if ( iimin >= ngroups ) iimin -= ngroups;
296 if ( ii < 0 ) ii += ngroups;
297 k = reverseorder*CompGroup(BHEAD ff,args,Lijst+gsize*iimin,Lijst+gsize*ii,gsize);
303 a2 = Lijst + gsize * (ngroups-1);
305 for ( k = 0; k < gsize; k++ ) {
307 args[a1[k]] = args[a2[k]];
310 a1 += gsize; a2 -= gsize;
319 arg = AN.arglist + func[1];
320 a1 = Lijst + gsize * jmin;
323 for ( i = 0; i < k; i++ ) {
324 if ( a1 >= a2 ) a1 = Lijst;
325 *arg++ = args[*a1++];
327 arg = AN.arglist + func[1];
329 for ( i = 0; i < k; i++ ) args[*a1++] = *arg++;
335 for ( i = 0; i < nargs; i++ ) {
337 if ( *(args[i]) == FUNNYWILD ) {
341 else *to++ = *(args[i]);
343 else if ( ( j = *args[i] ) < 0 ) {
345 if ( j > -FUNCTION ) *to++ = args[i][1];
356 return ( exch | nexch | neq );
372 WORD CompGroup(
PHEAD WORD type, WORD **args, WORD *a1, WORD *a2, WORD num)
375 WORD *t1, *t2, i1, i2, n, k;
377 for ( n = 0; n < num; n++ ) {
378 t1 = args[a1[n]]; t2 = args[a2[n]];
379 if ( type >= TENSORFUNCTION ) {
380 if ( AR.Eside == LHSIDE || AR.Eside == LHSIDEX ) {
381 if ( *t1 == FUNNYWILD ) {
382 if ( *t2 == FUNNYWILD ) {
383 if ( t1[1] < t2[1] )
return(1);
384 if ( t1[1] > t2[1] )
return(-1);
388 else if ( *t2 == FUNNYWILD ) {
392 if ( *t1 < *t2 )
return(1);
393 if ( *t1 > *t2 )
return(-1);
397 if ( *t1 < *t2 )
return(1);
398 if ( *t1 > *t2 )
return(-1);
401 else if ( type == 0 ) {
402 if ( AC.properorderflag ) {
404 if ( k < 0 )
return(1);
405 if ( k > 0 )
return(-1);
411 i1 = *t1 - ARGHEAD - 1;
414 i2 = *t2 - ARGHEAD - 1;
416 while ( i1 > 0 && i2 > 0 ) {
417 if ( *t1 > *t2 )
return(-1);
418 else if ( *t1 < *t2 )
return(1);
419 i1--; i2--; t1++; t2++;
421 if ( i1 > 0 )
return(-1);
422 else if ( i2 > 0 )
return(1);
430 else if ( *t2 > 0 )
return(1);
433 if ( *t1 <= -FUNCTION && *t2 <= -FUNCTION ) {
434 if ( *t1 < *t2 )
return(-1);
438 if ( *t1 < *t2 )
return(1);
442 if ( *t1 > -FUNCTION ) {
443 if ( t1[1] != t2[1] ) {
444 if ( t1[1] < t2[1] )
return(1);
472 int FullSymmetrize(
PHEAD WORD *fun,
int type)
475 WORD *Lijst, count = 0;
476 WORD *t, *funstop, i;
479 if ( functions[*fun-FUNCTION].spec > 0 ) {
480 count = fun[1] - FUNHEAD;
481 for ( i = fun[1]-1; i >= FUNHEAD; i-- ) {
482 if ( fun[i] == FUNNYWILD ) count--;
486 funstop = fun + fun[1];
488 while ( t < funstop ) { count++; NEXTARG(t) }
491 fun[2] &= ~DIRTYSYMFLAG;
494 Lijst = AT.WorkPointer;
495 for ( i = 0; i < count; i++ ) Lijst[i] = i;
496 AT.WorkPointer += count;
497 retval = Symmetrize(BHEAD fun,Lijst,count,1,type);
498 fun[2] &= ~DIRTYSYMFLAG;
499 AT.WorkPointer = Lijst;
517 WORD SymGen(
PHEAD WORD *term, WORD *params, WORD num, WORD level)
521 WORD i, j, k, c1, c2, ngroup;
522 WORD *rstop, Nlist, *inLijst, *Lijst, sign = 1, sumch = 0, count;
525 c2 = FUNCTION + WILDOFFSET;
527 if ( Nlist < 0 ) Nlist = 0;
528 else Nlist = params[0] - 7;
534 if ( *t == c1 || c1 > c2 ) {
535 if ( *t >= FUNCTION && functions[*t-FUNCTION].spec
536 >= TENSORFUNCTION ) {
537 count = t[1] - FUNHEAD;
544 while ( r < rstop ) { count++; NEXTARG(r) }
546 if ( ( j = params[4] ) > 0 && j != count )
goto NextFun;
549 for ( i = 0; i < Nlist; i++ )
550 if ( inLijst[i] > count-1 )
goto NextFun;
553 if ( Nlist > (params[0] - 7) ) Nlist = params[0] - 7;
554 Lijst = AT.WorkPointer;
555 inLijst = params + 7;
557 if ( Nlist > 0 && j < 0 ) {
559 for ( i = 0; i < ngroup; i++ ) {
560 for ( j = 0; j < params[6]; j++ ) {
561 if ( inLijst[j] > count+1 ) {
562 inLijst += params[6];
567 NCOPY(Lijst,inLijst,j);
571 if ( k <= 1 )
goto NextFun;
573 inLijst = AT.WorkPointer;
574 AT.WorkPointer = Lijst;
577 else if ( Nlist == 0 ) {
578 for ( i = 0; i < count; i++ ) Lijst[i] = i;
579 AT.WorkPointer += count;
583 for ( i = 0; i < Nlist; i++ ) Lijst[i] = inLijst[i];
584 AT.WorkPointer += Nlist;
586 j = Symmetrize(BHEAD t,Lijst,ngroup,params[6],params[2]);
587 AT.WorkPointer = Lijst;
588 if ( params[2] == 4 ) {
589 if ( ( j & 1 ) != 0 ) sign = -sign;
590 if ( ( j & 2 ) != 0 )
return(0);
592 if ( ( j & 4 ) != 0 ) sumch++;
593 t[2] &= ~DIRTYSYMFLAG;
604 if ( Normalize(BHEAD term) ) {
605 MLOCK(ErrorMessageLock);
607 MUNLOCK(ErrorMessageLock);
610 if ( !*term )
return(0);
613 if ( AR.CurDum > AM.IndDum && AR.sLevel <= 0 ) ReNumber(BHEAD term);
632 WORD SymFind(
PHEAD WORD *term, WORD *params)
636 WORD j, c1, c2, count;
639 c2 = FUNCTION + WILDOFFSET;
645 if ( *t == c1 || c1 > c2 ) {
646 if ( *t >= FUNCTION && functions[*t-FUNCTION].spec
647 >= TENSORFUNCTION ) { count = t[1] - FUNHEAD; }
653 while ( r < rstop ) { count++; NEXTARG(r) }
655 if ( ( j = params[5] ) > 0 && j != count )
goto NextFun;
658 rstop = params + params[1];
659 while ( r < rstop ) {
660 if ( *r > count + 1 )
goto NextFun;
690 int ChainIn(
PHEAD WORD *term, WORD funnum)
693 WORD *t, *tend, *m, *tt, *ts;
696 funnum = DolToFunction(BHEAD -funnum);
697 if ( AN.ErrorInDollar || funnum <= 0 ) {
698 MLOCK(ErrorMessageLock);
699 MesPrint(
"Dollar variable does not evaluate to function in ChainIn statement");
700 MUNLOCK(ErrorMessageLock);
707 tend -= ABS(tend[-1]);
710 if ( *t != funnum ) { t += t[1];
continue; }
714 if ( t >= tend || *t != funnum )
continue;
716 while ( t < tend && *t == funnum ) {
719 while ( t < ts ) *tt++ = *t++;
723 while ( t < ts ) *tt++ = *t++;
738 int ChainOut(
PHEAD WORD *term, WORD funnum)
741 WORD *t, *tend, *tt, *ts, *w, *ws;
744 funnum = DolToFunction(BHEAD -funnum);
745 if ( AN.ErrorInDollar || funnum <= 0 ) {
746 MLOCK(ErrorMessageLock);
747 MesPrint(
"Dollar variable does not evaluate to function in ChainOut statement");
748 MUNLOCK(ErrorMessageLock);
753 if ( AT.WorkPointer < tend ) AT.WorkPointer = tend;
754 tend -= ABS(tend[-1]);
755 t = term+1; tt = term; w = AT.WorkPointer;
757 if ( *t != funnum || t[1] == FUNHEAD ) { t += t[1];
continue; }
759 while ( tt < t ) *w++ = *tt++;
764 for ( i = 0; i < FUNHEAD; i++ ) *w++ = tt[i];
765 if ( functions[*tt-FUNCTION].spec >= TENSORFUNCTION ) {
769 if ( *t <= -FUNCTION ) *w++ = *t++;
770 else { *w++ = *t++; *w++ = *t++; }
773 i = *t; NCOPY(w,t,i);
781 while ( tt < ts ) *w++ = *tt++;
782 *AT.WorkPointer = w - AT.WorkPointer;
783 t = term; w = AT.WorkPointer; i = *w;
785 AT.WorkPointer = term + *term;
786 Normalize(BHEAD term);
819 WORD MatchFunction(
PHEAD WORD *pattern, WORD *interm, WORD *wilds)
823 WORD *mstop = 0, *tstop = 0;
824 WORD *argmstop, *argtstop;
825 WORD *mtrmstop, *ttrmstop;
826 WORD *msubstop, *mnextsub;
827 WORD msizcoef, mcount, tcount, newvalue, j;
829 WORD *OldWork, numofwildarg;
830 WORD nwstore, tobeeaten, reservevalue = 0, resernum = 0, withwild;
832 CBUF *C = cbuf+AT.ebufnum;
833 int ntwa = AN.NumTotWildArgs;
838 AN.RepFunList[AN.RepFunNum+1] = 0;
840 m = pattern; t = interm;
843 if ( *m < (FUNCTION + WILDOFFSET) )
return(0);
844 if ( *t < FUNCTION )
return(0);
845 if ( functions[*t-FUNCTION].spec !=
846 functions[*m-FUNCTION-WILDOFFSET].spec )
return(0);
849 if ( *m >= (FUNCTION + WILDOFFSET) ) { i--; m++; t++; }
850 do {
if ( *m++ != *t++ )
break; }
while ( --i > 0 );
852 if ( AN.SignCheck && AN.ExpectedSign )
return(0);
853 i = *pattern - WILDOFFSET;
854 if ( i >= FUNCTION ) {
855 if ( *interm != GAMMA
856 && !CheckWild(BHEAD i,FUNTOFUN,*interm,&newvalue) ) {
857 AddWild(BHEAD i,FUNTOFUN,newvalue);
868 t = wildargtaken = OldWork = AT.WorkPointer;
871 nwstore = i = (m[-SUBEXPSIZE+1]-SUBEXPSIZE)/4;
875 *t++ = *m++; *t++ = *m++; *t++ = *m++; *t++ = *m++; *t++ = *r++;
879 if ( t >= AT.WorkTop ) {
880 MLOCK(ErrorMessageLock);
882 MUNLOCK(ErrorMessageLock);
888 if ( *wilds == 1 )
goto endoloop;
891 m = pattern; t = interm;
908 if ( *m != GAMMA )
goto NoCaseB;
910 if ( m[1] == FUNHEAD+1 ) {
911 if ( i )
goto NoCaseB;
912 if ( m[FUNHEAD] < (AM.OffsetIndex+WILDOFFSET) ||
913 t[FUNHEAD] >= (AM.OffsetIndex+WILDOFFSET) )
goto NoCaseB;
915 if ( CheckWild(BHEAD m[FUNHEAD]-WILDOFFSET,INDTOIND,t[FUNHEAD],&newvalue) )
goto NoCaseB;
916 AddWild(BHEAD m[FUNHEAD]-WILDOFFSET,INDTOIND,newvalue);
918 AT.WorkPointer = OldWork;
919 if ( AN.SignCheck && AN.ExpectedSign )
return(0);
922 if ( i < 0 )
goto NoCaseB;
925 m += FUNHEAD; t += FUNHEAD;
926 if ( *m >= (AM.OffsetIndex+WILDOFFSET) && *t < (AM.OffsetIndex+WILDOFFSET) ) {
927 if ( CheckWild(BHEAD *m-WILDOFFSET,INDTOIND,*t,&newvalue) )
goto NoCaseB;
928 reservevalue = newvalue;
930 resernum = *m-WILDOFFSET;
931 AddWild(BHEAD *m-WILDOFFSET,INDTOIND,newvalue);
933 else if ( *m != *t )
goto NoCaseB;
936 oldm = m; argtstop = oldt = t;
942 if ( t < tstop && mstop < AN.patstop ) {
944 mnextsub = pattern + pattern[1];
946 while ( k == GAMMA && mnextsub[FUNHEAD]
947 != pattern[FUNHEAD] ) {
948 mnextsub += mnextsub[1];
949 if ( mnextsub >= AN.patstop )
goto FullOK;
952 if ( k >= FUNCTION ) {
953 if ( k > (FUNCTION + WILDOFFSET) ) k -= WILDOFFSET;
954 if ( functions[k-FUNCTION].commute )
goto NoGamma;
957 FullOK:
if ( AN.SignCheck && AN.ExpectedSign )
goto NoGamma;
958 AN.RepFunList[AN.RepFunNum+1] = WORDDIF(oldt,argtstop);
961 if ( t >= tstop )
goto NoCaseB;
963 else if ( *m >= (AM.OffsetIndex+WILDOFFSET)
964 && *m < (AM.OffsetIndex + (WILDOFFSET<<1)) && ( *t >= 0 ||
966 if ( !CheckWild(BHEAD *m-WILDOFFSET,INDTOIND,*t,&newvalue) ) {
967 AddWild(BHEAD *m-WILDOFFSET,INDTOIND,newvalue);
973 else if ( *m < MINSPEC && *m >= (AM.OffsetVector+WILDOFFSET)
975 if ( !CheckWild(BHEAD *m-WILDOFFSET,VECTOVEC,*t,&newvalue) ) {
976 AddWild(BHEAD *m-WILDOFFSET,VECTOVEC,newvalue);
986 t = OldWork + AN.NumTotWildArgs; r = AT.WildMask; j = nwstore;
989 *m++ = *t++; *m++ = *t++;
990 *m++ = *t++; *m++ = *t++; *r++ = *t++;
997 m = oldm; t = ++oldt; i--;
999 AddWild(BHEAD resernum,INDTOIND,reservevalue);
1009 else if ( *t >= FUNCTION && functions[*t-FUNCTION].spec >= TENSORFUNCTION ) {
1016 tcount = WORDDIF(tstop,t);
1017 while ( m < mstop ) {
1018 if ( *m == FUNNYWILD ) { m++; AN.WildArgs++; }
1021 tobeeaten = tcount - mcount + AN.WildArgs;
1023 if ( tobeeaten < 0 || AN.WildArgs == 0 ) {
1024 AT.WorkPointer = OldWork;
1028 AT.WildArgTaken[0] = AN.WildEat = tobeeaten;
1029 for ( i = 1; i < AN.WildArgs; i++ ) AT.WildArgTaken[i] = 0;
1033 m = pattern; t = interm;
1036 i = *m - WILDOFFSET;
1037 if ( CheckWild(BHEAD i,FUNTOFUN,*t,&newvalue) )
goto NoCaseB;
1038 AddWild(BHEAD i,FUNTOFUN,newvalue);
1042 while ( m < mstop ) {
1046 if ( *m == *t ) { m++; t++;
continue; }
1051 if ( *m == FUNNYWILD ) {
1052 tobeeaten = AT.WildArgTaken[numofwildarg++];
1053 i = tobeeaten | EATTENSOR;
1054 if ( CheckWild(BHEAD m[1],ARGTOARG,i,t) )
goto endloop;
1055 AddWild(BHEAD m[1],ARGTOARG,i);
1064 if ( i < MINSPEC ) {
1066 if ( *t >= MINSPEC )
goto endloop;
1068 if ( i < AM.OffsetVector )
goto endloop;
1069 if ( CheckWild(BHEAD i,VECTOVEC,*t,&newvalue) )
1071 AddWild(BHEAD i,VECTOVEC,newvalue);
1074 else if ( i >= AM.OffsetIndex ) {
1075 if ( i < ( AM.OffsetIndex + WILDOFFSET ) )
goto endloop;
1076 if ( i >= ( AM.OffsetIndex + (WILDOFFSET<<1) ) ) {
1081 if ( CheckWild(BHEAD i,INDTOIND,*t,&newvalue) )
1083 AddWild(BHEAD i,INDTOIND,newvalue);
1088 if ( AN.SignCheck && AN.ExpectedSign )
goto endloop;
1089 AT.WorkPointer = OldWork;
1090 if ( AN.WildArgs > 1 ) *wilds = 2;
1100 t = OldWork + ntwa; r = AT.WildMask;
1102 *m++ = *t++; *m++ = *t++; *m++ = *t++; *m++ = *t++; *r++ = *t++;
1103 }
while ( --i > 0 );
1108 i = AN.WildArgs - 1;
1110 AT.WorkPointer = OldWork;
1113 while ( --i >= 0 ) {
1114 if ( AT.WildArgTaken[i] == 0 ) {
1116 AT.WorkPointer = OldWork;
1122 (AT.WildArgTaken[i])--;
1124 for ( j = 0; j <= i; j++ ) {
1125 numofwildarg += AT.WildArgTaken[j];
1127 AT.WildArgTaken[j] = AN.WildEat-numofwildarg;
1128 for ( j++; j < AN.WildArgs; j++ ) AT.WildArgTaken[j] = 0;
1142 mcount = 0; tcount = 0;
1143 m += FUNHEAD; t += FUNHEAD;
1144 while ( t < tstop ) { tcount++; NEXTARG(t) }
1146 while ( m < mstop ) {
1148 if ( *m == -ARGWILD ) AN.WildArgs++;
1151 tobeeaten = tcount - mcount + AN.WildArgs;
1153 if ( tobeeaten < 0 || AN.WildArgs == 0 ) {
1154 AT.WorkPointer = OldWork;
1162 AT.WildArgTaken[0] = AN.WildEat = tobeeaten;
1163 for ( i = 1; i < AN.WildArgs; i++ ) AT.WildArgTaken[i] = 0;
1169 m = pattern; t = interm;
1171 i = *m - WILDOFFSET;
1172 if ( CheckWild(BHEAD i,FUNTOFUN,*t,&newvalue) )
goto NoCaseB;
1173 AddWild(BHEAD i,FUNTOFUN,newvalue);
1179 while ( m < mstop ) {
1180 argmstop = oldm = m;
1181 argtstop = oldt = t;
1185 if ( *m == -ARGWILD )
goto ArgAll;
1188 if ( *m < 0 && *t < 0 ) {
1189 if ( *t <= -FUNCTION ) {
1191 else if ( *m <= -FUNCTION-WILDOFFSET
1192 && functions[-*t-FUNCTION].spec
1193 == functions[-*m-FUNCTION-WILDOFFSET].spec ) {
1194 i = -*m - WILDOFFSET;
1195 if ( CheckWild(BHEAD i,FUNTOFUN,-*t,&newvalue) )
goto endofloop;
1196 AddWild(BHEAD i,FUNTOFUN,newvalue);
1198 else if ( *m == -SYMBOL && m[1] >= 2*MAXPOWER ) {
1199 i = m[1] - 2*MAXPOWER;
1200 AN.argaddress = AT.FunArg;
1201 AT.FunArg[ARGHEAD+1] = -*t;
1202 if ( CheckWild(BHEAD i,SYMTOSUB,1,AN.argaddress) )
goto endofloop;
1203 AddWild(BHEAD i,SYMTOSUB,0);
1205 else if ( *m == -ARGWILD ) {
1206 ArgAll: i = AT.WildArgTaken[numofwildarg++];
1208 if ( CheckWild(BHEAD m[1],ARGTOARG,i,t) )
goto endofloop;
1209 AddWild(BHEAD m[1],ARGTOARG,i);
1211 while ( --i >= 0 ) { NEXTARG(t) }
1214 else goto endofloop;
1216 else if ( *t == *m ) {
1217 if ( t[1] == m[1] ) {}
1218 else if ( *t == -SYMBOL ) {
1221 if ( ( i = m[1] - 2*MAXPOWER ) < 0 )
goto endofloop;
1222 if ( CheckWild(BHEAD i,j,t[1],&newvalue) )
goto endofloop;
1223 AddWild(BHEAD i,j,newvalue);
1225 else if ( *t == -INDEX ) {
1226 IndAll: i = m[1] - WILDOFFSET;
1227 if ( i < AM.OffsetIndex || i >= WILDOFFSET+AM.OffsetIndex )
1230 if ( CheckWild(BHEAD i,INDTOIND,t[1],&newvalue) )
goto endofloop;
1231 AddWild(BHEAD i,INDTOIND,newvalue);
1233 else if ( *t == -VECTOR || *t == -MINVECTOR ) {
1234 i = m[1] - WILDOFFSET;
1235 if ( i < AM.OffsetVector )
goto endofloop;
1236 if ( CheckWild(BHEAD i,VECTOVEC,t[1],&newvalue) )
goto endofloop;
1237 AddWild(BHEAD i,VECTOVEC,newvalue);
1239 else goto endofloop;
1241 else if ( *m == -ARGWILD )
goto ArgAll;
1242 else if ( *m == -INDEX && m[1] >= AM.OffsetIndex+WILDOFFSET
1243 && m[1] < AM.OffsetIndex+(WILDOFFSET<<1) ) {
1244 if ( *t == -VECTOR || *t == -SNUMBER )
goto IndAll;
1245 if ( *t == -MINVECTOR ) {
1246 i = m[1] - WILDOFFSET;
1247 AN.argaddress = AT.MinVecArg;
1248 AT.MinVecArg[ARGHEAD+3] = t[1];
1249 if ( CheckWild(BHEAD i,INDTOSUB,1,AN.argaddress) )
goto endofloop;
1250 AddWild(BHEAD i,INDTOSUB,(WORD)0);
1252 else goto endofloop;
1254 else if ( *m == -SYMBOL && m[1] >= 2*MAXPOWER && *t == -SNUMBER ) {
1258 else if ( *m == -VECTOR && *t == -MINVECTOR &&
1259 ( i = m[1] - WILDOFFSET ) >= AM.OffsetVector ) {
1260 AN.argaddress = AT.MinVecArg;
1261 AT.MinVecArg[ARGHEAD+3] = t[1];
1262 if ( CheckWild(BHEAD i,VECTOSUB,1,AN.argaddress) )
goto endofloop;
1263 AddWild(BHEAD i,VECTOSUB,(WORD)0);
1265 else goto endofloop;
1267 else if ( *t <= -FUNCTION && *m > 0 ) {
1268 if ( ( m[ARGHEAD]+ARGHEAD == *m ) && m[*m-1] == 3
1269 && m[*m-2] == 1 && m[*m-3] == 1 && m[ARGHEAD+1] >= FUNCTION
1270 && m[ARGHEAD+2] == *m-ARGHEAD-4 ) {
1272 if ( m[ARGHEAD+1] >= FUNCTION+WILDOFFSET ) {
1274 i = m[ARGHEAD+1] - WILDOFFSET;
1275 if ( CheckWild(BHEAD i,FUNTOFUN,-*t,&newvalue) )
goto endofloop;
1276 AddWild(BHEAD i,FUNTOFUN,newvalue);
1278 else if ( m[ARGHEAD+1] != -*t )
goto endofloop;
1283 mmm = m + ARGHEAD + FUNHEAD + 1;
1284 while ( mmm < mmmst ) {
1285 if ( *mmm != -ARGWILD )
goto endofloop;
1288 if ( CheckWild(BHEAD mmm[1],ARGTOARG,i,t) )
goto endofloop;
1289 AddWild(BHEAD mmm[1],ARGTOARG,i);
1293 else goto endofloop;
1295 else if ( *m < 0 && *t > 0 ) {
1296 if ( *m == -SYMBOL ) {
1297 if ( m[1] < 2*MAXPOWER )
goto endofloop;
1298 i = m[1] - 2*MAXPOWER;
1300 if ( CheckWild(BHEAD i,SYMTOSUB,1,AN.argaddress) )
goto endofloop;
1301 AddWild(BHEAD i,SYMTOSUB,0);
1303 else if ( *m == -VECTOR ) {
1304 if ( ( i = m[1] - WILDOFFSET ) < AM.OffsetVector )
1307 if ( CheckWild(BHEAD i,VECTOSUB,1,t) )
goto endofloop;
1308 AddWild(BHEAD i,VECTOSUB,(WORD)0);
1310 else if ( *m == -INDEX ) {
1311 if ( ( i = m[1] - WILDOFFSET ) < AM.OffsetIndex )
goto endofloop;
1312 if ( i >= AM.OffsetIndex + WILDOFFSET )
goto endofloop;
1314 if ( CheckWild(BHEAD i,INDTOSUB,1,AN.argaddress) )
goto endofloop;
1315 AddWild(BHEAD i,INDTOSUB,(WORD)0);
1317 else if ( *m == -ARGWILD )
goto ArgAll;
1318 else goto endofloop;
1320 else if ( *m > 0 && *t > 0 ) {
1322 do {
if ( *m++ != *t++ )
break; }
while ( --i > 0 );
1324 WORD *cto, *cfrom, *csav, ci;
1327 WORD *oterstart,*oterstop,*opatstop;
1329 WORD wildargs, wildeat;
1335 m += ARGHEAD; t += ARGHEAD;
1338 if ( mtrmstop < argmstop )
goto endofloop;
1339 msizcoef = mtrmstop[-1];
1340 if ( msizcoef < 0 ) msizcoef = -msizcoef;
1341 msubstop = mtrmstop - msizcoef;
1343 if ( m >= msubstop )
goto endofloop;
1357 if ( argtstop > ttrmstop )
goto endofloop;
1359 oterstart = AN.terstart;
1360 oterstop = AN.terstop;
1361 opatstop = AN.patstop;
1362 oRepFunList = AN.RepFunList;
1363 oRepFunNum = AN.RepFunNum;
1365 AN.RepFunList = AT.WorkPointer;
1366 AT.WorkPointer = (WORD *)(((UBYTE *)(AT.WorkPointer)) + AM.MaxTer);
1367 csav = cto = AT.WorkPointer;
1370 while ( --ci >= 0 ) *cto++ = *cfrom++;
1371 AT.WorkPointer = cto;
1375 if ( abs(*--cfrom) != abs(*--cto) ) {
1376 AT.WorkPointer = csav;
1377 AN.RepFunList = oRepFunList;
1378 AN.RepFunNum = oRepFunNum;
1379 AN.terstart = oterstart;
1380 AN.terstop = oterstop;
1381 AN.patstop = opatstop;
1384 i = (*cfrom != *cto) ? 1 : 0;
1385 while ( --ci >= 0 ) {
1386 if ( *--cfrom != *--cto ) {
1387 AT.WorkPointer = csav;
1388 AN.RepFunList = oRepFunList;
1389 AN.RepFunNum = oRepFunNum;
1390 AN.terstart = oterstart;
1391 AN.terstop = oterstop;
1392 AN.patstop = opatstop;
1396 oExpectedSign = AN.ExpectedSign;
1397 AN.ExpectedSign = i;
1399 wildargs = AN.WildArgs;
1400 wildeat = AN.WildEat;
1401 for ( i = 0; i < wildargs; i++ ) wildargtaken[i] = AT.WildArgTaken[i];
1402 AN.ForFindOnly = 0; AN.UseFindOnly = 1;
1404 if ( FindRest(BHEAD csav,m) && ( AN.UsedOtherFind || FindOnly(BHEAD csav,m) ) ) {}
1408 AT.WorkPointer = csav;
1409 AN.RepFunList = oRepFunList;
1410 AN.RepFunNum = oRepFunNum;
1411 AN.terstart = oterstart;
1412 AN.terstop = oterstop;
1413 AN.patstop = opatstop;
1414 AN.WildArgs = wildargs;
1415 AN.WildEat = wildeat;
1416 AN.ExpectedSign = oExpectedSign;
1418 for ( i = 0; i < wildargs; i++ ) AT.WildArgTaken[i] = wildargtaken[i];
1422 if ( *m == 1 || m[1] < FUNCTION ) {
1423 if ( AN.ExpectedSign )
goto nomatch;
1426 AN.ExpectedSign = oExpectedSign;
1427 AN.WildArgs = wildargs;
1428 AN.WildEat = wildeat;
1429 for ( i = 0; i < wildargs; i++ ) AT.WildArgTaken[i] = wildargtaken[i];
1430 Substitute(BHEAD csav,m,1);
1432 cfrom = cto + *cto - msizcoef;
1435 AT.WorkPointer = csav;
1436 AN.RepFunList = oRepFunList;
1437 AN.RepFunNum = oRepFunNum;
1438 AN.terstart = oterstart;
1439 AN.terstop = oterstop;
1440 AN.patstop = opatstop;
1441 if ( *cto != SUBEXPRESSION )
goto endofloop;
1443 if ( cto < cfrom )
goto endofloop;
1446 else goto endofloop;
1451 if ( AN.SignCheck && AN.ExpectedSign )
goto endofloop;
1452 AT.WorkPointer = OldWork;
1453 if ( AN.WildArgs > 1 ) *wilds = 1;
1454 if ( AN.SignCheck && AN.ExpectedSign )
return(0);
1464 t = OldWork + ntwa; r = AT.WildMask;
1466 *m++ = *t++; *m++ = *t++; *m++ = *t++; *m++ = *t++; *r++ = *t++;
1467 }
while ( --i > 0 );
1475 AT.WorkPointer = OldWork;
1478 while ( --i >= 0 ) {
1479 if ( AT.WildArgTaken[i] == 0 ) {
1481 AT.WorkPointer = OldWork;
1486 (AT.WildArgTaken[i])--;
1488 for ( j = 0; j <= i; j++ ) {
1489 numofwildarg += AT.WildArgTaken[j];
1491 AT.WildArgTaken[j] = AN.WildEat-numofwildarg;
1493 for ( j++; j < AN.WildArgs; j++ ) AT.WildArgTaken[j] = 0;
1505 t = OldWork + ntwa; r = AT.WildMask;
1507 *m++ = *t++; *m++ = *t++; *m++ = *t++; *m++ = *t++; *r++ = *t++;
1508 }
while ( --i > 0 );
1512 AT.WorkPointer = OldWork;
1560 WORD ScanFunctions(
PHEAD WORD *inpat, WORD *inter, WORD par)
1563 WORD i, *m, *t, *r, sym, psym;
1564 WORD *newpat, *newter, *instart, *oinpat = 0, *ointer = 0;
1565 WORD nwstore, offset, *OldWork, SetStop = 0, oRepFunNum = AN.RepFunNum;
1566 WORD wilds, wildargs = 0, wildeat = 0, *wildargtaken;
1567 WORD *Oterfirstcomm = AN.terfirstcomm;
1568 CBUF *C = cbuf+AT.ebufnum;
1569 int ntwa = AN.NumTotWildArgs;
1576 if ( AN.nogroundlevel ) {
1577 AN.SignCheck = ( inpat + inpat[1] >= AN.patstop ) ? 1 : 0;
1585 t = wildargtaken = OldWork = AT.WorkPointer;
1588 nwstore = i = (m[-SUBEXPSIZE+1]-SUBEXPSIZE)/4;
1592 *t++ = *m++; *t++ = *m++; *t++ = *m++; *t++ = *m++; *t++ = *r++;
1593 }
while ( --i > 0 );
1596 if ( t >= AT.WorkTop ) {
1597 MLOCK(ErrorMessageLock);
1599 MUNLOCK(ErrorMessageLock);
1608 if ( AN.RepFunNum > 0 ) {
1613 if ( *inter >= FUNCTION && functions[*inter-FUNCTION].commute ) {
1615 offset = WORDDIF(inter,AN.terstart);
1616 for ( i = 0; i < AN.RepFunNum; i += 2 ) {
1617 if ( AN.RepFunList[i] >= offset )
break;
1619 if ( i >= AN.RepFunNum )
break;
1621 }
while ( inter < AN.terfirstcomm );
1622 if ( inter < AN.terfirstcomm ) {
1623 for ( i = 0; i < AN.RepFunNum; i += 2 ) {
1624 if ( functions[AN.terstart[AN.RepFunList[i]]-FUNCTION].commute
1625 && AN.RepFunList[i]+AN.terstart[AN.RepFunList[i]+1] == offset )
break;
1627 if ( i < AN.RepFunNum )
goto trythis;
1629 inter = AN.terfirstcomm;
1634 while ( inter < AN.terstop ) {
1635 offset = WORDDIF(inter,AN.terstart);
1636 for ( i = 0; i < AN.RepFunNum; i += 2 ) {
1637 if ( AN.RepFunList[i] == offset )
break;
1639 if ( i >= AN.RepFunNum )
break;
1642 if ( inter >= AN.terstop ) { AT.WorkPointer = OldWork;
return(0); }
1649 offset = WORDDIF(inter,AN.terstart);
1654 offset = WORDDIF(inter,AN.terstart);
1655 for ( i = 0; i < AN.RepFunNum; i += 2 ) {
1656 if ( AN.RepFunList[i] == offset )
break;
1658 if ( i >= AN.RepFunNum )
break;
1660 }
while ( inter < AN.terstop );
1661 if ( inter >= AN.terstop ) { AT.WorkPointer = OldWork;
return(0); }
1665 if ( *inter >= FUNCTION && *inpat >= FUNCTION ) {
1666 if ( *inpat == *inter || *inpat >= FUNCTION + WILDOFFSET ) {
1670 if ( functions[*inter-FUNCTION].spec >= TENSORFUNCTION
1671 && ( *inter == *inpat ||
1672 functions[*inpat-FUNCTION-WILDOFFSET].spec >= TENSORFUNCTION ) ) {
1673 sym = functions[*inter-FUNCTION].symmetric & ~REVERSEORDER;
1674 if ( *inpat == *inter ) psym = sym;
1675 else psym = functions[*inpat-FUNCTION-WILDOFFSET].symmetric & ~REVERSEORDER;
1676 if ( sym == ANTISYMMETRIC || sym == SYMMETRIC
1677 || psym == SYMMETRIC || psym == ANTISYMMETRIC ) {
1678 if ( sym == ANTISYMMETRIC && psym == SYMMETRIC )
goto rewild;
1679 if ( sym == SYMMETRIC && psym == ANTISYMMETRIC )
goto rewild;
1683 if ( MatchE(BHEAD inpat,inter,instart,par) )
goto OnSuccess;
1685 else if ( sym == CYCLESYMMETRIC || sym == RCYCLESYMMETRIC
1686 || psym == CYCLESYMMETRIC || psym == RCYCLESYMMETRIC ) {
1690 if ( MatchCy(BHEAD inpat,inter,instart,par) )
goto OnSuccess;
1694 else if ( functions[*inter-FUNCTION].spec == 0
1695 && ( *inter == *inpat ||
1696 functions[*inpat-FUNCTION-WILDOFFSET].spec == 0 ) ) {
1697 sym = functions[*inter-FUNCTION].symmetric & ~REVERSEORDER;
1698 if ( *inpat == *inter ) psym = sym;
1699 else psym = functions[*inpat-FUNCTION-WILDOFFSET].symmetric & ~REVERSEORDER;
1700 if ( psym == SYMMETRIC || sym == SYMMETRIC
1706 || psym == ANTISYMMETRIC || sym == ANTISYMMETRIC
1708 if ( sym == ANTISYMMETRIC && psym == SYMMETRIC )
goto rewild;
1709 if ( sym == SYMMETRIC && psym == ANTISYMMETRIC )
goto rewild;
1710 if ( FunMatchSy(BHEAD inpat,inter,instart,par) )
goto OnSuccess;
1713 if ( sym == CYCLESYMMETRIC || sym == RCYCLESYMMETRIC
1714 || psym == CYCLESYMMETRIC || psym == RCYCLESYMMETRIC ) {
1715 if ( FunMatchCy(BHEAD inpat,inter,instart,par) )
goto OnSuccess;
1720 AN.terfirstcomm = Oterfirstcomm;
1722 else if ( par > 0 ) { SetStop = 1;
goto maybenext; }
1726 AN.terfirstcomm = Oterfirstcomm;
1727 if ( *inter != SUBEXPRESSION && MatchFunction(BHEAD inpat,inter,&wilds) ) {
1728 AN.terfirstcomm = Oterfirstcomm;
1730 wildargs = AN.WildArgs;
1731 wildeat = AN.WildEat;
1732 for ( i = 0; i < wildargs; i++ ) wildargtaken[i] = AT.WildArgTaken[i];
1733 oinpat = inpat; ointer = inter;
1735 if ( par && *inter == GAMMA && AN.RepFunList[AN.RepFunNum+1] ) {
1736 SetStop = 1;
goto NoMat;
1739 if ( *inter < FUNCTION || functions[*inter-FUNCTION].commute ) {
1744 AN.RepFunList[AN.RepFunNum] = offset;
1746 newpat = inpat + inpat[1];
1747 if ( newpat >= AN.patstop ) {
1748 if ( AN.UseFindOnly == 0 ) {
1749 if ( FindOnce(BHEAD AN.findTerm,AN.findPattern) ) {
1750 AN.UsedOtherFind = 1;
1758 if ( *inter < FUNCTION || functions[*inter-FUNCTION].commute ) {
1759 newter = inter + inter[1];
1760 if ( newter >= AN.terstop ) { AT.WorkPointer = OldWork;
return(0); }
1761 if ( *inter == GAMMA && inpat[1] <
1762 inter[1] - AN.RepFunList[AN.RepFunNum-1] ) {
1763 if ( ScanFunctions(BHEAD newpat,newter,2) )
goto OnSuccess;
1764 AN.terfirstcomm = Oterfirstcomm;
1766 else if ( *newter == SUBEXPRESSION ) {}
1767 else if ( functions[*inter-FUNCTION].commute ) {
1768 if ( ScanFunctions(BHEAD newpat,newter,1) )
goto OnSuccess;
1769 AN.terfirstcomm = Oterfirstcomm;
1770 if ( ( *newpat < (FUNCTION+WILDOFFSET)
1771 && ( functions[*newpat-FUNCTION].commute == 0 ) ) ||
1772 ( *newpat >= (FUNCTION+WILDOFFSET)
1773 && ( functions[*newpat-FUNCTION-WILDOFFSET].commute == 0 ) ) ) {
1774 newter = AN.terfirstcomm;
1775 if ( newter < AN.terstop && ScanFunctions(BHEAD newpat,newter,1) )
goto OnSuccess;
1779 if ( ScanFunctions(BHEAD newpat,instart,1) )
goto OnSuccess;
1780 AN.terfirstcomm = Oterfirstcomm;
1788 if ( par && inter > instart && ( ( *newpat < (FUNCTION+WILDOFFSET)
1789 && functions[*newpat-FUNCTION].commute ) ||
1790 ( *newpat >= (FUNCTION+WILDOFFSET)
1791 && functions[*newpat-FUNCTION-WILDOFFSET].commute ) ) ) {
1796 if ( ScanFunctions(BHEAD newpat,newter,par) )
goto OnSuccess;
1797 AN.terfirstcomm = Oterfirstcomm;
1807 t = OldWork + ntwa; r = AT.WildMask;
1809 *m++ = *t++; *m++ = *t++; *m++ = *t++; *m++ = *t++; *r++ = *t++;
1810 }
while ( --i > 0 );
1815 AN.RepFunNum = oRepFunNum;
1817 inter = ointer; inpat = oinpat;
1818 AN.WildArgs = wildargs;
1819 AN.WildEat = wildeat;
1820 for ( i = 0; i < wildargs; i++ ) AT.WildArgTaken[i] = wildargtaken[i];
1823 if ( SetStop )
break;
1827 if ( *inpat < (FUNCTION+WILDOFFSET) ) {
1828 if ( *inpat < FUNCTION ||
1829 functions[*inpat-FUNCTION].commute )
break;
1832 if ( functions[*inpat-FUNCTION-WILDOFFSET].commute )
break;
1836 }
while ( inter < AN.terstop );
1837 AT.WorkPointer = OldWork;
1840 AN.terfirstcomm = Oterfirstcomm;
1844 if ( AN.DisOrderFlag && AN.RepFunNum >= 4 ) {
1846 for ( i = 2; i < AN.RepFunNum; i += 2 ) {
1850 m = AN.terstart + AN.RepFunList[i-2];
1851 t = AN.terstart + AN.RepFunList[i];
1853 if ( *m > *t )
continue;
1854 jexch: AT.WorkPointer = OldWork;
1857 if ( *m >= FUNCTION && functions[*m-FUNCTION].spec >=
1860 kk = t[1] - FUNHEAD;
1866 kk = t[1] - FUNHEAD;
1870 while ( k > 0 && kk > 0 ) {
1871 if ( *m < *t )
goto NextFor;
1872 else if ( *m++ > *t++ )
goto jexch;
1875 if ( k > 0 )
goto jexch;
1881 AT.WorkPointer = OldWork;
WORD Generator(PHEAD WORD *, WORD)