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 ) {
148 if ( AR.PolyFunType == 2 ) t[2] |= MUSTCLEANPRF;
152 while ( t < endarg ) {
174 void 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;
213 WORD 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 );
373 WORD 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);
473 int 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;
518 WORD 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);
633 WORD 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;
691 int ChainIn(PHEAD WORD *term, WORD funnum)
694 WORD *t, *tend, *m, *tt, *ts;
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;
717 while ( t < tend && *t == funnum ) {
720 while ( t < ts ) *tt++ = *t++;
724 while ( t < ts ) *tt++ = *t++;
739 int ChainOut(PHEAD WORD *term, WORD funnum)
742 WORD *t, *tend, *tt, *ts, *w, *ws;
745 funnum = DolToFunction(BHEAD -funnum);
746 if ( AN.ErrorInDollar || funnum <= 0 ) {
747 MLOCK(ErrorMessageLock);
748 MesPrint(
"Dollar variable does not evaluate to function in ChainOut statement");
749 MUNLOCK(ErrorMessageLock);
754 if ( AT.WorkPointer < tend ) AT.WorkPointer = tend;
755 tend -= ABS(tend[-1]);
756 t = term+1; tt = term; w = AT.WorkPointer;
758 if ( *t != funnum || t[1] == FUNHEAD ) { t += t[1];
continue; }
760 while ( tt < t ) *w++ = *tt++;
765 for ( i = 0; i < FUNHEAD; i++ ) *w++ = tt[i];
766 if ( functions[*tt-FUNCTION].spec >= TENSORFUNCTION ) {
770 if ( *t <= -FUNCTION ) *w++ = *t++;
771 else { *w++ = *t++; *w++ = *t++; }
774 i = *t; NCOPY(w,t,i);
782 while ( tt < ts ) *w++ = *tt++;
783 *AT.WorkPointer = w - AT.WorkPointer;
784 t = term; w = AT.WorkPointer; i = *w;
786 AT.WorkPointer = term + *term;
787 Normalize(BHEAD term);
817 WORD MatchFunction(PHEAD WORD *pattern, WORD *interm, WORD *wilds)
821 WORD *mstop = 0, *tstop = 0;
822 WORD *argmstop, *argtstop;
823 WORD *mtrmstop, *ttrmstop;
824 WORD *msubstop, *mnextsub;
825 WORD msizcoef, mcount, tcount, newvalue, j;
827 WORD *OldWork, numofwildarg;
828 WORD nwstore, tobeeaten, reservevalue = 0, resernum = 0, withwild;
830 CBUF *C = cbuf+AT.ebufnum;
831 int ntwa = AN.NumTotWildArgs;
836 AN.RepFunList[AN.RepFunNum+1] = 0;
838 m = pattern; t = interm;
841 if ( *m < (FUNCTION + WILDOFFSET) )
return(0);
842 if ( *t < FUNCTION )
return(0);
843 if ( functions[*t-FUNCTION].spec !=
844 functions[*m-FUNCTION-WILDOFFSET].spec )
return(0);
847 if ( *m >= (FUNCTION + WILDOFFSET) ) { i--; m++; t++; }
848 do {
if ( *m++ != *t++ )
break; }
while ( --i > 0 );
850 if ( AN.SignCheck && AN.ExpectedSign )
return(0);
851 i = *pattern - WILDOFFSET;
852 if ( i >= FUNCTION ) {
853 if ( *interm != GAMMA
854 && !CheckWild(BHEAD i,FUNTOFUN,*interm,&newvalue) ) {
855 AddWild(BHEAD i,FUNTOFUN,newvalue);
866 t = wildargtaken = OldWork = AT.WorkPointer;
869 nwstore = i = (m[-SUBEXPSIZE+1]-SUBEXPSIZE)/4;
873 *t++ = *m++; *t++ = *m++; *t++ = *m++; *t++ = *m++; *t++ = *r++;
877 if ( t >= AT.WorkTop ) {
878 MLOCK(ErrorMessageLock);
880 MUNLOCK(ErrorMessageLock);
886 if ( *wilds == 1 )
goto endoloop;
889 m = pattern; t = interm;
906 if ( *m != GAMMA )
goto NoCaseB;
908 if ( m[1] == FUNHEAD+1 ) {
909 if ( i )
goto NoCaseB;
910 if ( m[FUNHEAD] < (AM.OffsetIndex+WILDOFFSET) ||
911 t[FUNHEAD] >= (AM.OffsetIndex+WILDOFFSET) )
goto NoCaseB;
913 if ( CheckWild(BHEAD m[FUNHEAD]-WILDOFFSET,INDTOIND,t[FUNHEAD],&newvalue) )
goto NoCaseB;
914 AddWild(BHEAD m[FUNHEAD]-WILDOFFSET,INDTOIND,newvalue);
916 AT.WorkPointer = OldWork;
917 if ( AN.SignCheck && AN.ExpectedSign )
return(0);
920 if ( i < 0 )
goto NoCaseB;
923 m += FUNHEAD; t += FUNHEAD;
924 if ( *m >= (AM.OffsetIndex+WILDOFFSET) && *t < (AM.OffsetIndex+WILDOFFSET) ) {
925 if ( CheckWild(BHEAD *m-WILDOFFSET,INDTOIND,*t,&newvalue) )
goto NoCaseB;
926 reservevalue = newvalue;
928 resernum = *m-WILDOFFSET;
929 AddWild(BHEAD *m-WILDOFFSET,INDTOIND,newvalue);
931 else if ( *m != *t )
goto NoCaseB;
934 oldm = m; argtstop = oldt = t;
940 if ( t < tstop && mstop < AN.patstop ) {
942 mnextsub = pattern + pattern[1];
944 while ( k == GAMMA && mnextsub[FUNHEAD]
945 != pattern[FUNHEAD] ) {
946 mnextsub += mnextsub[1];
947 if ( mnextsub >= AN.patstop )
goto FullOK;
950 if ( k >= FUNCTION ) {
951 if ( k > (FUNCTION + WILDOFFSET) ) k -= WILDOFFSET;
952 if ( functions[k-FUNCTION].commute )
goto NoGamma;
955 FullOK:
if ( AN.SignCheck && AN.ExpectedSign )
goto NoGamma;
956 AN.RepFunList[AN.RepFunNum+1] = WORDDIF(oldt,argtstop);
959 if ( t >= tstop )
goto NoCaseB;
961 else if ( *m >= (AM.OffsetIndex+WILDOFFSET)
962 && *m < (AM.OffsetIndex + (WILDOFFSET<<1)) && ( *t >= 0 ||
964 if ( !CheckWild(BHEAD *m-WILDOFFSET,INDTOIND,*t,&newvalue) ) {
965 AddWild(BHEAD *m-WILDOFFSET,INDTOIND,newvalue);
971 else if ( *m < MINSPEC && *m >= (AM.OffsetVector+WILDOFFSET)
973 if ( !CheckWild(BHEAD *m-WILDOFFSET,VECTOVEC,*t,&newvalue) ) {
974 AddWild(BHEAD *m-WILDOFFSET,VECTOVEC,newvalue);
984 t = OldWork + AN.NumTotWildArgs; r = AT.WildMask; j = nwstore;
987 *m++ = *t++; *m++ = *t++;
988 *m++ = *t++; *m++ = *t++; *r++ = *t++;
995 m = oldm; t = ++oldt; i--;
997 AddWild(BHEAD resernum,INDTOIND,reservevalue);
1007 else if ( *t >= FUNCTION && functions[*t-FUNCTION].spec >= TENSORFUNCTION ) {
1014 tcount = WORDDIF(tstop,t);
1015 while ( m < mstop ) {
1016 if ( *m == FUNNYWILD ) { m++; AN.WildArgs++; }
1019 tobeeaten = tcount - mcount + AN.WildArgs;
1021 if ( tobeeaten < 0 || AN.WildArgs == 0 ) {
1022 AT.WorkPointer = OldWork;
1026 AT.WildArgTaken[0] = AN.WildEat = tobeeaten;
1027 for ( i = 1; i < AN.WildArgs; i++ ) AT.WildArgTaken[i] = 0;
1031 m = pattern; t = interm;
1034 i = *m - WILDOFFSET;
1035 if ( CheckWild(BHEAD i,FUNTOFUN,*t,&newvalue) )
goto NoCaseB;
1036 AddWild(BHEAD i,FUNTOFUN,newvalue);
1040 while ( m < mstop ) {
1044 if ( *m == *t ) { m++; t++;
continue; }
1049 if ( *m == FUNNYWILD ) {
1050 tobeeaten = AT.WildArgTaken[numofwildarg++];
1051 i = tobeeaten | EATTENSOR;
1052 if ( CheckWild(BHEAD m[1],ARGTOARG,i,t) )
goto endloop;
1053 AddWild(BHEAD m[1],ARGTOARG,i);
1062 if ( i < MINSPEC ) {
1064 if ( *t >= MINSPEC )
goto endloop;
1066 if ( i < AM.OffsetVector )
goto endloop;
1067 if ( CheckWild(BHEAD i,VECTOVEC,*t,&newvalue) )
1069 AddWild(BHEAD i,VECTOVEC,newvalue);
1072 else if ( i >= AM.OffsetIndex ) {
1073 if ( i < ( AM.OffsetIndex + WILDOFFSET ) )
goto endloop;
1074 if ( i >= ( AM.OffsetIndex + (WILDOFFSET<<1) ) ) {
1079 if ( CheckWild(BHEAD i,INDTOIND,*t,&newvalue) )
1081 AddWild(BHEAD i,INDTOIND,newvalue);
1086 if ( AN.SignCheck && AN.ExpectedSign )
goto endloop;
1087 AT.WorkPointer = OldWork;
1088 if ( AN.WildArgs > 1 ) *wilds = 2;
1098 t = OldWork + ntwa; r = AT.WildMask;
1100 *m++ = *t++; *m++ = *t++; *m++ = *t++; *m++ = *t++; *r++ = *t++;
1101 }
while ( --i > 0 );
1106 i = AN.WildArgs - 1;
1108 AT.WorkPointer = OldWork;
1111 while ( --i >= 0 ) {
1112 if ( AT.WildArgTaken[i] == 0 ) {
1114 AT.WorkPointer = OldWork;
1120 (AT.WildArgTaken[i])--;
1122 for ( j = 0; j <= i; j++ ) {
1123 numofwildarg += AT.WildArgTaken[j];
1125 AT.WildArgTaken[j] = AN.WildEat-numofwildarg;
1126 for ( j++; j < AN.WildArgs; j++ ) AT.WildArgTaken[j] = 0;
1140 mcount = 0; tcount = 0;
1141 m += FUNHEAD; t += FUNHEAD;
1142 while ( t < tstop ) { tcount++; NEXTARG(t) }
1144 while ( m < mstop ) {
1146 if ( *m == -ARGWILD ) AN.WildArgs++;
1149 tobeeaten = tcount - mcount + AN.WildArgs;
1151 if ( tobeeaten < 0 || AN.WildArgs == 0 ) {
1152 AT.WorkPointer = OldWork;
1160 AT.WildArgTaken[0] = AN.WildEat = tobeeaten;
1161 for ( i = 1; i < AN.WildArgs; i++ ) AT.WildArgTaken[i] = 0;
1167 m = pattern; t = interm;
1169 i = *m - WILDOFFSET;
1170 if ( CheckWild(BHEAD i,FUNTOFUN,*t,&newvalue) )
goto NoCaseB;
1171 AddWild(BHEAD i,FUNTOFUN,newvalue);
1177 while ( m < mstop ) {
1178 argmstop = oldm = m;
1179 argtstop = oldt = t;
1183 if ( *m == -ARGWILD )
goto ArgAll;
1186 if ( *m < 0 && *t < 0 ) {
1187 if ( *t <= -FUNCTION ) {
1189 else if ( *m <= -FUNCTION-WILDOFFSET
1190 && functions[-*t-FUNCTION].spec
1191 == functions[-*m-FUNCTION-WILDOFFSET].spec ) {
1192 i = -*m - WILDOFFSET;
1193 if ( CheckWild(BHEAD i,FUNTOFUN,-*t,&newvalue) )
goto endofloop;
1194 AddWild(BHEAD i,FUNTOFUN,newvalue);
1196 else if ( *m == -SYMBOL && m[1] >= 2*MAXPOWER ) {
1197 i = m[1] - 2*MAXPOWER;
1198 AN.argaddress = AT.FunArg;
1199 AT.FunArg[ARGHEAD+1] = -*t;
1200 if ( CheckWild(BHEAD i,SYMTOSUB,1,AN.argaddress) )
goto endofloop;
1201 AddWild(BHEAD i,SYMTOSUB,0);
1203 else if ( *m == -ARGWILD ) {
1204 ArgAll: i = AT.WildArgTaken[numofwildarg++];
1206 if ( CheckWild(BHEAD m[1],ARGTOARG,i,t) )
goto endofloop;
1207 AddWild(BHEAD m[1],ARGTOARG,i);
1209 while ( --i >= 0 ) { NEXTARG(t) }
1212 else goto endofloop;
1214 else if ( *t == *m ) {
1215 if ( t[1] == m[1] ) {}
1216 else if ( *t == -SYMBOL ) {
1219 if ( ( i = m[1] - 2*MAXPOWER ) < 0 )
goto endofloop;
1220 if ( CheckWild(BHEAD i,j,t[1],&newvalue) )
goto endofloop;
1221 AddWild(BHEAD i,j,newvalue);
1223 else if ( *t == -INDEX ) {
1224 IndAll: i = m[1] - WILDOFFSET;
1225 if ( i < AM.OffsetIndex || i >= WILDOFFSET+AM.OffsetIndex )
1228 if ( CheckWild(BHEAD i,INDTOIND,t[1],&newvalue) )
goto endofloop;
1229 AddWild(BHEAD i,INDTOIND,newvalue);
1231 else if ( *t == -VECTOR || *t == -MINVECTOR ) {
1232 i = m[1] - WILDOFFSET;
1233 if ( i < AM.OffsetVector )
goto endofloop;
1234 if ( CheckWild(BHEAD i,VECTOVEC,t[1],&newvalue) )
goto endofloop;
1235 AddWild(BHEAD i,VECTOVEC,newvalue);
1237 else goto endofloop;
1239 else if ( *m == -ARGWILD )
goto ArgAll;
1240 else if ( *m == -INDEX && m[1] >= AM.OffsetIndex+WILDOFFSET
1241 && m[1] < AM.OffsetIndex+(WILDOFFSET<<1) ) {
1242 if ( *t == -VECTOR )
goto IndAll;
1243 if ( *t == -SNUMBER && t[1] >= 0 && t[1] < AM.OffsetIndex )
goto IndAll;
1244 if ( *t == -MINVECTOR ) {
1245 i = m[1] - WILDOFFSET;
1246 AN.argaddress = AT.MinVecArg;
1247 AT.MinVecArg[ARGHEAD+3] = t[1];
1248 if ( CheckWild(BHEAD i,INDTOSUB,1,AN.argaddress) )
goto endofloop;
1249 AddWild(BHEAD i,INDTOSUB,(WORD)0);
1251 else goto endofloop;
1253 else if ( *m == -SYMBOL && m[1] >= 2*MAXPOWER && *t == -SNUMBER ) {
1257 else if ( *m == -VECTOR && *t == -MINVECTOR &&
1258 ( i = m[1] - WILDOFFSET ) >= AM.OffsetVector ) {
1267 if ( CheckWild(BHEAD i,VECTOMIN,t[1],&newvalue) )
goto endofloop;
1268 AddWild(BHEAD i,VECTOMIN,newvalue);
1271 else if ( *m == -MINVECTOR && *t == -VECTOR &&
1272 ( i = m[1] - WILDOFFSET ) >= AM.OffsetVector ) {
1281 if ( CheckWild(BHEAD i,VECTOMIN,t[1],&newvalue) )
goto endofloop;
1282 AddWild(BHEAD i,VECTOMIN,newvalue);
1284 else goto endofloop;
1286 else if ( *t <= -FUNCTION && *m > 0 ) {
1287 if ( ( m[ARGHEAD]+ARGHEAD == *m ) && m[*m-1] == 3
1288 && m[*m-2] == 1 && m[*m-3] == 1 && m[ARGHEAD+1] >= FUNCTION
1289 && m[ARGHEAD+2] == *m-ARGHEAD-4 ) {
1291 if ( m[ARGHEAD+1] >= FUNCTION+WILDOFFSET ) {
1293 i = m[ARGHEAD+1] - WILDOFFSET;
1294 if ( CheckWild(BHEAD i,FUNTOFUN,-*t,&newvalue) )
goto endofloop;
1295 AddWild(BHEAD i,FUNTOFUN,newvalue);
1297 else if ( m[ARGHEAD+1] != -*t )
goto endofloop;
1302 mmm = m + ARGHEAD + FUNHEAD + 1;
1303 while ( mmm < mmmst ) {
1304 if ( *mmm != -ARGWILD )
goto endofloop;
1307 if ( CheckWild(BHEAD mmm[1],ARGTOARG,i,t) )
goto endofloop;
1308 AddWild(BHEAD mmm[1],ARGTOARG,i);
1312 else goto endofloop;
1314 else if ( *m < 0 && *t > 0 ) {
1315 if ( *m == -SYMBOL ) {
1316 if ( m[1] < 2*MAXPOWER )
goto endofloop;
1317 i = m[1] - 2*MAXPOWER;
1319 if ( CheckWild(BHEAD i,SYMTOSUB,1,AN.argaddress) )
goto endofloop;
1320 AddWild(BHEAD i,SYMTOSUB,0);
1322 else if ( *m == -VECTOR ) {
1323 if ( ( i = m[1] - WILDOFFSET ) < AM.OffsetVector )
1326 if ( CheckWild(BHEAD i,VECTOSUB,1,t) )
goto endofloop;
1327 AddWild(BHEAD i,VECTOSUB,(WORD)0);
1329 else if ( *m == -INDEX ) {
1330 if ( ( i = m[1] - WILDOFFSET ) < AM.OffsetIndex )
goto endofloop;
1331 if ( i >= AM.OffsetIndex + WILDOFFSET )
goto endofloop;
1333 if ( CheckWild(BHEAD i,INDTOSUB,1,AN.argaddress) )
goto endofloop;
1334 AddWild(BHEAD i,INDTOSUB,(WORD)0);
1336 else if ( *m == -ARGWILD )
goto ArgAll;
1337 else goto endofloop;
1339 else if ( *m > 0 && *t > 0 ) {
1342 do {
if ( *m++ != *t++ )
break; }
while ( --i > 0 );
1343 if ( i == 1 && ii == 0 ) {
1347 WORD *cto, *cfrom, *csav, ci;
1350 WORD *oterstart,*oterstop,*opatstop;
1352 WORD wildargs, wildeat;
1358 m += ARGHEAD; t += ARGHEAD;
1361 if ( mtrmstop < argmstop )
goto endofloop;
1362 msizcoef = mtrmstop[-1];
1363 if ( msizcoef < 0 ) msizcoef = -msizcoef;
1364 msubstop = mtrmstop - msizcoef;
1366 if ( m >= msubstop )
goto endofloop;
1380 if ( argtstop > ttrmstop )
goto endofloop;
1382 oterstart = AN.terstart;
1383 oterstop = AN.terstop;
1384 opatstop = AN.patstop;
1385 oRepFunList = AN.RepFunList;
1386 oRepFunNum = AN.RepFunNum;
1388 AN.RepFunList = AT.WorkPointer;
1389 AT.WorkPointer = (WORD *)(((UBYTE *)(AT.WorkPointer)) + AM.MaxTer);
1390 if ( AT.WorkPointer+*t+5 > AT.WorkTop ) {
1391 MLOCK(ErrorMessageLock);
1393 MUNLOCK(ErrorMessageLock);
1396 csav = cto = AT.WorkPointer;
1399 while ( --ci >= 0 ) *cto++ = *cfrom++;
1400 AT.WorkPointer = cto;
1404 if ( abs(*--cfrom) != abs(*--cto) ) {
1405 AT.WorkPointer = csav;
1406 AN.RepFunList = oRepFunList;
1407 AN.RepFunNum = oRepFunNum;
1408 AN.terstart = oterstart;
1409 AN.terstop = oterstop;
1410 AN.patstop = opatstop;
1413 i = (*cfrom != *cto) ? 1 : 0;
1414 while ( --ci >= 0 ) {
1415 if ( *--cfrom != *--cto ) {
1416 AT.WorkPointer = csav;
1417 AN.RepFunList = oRepFunList;
1418 AN.RepFunNum = oRepFunNum;
1419 AN.terstart = oterstart;
1420 AN.terstop = oterstop;
1421 AN.patstop = opatstop;
1425 oExpectedSign = AN.ExpectedSign;
1426 AN.ExpectedSign = i;
1428 wildargs = AN.WildArgs;
1429 wildeat = AN.WildEat;
1430 for ( i = 0; i < wildargs; i++ ) wildargtaken[i] = AT.WildArgTaken[i];
1431 AN.ForFindOnly = 0; AN.UseFindOnly = 1;
1433 if ( FindRest(BHEAD csav,m) && ( AN.UsedOtherFind || FindOnly(BHEAD csav,m) ) ) {}
1437 AT.WorkPointer = csav;
1438 AN.RepFunList = oRepFunList;
1439 AN.RepFunNum = oRepFunNum;
1440 AN.terstart = oterstart;
1441 AN.terstop = oterstop;
1442 AN.patstop = opatstop;
1443 AN.WildArgs = wildargs;
1444 AN.WildEat = wildeat;
1445 AN.ExpectedSign = oExpectedSign;
1447 for ( i = 0; i < wildargs; i++ ) AT.WildArgTaken[i] = wildargtaken[i];
1451 if ( *m == 1 || m[1] < FUNCTION ) {
1452 if ( AN.ExpectedSign )
goto nomatch;
1455 if ( m[1] > FUNCTION + WILDOFFSET ) {
1456 if ( functions[m[1]-FUNCTION-WILDOFFSET].spec >= TENSORFUNCTION ) {
1457 if ( AN.ExpectedSign != AN.RepFunList[AN.RepFunNum-1] )
goto nomatch;
1461 if ( AN.ExpectedSign != AN.RepFunList[AN.RepFunNum-1] )
goto nomatch;
1470 AN.ExpectedSign = oExpectedSign;
1471 AN.WildArgs = wildargs;
1472 AN.WildEat = wildeat;
1473 for ( i = 0; i < wildargs; i++ ) AT.WildArgTaken[i] = wildargtaken[i];
1474 Substitute(BHEAD csav,m,1);
1476 cfrom = cto + *cto - msizcoef;
1479 AT.WorkPointer = csav;
1480 AN.RepFunList = oRepFunList;
1481 AN.RepFunNum = oRepFunNum;
1482 AN.terstart = oterstart;
1483 AN.terstop = oterstop;
1484 AN.patstop = opatstop;
1485 if ( *cto != SUBEXPRESSION )
goto endofloop;
1487 if ( cto < cfrom )
goto endofloop;
1490 else goto endofloop;
1495 if ( AN.SignCheck && AN.ExpectedSign )
goto endofloop;
1496 AT.WorkPointer = OldWork;
1497 if ( AN.WildArgs > 1 ) *wilds = 1;
1498 if ( AN.SignCheck && AN.ExpectedSign )
return(0);
1508 t = OldWork + ntwa; r = AT.WildMask;
1510 *m++ = *t++; *m++ = *t++; *m++ = *t++; *m++ = *t++; *r++ = *t++;
1511 }
while ( --i > 0 );
1519 AT.WorkPointer = OldWork;
1522 while ( --i >= 0 ) {
1523 if ( AT.WildArgTaken[i] == 0 ) {
1525 AT.WorkPointer = OldWork;
1530 (AT.WildArgTaken[i])--;
1532 for ( j = 0; j <= i; j++ ) {
1533 numofwildarg += AT.WildArgTaken[j];
1535 AT.WildArgTaken[j] = AN.WildEat-numofwildarg;
1537 for ( j++; j < AN.WildArgs; j++ ) AT.WildArgTaken[j] = 0;
1549 t = OldWork + ntwa; r = AT.WildMask;
1551 *m++ = *t++; *m++ = *t++; *m++ = *t++; *m++ = *t++; *r++ = *t++;
1552 }
while ( --i > 0 );
1556 AT.WorkPointer = OldWork;
1604 WORD ScanFunctions(PHEAD WORD *inpat, WORD *inter, WORD par)
1607 WORD i, *m, *t, *r, sym, psym;
1608 WORD *newpat, *newter, *instart, *oinpat = 0, *ointer = 0;
1609 WORD nwstore, offset, *OldWork, SetStop = 0, oRepFunNum = AN.RepFunNum;
1610 WORD wilds, wildargs = 0, wildeat = 0, *wildargtaken;
1611 WORD *Oterfirstcomm = AN.terfirstcomm;
1612 CBUF *C = cbuf+AT.ebufnum;
1613 int ntwa = AN.NumTotWildArgs;
1615 WORD oldSignCheck = AN.SignCheck;
1621 if ( AN.nogroundlevel ) {
1622 AN.SignCheck = ( inpat + inpat[1] >= AN.patstop ) ? 1 : 0;
1630 t = wildargtaken = OldWork = AT.WorkPointer;
1633 nwstore = i = (m[-SUBEXPSIZE+1]-SUBEXPSIZE)/4;
1637 *t++ = *m++; *t++ = *m++; *t++ = *m++; *t++ = *m++; *t++ = *r++;
1638 }
while ( --i > 0 );
1641 if ( t >= AT.WorkTop ) {
1642 MLOCK(ErrorMessageLock);
1644 MUNLOCK(ErrorMessageLock);
1653 if ( AN.RepFunNum > 0 ) {
1658 if ( *inter >= FUNCTION && functions[*inter-FUNCTION].commute ) {
1660 offset = WORDDIF(inter,AN.terstart);
1661 for ( i = 0; i < AN.RepFunNum; i += 2 ) {
1662 if ( AN.RepFunList[i] >= offset )
break;
1664 if ( i >= AN.RepFunNum )
break;
1666 }
while ( inter < AN.terfirstcomm );
1667 if ( inter < AN.terfirstcomm ) {
1668 for ( i = 0; i < AN.RepFunNum; i += 2 ) {
1669 if ( functions[AN.terstart[AN.RepFunList[i]]-FUNCTION].commute
1670 && AN.RepFunList[i]+AN.terstart[AN.RepFunList[i]+1] == offset )
break;
1672 if ( i < AN.RepFunNum )
goto trythis;
1674 inter = AN.terfirstcomm;
1679 while ( inter < AN.terstop ) {
1680 offset = WORDDIF(inter,AN.terstart);
1681 for ( i = 0; i < AN.RepFunNum; i += 2 ) {
1682 if ( AN.RepFunList[i] == offset )
break;
1684 if ( i >= AN.RepFunNum )
break;
1687 if ( inter >= AN.terstop )
goto Failure;
1694 offset = WORDDIF(inter,AN.terstart);
1699 offset = WORDDIF(inter,AN.terstart);
1700 for ( i = 0; i < AN.RepFunNum; i += 2 ) {
1701 if ( AN.RepFunList[i] == offset )
break;
1703 if ( i >= AN.RepFunNum )
break;
1705 }
while ( inter < AN.terstop );
1706 if ( inter >= AN.terstop )
goto Failure;
1710 if ( *inter >= FUNCTION && *inpat >= FUNCTION ) {
1711 if ( *inpat == *inter || *inpat >= FUNCTION + WILDOFFSET ) {
1715 if ( functions[*inter-FUNCTION].spec >= TENSORFUNCTION
1716 && ( *inter == *inpat ||
1717 functions[*inpat-FUNCTION-WILDOFFSET].spec >= TENSORFUNCTION ) ) {
1718 sym = functions[*inter-FUNCTION].symmetric & ~REVERSEORDER;
1719 if ( *inpat == *inter ) psym = sym;
1720 else psym = functions[*inpat-FUNCTION-WILDOFFSET].symmetric & ~REVERSEORDER;
1721 if ( sym == ANTISYMMETRIC || sym == SYMMETRIC
1722 || psym == SYMMETRIC || psym == ANTISYMMETRIC ) {
1723 if ( sym == ANTISYMMETRIC && psym == SYMMETRIC )
goto rewild;
1724 if ( sym == SYMMETRIC && psym == ANTISYMMETRIC )
goto rewild;
1728 if ( MatchE(BHEAD inpat,inter,instart,par) )
goto OnSuccess;
1730 else if ( sym == CYCLESYMMETRIC || sym == RCYCLESYMMETRIC
1731 || psym == CYCLESYMMETRIC || psym == RCYCLESYMMETRIC ) {
1735 if ( MatchCy(BHEAD inpat,inter,instart,par) )
goto OnSuccess;
1739 else if ( functions[*inter-FUNCTION].spec == 0
1740 && ( *inter == *inpat ||
1741 functions[*inpat-FUNCTION-WILDOFFSET].spec == 0 ) ) {
1742 sym = functions[*inter-FUNCTION].symmetric & ~REVERSEORDER;
1743 if ( *inpat == *inter ) psym = sym;
1744 else psym = functions[*inpat-FUNCTION-WILDOFFSET].symmetric & ~REVERSEORDER;
1745 if ( psym == SYMMETRIC || sym == SYMMETRIC
1751 || psym == ANTISYMMETRIC || sym == ANTISYMMETRIC
1753 if ( sym == ANTISYMMETRIC && psym == SYMMETRIC )
goto rewild;
1754 if ( sym == SYMMETRIC && psym == ANTISYMMETRIC )
goto rewild;
1755 if ( FunMatchSy(BHEAD inpat,inter,instart,par) )
goto OnSuccess;
1758 if ( sym == CYCLESYMMETRIC || sym == RCYCLESYMMETRIC
1759 || psym == CYCLESYMMETRIC || psym == RCYCLESYMMETRIC ) {
1760 if ( FunMatchCy(BHEAD inpat,inter,instart,par) )
goto OnSuccess;
1765 AN.terfirstcomm = Oterfirstcomm;
1767 else if ( par > 0 ) { SetStop = 1;
goto maybenext; }
1771 AN.terfirstcomm = Oterfirstcomm;
1772 if ( *inter != SUBEXPRESSION && MatchFunction(BHEAD inpat,inter,&wilds) ) {
1773 AN.terfirstcomm = Oterfirstcomm;
1779 wildargs = AN.WildArgs;
1780 wildeat = AN.WildEat;
1781 for ( i = 0; i < wildargs; i++ ) wildargtaken[i] = AT.WildArgTaken[i];
1782 oinpat = inpat; ointer = inter;
1784 if ( par && *inter == GAMMA && AN.RepFunList[AN.RepFunNum+1] ) {
1785 SetStop = 1;
goto NoMat;
1788 if ( *inter < FUNCTION || functions[*inter-FUNCTION].commute ) {
1793 AN.RepFunList[AN.RepFunNum] = offset;
1795 newpat = inpat + inpat[1];
1796 if ( newpat >= AN.patstop ) {
1797 if ( AN.UseFindOnly == 0 ) {
1798 if ( FindOnce(BHEAD AN.findTerm,AN.findPattern) ) {
1799 AN.UsedOtherFind = 1;
1807 if ( *inter < FUNCTION || functions[*inter-FUNCTION].commute ) {
1808 newter = inter + inter[1];
1809 if ( newter >= AN.terstop )
goto Failure;
1810 if ( *inter == GAMMA && inpat[1] <
1811 inter[1] - AN.RepFunList[AN.RepFunNum-1] ) {
1812 if ( ScanFunctions(BHEAD newpat,newter,2) )
goto OnSuccess;
1813 AN.terfirstcomm = Oterfirstcomm;
1815 else if ( *newter == SUBEXPRESSION ) {}
1816 else if ( functions[*inter-FUNCTION].commute ) {
1817 if ( ScanFunctions(BHEAD newpat,newter,1) )
goto OnSuccess;
1818 AN.terfirstcomm = Oterfirstcomm;
1819 if ( ( *newpat < (FUNCTION+WILDOFFSET)
1820 && ( functions[*newpat-FUNCTION].commute == 0 ) ) ||
1821 ( *newpat >= (FUNCTION+WILDOFFSET)
1822 && ( functions[*newpat-FUNCTION-WILDOFFSET].commute == 0 ) ) ) {
1823 newter = AN.terfirstcomm;
1824 if ( newter < AN.terstop && ScanFunctions(BHEAD newpat,newter,1) )
goto OnSuccess;
1828 if ( ScanFunctions(BHEAD newpat,instart,1) )
goto OnSuccess;
1829 AN.terfirstcomm = Oterfirstcomm;
1837 if ( par && inter > instart && ( ( *newpat < (FUNCTION+WILDOFFSET)
1838 && functions[*newpat-FUNCTION].commute ) ||
1839 ( *newpat >= (FUNCTION+WILDOFFSET)
1840 && functions[*newpat-FUNCTION-WILDOFFSET].commute ) ) ) {
1845 if ( ScanFunctions(BHEAD newpat,newter,par) )
goto OnSuccess;
1846 AN.terfirstcomm = Oterfirstcomm;
1856 t = OldWork + ntwa; r = AT.WildMask;
1858 *m++ = *t++; *m++ = *t++; *m++ = *t++; *m++ = *t++; *r++ = *t++;
1859 }
while ( --i > 0 );
1864 AN.RepFunNum = oRepFunNum;
1866 inter = ointer; inpat = oinpat;
1867 AN.WildArgs = wildargs;
1868 AN.WildEat = wildeat;
1869 for ( i = 0; i < wildargs; i++ ) AT.WildArgTaken[i] = wildargtaken[i];
1872 if ( SetStop )
break;
1876 if ( *inpat < (FUNCTION+WILDOFFSET) ) {
1877 if ( *inpat < FUNCTION ||
1878 functions[*inpat-FUNCTION].commute )
break;
1881 if ( functions[*inpat-FUNCTION-WILDOFFSET].commute )
break;
1885 }
while ( inter < AN.terstop );
1887 AN.SignCheck = oldSignCheck;
1888 AT.WorkPointer = OldWork;
1891 if ( AT.idallflag && AN.nogroundlevel <= 0 ) {
1892 if ( AT.idallmaxnum > 0 && AT.idallnum >= AT.idallmaxnum ) {
1893 AN.terfirstcomm = Oterfirstcomm;
1894 AN.SignCheck = oldSignCheck;
1895 AT.WorkPointer = OldWork;
1900 if ( AT.idallmaxnum == 0 || AT.idallnum < AT.idallmaxnum )
goto NoMat;
1902 AN.terfirstcomm = Oterfirstcomm;
1903 AN.SignCheck = oldSignCheck;
1907 if ( AN.DisOrderFlag && AN.RepFunNum >= 4 ) {
1909 for ( i = 2; i < AN.RepFunNum; i += 2 ) {
1913 m = AN.terstart + AN.RepFunList[i-2];
1914 t = AN.terstart + AN.RepFunList[i];
1916 if ( *m > *t )
continue;
1919 if ( *m >= FUNCTION && functions[*m-FUNCTION].spec >=
1922 kk = t[1] - FUNHEAD;
1928 kk = t[1] - FUNHEAD;
1932 while ( k > 0 && kk > 0 ) {
1933 if ( *m < *t )
goto NextFor;
1934 else if ( *m++ > *t++ )
goto doesmatch;
1937 if ( k > 0 )
goto doesmatch;
1944 AT.WorkPointer = OldWork;
WORD Generator(PHEAD WORD *, WORD)