56int MatchE(PHEAD WORD *pattern, WORD *fun, WORD *inter, WORD par)
61 WORD *mstop, *tstop, j, newvalue, newfun;
62 WORD fixvec[MAXMATCH],wcvec[MAXMATCH],fixind[MAXMATCH],wcind[MAXMATCH];
63 WORD tfixvec[MAXMATCH],tfixind[MAXMATCH];
64 WORD vwc,vfix,ifix,iwc,tvfix,tifix,nv,ni;
65 WORD sign = 0, *rstop, first1, first2, first3, funwild;
66 WORD *OldWork, nwstore, oRepFunNum;
71 offset = WORDDIF(fun,AN.terstart);
72 if ( pattern[1] != fun[1] )
return(0);
73 if ( *pattern >= FUNCTION+WILDOFFSET ) {
74 if ( CheckWild(BHEAD *pattern-WILDOFFSET,FUNTOFUN,*fun,&newfun) )
return(0);
78 mstop = pattern + pattern[1];
80 m = pattern + FUNHEAD;
83 if ( *m != *t )
break;
87 AN.RepFunList[AN.RepFunNum++] = offset;
88 AN.RepFunList[AN.RepFunNum++] = 0;
89 newpat = pattern + pattern[1];
92 t = OldWork = AT.WorkPointer;
93 nwstore = i = (m[-SUBEXPSIZE+1]-SUBEXPSIZE)/4;
97 *t++ = *m++; *t++ = *m++; *t++ = *m++; *t++ = *m++; *t++ = *r++;
100 if ( t >= AT.WorkTop ) {
101 MLOCK(ErrorMessageLock);
103 MUNLOCK(ErrorMessageLock);
107 AddWild(BHEAD *pattern-WILDOFFSET,FUNTOFUN,newfun);
108 if ( newpat >= AN.patstop ) {
109 if ( AN.UseFindOnly == 0 ) {
110 if ( FindOnce(BHEAD AN.findTerm,AN.findPattern) ) {
111 AN.UsedOtherFind = 1;
120 retval = ScanFunctions(BHEAD newpat,inter,par);
124 t = OldWork; r = AT.WildMask; i = nwstore;
127 *m++ = *t++; *m++ = *t++; *m++ = *t++; *m++ = *t++; *r++ = *t++;
131 AT.WorkPointer = OldWork;
135 if ( newpat >= AN.patstop ) {
136 if ( AN.UseFindOnly == 0 ) {
137 if ( FindOnce(BHEAD AN.findTerm,AN.findPattern) ) {
138 AN.UsedOtherFind = 1;
146 retval = ScanFunctions(BHEAD newpat,inter,par);
164 while ( r < mstop ) {
165 if ( *r < (AM.OffsetVector+WILDOFFSET) ) {
167 sign += vwc + ifix + iwc;
169 else if ( *r < MINSPEC ) {
173 else if ( *r < (AM.OffsetIndex+WILDOFFSET) ) {
177 else if ( *r < (AM.OffsetIndex+(WILDOFFSET<<1)) ) {
186 if ( iwc == 0 && vwc == 0 )
return(0);
194 while ( t < tstop ) {
197 if ( m < mstop && *t == *m ) {
201 sign += WORDDIF(mstop,m);
202 tfixvec[tvfix++] = *t;
207 if ( r < rstop && *r == *t ) {
211 sign += WORDDIF(rstop,r);
212 tfixind[tifix++] = *t;
217 if ( m < mstop || r < rstop )
return(0);
218 if ( tvfix < vwc || (tvfix+tifix) < (vwc+iwc) )
return(0);
219 sign += ( nv - vfix - vwc ) & ni;
231 if ( *wv == VECTOVEC ) {
232 for ( ni = 0; ni < vwc; ni++ ) {
233 if ( wcvec[ni]-WILDOFFSET == wv[2] ) {
237 wcvec[ni] = wcvec[ni+1];
241 for ( ni = 0; ni < tvfix; ni++ ) {
242 if ( tfixvec[ni] == wv[3] ) {
245 while ( ni < tvfix ) {
246 tfixvec[ni] = tfixvec[ni+1];
256 else if ( *wv == INDTOIND ) {
257 for ( ni = 0; ni < iwc; ni++ ) {
258 if ( wcind[ni]-WILDOFFSET == wv[2] ) {
262 wcind[ni] = wcind[ni+1];
265 for ( ni = 0; ni < tifix; ni++ ) {
266 if ( tfixind[ni] == wv[3] ) {
269 while ( ni < tifix ) {
270 tfixind[ni] = tfixind[ni+1];
282 else if ( *wv == VECTOSUB ) {
283 for ( ni = 0; ni < vwc; ni++ ) {
284 if ( wcvec[ni]-WILDOFFSET == wv[2] )
return(0);
287 else if ( *wv == INDTOSUB ) {
288 for ( ni = 0; ni < iwc; ni++ ) {
289 if ( wcind[ni]-WILDOFFSET == wv[2] )
return(0);
298 while ( n > 0 && ( *wv == FROMSET || *wv == SETTONUM
299 || *wv == LOADDOLLAR ) ) { wv += wv[1]; wm++; n--; }
332 if ( tvfix < vwc ) {
return(0); }
335 perm1.objects = tfixvec;
338 perm2.objects = tfixind;
339 distr.n1 = tvfix - vwc;
341 distr.obj1 = tfixvec + vwc;
342 distr.obj2 = tfixind;
349 t = OldWork = AT.WorkPointer;
350 nwstore = i = (m[-SUBEXPSIZE+1]-SUBEXPSIZE)/4;
354 *t++ = *m++; *t++ = *m++; *t++ = *m++; *t++ = *m++; *t++ = *r++;
357 if ( t >= AT.WorkTop ) {
358 MLOCK(ErrorMessageLock);
360 MUNLOCK(ErrorMessageLock);
364 while ( (first1 = Permute(&perm1,first1) ) == 0 ) {
366 while ( (first2 = Permute(&perm2,first2) ) == 0 ) {
368 while ( (first3 = Distribute(&distr,first3) ) == 0 ) {
372 for ( i = 0; i < vwc; i++ ) {
373 j = wcvec[i] - WILDOFFSET;
374 if ( CheckWild(BHEAD j,VECTOVEC,tfixvec[i],&newvalue) )
376 AddWild(BHEAD j,VECTOVEC,newvalue);
378 for ( i = 0; i < iwc; i++ ) {
379 j = wcind[i] - WILDOFFSET;
380 if ( CheckWild(BHEAD j,INDTOIND,fixvec[i],&newvalue) )
382 AddWild(BHEAD j,INDTOIND,newvalue);
387 oRepFunNum = AN.RepFunNum;
388 AN.RepFunList[AN.RepFunNum++] = offset;
389 AN.RepFunList[AN.RepFunNum++] =
390 ( perm1.sign + perm2.sign + distr.sign + sign ) & 1;
391 newpat = pattern + pattern[1];
392 if ( funwild ) AddWild(BHEAD *pattern-WILDOFFSET,FUNTOFUN,newfun);
393 if ( newpat >= AN.patstop ) {
394 if ( AN.UseFindOnly == 0 ) {
395 if ( FindOnce(BHEAD AN.findTerm,AN.findPattern) ) {
396 AN.UsedOtherFind = 1;
404 if ( ScanFunctions(BHEAD newpat,inter,par) ) {
return(1); }
409 AN.RepFunNum = oRepFunNum;
410NoCaseB: m = AN.WildValue;
411 t = OldWork; r = AT.WildMask; i = nwstore;
414 *m++ = *t++; *m++ = *t++; *m++ = *t++; *m++ = *t++; *r++ = *t++;
421 AT.WorkPointer = OldWork;
444int Permute(
PERM *perm, WORD first)
448 perm->sign = ( perm->sign <= 1 ) ? 0: 1;
449 for ( i = 0; i < perm->n; i++ ) perm->cycle[i] = 0;
457 while ( --j >= 0 ) { *s = s[1]; s++; }
459 if ( ( i & 1 ) != 0 ) perm->sign ^= 1;
460 if ( perm->cycle[i] < i ) {
478int PermuteP(
PERMP *perm, WORD first)
482 perm->sign = ( perm->sign <= 1 ) ? 0: 1;
483 for ( i = 0; i < perm->n; i++ ) perm->cycle[i] = 0;
491 while ( --j >= 0 ) { *s = s[1]; s++; }
493 if ( ( i & 1 ) != 0 ) perm->sign ^= 1;
494 if ( perm->cycle[i] < i ) {
512 WORD *to, *from, *inc, *from2, i, j;
514 d->n = d->n1 + d->n2;
517 for ( i = 0; i < d->n2; i++ ) {
529 if ( d->n1 == 0 || d->n2 == 0 )
return(1);
534 while ( *inc ) { j++; inc++; }
535 while ( inc < from && !*inc ) { i++; inc++; }
536 if ( inc >= from )
return(1);
537 d->sign ^= ((i&j)-j+1) & 1;
540 while ( --j >= 0 ) *--inc = 1;
541 while ( --i > 0 ) *--inc = 0;
545 for ( i = 0; i < d->n; i++ ) {
571int MatchCy(PHEAD WORD *pattern, WORD *fun, WORD *inter, WORD par)
574 WORD *t, *tstop, *p, *pstop, *m, *r, *oldworkpointer = AT.WorkPointer;
575 WORD *thewildcards, *multiplicity, *renum, wc, newvalue, oldwilval = 0;
576 WORD *params, *lowlevel = 0;
577 int argcount = 0, funnycount = 0, tcount = fun[1] - FUNHEAD;
578 int type = 0, pnum, i, j, k, nwstore, iraise, itop, sumeat;
579 CBUF *C = cbuf+AT.ebufnum;
580 int ntwa = 3*AN.NumTotWildArgs+1;
582 WORD offset = fun-AN.terstart, *newpat;
584 if ( (functions[fun[0]-FUNCTION].symmetric & ~REVERSEORDER) == RCYCLESYMMETRIC ) type = 1;
586 nwstore = (AN.WildValue[-SUBEXPSIZE+1]-SUBEXPSIZE)/4;
587 if ( pnum > FUNCTION + WILDOFFSET ) {
589 if ( CheckWild(BHEAD pnum,FUNTOFUN,fun[0],&newvalue) )
return(0);
591 t = lowlevel = AT.WorkPointer;
597 *t++ = *m++; *t++ = *m++; *t++ = *m++; *t++ = *m++; *t++ = *r++;
601 if ( t >= AT.WorkTop ) {
602 MLOCK(ErrorMessageLock);
604 MUNLOCK(ErrorMessageLock);
608 AddWild(BHEAD pnum,FUNTOFUN,newvalue);
610 if ( (functions[pnum-FUNCTION].symmetric & ~REVERSEORDER) == RCYCLESYMMETRIC ) type = 1;
614 p = pattern + FUNHEAD;
615 pstop = pattern + pattern[1];
616 while ( p < pstop ) {
617 if ( *p == FUNNYWILD ) { p += 2; funnycount++; }
618 else { p++; argcount++; }
620 if ( argcount > tcount )
goto NoSuccess;
621 if ( argcount < tcount && funnycount == 0 )
goto NoSuccess;
622 if ( argcount == 0 && tcount == 0 && funnycount == 0 ) {
623 AN.RepFunList[AN.RepFunNum++] = offset;
624 AN.RepFunList[AN.RepFunNum++] = 0;
625 newpat = pattern + pattern[1];
626 if ( newpat >= AN.patstop ) {
627 if ( AN.UseFindOnly == 0 ) {
628 if ( FindOnce(BHEAD AN.findTerm,AN.findPattern) ) {
629 AT.WorkPointer = oldworkpointer;
630 AN.UsedOtherFind = 1;
636 AT.WorkPointer = oldworkpointer;
640 else j = ScanFunctions(BHEAD newpat,inter,par);
644 tstop = fun + fun[1];
648 params = AT.WorkPointer;
649 thewildcards = t = params + tcount;
651 if ( oldwilval ) lowlevel = oldworkpointer;
658 *t++ = *m++; *t++ = *m++; *t++ = *m++; *t++ = *m++; *t++ = *r++;
662 if ( t >= AT.WorkTop ) {
663 MLOCK(ErrorMessageLock);
665 MUNLOCK(ErrorMessageLock);
672 if ( argcount == tcount ) {
673 if ( funnycount > 0 ) {
674 p = pattern + FUNHEAD;
676 while ( p < pstop ) {
677 if ( *p != FUNNYWILD ) { p++;
continue; }
679 if ( CheckWild(BHEAD p[1],ARGTOARG,0,t) )
goto nomatch;
680 AddWild(BHEAD p[1],ARGTOARG,0);
685 for ( k = 0; k <= type; k++ ) {
687 p = params; t = fun + FUNHEAD;
688 while ( t < tstop ) *p++ = *t++;
691 p = params+tcount; t = fun + FUNHEAD;
692 while ( t < tstop ) *--p = *t++;
694 for ( i = 0; i < tcount; i++ ) {
695 p = pattern + FUNHEAD;
697 for ( j = 0; j < tcount; j++, p++ ) {
698 while ( *p == FUNNYWILD ) p += 2;
699 t = params + (i+j)%tcount;
700 if ( *t == *p )
continue;
701 if ( *p >= AM.OffsetIndex + WILDOFFSET
702 && *p < AM.OffsetIndex + 2*WILDOFFSET ) {
706 wc = *p - WILDOFFSET;
707 if ( CheckWild(BHEAD wc,INDTOIND,*t,&newvalue) )
break;
708 AddWild(BHEAD wc,INDTOIND,newvalue);
710 else if ( *t < MINSPEC && p[j] < MINSPEC
711 && *p >= AM.OffsetVector + WILDOFFSET ) {
715 wc = *p - WILDOFFSET;
716 if ( CheckWild(BHEAD wc,VECTOVEC,*t,&newvalue) )
break;
717 AddWild(BHEAD wc,VECTOVEC,newvalue);
725 AN.RepFunList[AN.RepFunNum++] = offset;
726 AN.RepFunList[AN.RepFunNum++] = 0;
728 if ( funnycount > 0 ) {
729 p = pattern + FUNHEAD;
731 while ( p < pstop ) {
732 if ( *p != FUNNYWILD ) { p++;
continue; }
734 AddWild(BHEAD p[1],ARGTOARG,0);
738 newpat = pattern + pattern[1];
739 if ( newpat >= AN.patstop ) {
740 if ( AN.UseFindOnly == 0 ) {
741 if ( FindOnce(BHEAD AN.findTerm,AN.findPattern) ) {
742 AT.WorkPointer = oldworkpointer;
743 AN.UsedOtherFind = 1;
749 AT.WorkPointer = oldworkpointer;
753 else j = ScanFunctions(BHEAD newpat,inter,par);
755 AT.WorkPointer = oldworkpointer;
763 if ( wc && nwstore > 0 ) {
766 t = thewildcards + ntwa; r = AT.WildMask;
769 *m++ = *t++; *m++ = *t++; *m++ = *t++; *m++ = *t++; *r++ = *t++;
783 if ( funnycount == 1 ) {
784 funnycount = tcount - argcount;
785 for ( k = 0; k <= type; k++ ) {
787 p = params; t = fun + FUNHEAD;
788 while ( t < tstop ) *p++ = *t++;
791 p = params+tcount; t = fun + FUNHEAD;
792 while ( t < tstop ) *--p = *t++;
794 for ( i = 0; i < tcount; i++ ) {
795 p = pattern + FUNHEAD;
798 for ( j = 0; j < tcount; j++, p++, t++ ) {
799 if ( *t == *p )
continue;
800 if ( *p == FUNNYWILD ) {
803 if ( CheckWild(BHEAD *p,ARGTOARG|EATTENSOR,funnycount,t) )
break;
804 AddWild(BHEAD *p,ARGTOARG|EATTENSOR,funnycount);
805 j += funnycount-1; t += funnycount-1;
807 else if ( *p >= AM.OffsetIndex + WILDOFFSET
808 && *p < AM.OffsetIndex + 2*WILDOFFSET ) {
812 wc = *p - WILDOFFSET;
813 if ( CheckWild(BHEAD wc,INDTOIND,*t,&newvalue) )
break;
814 AddWild(BHEAD wc,INDTOIND,newvalue);
816 else if ( *t < MINSPEC && *p < MINSPEC
817 && *p >= AM.OffsetVector + WILDOFFSET ) {
821 wc = *p - WILDOFFSET;
822 if ( CheckWild(BHEAD wc,VECTOVEC,*t,&newvalue) )
break;
823 AddWild(BHEAD wc,VECTOVEC,newvalue);
831 AN.RepFunList[AN.RepFunNum++] = offset;
832 AN.RepFunList[AN.RepFunNum++] = 0;
833 newpat = pattern + pattern[1];
834 if ( newpat >= AN.patstop ) {
835 if ( AN.UseFindOnly == 0 ) {
836 if ( FindOnce(BHEAD AN.findTerm,AN.findPattern) ) {
837 AT.WorkPointer = oldworkpointer;
838 AN.UsedOtherFind = 1;
844 AT.WorkPointer = oldworkpointer;
848 else j = ScanFunctions(BHEAD newpat,inter,par);
850 AT.WorkPointer = oldworkpointer;
861 t = thewildcards + ntwa; r = AT.WildMask;
864 *m++ = *t++; *m++ = *t++; *m++ = *t++; *m++ = *t++; *r++ = *t++;
872 for ( j = 1; j < tcount; j++ ) { *t = t[1]; t++; }
883 sumeat = tcount - argcount;
892 for ( i = funnycount; i < ntwa; i++ ) thewildcards[i] = -1;
893 multiplicity = thewildcards + funnycount;
894 renum = multiplicity + funnycount;
896 while ( p < pstop ) {
897 if ( *p != FUNNYWILD ) { p++;
continue; }
899 if ( renum[*p] < 0 ) {
904 else multiplicity[renum[*p]]++;
910 for ( i = 1; i < AN.NumTotWildArgs; i++ ) {
911 if ( renum[i] < 0 )
continue;
912 for ( j = i+1; j <= AN.NumTotWildArgs; j++ ) {
913 if ( renum[j] < 0 )
continue;
914 if ( renum[i] < renum[j] )
continue;
915 k = multiplicity[renum[i]];
916 multiplicity[renum[i]] = multiplicity[renum[j]];
917 multiplicity[renum[j]] = k;
918 k = renum[i]; renum[i] = renum[j]; renum[j] = k;
921 for ( i = 0; i < funnycount; i++ ) thewildcards[i] = 0;
922 iraise = funnycount-1;
924 for ( i = 0, j = sumeat; i < iraise; i++ )
925 j -= thewildcards[i]*multiplicity[i];
926 if ( j < 0 || j % multiplicity[iraise] != 0 ) {
928 thewildcards[iraise-1]++;
932 while ( itop > 0 && j < 0 ) {
933 j += thewildcards[itop]*multiplicity[itop];
934 thewildcards[itop] = 0;
937 if ( itop <= 0 && j <= 0 )
break;
938 thewildcards[itop]++;
941 thewildcards[iraise] = j / multiplicity[iraise];
943 for ( k = 0; k <= type; k++ ) {
945 p = params; t = fun + FUNHEAD;
946 while ( t < tstop ) *p++ = *t++;
949 p = params+tcount; t = fun + FUNHEAD;
950 while ( t < tstop ) *--p = *t++;
952 for ( i = 0; i < tcount; i++ ) {
953 p = pattern + FUNHEAD;
956 for ( j = 0; j < tcount; j++, p++, t++ ) {
957 if ( *t == *p )
continue;
958 if ( *p == FUNNYWILD ) {
959 p++; wc = thewildcards[renum[*p]];
961 if ( CheckWild(BHEAD *p,ARGTOARG|EATTENSOR,wc,t) )
break;
962 AddWild(BHEAD *p,ARGTOARG|EATTENSOR,wc);
963 j += wc-1; t += wc-1; wc = 1;
965 else if ( *p >= AM.OffsetIndex + WILDOFFSET
966 && *p < AM.OffsetIndex + 2*WILDOFFSET ) {
970 wc = *p - WILDOFFSET;
971 if ( CheckWild(BHEAD wc,INDTOIND,*t,&newvalue) )
break;
972 AddWild(BHEAD wc,INDTOIND,newvalue);
974 else if ( *t < MINSPEC && *p < MINSPEC
975 && *p >= AM.OffsetVector + WILDOFFSET ) {
979 wc = *p - WILDOFFSET;
980 if ( CheckWild(BHEAD wc,VECTOVEC,*t,&newvalue) )
break;
981 AddWild(BHEAD wc,VECTOVEC,newvalue);
989 AN.RepFunList[AN.RepFunNum++] = offset;
990 AN.RepFunList[AN.RepFunNum++] = 0;
991 newpat = pattern + pattern[1];
992 if ( newpat >= AN.patstop ) {
993 if ( AN.UseFindOnly == 0 ) {
994 if ( FindOnce(BHEAD AN.findTerm,AN.findPattern) ) {
995 AT.WorkPointer = oldworkpointer;
996 AN.UsedOtherFind = 1;
1002 AT.WorkPointer = oldworkpointer;
1006 else j = ScanFunctions(BHEAD newpat,inter,par);
1008 AT.WorkPointer = oldworkpointer;
1019 t = thewildcards + ntwa; r = AT.WildMask;
1022 *m++ = *t++; *m++ = *t++; *m++ = *t++; *m++ = *t++; *r++ = *t++;
1023 }
while ( --j > 0 );
1030 for ( j = 1; j < tcount; j++ ) { *t = t[1]; t++; }
1034 (thewildcards[iraise-1])++;
1040 if ( oldwilval > 0 ) {
1045 t = lowlevel; r = AT.WildMask;
1048 *m++ = *t++; *m++ = *t++; *m++ = *t++; *m++ = *t++; *r++ = *t++;
1049 }
while ( --j > 0 );
1055 AT.WorkPointer = oldworkpointer;
1067int FunMatchCy(PHEAD WORD *pattern, WORD *fun, WORD *inter, WORD par)
1070 WORD *t, *tstop, *p, *pstop, *m, *r, *oldworkpointer = AT.WorkPointer;
1071 WORD **a, *thewildcards, *multiplicity, *renum, wc, wcc, oldwilval = 0;
1072 LONG oww = AT.pWorkPointer;
1073 WORD newvalue, *lowlevel = 0;
1074 int argcount = 0, funnycount = 0, tcount = 0;
1075 int type = 0, pnum, i, j, k, nwstore, iraise, itop, sumeat;
1076 CBUF *C = cbuf+AT.ebufnum;
1077 int ntwa = 3*AN.NumTotWildArgs+1;
1079 WORD offset = fun-AN.terstart, *newpat;
1081 if ( (functions[fun[0]-FUNCTION].symmetric & ~REVERSEORDER) == RCYCLESYMMETRIC ) type = 1;
1083 nwstore = (AN.WildValue[-SUBEXPSIZE+1]-SUBEXPSIZE)/4;
1084 if ( pnum > FUNCTION + WILDOFFSET ) {
1086 if ( CheckWild(BHEAD pnum,FUNTOFUN,fun[0],&newvalue) )
return(0);
1088 t = lowlevel = oldworkpointer;
1094 *t++ = *m++; *t++ = *m++; *t++ = *m++; *t++ = *m++; *t++ = *r++;
1095 }
while ( --i > 0 );
1098 if ( t >= AT.WorkTop ) {
1099 MLOCK(ErrorMessageLock);
1101 MUNLOCK(ErrorMessageLock);
1105 AddWild(BHEAD pnum,FUNTOFUN,newvalue);
1107 if ( (functions[pnum-FUNCTION].symmetric & ~REVERSEORDER) == RCYCLESYMMETRIC ) type = 1;
1111 p = pattern + FUNHEAD;
1112 pstop = pattern + pattern[1];
1113 while ( p < pstop ) {
1114 if ( *p == -ARGWILD ) { p += 2; funnycount++; }
1115 else { NEXTARG(p); argcount++; }
1118 tstop = fun + fun[1];
1119 while ( t < tstop ) { NEXTARG(t); tcount++; }
1121 if ( argcount > tcount )
return(0);
1122 if ( argcount < tcount && funnycount == 0 )
return(0);
1123 if ( argcount == 0 && tcount == 0 && funnycount == 0 ) {
1124 AN.RepFunList[AN.RepFunNum++] = offset;
1125 AN.RepFunList[AN.RepFunNum++] = 0;
1126 newpat = pattern + pattern[1];
1127 if ( newpat >= AN.patstop ) {
1128 if ( AN.UseFindOnly == 0 ) {
1129 if ( FindOnce(BHEAD AN.findTerm,AN.findPattern) ) {
1130 AT.WorkPointer = oldworkpointer;
1131 AN.UsedOtherFind = 1;
1137 AT.WorkPointer = oldworkpointer;
1141 else j = ScanFunctions(BHEAD newpat,inter,par);
1148 WantAddPointers(tcount);
1149 AT.pWorkPointer += tcount;
1150 thewildcards = t = AT.WorkPointer;
1152 if ( oldwilval ) lowlevel = oldworkpointer;
1159 *t++ = *m++; *t++ = *m++; *t++ = *m++; *t++ = *m++; *t++ = *r++;
1160 }
while ( --i > 0 );
1163 if ( t >= AT.WorkTop ) {
1164 MLOCK(ErrorMessageLock);
1166 MUNLOCK(ErrorMessageLock);
1173 if ( argcount == tcount ) {
1174 if ( funnycount > 0 ) {
1175 p = pattern + FUNHEAD;
1177 while ( p < pstop ) {
1178 if ( *p != -ARGWILD ) { p++;
continue; }
1180 if ( CheckWild(BHEAD p[1],ARGTOARG,0,t) )
goto nomatch;
1181 AddWild(BHEAD p[1],ARGTOARG,0);
1186 for ( k = 0; k <= type; k++ ) {
1188 a = AT.pWorkSpace+oww; t = fun + FUNHEAD;
1189 while ( t < tstop ) { *a++ = t; NEXTARG(t); }
1192 a = AT.pWorkSpace+oww+tcount; t = fun + FUNHEAD;
1193 while ( t < tstop ) { *--a = t; NEXTARG(t); }
1195 for ( i = 0; i < tcount; i++ ) {
1196 p = pattern + FUNHEAD;
1198 for ( j = 0; j < tcount; j++ ) {
1199 while ( *p == -ARGWILD ) p += 2;
1200 t = AT.pWorkSpace[oww+((i+j)%tcount)];
1201 if ( ( wcc = MatchArgument(BHEAD t,p) ) == 0 )
break;
1202 if ( wcc > 1 ) wc = 1;
1205 if ( j >= tcount ) {
1209 AN.RepFunList[AN.RepFunNum++] = offset;
1210 AN.RepFunList[AN.RepFunNum++] = 0;
1212 if ( funnycount > 0 ) {
1213 p = pattern + FUNHEAD;
1215 while ( p < pstop ) {
1216 if ( *p != -ARGWILD ) { p++;
continue; }
1218 AddWild(BHEAD p[1],ARGTOARG,0);
1222 newpat = pattern + pattern[1];
1223 if ( newpat >= AN.patstop ) {
1224 if ( AN.UseFindOnly == 0 ) {
1225 if ( FindOnce(BHEAD AN.findTerm,AN.findPattern) ) {
1226 AT.WorkPointer = oldworkpointer;
1227 AT.pWorkPointer = oww;
1228 AN.UsedOtherFind = 1;
1234 AT.WorkPointer = oldworkpointer;
1235 AT.pWorkPointer = oww;
1239 else j = ScanFunctions(BHEAD newpat,inter,par);
1241 AT.WorkPointer = oldworkpointer;
1242 AT.pWorkPointer = oww;
1250 if ( wc && nwstore > 0 ) {
1253 t = thewildcards + ntwa; r = AT.WildMask;
1256 *m++ = *t++; *m++ = *t++; *m++ = *t++; *m++ = *t++; *r++ = *t++;
1257 }
while ( --j > 0 );
1270 if ( funnycount == 1 ) {
1271 funnycount = tcount - argcount;
1272 for ( k = 0; k <= type; k++ ) {
1274 a = AT.pWorkSpace+oww; t = fun + FUNHEAD;
1275 while ( t < tstop ) { *a++ = t; NEXTARG(t); }
1278 a = AT.pWorkSpace+oww+tcount; t = fun + FUNHEAD;
1279 while ( t < tstop ) { *--a = t; NEXTARG(t); }
1281 for ( i = 0; i < tcount; i++ ) {
1282 p = pattern + FUNHEAD;
1283 a = AT.pWorkSpace+oww;
1285 for ( j = 0; j < tcount; j++, a++ ) {
1287 if ( *p == -ARGWILD ) {
1289 AN.argaddress = (WORD *)a;
1290 if ( CheckWild(BHEAD p[1],ARLTOARL,funnycount,(WORD *)a) )
break;
1291 AddWild(BHEAD p[1],ARLTOARL,funnycount);
1292 j += funnycount-1; a += funnycount-1;
1294 else if ( MatchArgument(BHEAD t,p) == 0 )
break;
1297 if ( j >= tcount ) {
1301 AN.RepFunList[AN.RepFunNum++] = offset;
1302 AN.RepFunList[AN.RepFunNum++] = 0;
1303 newpat = pattern + pattern[1];
1304 if ( newpat >= AN.patstop ) {
1305 if ( AN.UseFindOnly == 0 ) {
1306 if ( FindOnce(BHEAD AN.findTerm,AN.findPattern) ) {
1307 AT.WorkPointer = oldworkpointer;
1308 AT.pWorkPointer = oww;
1309 AN.UsedOtherFind = 1;
1315 AT.WorkPointer = oldworkpointer;
1316 AT.pWorkPointer = oww;
1320 else j = ScanFunctions(BHEAD newpat,inter,par);
1322 AT.WorkPointer = oldworkpointer;
1323 AT.pWorkPointer = oww;
1334 t = thewildcards + ntwa; r = AT.WildMask;
1337 *m++ = *t++; *m++ = *t++; *m++ = *t++; *m++ = *t++; *r++ = *t++;
1338 }
while ( --j > 0 );
1343 a = AT.pWorkSpace+oww;
1345 for ( j = 1; j < tcount; j++ ) { *a = a[1]; a++; }
1356 sumeat = tcount - argcount;
1364 p = pattern+FUNHEAD;
1365 for ( i = funnycount; i < ntwa; i++ ) thewildcards[i] = -1;
1366 multiplicity = thewildcards + funnycount;
1367 renum = multiplicity + funnycount;
1369 while ( p < pstop ) {
1370 if ( *p != -ARGWILD ) { p++;
continue; }
1372 if ( renum[*p] < 0 ) {
1374 multiplicity[j] = 1;
1377 else multiplicity[renum[*p]]++;
1383 for ( i = 1; i < AN.NumTotWildArgs; i++ ) {
1384 if ( renum[i] < 0 )
continue;
1385 for ( j = i+1; j <= AN.NumTotWildArgs; j++ ) {
1386 if ( renum[j] < 0 )
continue;
1387 if ( renum[i] < renum[j] )
continue;
1388 k = multiplicity[renum[i]];
1389 multiplicity[renum[i]] = multiplicity[renum[j]];
1390 multiplicity[renum[j]] = k;
1391 k = renum[i]; renum[i] = renum[j]; renum[j] = k;
1394 for ( i = 0; i < funnycount; i++ ) thewildcards[i] = 0;
1395 iraise = funnycount-1;
1397 for ( i = 0, j = sumeat; i < iraise; i++ )
1398 j -= thewildcards[i]*multiplicity[i];
1399 if ( j < 0 || j % multiplicity[iraise] != 0 ) {
1401 thewildcards[iraise-1]++;
1405 while ( itop > 0 && j < 0 ) {
1406 j += thewildcards[itop]*multiplicity[itop];
1407 thewildcards[itop] = 0;
1410 if ( itop <= 0 && j <= 0 )
break;
1411 thewildcards[itop]++;
1414 thewildcards[iraise] = j / multiplicity[iraise];
1416 for ( k = 0; k <= type; k++ ) {
1418 a = AT.pWorkSpace+oww; t = fun + FUNHEAD;
1419 while ( t < tstop ) { *a++ = t; NEXTARG(t); }
1422 a = AT.pWorkSpace+oww+tcount; t = fun + FUNHEAD;
1423 while ( t < tstop ) { *--a = t; NEXTARG(t); }
1425 for ( i = 0; i < tcount; i++ ) {
1426 p = pattern + FUNHEAD;
1427 a = AT.pWorkSpace+oww;
1429 for ( j = 0; j < tcount; j++, a++ ) {
1431 if ( *p == -ARGWILD ) {
1432 wc = thewildcards[renum[p[1]]];
1433 AN.argaddress = (WORD *)a;
1434 if ( CheckWild(BHEAD p[1],ARLTOARL,wc,(WORD *)a) )
break;
1435 AddWild(BHEAD p[1],ARLTOARL,wc);
1436 j += wc-1; a += wc-1; wc = 1;
1438 else if ( MatchArgument(BHEAD t,p) == 0 )
break;
1441 if ( j >= tcount ) {
1445 AN.RepFunList[AN.RepFunNum++] = offset;
1446 AN.RepFunList[AN.RepFunNum++] = 0;
1447 newpat = pattern + pattern[1];
1448 if ( newpat >= AN.patstop ) {
1449 if ( AN.UseFindOnly == 0 ) {
1450 if ( FindOnce(BHEAD AN.findTerm,AN.findPattern) ) {
1451 AT.WorkPointer = oldworkpointer;
1452 AT.pWorkPointer = oww;
1453 AN.UsedOtherFind = 1;
1459 AT.WorkPointer = oldworkpointer;
1460 AT.pWorkPointer = oww;
1464 else j = ScanFunctions(BHEAD newpat,inter,par);
1466 AT.WorkPointer = oldworkpointer;
1467 AT.pWorkPointer = oww;
1478 t = thewildcards + ntwa; r = AT.WildMask;
1481 *m++ = *t++; *m++ = *t++; *m++ = *t++; *m++ = *t++; *r++ = *t++;
1482 }
while ( --j > 0 );
1487 a = AT.pWorkSpace+oww;
1489 for ( j = 1; j < tcount; j++ ) { *a = a[1]; a++; }
1493 (thewildcards[iraise-1])++;
1499 if ( oldwilval > 0 ) {
1503 t = lowlevel; r = AT.WildMask;
1506 *m++ = *t++; *m++ = *t++; *m++ = *t++; *m++ = *t++; *r++ = *t++;
1507 }
while ( --j > 0 );
1512 AT.WorkPointer = oldworkpointer;
1513 AT.pWorkPointer = oww;
1525int FunMatchSy(PHEAD WORD *pattern, WORD *fun, WORD *inter, WORD par)
1528 WORD *t, *tstop, *p, *pstop, *m, *r, *oldworkpointer = AT.WorkPointer;
1529 WORD **a, *thewildcards, oldwilval = 0;
1530 WORD newvalue, *lowlevel = 0, num, assig;
1532 LONG oww = AT.pWorkPointer, lhpars, lhfunnies;
1533 int argcount = 0, funnycount = 0, tcount = 0, signs = 0, signfun = 0, signo;
1534 int type = 0, pnum, i, j, k, nwstore, iraise, cou2;
1535 CBUF *C = cbuf+AT.ebufnum;
1536 int ntwa = 3*AN.NumTotWildArgs+1;
1538 WORD offset = fun-AN.terstart, *newpat;
1540 if ( (functions[fun[0]-FUNCTION].symmetric & ~REVERSEORDER) == RCYCLESYMMETRIC ) type = 1;
1542 nwstore = (AN.WildValue[-SUBEXPSIZE+1]-SUBEXPSIZE)/4;
1543 if ( pnum > FUNCTION + WILDOFFSET ) {
1545 if ( CheckWild(BHEAD pnum,FUNTOFUN,fun[0],&newvalue) )
return(0);
1547 t = lowlevel = oldworkpointer;
1553 *t++ = *m++; *t++ = *m++; *t++ = *m++; *t++ = *m++; *t++ = *r++;
1554 }
while ( --i > 0 );
1557 if ( t >= AT.WorkTop ) {
1558 MLOCK(ErrorMessageLock);
1560 MUNLOCK(ErrorMessageLock);
1564 AddWild(BHEAD pnum,FUNTOFUN,newvalue);
1566 if ( (functions[pnum-FUNCTION].symmetric & ~REVERSEORDER) == RCYCLESYMMETRIC ) type = 1;
1570 if ( fun[1] == pattern[1] ) {
1571 i = fun[1]-FUNHEAD; p = pattern+FUNHEAD; t = fun + FUNHEAD;
1572 while ( --i >= 0 ) {
if ( *p++ != *t++ )
break; }
1573 if ( i < 0 )
goto quicky;
1578 p = pattern + FUNHEAD;
1579 pstop = pattern + pattern[1];
1580 while ( p < pstop ) {
1581 if ( *p == -ARGWILD ) { p += 2; funnycount++; }
1582 else { NEXTARG(p); argcount++; }
1585 tstop = fun + fun[1];
1586 while ( t < tstop ) { NEXTARG(t); tcount++; }
1588 if ( argcount > tcount )
return(0);
1589 if ( argcount < tcount && funnycount == 0 )
return(0);
1590 if ( argcount == 0 && tcount == 0 && funnycount == 0 ) {
1592 if ( AN.SignCheck && signs != AN.ExpectedSign )
goto NoSuccess;
1593 AN.RepFunList[AN.RepFunNum++] = offset;
1594 AN.RepFunList[AN.RepFunNum++] = signs;
1595 newpat = pattern + pattern[1];
1596 if ( newpat >= AN.patstop ) {
1597 if ( AN.UseFindOnly == 0 ) {
1598 if ( FindOnce(BHEAD AN.findTerm,AN.findPattern) ) {
1599 AT.WorkPointer = oldworkpointer;
1600 AN.UsedOtherFind = 1;
1606 AT.WorkPointer = oldworkpointer;
1610 else j = ScanFunctions(BHEAD newpat,inter,par);
1612 AT.WorkPointer = oldworkpointer;
1620 WantAddPointers(tcount+argcount+funnycount);
1621 AT.pWorkPointer += tcount+argcount+funnycount;
1622 thewildcards = t = AT.WorkPointer;
1624 if ( oldwilval ) lowlevel = oldworkpointer;
1627 i = nwstore; assig = 0;
1632 *t++ = *m++; *t++ = *m++; *t++ = *m++; *t++ = *m++; *t++ = *r++;
1633 }
while ( --i > 0 );
1636 if ( t >= AT.WorkTop ) {
1637 MLOCK(ErrorMessageLock);
1639 MUNLOCK(ErrorMessageLock);
1646 t = fun + FUNHEAD; a = AT.pWorkSpace+oww;
1647 while ( t < tstop ) { *a++ = t; NEXTARG(t) }
1648 lhpars = a-AT.pWorkSpace;
1649 t = pattern + FUNHEAD;
1650 while ( t < pstop ) {
1651 if ( *t != -ARGWILD ) *a++ = t;
1654 lhfunnies = a-AT.pWorkSpace;
1655 t = pattern + FUNHEAD; cou2 = 0;
1656 while ( t < pstop ) {
1658 if ( *t == -ARGWILD ) {
1665 signfun = ((argcount+funnycount-cou2)*(tcount-argcount)) & 1;
1670 if ( funnycount > 0 ) {
1671 if ( ( (functions[fun[0]-FUNCTION].symmetric & ~REVERSEORDER) == SYMMETRIC )
1672 || ( (functions[fun[0]-FUNCTION].symmetric & ~REVERSEORDER) == ANTISYMMETRIC )
1673 || ( (functions[pnum-FUNCTION].symmetric & ~REVERSEORDER) == SYMMETRIC )
1674 || ( (functions[pnum-FUNCTION].symmetric & ~REVERSEORDER) == ANTISYMMETRIC ) ) {
1675 AT.WorkPointer = oldworkpointer;
1676 AT.pWorkPointer = oww;
1677 MLOCK(ErrorMessageLock);
1678 MesPrint(
"Sorry: no argument field wildcards yet in (anti)symmetric functions");
1679 MUNLOCK(ErrorMessageLock);
1691 for ( i = 0; i < iraise; i++ ) {
1692 t = AT.pWorkSpace[i+lhpars];
1696 else if ( *t <= -FUNCTION ) {
1697 if ( *t > -FUNCTION - WILDOFFSET )
goto cat1;
1698 type = FUNTOFUN; num = -*t - WILDOFFSET;
1700 else if ( *t == -SYMBOL ) {
1701 if ( t[1] < 2*MAXPOWER )
goto cat1;
1702 type = SYMTOSYM; num = t[1] - 2*MAXPOWER;
1704 else if ( *t == -INDEX ) {
1705 if ( t[1] < AM.OffsetIndex + WILDOFFSET )
goto cat1;
1706 type = INDTOIND; num = t[1] - WILDOFFSET;
1708 else if ( *t == -VECTOR || *t == -MINVECTOR ) {
1709 if ( t[1] < AM.OffsetVector + WILDOFFSET )
goto cat1;
1710 type = VECTOVEC; num = t[1] - WILDOFFSET;
1719 while ( --j >= 0 ) {
1720 if ( m[2] == num && *r ) {
1721 if ( type == *m )
break;
1722 if ( type == SYMTOSYM ) {
1723 if ( *m == SYMTONUM || *m == SYMTOSUB )
break;
1725 else if ( type == INDTOIND ) {
1726 if ( *m == INDTOSUB )
break;
1728 else if ( type == VECTOVEC ) {
1729 if ( *m == VECTOMIN || *m == VECTOSUB )
break;
1735 a = AT.pWorkSpace+lhpars;
1737 if ( iraise != i ) signs++;
1743 for ( j = 0; j < tcount; j++ ) {
1744 if ( MatchArgument(BHEAD AT.pWorkSpace[oww+j],t) ) {
1748 while ( --k >= 0 ) num += *r++;
1749 if ( num == assig ) {
1755 if ( j >= tcount )
goto NoSuccess;
1758 t = thewildcards + ntwa; r = AT.WildMask;
1761 *m++ = *t++; *m++ = *t++; *m++ = *t++; *m++ = *t++; *r++ = *t++;
1762 }
while ( --j > 0 );
1768 for ( j = 0; j < tcount; j++ ) {
1769 m = AT.pWorkSpace[j+oww];
1770 if ( *t != *m )
continue;
1772 if ( *t <= -FUNCTION )
break;
1773 if ( t[1] == m[1] )
break;
1777 while ( --k >= 0 && *m++ == *r++ ) {}
1781 if ( j >= tcount )
goto NoSuccess;
1788 while ( j < tcount ) {
1789 AT.pWorkSpace[oww+j] = AT.pWorkSpace[oww+j+1]; j++;
1795 while ( j < argcount ) {
1796 AT.pWorkSpace[lhpars+j] = AT.pWorkSpace[lhpars+j+1]; j++;
1806 for ( i = 0; i < funnycount; i++ ) {
1807 k = AT.pWorkSpace[lhfunnies+i][1];
1811 while ( --j >= 0 ) {
1812 if ( *m == ARGTOARG && m[2] == k )
break;
1815 if ( *r == 0 )
continue;
1816 m = cbuf[AT.ebufnum].rhs[m[3]];
1819 if ( j > tcount - argcount )
goto NoSuccess;
1820 while ( --j >= 0 ) {
1822 if ( *m < 0 ) type = -VECTOR;
1823 else if ( *m < AM.OffsetIndex ) type = -SNUMBER;
1825 a = AT.pWorkSpace+oww;
1826 for ( k = 0; k < tcount; k++ ) {
1827 if ( a[k][0] != type || a[k][1] != *m )
continue;
1838 for ( k = 0; k < tcount; k++ ) {
1839 t = AT.pWorkSpace[oww+k];
1840 if ( *t != *m )
continue;
1843 if ( *r < -FUNCTION )
goto nextargw;
1844 else if ( r[1] == t[1] )
goto nextargw;
1848 while ( --j >= 0 && *r++ == *t++ ) {}
1849 if ( j < 0 )
goto nextargw;
1854 AT.pWorkSpace[oww+k] = AT.pWorkSpace[oww+(--tcount)];
1858 AT.pWorkSpace[lhfunnies+i] = AT.pWorkSpace[lhfunnies+(--funnycount)];
1860 if ( tcount == 0 ) {
1861 if ( argcount > 0 )
goto NoSuccess;
1862 for ( i = 0; i < funnycount; i++ ) {
1863 AddWild(BHEAD AT.pWorkSpace[lhfunnies+i][1],ARGTOARG,0);
1875 for ( i = 0; i < iraise; i++ ) {
1876 for ( j = 0; j < tcount; j++ ) {
1877 if ( MatchArgument(BHEAD AT.pWorkSpace[oww+j],AT.pWorkSpace[lhpars+i]) ) {
1881 while ( --k >= 0 ) num += *r++;
1882 if ( num == assig ) {
1884 AT.pWorkSpace[oww+j] = AT.pWorkSpace[oww+(--tcount)];
1885 if ( tcount > j ) signs += tcount-j-1;
1887 a = AT.pWorkSpace + lhpars;
1888 for ( j = i; j < argcount; j++ ) a[j] = a[j+1];
1895 t = thewildcards + ntwa; r = AT.WildMask;
1898 *m++ = *t++; *m++ = *t++; *m++ = *t++; *m++ = *t++; *r++ = *t++;
1899 }
while ( --j > 0 );
1921 cycles = AT.WorkPointer;
1922 for ( i = 0; i < tcount; i++ ) cycles[i] = tcount-i;
1923 AT.WorkPointer += tcount;
1927 WORD oRepFunNum = AN.RepFunNum;
1928 for ( j = 0; j < argcount; j++ ) {
1929 if ( MatchArgument(BHEAD AT.pWorkSpace[oww+j],AT.pWorkSpace[lhpars+j]) == 0 ) {
1933 if ( j >= argcount ) {
1938 AT.WorkPointer = oldworkpointer;
1939 AT.pWorkPointer = oww;
1940 MLOCK(ErrorMessageLock);
1941 MesPrint(
"Sorry: no argument field wildcards yet in (anti)symmetric functions");
1942 MUNLOCK(ErrorMessageLock);
1953 AN.RepFunList[AN.RepFunNum++] = offset;
1954 if ( ( (functions[fun[0]-FUNCTION].symmetric & ~REVERSEORDER) == ANTISYMMETRIC )
1955 || ( (functions[pnum-FUNCTION].symmetric & ~REVERSEORDER) == ANTISYMMETRIC ) ) {
1956 AN.RepFunList[AN.RepFunNum++] = ( signs + signo ) & 1;
1959 AN.RepFunList[AN.RepFunNum++] = 0;
1961 newpat = pattern + pattern[1];
1962 if ( newpat >= AN.patstop ) {
1963 WORD countsgn, sgn = 0;
1964 for ( countsgn = oRepFunNum+1; countsgn < AN.RepFunNum; countsgn += 2 ) {
1965 if ( AN.RepFunList[countsgn] ) sgn ^= 1;
1967 if ( AN.SignCheck == 0 || sgn == AN.ExpectedSign ) {
1968 AT.WorkPointer = oldworkpointer;
1969 AT.pWorkPointer = oww;
1972 if ( AN.UseFindOnly == 0 ) {
1973 if ( FindOnce(BHEAD AN.findTerm,AN.findPattern) ) {
1974 AT.WorkPointer = oldworkpointer;
1975 AT.pWorkPointer = oww;
1976 AN.UsedOtherFind = 1;
1982 else j = ScanFunctions(BHEAD newpat,inter,par);
1984 WORD countsgn, sgn = 0;
1985 for ( countsgn = oRepFunNum+1; countsgn < AN.RepFunNum; countsgn += 2 ) {
1986 if ( AN.RepFunList[countsgn] ) sgn ^= 1;
1988 if ( AN.SignCheck == 0 || sgn == AN.ExpectedSign ) {
1989 AT.WorkPointer = oldworkpointer;
1990 AT.pWorkPointer = oww;
1994 AN.RepFunNum = oRepFunNum;
2000 t = thewildcards + ntwa; r = AT.WildMask;
2003 *m++ = *t++; *m++ = *t++; *m++ = *t++; *m++ = *t++; *r++ = *t++;
2004 }
while ( --j > 0 );
2011 a = AT.pWorkSpace + oww;
2012 for ( j = i+1, t = a[i]; j < tcount; j++ ) a[j-1] = a[j];
2013 a[tcount-1] = t; cycles[i]--;
2014 signo += tcount - i - 1;
2015 while ( cycles[i] <= 0 ) {
2016 cycles[i] = tcount - i;
2018 if ( i < 0 )
goto NoSuccess;
2024 for ( j = i+1, t = a[i]; j < tcount; j++ ) a[j-1] = a[j];
2025 a[tcount-1] = t; cycles[i]--;
2026 signo += tcount - i - 1;
2030 if ( oldwilval > 0 ) {
2033 t = lowlevel; r = AT.WildMask;
2036 *m++ = *t++; *m++ = *t++; *m++ = *t++; *m++ = *t++; *r++ = *t++;
2037 }
while ( --j > 0 );
2042 AT.WorkPointer = oldworkpointer;
2043 AT.pWorkPointer = oww;
2052int MatchArgument(PHEAD WORD *arg, WORD *pat)
2055 WORD *m = pat, *t = arg, i, j, newvalue;
2056 WORD *argmstop = pat, *argtstop = arg;
2057 WORD *cto, *cfrom, *csav, ci;
2058 WORD oRepFunNum, *oRepFunList;
2059 WORD *oterstart,*oterstop,*opatstop;
2060 WORD wildargs, wildeat;
2061 WORD *mtrmstop, *ttrmstop, *msubstop, msizcoef;
2070 if ( *m < 0 && *t < 0 ) {
2071 if ( *t <= -FUNCTION ) {
2073 else if ( *m <= -FUNCTION-WILDOFFSET
2074 && functions[-*t-FUNCTION].spec
2075 == functions[-*m-FUNCTION-WILDOFFSET].spec ) {
2076 i = -*m - WILDOFFSET; wc = 2;
2077 if ( CheckWild(BHEAD i,FUNTOFUN,-*t,&newvalue) ) {
2080 AddWild(BHEAD i,FUNTOFUN,newvalue);
2082 else if ( *m == -SYMBOL && m[1] >= 2*MAXPOWER ) {
2083 i = m[1] - 2*MAXPOWER;
2084 AN.argaddress = AT.FunArg;
2085 AT.FunArg[ARGHEAD+1] = -*t;
2086 if ( CheckWild(BHEAD i,SYMTOSUB,1,AN.argaddress) )
return(0);
2087 AddWild(BHEAD i,SYMTOSUB,0);
2091 else if ( *t == *m ) {
2092 if ( t[1] == m[1] ) {}
2093 else if ( *t == -SYMBOL ) {
2095SymAll:
if ( ( i = m[1] - 2*MAXPOWER ) < 0 )
return(0);
2097 if ( CheckWild(BHEAD i,j,t[1],&newvalue) )
return(0);
2098 AddWild(BHEAD i,j,newvalue);
2100 else if ( *t == -INDEX ) {
2101IndAll: i = m[1] - WILDOFFSET;
2102 if ( i < AM.OffsetIndex || i >= WILDOFFSET+AM.OffsetIndex )
2106 if ( CheckWild(BHEAD i,INDTOIND,t[1],&newvalue) )
return(0);
2107 AddWild(BHEAD i,INDTOIND,newvalue);
2109 else if ( *t == -VECTOR || *t == -MINVECTOR ) {
2110 i = m[1] - WILDOFFSET;
2111 if ( i < AM.OffsetVector )
return(0);
2113 if ( CheckWild(BHEAD i,VECTOVEC,t[1],&newvalue) )
return(0);
2114 AddWild(BHEAD i,VECTOVEC,newvalue);
2118 else if ( *m == -INDEX && m[1] >= AM.OffsetIndex+WILDOFFSET
2119 && m[1] < AM.OffsetIndex+(WILDOFFSET<<1) ) {
2120 if ( *t == -VECTOR )
goto IndAll;
2121 if ( *t == -SNUMBER && t[1] >= 0 && t[1] < AM.OffsetIndex )
goto IndAll;
2122 if ( *t == -MINVECTOR ) {
2123 i = m[1] - WILDOFFSET;
2124 AN.argaddress = AT.MinVecArg;
2125 AT.MinVecArg[ARGHEAD+3] = t[1];
2127 if ( CheckWild(BHEAD i,INDTOSUB,1,AN.argaddress) )
return(0);
2128 AddWild(BHEAD i,INDTOSUB,(WORD)0);
2132 else if ( *m == -SYMBOL && m[1] >= 2*MAXPOWER && *t == -SNUMBER ) {
2136 else if ( *m == -VECTOR && *t == -MINVECTOR &&
2137 ( i = m[1] - WILDOFFSET ) >= AM.OffsetVector ) {
2145 if ( CheckWild(BHEAD i,VECTOMIN,t[1],&newvalue) )
return(0);
2146 AddWild(BHEAD i,VECTOMIN,newvalue);
2149 else if ( *m == -MINVECTOR && *t == -VECTOR &&
2150 ( i = m[1] - WILDOFFSET ) >= AM.OffsetVector ) {
2158 if ( CheckWild(BHEAD i,VECTOMIN,t[1],&newvalue) )
return(0);
2159 AddWild(BHEAD i,VECTOMIN,newvalue);
2167 else if ( *m > 0 && *t <= -FUNCTION ) {
2168 if ( ( m[ARGHEAD]+ARGHEAD == *m ) && m[*m-1] == 3
2169 && m[*m-2] == 1 && m[*m-3] == 1 && m[ARGHEAD+1] >= FUNCTION
2170 && m[ARGHEAD+2] == *m-ARGHEAD-4 ) {
2171 WORD *mmmst, *mmm, mmmi;
2172 if ( m[ARGHEAD+1] >= FUNCTION+WILDOFFSET ) {
2173 mmmi = *m - WILDOFFSET;
2175 if ( CheckWild(BHEAD mmmi,FUNTOFUN,-*t,&newvalue) )
return(0);
2176 AddWild(BHEAD mmmi,FUNTOFUN,newvalue);
2178 else if ( m[ARGHEAD+1] != -*t )
return(0);
2183 mmm = m + ARGHEAD + FUNHEAD + 1;
2184 while ( mmm < mmmst ) {
2185 if ( *mmm != -ARGWILD )
return(0);
2187 AN.argaddress = t; wc = 2;
2188 if ( CheckWild(BHEAD mmm[1],ARGTOARG,mmmi,t) )
return(0);
2189 AddWild(BHEAD mmm[1],ARGTOARG,mmmi);
2199 else if ( *m < 0 && *t > 0 ) {
2200 if ( *m == -SYMBOL ) {
2201 if ( m[1] < 2*MAXPOWER )
return(0);
2202 i = m[1] - 2*MAXPOWER;
2203 AN.argaddress = t; wc = 2;
2204 if ( CheckWild(BHEAD i,SYMTOSUB,1,AN.argaddress) )
return(0);
2205 AddWild(BHEAD i,SYMTOSUB,0);
2207 else if ( *m == -VECTOR ) {
2208 if ( ( i = m[1] - WILDOFFSET ) < AM.OffsetVector )
return(0);
2209 AN.argaddress = t; wc = 2;
2210 if ( CheckWild(BHEAD i,VECTOSUB,1,t) )
return(0);
2211 AddWild(BHEAD i,VECTOSUB,(WORD)0);
2213 else if ( *m == -INDEX ) {
2214 if ( ( i = m[1] - WILDOFFSET ) < AM.OffsetIndex )
return(0);
2215 if ( i >= AM.OffsetIndex + WILDOFFSET )
return(0);
2216 AN.argaddress = t; wc = 2;
2217 if ( CheckWild(BHEAD i,INDTOSUB,1,AN.argaddress) )
return(0);
2218 AddWild(BHEAD i,INDTOSUB,(WORD)0);
2226 else if ( *m > 0 && *t > 0 ) {
2228 do {
if ( *m++ != *t++ )
break; }
while ( --i > 0 );
2235 m += ARGHEAD; t += ARGHEAD;
2238 if ( mtrmstop < argmstop )
return(0);
2239 msizcoef = mtrmstop[-1];
2240 if ( msizcoef < 0 ) msizcoef = -msizcoef;
2241 msubstop = mtrmstop - msizcoef;
2243 if ( m >= msubstop )
return(0);
2256 if ( argtstop > ttrmstop )
return(0);
2259 oterstart = AN.terstart;
2260 oterstop = AN.terstop;
2261 opatstop = AN.patstop;
2262 oRepFunList = AN.RepFunList;
2263 oRepFunNum = AN.RepFunNum;
2265 wildargtaken = AT.WorkPointer;
2266 AN.RepFunList = wildargtaken + AN.NumTotWildArgs;
2267 AT.WorkPointer = (WORD *)(((UBYTE *)(AN.RepFunList)) + AM.MaxTer/2);
2268 csav = cto = AT.WorkPointer;
2271 while ( --ci >= 0 ) *cto++ = *cfrom++;
2272 AT.WorkPointer = cto;
2275 while ( --ci >= 0 ) {
2276 if ( *--cfrom != *--cto ) {
2277 AT.WorkPointer = wildargtaken;
2278 AN.RepFunList = oRepFunList;
2279 AN.RepFunNum = oRepFunNum;
2280 AN.terstart = oterstart;
2281 AN.terstop = oterstop;
2282 AN.patstop = opatstop;
2287 wildargs = AN.WildArgs;
2288 wildeat = AN.WildEat;
2289 for ( i = 0; i < wildargs; i++ ) wildargtaken[i] = AT.WildArgTaken[i];
2290 AN.ForFindOnly = 0; AN.UseFindOnly = 1;
2292 if ( FindRest(BHEAD csav,m) && ( AN.UsedOtherFind || FindOnly(BHEAD csav,m) ) ) { }
2295 AT.WorkPointer = wildargtaken;
2296 AN.RepFunList = oRepFunList;
2297 AN.RepFunNum = oRepFunNum;
2298 AN.terstart = oterstart;
2299 AN.terstop = oterstop;
2300 AN.patstop = opatstop;
2301 AN.WildArgs = wildargs;
2302 AN.WildEat = wildeat;
2304 for ( i = 0; i < wildargs; i++ ) AT.WildArgTaken[i] = wildargtaken[i];
2308 AN.WildArgs = wildargs;
2309 AN.WildEat = wildeat;
2310 for ( i = 0; i < wildargs; i++ ) AT.WildArgTaken[i] = wildargtaken[i];
2311 Substitute(BHEAD csav,m,1);
2313 cfrom = cto + *cto - msizcoef;
2316 AT.WorkPointer = wildargtaken;
2317 AN.RepFunList = oRepFunList;
2318 AN.RepFunNum = oRepFunNum;
2319 AN.terstart = oterstart;
2320 AN.terstop = oterstop;
2321 AN.patstop = opatstop;
2322 if ( *cto != SUBEXPRESSION )
return(0);
2324 if ( cto < cfrom )
return(0);