100 WORD *ll, *m, *w, *llf, *OldWork, *StartWork, *ww, *mm, *t, *OldTermBuffer = 0;
101 WORD power = 0, i, msign = 0, ll2;
103 int numdollars = 0, protosize, oldallnumrhs;
104 CBUF *C = cbuf+AM.rbufnum, *CC;
111 if ( *ll == TYPEEXPRESSION ) {
117 else if ( *ll == TYPEREPEAT ) {
121 else if ( *ll == TYPEENDREPEAT ) {
122 if ( *AN.RepPoint ) {
129 if ( AN.RepPoint < AT.RepCount ) {
131 MLOCK(ErrorMessageLock);
132 MesPrint(
"!>Internal problems with REPEAT count");
133 MUNLOCK(ErrorMessageLock);
140 else if ( *ll == TYPEOPERATION ) {
144 if ( (*(FG.OperaFind[ll[2]]))(BHEAD term,ll) )
return(-1);
150 OldWork = AT.WorkPointer;
151 if ( AT.WorkPointer < term + *term ) AT.WorkPointer = term + *term;
169 if ( ( ja + 2 ) > AN.patternbuffersize ) {
170 if ( AN.patternbuffer ) M_free(AN.patternbuffer,
"AN.patternbuffer");
171 AN.patternbuffersize = 2 * ja + 2;
172 AN.patternbuffer = (WORD *)Malloc1(AN.patternbuffersize *
sizeof(WORD),
175 ma = AN.patternbuffer;
181 AN.WildValue = w = m + SUBEXPSIZE;
182 protosize = IDHEAD + m[1];
190 if ( ( ll[4] & DOLLARFLAG ) != 0 ) {
191 WORD oldRepPoint = *AN.RepPoint, olddefer = AR.DeferFlag;
196 ww = AT.WorkPointer; i = m[0]; mm = m;
199 *ww++ = 1; *ww++ = 1; *ww++ = 3;
203 if (
Generator(BHEAD StartWork,AR.Cnumlhs) ) {
205 AT.WorkPointer = OldWork;
206 AR.DeferFlag = olddefer;
210 if (
EndSort(BHEAD ww,0) < 0 ) {}
211 AR.DeferFlag = olddefer;
212 if ( *ww == 0 || *(ww+*ww) != 0 ) {
213 if ( AP.lhdollarerror == 0 ) {
217 MLOCK(ErrorMessageLock);
218 MesPrint(
"&LHS must be one term");
219 MUNLOCK(ErrorMessageLock);
220 AP.lhdollarerror = 1;
222 AT.WorkPointer = OldWork;
226 if ( m[*m-1] < 0 ) { msign = 1; m[*m-1] = -m[*m-1]; }
227 if ( *ww || m[*m-1] != 3 || m[*m-2] != 1 || m[*m-3] != 1 ) {
228 MLOCK(ErrorMessageLock);
229 MesPrint(
"Dollar variable develops into an illegal pattern in id-statement");
230 MUNLOCK(ErrorMessageLock);
234 if ( ( *m + 1 + protosize ) > AN.patternbuffersize ) {
235 if ( AN.patternbuffer ) M_free(AN.patternbuffer,
"AN.patternbuffer");
236 AN.patternbuffersize = 2 * (*m) + 2 + protosize;
237 AN.patternbuffer = (WORD *)Malloc1(AN.patternbuffersize *
sizeof(WORD),
239 mm = ll; ww = AN.patternbuffer; i = protosize;
241 AN.FullProto = AN.patternbuffer + IDHEAD;
242 AN.WildValue = w = AN.FullProto + SUBEXPSIZE;
243 AN.WildStop = AN.patternbuffer + protosize;
245 mm = AN.patternbuffer + protosize;
248 m = AN.patternbuffer + protosize;
255 WORD *mmm = m + *m, *m1 = m+1, jm, noveto = 0;
257 if ( *m1 == SYMBOL ) {
258 for ( jm = 2; jm < m1[1]; jm+=2 ) {
259 if ( m1[jm+1] < MAXPOWER && m1[jm+1] > -MAXPOWER )
break;
261 if ( jm < m1[1] ) { noveto = 1;
break; }
263 else if ( *m1 == DOTPRODUCT ) {
264 for ( jm = 2; jm < m1[1]; jm+=3 ) {
265 if ( m1[jm+2] < MAXPOWER && m1[jm+2] > -MAXPOWER )
break;
267 if ( jm < m1[1] ) { noveto = 1;
break; }
269 else { noveto = 1;
break; }
273 ll2 = ll2 & ~SUBMASK;
277 AT.WorkPointer = ww = StartWork;
278 *AN.RepPoint = oldRepPoint;
286 if ( ( ll2 & SUBMASK ) == SUBALL ) {
287 WORD *t = AN.patternbuffer+IDHEAD, *tt;
288 WORD *tstop, *ttstop, ii;
289 t += t[1]; tstop = t + *t; t++;
290 while ( t < tstop ) {
291 if ( *t < FUNCTION )
break;
295 MLOCK(ErrorMessageLock);
296 MesPrint(
"Error: id,all can only be used with (products of) functions and/or tensors.");
297 MUNLOCK(ErrorMessageLock);
300 OldTermBuffer = AN.termbuffer;
301 AN.termbuffer = TermMalloc(
"id,all");
305 tt = term; ttstop = tt+*tt; ttstop -= ABS(ttstop[-1]); tt++;
307 while ( tt < ttstop ) {
308 if ( *tt >= FUNCTION && *tt != AR.PolyFun && *tt != AR.PolyFunInv ) {
309 ii = tt[1]; NCOPY(t,tt,ii);
313 *t++ = 1; *t++ = 1; *t++ = 3; AN.termbuffer[0] = t-AN.termbuffer;
321 while ( w < AN.WildStop ) {
322 if ( *w == LOADDOLLAR ) numdollars++;
326 AN.RepFunList = AT.WorkPointer;
327 AT.WorkPointer = (WORD *)(((UBYTE *)(AT.WorkPointer)) + AM.MaxTer/2);
328 if ( AT.WorkPointer >= AT.WorkTop ) {
329 MLOCK(ErrorMessageLock);
331 MUNLOCK(ErrorMessageLock);
334 AN.DisOrderFlag = ll2 & SUBDISORDER;
335 AN.nogroundlevel = 0;
336 switch ( ll2 & SUBMASK ) {
339 AN.UseFindOnly = 1; AN.ForFindOnly = 0;
340 if ( FindRest(BHEAD term,m) && ( AN.UsedOtherFind ||
341 FindOnly(BHEAD term,m) ) ) {
343 if ( msign ) term[term[0]-1] = -term[term[0]-1];
349 if ( ( power = FindRest(BHEAD term,m) ) > 0 ) {
350 if ( ( power = FindOnce(BHEAD term,m) ) > 0 ) {
353 if ( msign ) term[term[0]-1] = -term[term[0]-1];
354 Substitute(BHEAD term,m,1);
356 WildDollars(BHEAD (WORD *)0);
359 if ( ww < term+term[0] ) ww = term+term[0];
365 AT.WorkPointer = (WORD *)(((UBYTE *)(AT.WorkPointer)) + AM.MaxTer/2);
366 if ( AT.WorkPointer >= AT.WorkTop ) {
367 MLOCK(ErrorMessageLock);
369 MUNLOCK(ErrorMessageLock);
379 AN.nogroundlevel = 0;
380 }
while ( FindRest(BHEAD term,m) && ( AN.UsedOtherFind ||
381 FindOnce(BHEAD term,m) ) );
384 else if ( power < 0 ) {
386 if ( msign ) term[term[0]-1] = -term[term[0]-1];
387 Substitute(BHEAD term,m,1);
389 WildDollars(BHEAD (WORD *)0);
392 if ( ww < term+term[0] ) ww = term+term[0];
398 AT.WorkPointer = (WORD *)(((UBYTE *)(AT.WorkPointer)) + AM.MaxTer/2);
399 if ( AT.WorkPointer >= AT.WorkTop ) {
400 MLOCK(ErrorMessageLock);
402 MUNLOCK(ErrorMessageLock);
412 }
while ( FindRest(BHEAD term,m) );
416 else if ( power < 0 ) {
417 if ( FindOnce(BHEAD term,m) ) {
419 if ( msign ) term[term[0]-1] = -term[term[0]-1];
420 Substitute(BHEAD term,m,1);
422 WildDollars(BHEAD (WORD *)0);
425 if ( ww < term+term[0] ) ww = term+term[0];
431 AT.WorkPointer = (WORD *)(((UBYTE *)(AT.WorkPointer)) + AM.MaxTer/2);
432 if ( AT.WorkPointer >= AT.WorkTop ) {
433 MLOCK(ErrorMessageLock);
435 MUNLOCK(ErrorMessageLock);
445 }
while ( FindOnce(BHEAD term,m) );
450 if ( ( ll2 & SUBAFTER ) != 0 ) *level = AC.Labels[ll[3]];
453 if ( ( ll2 & SUBAFTERNOT ) != 0 ) *level = AC.Labels[ll[3]];
458 if ( FindRest(BHEAD term,m) && ( AN.UsedOtherFind || FindOnce(BHEAD term,m) ) ) {
460 if ( msign ) term[term[0]-1] = -term[term[0]-1];
465 power = FindMulti(BHEAD term,m);
466 if ( ( power & 1 ) != 0 && msign ) term[term[0]-1] = -term[term[0]-1];
469 while ( ( power = FindAll(BHEAD term,m,*level,(WORD *)0) ) != 0 ) {
470 if ( ( power & 1 ) != 0 && msign ) term[term[0]-1] = -term[term[0]-1];
475 llf = ll + IDHEAD; llf += llf[1]; llf += *llf;
476 AN.UseFindOnly = 1; AN.ForFindOnly = llf;
477 if ( FindRest(BHEAD term,m) && ( AN.UsedOtherFind || FindOnly(BHEAD term,m) ) ) {
478 if ( msign ) term[term[0]-1] = -term[term[0]-1];
486 if ( *term > AN.sizeselecttermundo ) {
487 if ( AN.selecttermundo ) M_free(AN.selecttermundo,
"AN.selecttermundo");
488 AN.sizeselecttermundo = *term +10;
489 AN.selecttermundo = (WORD *)Malloc1(
490 AN.sizeselecttermundo*
sizeof(WORD),
"AN.selecttermundo");
492 t1 = term; t2 = AN.selecttermundo; i = *term;
496 Substitute(BHEAD term,m,power);
498 if ( TestSelect(term,llf) ) {
501 t1 = term; t2 = AN.selecttermundo; i = *t2;
504 if ( ( ll2 & SUBAFTERNOT ) != 0 ) {
505 *level = AC.Labels[ll[3]];
512 WildDollars(BHEAD (WORD *)0);
516 if ( ( ll2 & SUBAFTER ) != 0 ) {
517 *level = AC.Labels[ll[3]];
521 if ( ( ll2 & SUBAFTERNOT ) != 0 ) {
522 *level = AC.Labels[ll[3]];
529 CC = cbuf+AT.allbufnum;
530 oldallnumrhs = CC->numrhs;
531 t =
AddRHS(AT.allbufnum,1);
534 AT.idallmaxnum = ll[5];
536 if ( FindRest(BHEAD AN.termbuffer,m) || AT.idallflag > 1 ) {
537 WORD *t, *tstop, *tt, first = 1, ii;
540 if ( msign ) term[term[0]-1] = -term[term[0]-1];
552 t = term; tstop = t + *t; ii = ABS(tstop[-1]); tstop -= ii;
553 tt = AT.WorkPointer+1;
555 while ( t < tstop ) {
556 if ( *t >= FUNCTION && *t != AR.PolyFun && *t != AR.PolyFunInv ) {
558 *tt++ = SUBEXPRESSION;
562 *tt++ = AT.allbufnum;
569 i = t[1]; NCOPY(tt,t,i);
572 if ( ( ll[4] & NORMALIZEFLAG ) != 0 ) {
579 for ( i = 0; i < ii; i++ ) tt[i] = t[i];
580 Divvy(BHEAD (UWORD *)tt,&na,(UWORD *)(&(AT.idallnum)),1);
589 ii = tt-AT.WorkPointer;
590 *(AT.WorkPointer) = ii;
591 tt = AT.WorkPointer; t = term;
594 if ( ( ll2 & SUBAFTER ) != 0 ) {
595 *level = AC.Labels[ll[3]];
597 TermFree(AN.termbuffer,
"id,all");
598 AN.termbuffer = OldTermBuffer;
599 AT.WorkPointer = AN.RepFunList;
602 TransferBuffer(AT.aebufnum,AT.ebufnum,AT.allbufnum);
607 CC->numrhs = oldallnumrhs;
608 TermFree(AN.termbuffer,
"id,all");
609 AN.termbuffer = OldTermBuffer;
615 Substitute(BHEAD term,m,power);
617 WildDollars(BHEAD (WORD *)0);
621 if ( ( ll2 & SUBAFTER ) != 0 ) {
622 *level = AC.Labels[ll[3]];
626 AT.WorkPointer = AN.RepFunList;
627 if ( ( ll2 & SUBAFTERNOT ) != 0 ) {
628 *level = AC.Labels[ll[3]];
632 }
while ( (*level)++ < AR.Cnumlhs && C->
lhs[*level][0] == TYPEIDOLD );
634 AT.WorkPointer = AN.RepFunList;
643void Substitute(PHEAD WORD *term, WORD *pattern, WORD power)
650 WORD nt, *fill, nq, mt;
651 WORD *q, *subterm, *tcoef, oldval1 = 0, newval3, i = 0;
652 WORD PutExpr = 0, sign = 0;
653 TemTerm = AT.WorkPointer;
654 if ( ( (WORD *)(((UBYTE *)(AT.WorkPointer)) + AM.MaxTer*2) ) > AT.WorkTop ) {
655 MLOCK(ErrorMessageLock);
657 MUNLOCK(ErrorMessageLock);
666 tstop = t - ABS(*t) + 1;
671 if ( m < mstop ) {
do {
675 if ( *m == SYMBOL ) {
678 while ( *t != SYMBOL && t < tstop ) {
682 if ( t >= tstop )
goto SubCoef;
689 if ( *m == *t && t < xstop ) {
692 if ( mt >= 2*MAXPOWER ) {
693 if ( CheckWild(BHEAD mt-2*MAXPOWER,SYMTONUM,-MAXPOWER,&newval3) ) {
698 else if ( mt <= -2*MAXPOWER ) {
699 if ( CheckWild(BHEAD -mt-2*MAXPOWER,SYMTONUM,-MAXPOWER,&newval3) ) {
713 else if ( *m >= 2*MAXPOWER ) {
714 while ( t < xstop ) { *fill++ = *t++; *fill++ = *t++; }
715 nq = WORDDIF(fill,subterm);
718 if ( !CheckWild(BHEAD *m-2*MAXPOWER,SYMTOSYM,*fill,&newval3) ) {
720 if ( mt >= 2*MAXPOWER ) {
721 if ( CheckWild(BHEAD mt-2*MAXPOWER,SYMTONUM,-MAXPOWER,&newval3) ) {
722 if ( fill[1] -= AN.oldvalue )
goto SubsL2;
725 else if ( mt <= -2*MAXPOWER ) {
726 if ( CheckWild(BHEAD -mt-2*MAXPOWER,SYMTONUM,-MAXPOWER,&newval3) ) {
727 if ( fill[1] += AN.oldvalue )
goto SubsL2;
731 if ( fill[1] -= mt * power ) {
744 while ( --nq >= 0 ) *fill++ = *q++;
748 else if ( *m < *t || t >= xstop ) { m += 2; }
749 else { *fill++ = *t++; *fill++ = *t++; }
750 }
while ( m < ystop );
751 while ( t < xstop ) *fill++ = *t++;
752 nq = WORDDIF(fill,subterm);
757 else { fill = subterm; fill -= 2; }
763 else if ( *m == DOTPRODUCT ) {
766 while ( *t > DOTPRODUCT && t < tstop ) {
770 if ( t >= tstop )
goto SubCoef;
771 if ( *t != DOTPRODUCT ) {
775 *fill++ = DOTPRODUCT;
781 if ( *m == *t && m[1] == t[1] && t < xstop ) {
784 if ( mt >= 2*MAXPOWER ) {
785 if ( CheckWild(BHEAD mt-2*MAXPOWER,SYMTONUM,-MAXPOWER,&newval3) ) {
790 else if ( mt <= -2*MAXPOWER ) {
791 if ( CheckWild(BHEAD -mt-2*MAXPOWER,SYMTONUM,-MAXPOWER,&newval3) ) {
808 else if ( *m >= (AM.OffsetVector+WILDOFFSET) ) {
809 while ( t < xstop ) {
810 *fill++ = *t++; *fill++ = *t++; *fill++ = *t++;
815 else if ( m[1] >= (AM.OffsetVector+WILDOFFSET) ) {
816 while ( *m >= *t && t < xstop ) {
817 *fill++ = *t++; *fill++ = *t++; *fill++ = *t++;
820SubsL4: nq = WORDDIF(fill,subterm);
823 if ( ( oldval1 && ( (
824 !CheckWild(BHEAD *m-WILDOFFSET,VECTOVEC,*fill,&newval3)
825 && !CheckWild(BHEAD m[1]-WILDOFFSET,VECTOVEC,fill[1],&newval3)
827 !CheckWild(BHEAD m[1]-WILDOFFSET,VECTOVEC,*fill,&newval3)
828 && !CheckWild(BHEAD *m-WILDOFFSET,VECTOVEC,fill[1],&newval3)
829 ) ) ) || ( !oldval1 && ( (
831 && !CheckWild(BHEAD m[1]-WILDOFFSET,VECTOVEC,fill[1],&newval3)
833 !CheckWild(BHEAD m[1]-WILDOFFSET,VECTOVEC,*fill,&newval3)
834 && *m == fill[1] ) ) ) ) {
836 if ( mt >= 2*MAXPOWER ) {
837 if ( CheckWild(BHEAD mt-2*MAXPOWER,SYMTONUM,-MAXPOWER,&newval3) ) {
838 if ( fill[2] -= AN.oldvalue )
842 else if ( mt <= -2*MAXPOWER ) {
843 if ( CheckWild(BHEAD -mt-2*MAXPOWER,SYMTONUM,-MAXPOWER,&newval3) ) {
844 if ( fill[2] += AN.oldvalue )
849 if ( fill[2] -= mt * power ) {
862 while ( --nq >= 0 ) *fill++ = *q++;
865 else if ( t >= xstop || *m < *t || ( *m == *t && m[1] < t[1] ) )
868 *fill++ = *t++; *fill++ = *t++; *fill++ = *t++;
870 }
while ( m < ystop );
871 while ( t < xstop ) *fill++ = *t++;
872 nq = WORDDIF(fill,subterm);
877 else { fill = subterm; fill -= 2; }
883 else if ( *m >= FUNCTION ) {
884 while ( *t >= FUNCTION || *t == SUBEXPRESSION ) {
885 nt = WORDDIF(t,term);
886 for ( mt = 0; mt < AN.RepFunNum; mt += 2 ) {
887 if ( nt == AN.RepFunList[mt] )
break;
889 if ( mt >= AN.RepFunNum ) {
895 if ( *m == GAMMA && m[1] != FUNHEAD+1 ) {
897 if ( ( i = AN.RepFunList[mt+1] ) > 0 ) {
899 *fill++ = i + FUNHEAD+1;
907 else if ( ( *t == LEVICIVITA ) || ( *t >= FUNCTION
908 && (functions[*t-FUNCTION].symmetric & ~REVERSEORDER) == ANTISYMMETRIC )
909 ) sign += AN.RepFunList[mt+1];
910 else if ( *m >= FUNCTION+WILDOFFSET
911 && (functions[*m-FUNCTION-WILDOFFSET].symmetric & ~REVERSEORDER) == ANTISYMMETRIC
912 ) sign += AN.RepFunList[mt+1];
923 if ( *m == GAMMA && m[1] != FUNHEAD+1 ) {
924 i = oldt[1] - m[1] - i;
927 *fill++ = i + FUNHEAD+1;
929 *fill++ = oldt[FUNHEAD];
943 else if ( *m == VECTOR ) {
944 while ( *t > VECTOR ) {
956 if ( *m == *t && m[1] == t[1] ) {
959 else if ( *m >= (AM.OffsetVector+WILDOFFSET) ) {
960 while ( t < xstop ) *fill++ = *t++;
961 nq = WORDDIF(fill,subterm);
963 if ( m[1] < (AM.OffsetIndex+WILDOFFSET) ) {
965 if ( m[1] == fill[1] &&
966 !CheckWild(BHEAD *m-WILDOFFSET,VECTOVEC,*fill,&newval3) )
974 if ( !CheckWild(BHEAD m[1]-WILDOFFSET,INDTOIND,fill[1],&newval3)
975 && !CheckWild(BHEAD *m-WILDOFFSET,VECTOVEC,*fill,&newval3) )
977 if ( *fill == oldval1 && fill[1] == AN.oldvalue )
break;
984 if ( nq > 0 ) { NCOPY(fill,q,nq); }
987 else if ( *m <= *t &&
988 m[1] >= (AM.OffsetIndex + WILDOFFSET) ) {
989 while ( *m == *t && t < xstop )
990 { *fill++ = *t++; *fill++ = *t++; }
991 nq = WORDDIF(fill,subterm);
995 !CheckWild(BHEAD m[1]-WILDOFFSET,INDTOIND,fill[1],&newval3) )
1002 if ( nq > 0 ) { NCOPY(fill,q,nq); }
1005 else { *fill++ = *t++; *fill++ = *t++; }
1006 }
while ( m < ystop );
1007 while ( t < xstop ) *fill++ = *t++;
1008 nq = WORDDIF(fill,subterm);
1013 else { fill = subterm; fill -= 2; }
1021 else if ( *m == INDEX ) {
1022 while ( *t > INDEX ) {
1037 else if ( ( *m >= (AM.OffsetVector+WILDOFFSET) )
1038 && ( *m < (AM.OffsetVector+2*WILDOFFSET) ) ) {
1039 while ( t < xstop ) *fill++ = *t++;
1040 nq = WORDDIF(fill,subterm);
1043 if ( !CheckWild(BHEAD *m-WILDOFFSET,VECTOVEC,*fill,&newval3) )
1054 if ( nq > 0 ) { NCOPY(fill,q,nq); }
1057 else if ( ( *m >= (AM.OffsetIndex+WILDOFFSET) )
1058 && ( *m < (AM.OffsetIndex+2*WILDOFFSET) ) ) {
1059 while ( t < xstop ) *fill++ = *t++;
1060 nq = WORDDIF(fill, subterm);
1063 if ( !CheckWild(BHEAD *m-WILDOFFSET,INDTOIND,*fill,&newval3) ) {
1079 }
while ( m < ystop );
1080 while ( t < xstop ) *fill++ = *t++;
1081 nq = WORDDIF(fill,subterm);
1086 else { fill = subterm; fill -= 2; }
1092 else if ( *m == DELTA ) {
1093 while ( *t > DELTA ) {
1105 if ( *t == *m && t[1] == m[1] ) { m += 2; t += 2; }
1106 else if ( *m >= (AM.OffsetIndex+WILDOFFSET) ) {
1107 while ( t < xstop ) *fill++ = *t++;
1112 else if ( m[1] >= (AM.OffsetIndex+WILDOFFSET) ) {
1113 while ( (*m == *t || *m == t[1] ) && ( t < xstop ) ) {
1114 *fill++ = *t++; *fill++ = *t++;
1117SubsL6: nq = WORDDIF(fill,subterm);
1120 if ( ( oldval1 && ( (
1121 !CheckWild(BHEAD *m-WILDOFFSET,INDTOIND,*fill,&newval3)
1122 && !CheckWild(BHEAD m[1]-WILDOFFSET,INDTOIND,fill[1],&newval3)
1124 !CheckWild(BHEAD m[1]-WILDOFFSET,INDTOIND,*fill,&newval3)
1125 && !CheckWild(BHEAD *m-WILDOFFSET,INDTOIND,fill[1],&newval3)
1126 ) ) ) || ( !oldval1 && ( (
1128 && !CheckWild(BHEAD m[1]-WILDOFFSET,INDTOIND,fill[1],&newval3)
1131 && !CheckWild(BHEAD m[1]-WILDOFFSET,INDTOIND,*fill,&newval3)
1144 *fill++ = *t++; *fill++ = *t++;
1146 }
while ( m < ystop );
1147 while ( t < xstop ) *fill++ = *t++;
1148 nq = WORDDIF(fill,subterm);
1153 else { fill = subterm; fill -= 2; }
1159 }
while ( m < mstop ); }
1160 while ( t < tstop ) *fill++ = *t++;
1172 nq = WORDDIF(fill,TemTerm);
1179 if ( ( sign & 1 ) != 0 ) fill[-1] = -fill[-1];
1181 if ( AT.WorkPointer < fill ) AT.WorkPointer = fill;
1220int FindAll(PHEAD WORD *term, WORD *pattern, WORD level, WORD *par)
1223 WORD *t, *m, *r, *mm, rnum;
1224 WORD *tstop, *mstop, *TwoProto, *vwhere = 0, oldv, oldvv, vv, level2;
1225 WORD v, nq, OffNum = AM.OffsetVector + WILDOFFSET, i, ii = 0, jj;
1226 WORD fromindex, *intens, notflag1 = 0, notflag2 = 0;
1228 C = cbuf+AM.rbufnum;
1240 if ( *t == VECTOR ) {
1244 while ( r < tstop ) {
1246 if ( v >= OffNum ) {
1247 vwhere = AN.FullProto + 3 + SUBEXPSIZE;
1248 if ( vwhere[1] == FROMSET || vwhere[1] == SETTONUM ) {
1249 WORD *afirst, *alast, j;
1251 if ( j > WILDOFFSET ) { j -= 2*WILDOFFSET; notflag1 = 1; }
1252 else { notflag1 = 0; }
1253 afirst = SetElements + Sets[j].first;
1254 alast = SetElements + Sets[j].last;
1256 if ( notflag1 == 0 ) {
1258 if ( *afirst == *r ) {
1259 if ( vwhere[1] == SETTONUM ) {
1260 AN.FullProto[8+SUBEXPSIZE] = SYMTONUM;
1261 AN.FullProto[11+SUBEXPSIZE] = ii;
1263 else if ( vwhere[4] >= 0 ) {
1264 oldv = *(afirst - Sets[j].first
1265 + Sets[vwhere[4]].first);
1270 }
while ( ++afirst < alast );
1274 if ( *afirst == *r )
break;
1275 }
while ( ++afirst < alast );
1276 if ( afirst >= alast )
goto DoVect;
1281 else if ( v == *r ) {
1282DoVect: m = AT.WorkPointer;
1286 do { *m++ = *t++; }
while ( t < tstop );
1293 if ( fromindex == 1 ) m[-1] = FUNNYVEC;
1295 if ( v >= OffNum ) vwhere[3+SUBEXPSIZE] = oldv;
1296 if ( vwhere[1] > 12+SUBEXPSIZE ) {
1297 vwhere[11+SUBEXPSIZE] = ii;
1298 vwhere[8+SUBEXPSIZE] = SYMTONUM;
1300 if ( t[1] > fromindex+2 ) {
1302 *m++ = *t++ - fromindex;
1303 while ( t < r ) *m++ = *t++;
1307 do { *m++ = *t++; }
while ( t < mstop );
1308 *AT.WorkPointer = nq = WORDDIF(m,AT.WorkPointer);
1322 else if ( *t == DOTPRODUCT ) {
1326 if ( ( i = r[2] ) < 0 )
goto NextDot;
1330TwoVec: m = AT.WorkPointer;
1334 do { *m++ = *t++; }
while ( t < tstop );
1341 m[-1] = ++AR.CurDum;
1342 if ( v >= OffNum ) vwhere[3+SUBEXPSIZE] = oldv;
1343 }
while ( --i > 0 );
1348 while ( t < r ) *m++ = *t++;
1352 do { *m++ = *t++; }
while ( t < mstop );
1353 *AT.WorkPointer = nq = WORDDIF(m,AT.WorkPointer);
1360 else if ( v >= OffNum ) {
1361 vwhere = AN.FullProto + 3+SUBEXPSIZE;
1362 if ( vwhere[1] == FROMSET || vwhere[1] == SETTONUM ) {
1363 WORD *afirst, *alast, j;
1365 if ( j > WILDOFFSET ) { j -= 2*WILDOFFSET; notflag1 = 1; }
1366 else { notflag1 = 0; }
1367 afirst = SetElements + Sets[j].first;
1368 alast = SetElements + Sets[j].last;
1370 if ( notflag1 == 0 ) {
1372 if ( *afirst == *r ) {
1373 if ( vwhere[1] == SETTONUM ) {
1374 AN.FullProto[8+SUBEXPSIZE] = SYMTONUM;
1375 AN.FullProto[11+SUBEXPSIZE] = ii;
1377 else if ( vwhere[4] >= 0 ) {
1378 oldv = *(afirst - Sets[j].first
1379 + Sets[vwhere[4]].first);
1384 }
while ( ++afirst < alast );
1388 if ( *afirst == *r )
break;
1389 }
while ( ++afirst < alast );
1390 if ( afirst >= alast )
goto TwoVec;
1397 if ( v == r[1] ) { r[1] = *r; *r = v; }
1401 if ( !par ) {
while ( ++level <= AR.Cnumlhs
1402 && C->
lhs[level][0] == TYPEIDOLD ) {
1405 if ( m[-IDHEAD+2] == SUBVECTOR ) {
1406 if ( ( vv = m[m[1]+3] ) == r[1] ) {
1407OnePV: TwoProto = AN.FullProto;
1408TwoPV: m = AT.WorkPointer;
1412 do { *m++ = *t++; }
while ( t < tstop );
1415 vwhere = m + 3 +SUBEXPSIZE;
1419 m[-1] = ++AR.CurDum;
1420 if ( v >= OffNum ) *vwhere = oldv;
1421 if ( vwhere[-2-SUBEXPSIZE] > 12+SUBEXPSIZE ) {
1423 vwhere[5] = SYMTONUM;
1426 vwhere = m + 3+SUBEXPSIZE;
1435 mm[2] = C->
lhs[level][IDHEAD+2];
1436 mm[4] = C->
lhs[level][IDHEAD+4];
1438 if ( vv >= OffNum ) *vwhere = oldvv;
1439 }
while ( --i > 0 );
1442 else if ( vv > OffNum ) {
1443 vwhere = AN.FullProto + 3+SUBEXPSIZE;
1444 if ( vwhere[1] == FROMSET || vwhere[1] == SETTONUM ) {
1445 WORD *afirst, *alast, j;
1447 if ( j > WILDOFFSET ) { j -= 2*WILDOFFSET; notflag1 = 1; }
1448 else { notflag1 = 0; }
1449 afirst = SetElements + Sets[j].first;
1450 alast = SetElements + Sets[j].last;
1451 if ( notflag1 == 0 ) {
1454 if ( *afirst == r[1] ) {
1455 if ( vwhere[1] == SETTONUM ) {
1456 AN.FullProto[8+SUBEXPSIZE] = SYMTONUM;
1457 AN.FullProto[11+SUBEXPSIZE] = ii;
1459 else if ( vwhere[4] >= 0 ) {
1460 oldvv = *(afirst - Sets[j].first
1461 + Sets[vwhere[4]].first);
1466 }
while ( ++afirst < alast );
1470 if ( *afirst == *r )
break;
1471 }
while ( ++afirst < alast );
1472 if ( afirst >= alast )
goto OnePV;
1485OneOnly: m = AT.WorkPointer;
1489 do { *m++ = *t++; }
while ( t < tstop );
1497 if ( v >= OffNum ) vwhere[3+SUBEXPSIZE] = oldv;
1500 else if ( v >= OffNum ) {
1501 vwhere = AN.FullProto + 3+SUBEXPSIZE;
1502 if ( vwhere[1] == FROMSET || vwhere[1] == SETTONUM ) {
1503 WORD *afirst, *alast, *bfirst, *blast, j;
1505 if ( j > WILDOFFSET ) { j -= 2*WILDOFFSET; notflag1 = 1; }
1506 else { notflag1 = 0; }
1507 afirst = SetElements + Sets[j].first;
1508 alast = SetElements + Sets[j].last;
1510 if ( notflag1 == 0 ) {
1512 if ( *afirst == *r ) {
1513 if ( vwhere[1] == SETTONUM ) {
1514 AN.FullProto[8+SUBEXPSIZE] = SYMTONUM;
1515 AN.FullProto[11+SUBEXPSIZE] = ii;
1517 else if ( vwhere[4] >= 0 ) {
1518 oldv = *(afirst - Sets[j].first
1519 + Sets[vwhere[4]].first);
1521Hitlevel1: level2 = level;
1523 if ( !par ) m = C->
lhs[level2];
1526 if ( m[-IDHEAD+2] == SUBVECTOR ) {
1527 if ( ( vv = m[m[1]+3] ) == r[1] )
1529 else if ( vv >= OffNum ) {
1530 if ( m[SUBEXPSIZE+4] != FROMSET &&
1531 m[SUBEXPSIZE+4] != SETTONUM )
goto OnePV;
1532 j = m[SUBEXPSIZE+6];
1533 if ( j > WILDOFFSET ) { j -= 2*WILDOFFSET; notflag2 = 1; }
1534 else { notflag2 = 0; }
1535 bfirst = SetElements + Sets[j].first;
1536 blast = SetElements + Sets[j].last;
1538 if ( notflag2 == 0 ) {
1540 if ( *bfirst == r[1] ) {
1541 if ( m[SUBEXPSIZE+4] == SETTONUM ) {
1542 m[SUBEXPSIZE+8] = SYMTONUM;
1543 m[SUBEXPSIZE+11] = jj;
1545 else if ( m[SUBEXPSIZE+7] >= 0 ) {
1546 oldvv = *(bfirst - Sets[j].first
1547 + Sets[m[SUBEXPSIZE+7]].first);
1552 }
while ( ++bfirst < blast );
1556 if ( *bfirst == r[1] )
break;
1557 }
while ( ++bfirst < blast );
1558 if ( bfirst >= blast )
goto OnePV;
1562 }
while ( ++level2 < AR.Cnumlhs &&
1563 C->
lhs[level2][0] == TYPEIDOLD );
1567 else if ( *afirst == r[1] ) {
1568 if ( vwhere[1] == SETTONUM ) {
1569 AN.FullProto[8+SUBEXPSIZE] = SYMTONUM;
1570 AN.FullProto[11+SUBEXPSIZE] = ii;
1572 else if ( vwhere[4] >= 0 ) {
1573 oldv = *(afirst - Sets[j].first
1574 + Sets[vwhere[4]].first);
1576Hitlevel2: level2 = level;
1577 while ( ++level2 < AR.Cnumlhs &&
1578 C->
lhs[level2][0] == TYPEIDOLD ) {
1579 if ( !par ) m = C->
lhs[level2];
1582 if ( m[-IDHEAD+2] == SUBVECTOR ) {
1583 if ( ( vv = m[6] ) == *r )
1585 else if ( vv >= OffNum ) {
1586 if ( m[SUBEXPSIZE+4] != FROMSET && m[SUBEXPSIZE+4]
1593 j = m[SUBEXPSIZE+6];
1594 bfirst = SetElements + Sets[j].first;
1595 blast = SetElements + Sets[j].last;
1598 if ( *bfirst == *r ) {
1599 if ( m[SUBEXPSIZE+4] == SETTONUM ) {
1600 m[SUBEXPSIZE+8] = SYMTONUM;
1601 m[SUBEXPSIZE+11] = jj;
1603 else if ( m[SUBEXPSIZE+7] >= 0 ) {
1604 oldvv = *(bfirst - Sets[j].first
1605 + Sets[m[SUBEXPSIZE+7]].first);
1610 j = oldv; oldv = oldvv; oldvv = j;
1614 }
while ( ++bfirst < blast );
1618 jj = *r; *r = r[1]; r[1] = jj;
1619 jj = oldv; oldv = oldvv; oldvv = j;
1624 }
while ( ++afirst < alast );
1628 if ( *afirst == *r )
break;
1629 }
while ( ++afirst < alast );
1630 if ( afirst >= alast )
goto Hitlevel1;
1632 if ( *afirst == r[1] )
break;
1633 }
while ( ++afirst < alast );
1634 if ( afirst >= alast )
goto Hitlevel2;
1639 TwoProto = AN.FullProto;
1645 }
while ( r < tstop );
1651 else if ( *t == LEVICIVITA ) {
1656 while ( r < tstop ) {
1658 if ( v >= OffNum && *r < -10 ) {
1659 vwhere = AN.FullProto + 3+SUBEXPSIZE;
1660 if ( vwhere[1] == FROMSET || vwhere[1] == SETTONUM ) {
1661 WORD *afirst, *alast, j;
1663 if ( j > WILDOFFSET ) { j -= 2*WILDOFFSET; notflag1 = 1; }
1664 else { notflag1 = 0; }
1665 afirst = SetElements + Sets[j].first;
1666 alast = SetElements + Sets[j].last;
1668 if ( notflag1 == 0 ) {
1670 if ( *afirst == *r ) {
1671 if ( vwhere[1] == SETTONUM ) {
1672 AN.FullProto[8+SUBEXPSIZE] = SYMTONUM;
1673 AN.FullProto[11+SUBEXPSIZE] = ii;
1675 else if ( vwhere[4] >= 0 ) {
1676 oldv = *(afirst - Sets[j].first
1677 + Sets[vwhere[4]].first);
1682 }
while ( ++afirst < alast );
1686 if ( *afirst == *r )
break;
1687 }
while ( ++afirst < alast );
1688 if ( afirst >= alast )
goto DoVect;
1693 else if ( v == *r ) {
1694LeVect: m = AT.WorkPointer;
1695 mstop = term + *term;
1698 if ( intens ) *intens = DIRTYSYMFLAG;
1699 do { *m++ = *t++; }
while ( t < tstop );
1703 if ( v >= OffNum ) *vwhere = oldv;
1707 do { *m++ = *t++; }
while ( t < mstop );
1708 *AT.WorkPointer = nq = WORDDIF(m,AT.WorkPointer);
1722 else if ( *t == GAMMA ) {
1726 if ( r < tstop )
goto OneVect;
1732 else if ( *t == INDEX ) {
1742 else if ( *t >= FUNCTION ) {
1744 && functions[*t-FUNCTION].spec >= TENSORFUNCTION
1745 && t[1] > FUNHEAD ) {
1771int TestSelect(WORD *term, WORD *setp)
1773 WORD *tstop, *t, *s, *el, *elstop, *termstop, *tt, n, ns;
1774 GETSTOP(term,tstop);
1776 while ( term < tstop ) {
1784 while ( --ns >= 0 ) {
1785 if ( Sets[*s].type != CSYMBOL ) { s++;
continue; }
1786 el = SetElements + Sets[*s].first;
1787 elstop = SetElements + Sets[*s].last;
1788 while ( el < elstop ) {
1789 if ( *el++ == *t )
return(1);
1803 while ( --ns >= 0 ) {
1804 if ( Sets[*s].type != CVECTOR ) { s++;
continue; }
1805 el = SetElements + Sets[*s].first;
1806 elstop = SetElements + Sets[*s].last;
1807 while ( el < elstop ) {
1808 if ( *el++ == *t )
return(1);
1815 while ( --ns >= 0 ) {
1816 if ( Sets[*s].type != CINDEX
1817 && Sets[*s].type != CNUMBER ) { s++;
continue; }
1818 el = SetElements + Sets[*s].first;
1819 elstop = SetElements + Sets[*s].last;
1820 while ( el < elstop ) {
1821 if ( *el++ == *t )
return(1);
1839 while ( --ns >= 0 ) {
1840 if ( Sets[*s].type != CVECTOR ) { s++;
continue; }
1841 el = SetElements + Sets[*s].first;
1842 elstop = SetElements + Sets[*s].last;
1843 while ( el < elstop ) {
1844 if ( *el++ == *t )
return(1);
1851 while ( --ns >= 0 ) {
1852 if ( Sets[*s].type != CVECTOR ) { s++;
continue; }
1853 el = SetElements + Sets[*s].first;
1854 elstop = SetElements + Sets[*s].last;
1855 while ( el < elstop ) {
1856 if ( *el++ == *t )
return(1);
1869 if ( *term < FUNCTION )
break;
1872 while ( --ns >= 0 ) {
1873 if ( Sets[*s].type != CFUNCTION ) { s++;
continue; }
1874 el = SetElements + Sets[*s].first;
1875 elstop = SetElements + Sets[*s].last;
1876 while ( el < elstop ) {
1877 if ( *el++ == *term )
return(1);
1881 if ( functions[*term-FUNCTION].spec > 0 ) {
1882 n = term[1] - FUNHEAD;
1888 while ( --ns >= 0 ) {
1889 if ( *t < MINSPEC ) {
1890 if ( Sets[*s].type != CVECTOR ) { s++;
continue; }
1892 else if ( *t >= 0 ) {
1893 if ( Sets[*s].type != CINDEX
1894 && Sets[*s].type != CNUMBER ) { s++;
continue; }
1896 else { s++;
continue; }
1897 el = SetElements + Sets[*s].first;
1898 elstop = SetElements + Sets[*s].last;
1899 while ( el < elstop ) {
1900 if ( *el++ == *t )
return(1);
1909 termstop = term + term[1];
1910 tt = term + FUNHEAD;
1911 while ( tt < termstop ) {
1913 if ( *tt == -SYMBOL ) {
1916 while ( --ns >= 0 ) {
1917 if ( Sets[*s].type != CSYMBOL ) { s++;
continue; }
1918 el = SetElements + Sets[*s].first;
1919 elstop = SetElements + Sets[*s].last;
1920 while ( el < elstop ) {
1921 if ( *el++ == tt[1] )
return(1);
1927 else if ( *tt == -VECTOR || *tt == -MINVECTOR ) {
1930 while ( --ns >= 0 ) {
1931 if ( Sets[*s].type != CVECTOR ) { s++;
continue; }
1932 el = SetElements + Sets[*s].first;
1933 elstop = SetElements + Sets[*s].last;
1934 while ( el < elstop ) {
1935 if ( *el++ == tt[1] )
return(1);
1941 else if ( *tt == -INDEX ) {
1944 while ( --ns >= 0 ) {
1945 if ( Sets[*s].type != CINDEX
1946 && Sets[*s].type != CNUMBER ) { s++;
continue; }
1947 el = SetElements + Sets[*s].first;
1948 elstop = SetElements + Sets[*s].last;
1949 while ( el < elstop ) {
1950 if ( *el++ == tt[1] )
return(1);
1956 else if ( *tt <= -FUNCTION ) {
1959 while ( --ns >= 0 ) {
1960 if ( Sets[*s].type != CFUNCTION ) { s++;
continue; }
1961 el = SetElements + Sets[*s].first;
1962 elstop = SetElements + Sets[*s].last;
1963 while ( el < elstop ) {
1964 if ( *el++ == -(*tt) )
return(1);
1976 if ( TestSelect(t,setp) )
return(1);
2005void SubsInAll(PHEAD0)
2010 WORD *tstop, *mstop, *xstop;
2011 WORD nt, *fill, nq, mt;
2013 WORD PutExpr = 0, sign = 0;
2020 TemTerm = AT.WorkPointer;
2021 if ( ( (WORD *)(((UBYTE *)(AT.WorkPointer)) + AM.MaxTer*2) ) > AT.WorkTop ) {
2022 MLOCK(ErrorMessageLock);
2024 MUNLOCK(ErrorMessageLock);
2027 m = AN.patternbuffer + IDHEAD; m += m[1];
2030 term = AN.termbuffer;
2031 tstop = term + *term; tcoef = tstop-1; tstop -= ABS(tstop[-1]);
2036 while ( m < mstop ) {
2037 while ( t < tstop ) {
2038 nt = WORDDIF(t,term);
2039 for ( mt = 0; mt < AN.RepFunNum; mt += 2 ) {
2040 if ( nt == AN.RepFunList[mt] )
break;
2042 if ( mt >= AN.RepFunNum ) {
2048 if ( *m == GAMMA && m[1] != FUNHEAD+1 ) {
2050 if ( ( i = AN.RepFunList[mt+1] ) > 0 ) {
2052 *fill++ = i + FUNHEAD+1;
2060 else if ( ( *t == LEVICIVITA ) || ( *t >= FUNCTION
2061 && (functions[*t-FUNCTION].symmetric & ~REVERSEORDER) == ANTISYMMETRIC )
2062 ) sign += AN.RepFunList[mt+1];
2063 else if ( *m >= FUNCTION+WILDOFFSET
2064 && (functions[*m-FUNCTION-WILDOFFSET].symmetric & ~REVERSEORDER) == ANTISYMMETRIC
2065 ) sign += AN.RepFunList[mt+1];
2067 WORD *pstart = fill, *p, *w, *ww;
2083 p = pstart + SUBEXPSIZE;
2084 while ( p < fill ) {
2091 w = cbuf[AT.ebufnum].rhs[p[3]];
2092 ww = cbuf[AT.ebufnum].rhs[p[3]+1];
2100 AddNtoC(AT.aebufnum,ww-w,w,11);
2101 p[3] = cbuf[AT.aebufnum].numrhs;
2102 cbuf[AT.aebufnum].rhs[p[3]+1] = cbuf[AT.aebufnum].Pointer;
2118 if ( *m == GAMMA && m[1] != FUNHEAD+1 ) {
2119 i = oldt[1] - m[1] - i;
2122 *fill++ = i + FUNHEAD+1;
2124 *fill++ = oldt[FUNHEAD];
2134 while ( t < tstop ) *fill++ = *t++;
2146 if ( ( sign & 1 ) != 0 ) fill[-1] = -fill[-1];
2148 *TemTerm = fill-TemTerm;
2152 AddNtoC(AT.allbufnum,TemTerm[0],TemTerm,12);
2153 cbuf[AT.allbufnum].Pointer[0] = 0;
2166void TransferBuffer(
int from,
int to,
int spectator)
2168 CBUF *C = cbuf + spectator;
2169 CBUF *Cf = cbuf + from;
2170 CBUF *Ct = cbuf + to;
2171 int offset = Ct->numrhs;
2173 WORD *t, *tt, *ttt, *tstop, size;
2174 for ( i = 1; i <= Cf->numrhs; i++ ) {
2175 size = Cf->
rhs[i+1]-Cf->
rhs[i];
2184 t = C->
rhs[C->numrhs];
2187 tstop = t-ABS(t[-1]);
2188 while ( tt < tstop ) {
2189 if ( *tt == SUBEXPRESSION ) {
2190 ttt = tt+SUBEXPSIZE; tt += tt[1];
2191 while ( ttt < tt ) {
2216#define PutInBuffers(pow) \
2217 AddRHS(AT.ebufnum,1); \
2218 *out++ = SUBEXPRESSION; \
2219 *out++ = SUBEXPSIZE; \
2220 *out++ = C->numrhs; \
2222 *out++ = AT.ebufnum; \
2224 r = AT.pWorkSpace[rhs+i]; \
2226 oldinr = r[*r]; r[*r] = 0; \
2227 AddNtoC(AT.ebufnum,(*r+1-ARGHEAD),(r+ARGHEAD),14); \
2231 ToGeneral(r,buffer,1); \
2232 buffer[buffer[0]] = 0; \
2233 AddNtoC(AT.ebufnum,buffer[0]+1,buffer,15); \
2236int TakeIDfunction(PHEAD WORD *term)
2238 WORD *tstop, *t, *r, *m, *f, *nextf, *funstop, *left, *l, *newterm;
2239 WORD *out, oldinr, pow;
2241 int i, ii, j, numsub, numfound = 0, first;
2244 GETSTOP(term,tstop);
2245 for ( t = term+1; t < tstop; t += t[1] ) {
if ( *t == IDFUNCTION )
break; }
2246 if ( t >= tstop )
return(0);
2250 funstop = t + t[1]; f = t + FUNHEAD;
2251 left = term + *term;
2252 l = left+1; numsub = 0;
2253 while ( f < funstop ) {
2254 nextf = f; NEXTARG(nextf)
2255 if ( nextf >= funstop ) {
return(0); }
2256 if ( *f == -SYMBOL ) { *l++ = SYMBOL; *l++ = 4; *l++ = f[1]; *l++ = 1; }
2257 else if ( *f < -FUNCTION ) { *l++ = *f; *l++ = FUNHEAD; FILLFUN(l) }
2258 else if ( *f > 0 ) {
2259 if ( *f != f[ARGHEAD]+ARGHEAD )
goto noaction;
2260 if ( nextf[-1] != 3 || nextf[-2] != 1 || nextf[-3] != 1 )
goto noaction;
2261 if ( f[ARGHEAD] <= 4 )
goto noaction;
2262 if ( f[ARGHEAD] != f[ARGHEAD+2]+4 )
goto noaction;
2263 if ( f[ARGHEAD] == 8 && f[ARGHEAD+1] == SYMBOL ) {
2264 for ( i = 0; i < 4; i++ ) *l++ = f[ARGHEAD+1+i];
2266 else if ( f[ARGHEAD] == 9 && f[ARGHEAD+1] == DOTPRODUCT ) {
2267 for ( i = 0; i < 5; i++ ) *l++ = f[ARGHEAD+1+i];
2269 else if ( f[ARGHEAD+1] >= FUNCTION ) {
2270 for ( i = 0; i < f[ARGHEAD+1]-4; i++ ) *l++ = f[ARGHEAD+1+i];
2279 C = cbuf+AT.ebufnum;
2285 WantAddPointers(2*numsub);
2286 lhs = AT.pWorkPointer;
2288 AT.pWorkPointer = rhs+numsub;
2289 f = t + FUNHEAD; l = left+1;
2290 for ( i = 0; i < numsub; i++ ) {
2291 AT.pWorkSpace[lhs+i] = l; l += l[1];
2293 AT.pWorkSpace[rhs+i] = f;
2302 t = term+1; newterm = AT.WorkPointer; out = newterm+1;
2303 while ( t < tstop ) {
2304 if ( *t == IDFUNCTION && first ) { first = 0; t += t[1];
continue; }
2305 if ( *t >= FUNCTION ) {
2306 for ( i = 0; i < numsub; i++ ) {
2307 m = AT.pWorkSpace[lhs+i];
2308 if ( *m != *t )
continue;
2309 for ( j = 1; j < t[1]; j++ ) {
2310 if ( m[j] != t[j] )
break;
2312 if ( j != t[1] )
continue;
2321 if ( i == numsub ) {
2322 j = t[1]; NCOPY(out,t,j)
2325 else if ( *t == SYMBOL ) {
2326 for ( i = 0; i < numsub; i++ ) {
2327 m = AT.pWorkSpace[lhs+i];
2328 if ( *m != SYMBOL )
continue;
2329 for ( ii = 2; ii < t[1]; ii += 2 ) {
2330 if ( m[2] != t[ii] )
continue;
2332 if ( pow <= 0 )
continue;
2333 t[ii+1] = t[ii+1]%m[3];
2345 m = out; *out++ = t[0]; *out++ = t[1];
2346 for ( ii = 2; ii < t[1]; ii += 2 ) {
2347 if ( t[ii+1] ) { *out++ = t[ii]; *out++ = t[ii+1]; }
2350 if ( m[1] == 2 ) out = m;
2353 else if ( *t == DOTPRODUCT ) {
2354 for ( i = 0; i < numsub; i++ ) {
2355 m = AT.pWorkSpace[lhs+i];
2356 if ( *m != DOTPRODUCT )
continue;
2357 for ( ii = 2; ii < t[1]; ii += 3 ) {
2358 if ( m[2] != t[ii] || m[3] != t[ii+1] )
continue;
2360 if ( pow <= 0 )
continue;
2361 t[ii+2] = t[ii+2]%m[4];
2373 m = out; *out++ = t[0]; *out++ = t[1];
2374 for ( ii = 2; ii < t[1]; ii += 3 ) {
2375 if ( t[ii+2] ) { *out++ = t[ii]; *out++ = t[ii+1]; *out++ = t[ii+2]; }
2378 if ( m[1] == 2 ) out = m;
2382 j = t[1]; NCOPY(out,t,j)
2388 t = tstop; r = term+*term;
while ( t < r ) *out++ = *t++;
2389 *newterm = out-newterm;
2394 t = term; r = newterm; NCOPY(t,r,i)
2399 AT.pWorkPointer = lhs;
LONG EndSort(PHEAD WORD *, int)
int Generator(PHEAD WORD *, WORD)
void LowerSortLevel(void)
int TestMatch(PHEAD WORD *term, WORD *level)