56 WORD MatchE(PHEAD WORD *pattern, WORD *fun, WORD *inter, WORD par)
59 WORD *m, *t, *r, i, retval;
60 WORD *mstop, *tstop, j, newvalue, newfun;
61 WORD fixvec[MAXMATCH],wcvec[MAXMATCH],fixind[MAXMATCH],wcind[MAXMATCH];
62 WORD tfixvec[MAXMATCH],tfixind[MAXMATCH];
63 WORD vwc,vfix,ifix,iwc,tvfix,tifix,nv,ni;
64 WORD sign = 0, *rstop, first1, first2, first3, funwild;
65 WORD *OldWork, nwstore, oRepFunNum;
70 offset = WORDDIF(fun,AN.terstart);
71 if ( pattern[1] != fun[1] )
return(0);
72 if ( *pattern >= FUNCTION+WILDOFFSET ) {
73 if ( CheckWild(BHEAD *pattern-WILDOFFSET,FUNTOFUN,*fun,&newfun) )
return(0);
77 mstop = pattern + pattern[1];
79 m = pattern + FUNHEAD;
82 if ( *m != *t )
break;
86 AN.RepFunList[AN.RepFunNum++] = offset;
87 AN.RepFunList[AN.RepFunNum++] = 0;
88 newpat = pattern + pattern[1];
91 t = OldWork = AT.WorkPointer;
92 nwstore = i = (m[-SUBEXPSIZE+1]-SUBEXPSIZE)/4;
96 *t++ = *m++; *t++ = *m++; *t++ = *m++; *t++ = *m++; *t++ = *r++;
99 if ( t >= AT.WorkTop ) {
100 MLOCK(ErrorMessageLock);
102 MUNLOCK(ErrorMessageLock);
106 AddWild(BHEAD *pattern-WILDOFFSET,FUNTOFUN,newfun);
107 if ( newpat >= AN.patstop ) {
108 if ( AN.UseFindOnly == 0 ) {
109 if ( FindOnce(BHEAD AN.findTerm,AN.findPattern) ) {
110 AN.UsedOtherFind = 1;
119 retval = ScanFunctions(BHEAD newpat,inter,par);
123 t = OldWork; r = AT.WildMask; i = nwstore;
126 *m++ = *t++; *m++ = *t++; *m++ = *t++; *m++ = *t++; *r++ = *t++;
130 AT.WorkPointer = OldWork;
134 if ( newpat >= AN.patstop ) {
135 if ( AN.UseFindOnly == 0 ) {
136 if ( FindOnce(BHEAD AN.findTerm,AN.findPattern) ) {
137 AN.UsedOtherFind = 1;
145 i = ScanFunctions(BHEAD newpat,inter,par);
163 while ( r < mstop ) {
164 if ( *r < (AM.OffsetVector+WILDOFFSET) ) {
166 sign += vwc + ifix + iwc;
168 else if ( *r < MINSPEC ) {
172 else if ( *r < (AM.OffsetIndex+WILDOFFSET) ) {
176 else if ( *r < (AM.OffsetIndex+(WILDOFFSET<<1)) ) {
185 if ( iwc == 0 && vwc == 0 )
return(0);
193 while ( t < tstop ) {
196 if ( m < mstop && *t == *m ) {
200 sign += WORDDIF(mstop,m);
201 tfixvec[tvfix++] = *t;
206 if ( r < rstop && *r == *t ) {
210 sign += WORDDIF(rstop,r);
211 tfixind[tifix++] = *t;
216 if ( m < mstop || r < rstop )
return(0);
217 if ( tvfix < vwc || (tvfix+tifix) < (vwc+iwc) )
return(0);
218 sign += ( nv - vfix - vwc ) & ni;
230 if ( *wv == VECTOVEC ) {
231 for ( ni = 0; ni < vwc; ni++ ) {
232 if ( wcvec[ni]-WILDOFFSET == wv[2] ) {
236 wcvec[ni] = wcvec[ni+1];
240 for ( ni = 0; ni < tvfix; ni++ ) {
241 if ( tfixvec[ni] == wv[3] ) {
244 while ( ni < tvfix ) {
245 tfixvec[ni] = tfixvec[ni+1];
255 else if ( *wv == INDTOIND ) {
256 for ( ni = 0; ni < iwc; ni++ ) {
257 if ( wcind[ni]-WILDOFFSET == wv[2] ) {
261 wcind[ni] = wcind[ni+1];
264 for ( ni = 0; ni < tifix; ni++ ) {
265 if ( tfixind[ni] == wv[3] ) {
268 while ( ni < tifix ) {
269 tfixind[ni] = tfixind[ni+1];
281 else if ( *wv == VECTOSUB ) {
282 for ( ni = 0; ni < vwc; ni++ ) {
283 if ( wcvec[ni]-WILDOFFSET == wv[2] )
return(0);
286 else if ( *wv == INDTOSUB ) {
287 for ( ni = 0; ni < iwc; ni++ ) {
288 if ( wcind[ni]-WILDOFFSET == wv[2] )
return(0);
297 while ( n > 0 && ( *wv == FROMSET || *wv == SETTONUM
298 || *wv == LOADDOLLAR ) ) { wv += wv[1]; wm++; n--; }
331 if ( tvfix < vwc ) {
return(0); }
334 perm1.objects = tfixvec;
337 perm2.objects = tfixind;
338 distr.n1 = tvfix - vwc;
340 distr.obj1 = tfixvec + vwc;
341 distr.obj2 = tfixind;
348 t = OldWork = AT.WorkPointer;
349 nwstore = i = (m[-SUBEXPSIZE+1]-SUBEXPSIZE)/4;
353 *t++ = *m++; *t++ = *m++; *t++ = *m++; *t++ = *m++; *t++ = *r++;
356 if ( t >= AT.WorkTop ) {
357 MLOCK(ErrorMessageLock);
359 MUNLOCK(ErrorMessageLock);
363 while ( (first1 = Permute(&perm1,first1) ) == 0 ) {
365 while ( (first2 = Permute(&perm2,first2) ) == 0 ) {
367 while ( (first3 = Distribute(&distr,first3) ) == 0 ) {
371 for ( i = 0; i < vwc; i++ ) {
372 j = wcvec[i] - WILDOFFSET;
373 if ( CheckWild(BHEAD j,VECTOVEC,tfixvec[i],&newvalue) )
375 AddWild(BHEAD j,VECTOVEC,newvalue);
377 for ( i = 0; i < iwc; i++ ) {
378 j = wcind[i] - WILDOFFSET;
379 if ( CheckWild(BHEAD j,INDTOIND,fixvec[i],&newvalue) )
381 AddWild(BHEAD j,INDTOIND,newvalue);
386 oRepFunNum = AN.RepFunNum;
387 AN.RepFunList[AN.RepFunNum++] = offset;
388 AN.RepFunList[AN.RepFunNum++] =
389 ( perm1.sign + perm2.sign + distr.sign + sign ) & 1;
390 newpat = pattern + pattern[1];
391 if ( funwild ) AddWild(BHEAD *pattern-WILDOFFSET,FUNTOFUN,newfun);
392 if ( newpat >= AN.patstop ) {
393 if ( AN.UseFindOnly == 0 ) {
394 if ( FindOnce(BHEAD AN.findTerm,AN.findPattern) ) {
395 AN.UsedOtherFind = 1;
403 if ( ScanFunctions(BHEAD newpat,inter,par) ) {
return(1); }
408 AN.RepFunNum = oRepFunNum;
409 NoCaseB: m = AN.WildValue;
410 t = OldWork; r = AT.WildMask; i = nwstore;
413 *m++ = *t++; *m++ = *t++; *m++ = *t++; *m++ = *t++; *r++ = *t++;
420 AT.WorkPointer = OldWork;
443 WORD Permute(
PERM *perm, WORD first)
447 perm->sign = ( perm->sign <= 1 ) ? 0: 1;
448 for ( i = 0; i < perm->n; i++ ) perm->cycle[i] = 0;
456 while ( --j >= 0 ) { *s = s[1]; s++; }
458 if ( ( i & 1 ) != 0 ) perm->sign ^= 1;
459 if ( perm->cycle[i] < i ) {
477 WORD PermuteP(
PERMP *perm, WORD first)
481 perm->sign = ( perm->sign <= 1 ) ? 0: 1;
482 for ( i = 0; i < perm->n; i++ ) perm->cycle[i] = 0;
490 while ( --j >= 0 ) { *s = s[1]; s++; }
492 if ( ( i & 1 ) != 0 ) perm->sign ^= 1;
493 if ( perm->cycle[i] < i ) {
511 WORD *to, *from, *inc, *from2, i, j;
513 d->n = d->n1 + d->n2;
516 for ( i = 0; i < d->n2; i++ ) {
528 if ( d->n1 == 0 || d->n2 == 0 )
return(1);
533 while ( *inc ) { j++; inc++; }
534 while ( !*inc && inc < from ) { i++; inc++; }
535 if ( inc >= from )
return(1);
536 d->sign ^= ((i&j)-j+1) & 1;
539 while ( --j >= 0 ) *--inc = 1;
540 while ( --i > 0 ) *--inc = 0;
544 for ( i = 0; i < d->n; i++ ) {
570 int MatchCy(PHEAD WORD *pattern, WORD *fun, WORD *inter, WORD par)
573 WORD *t, *tstop, *p, *pstop, *m, *r, *oldworkpointer = AT.WorkPointer;
574 WORD *thewildcards, *multiplicity, *renum, wc, newvalue, oldwilval = 0;
575 WORD *params, *lowlevel = 0;
576 int argcount = 0, funnycount = 0, tcount = fun[1] - FUNHEAD;
577 int type = 0, pnum, i, j, k, nwstore, iraise, itop, sumeat;
578 CBUF *C = cbuf+AT.ebufnum;
579 int ntwa = 3*AN.NumTotWildArgs+1;
581 WORD offset = fun-AN.terstart, *newpat;
583 if ( (functions[fun[0]-FUNCTION].symmetric & ~REVERSEORDER) == RCYCLESYMMETRIC ) type = 1;
585 nwstore = (AN.WildValue[-SUBEXPSIZE+1]-SUBEXPSIZE)/4;
586 if ( pnum > FUNCTION + WILDOFFSET ) {
588 if ( CheckWild(BHEAD pnum,FUNTOFUN,fun[0],&newvalue) )
return(0);
590 t = lowlevel = AT.WorkPointer;
596 *t++ = *m++; *t++ = *m++; *t++ = *m++; *t++ = *m++; *t++ = *r++;
600 if ( t >= AT.WorkTop ) {
601 MLOCK(ErrorMessageLock);
603 MUNLOCK(ErrorMessageLock);
607 AddWild(BHEAD pnum,FUNTOFUN,newvalue);
609 if ( (functions[pnum-FUNCTION].symmetric & ~REVERSEORDER) == RCYCLESYMMETRIC ) type = 1;
613 p = pattern + FUNHEAD;
614 pstop = pattern + pattern[1];
615 while ( p < pstop ) {
616 if ( *p == FUNNYWILD ) { p += 2; funnycount++; }
617 else { p++; argcount++; }
619 if ( argcount > tcount )
goto NoSuccess;
620 if ( argcount < tcount && funnycount == 0 )
goto NoSuccess;
621 if ( argcount == 0 && tcount == 0 && funnycount == 0 ) {
622 AN.RepFunList[AN.RepFunNum++] = offset;
623 AN.RepFunList[AN.RepFunNum++] = 0;
624 newpat = pattern + pattern[1];
625 if ( newpat >= AN.patstop ) {
626 if ( AN.UseFindOnly == 0 ) {
627 if ( FindOnce(BHEAD AN.findTerm,AN.findPattern) ) {
628 AT.WorkPointer = oldworkpointer;
629 AN.UsedOtherFind = 1;
635 AT.WorkPointer = oldworkpointer;
639 else j = ScanFunctions(BHEAD newpat,inter,par);
643 tstop = fun + fun[1];
647 params = AT.WorkPointer;
648 thewildcards = t = params + tcount;
650 if ( oldwilval ) lowlevel = oldworkpointer;
657 *t++ = *m++; *t++ = *m++; *t++ = *m++; *t++ = *m++; *t++ = *r++;
661 if ( t >= AT.WorkTop ) {
662 MLOCK(ErrorMessageLock);
664 MUNLOCK(ErrorMessageLock);
671 if ( argcount == tcount ) {
672 if ( funnycount > 0 ) {
673 p = pattern + FUNHEAD;
675 while ( p < pstop ) {
676 if ( *p != FUNNYWILD ) { p++;
continue; }
678 if ( CheckWild(BHEAD p[1],ARGTOARG,0,t) )
goto nomatch;
679 AddWild(BHEAD p[1],ARGTOARG,0);
684 for ( k = 0; k <= type; k++ ) {
686 p = params; t = fun + FUNHEAD;
687 while ( t < tstop ) *p++ = *t++;
690 p = params+tcount; t = fun + FUNHEAD;
691 while ( t < tstop ) *--p = *t++;
693 for ( i = 0; i < tcount; i++ ) {
694 p = pattern + FUNHEAD;
696 for ( j = 0; j < tcount; j++, p++ ) {
697 while ( *p == FUNNYWILD ) p += 2;
698 t = params + (i+j)%tcount;
699 if ( *t == *p )
continue;
700 if ( *p >= AM.OffsetIndex + WILDOFFSET
701 && *p < AM.OffsetIndex + 2*WILDOFFSET ) {
705 wc = *p - WILDOFFSET;
706 if ( CheckWild(BHEAD wc,INDTOIND,*t,&newvalue) )
break;
707 AddWild(BHEAD wc,INDTOIND,newvalue);
709 else if ( *t < MINSPEC && p[j] < MINSPEC
710 && *p >= AM.OffsetVector + WILDOFFSET ) {
714 wc = *p - WILDOFFSET;
715 if ( CheckWild(BHEAD wc,VECTOVEC,*t,&newvalue) )
break;
716 AddWild(BHEAD wc,VECTOVEC,newvalue);
724 AN.RepFunList[AN.RepFunNum++] = offset;
725 AN.RepFunList[AN.RepFunNum++] = 0;
727 if ( funnycount > 0 ) {
728 p = pattern + FUNHEAD;
730 while ( p < pstop ) {
731 if ( *p != FUNNYWILD ) { p++;
continue; }
733 AddWild(BHEAD p[1],ARGTOARG,0);
737 newpat = pattern + pattern[1];
738 if ( newpat >= AN.patstop ) {
739 if ( AN.UseFindOnly == 0 ) {
740 if ( FindOnce(BHEAD AN.findTerm,AN.findPattern) ) {
741 AT.WorkPointer = oldworkpointer;
742 AN.UsedOtherFind = 1;
748 AT.WorkPointer = oldworkpointer;
752 else j = ScanFunctions(BHEAD newpat,inter,par);
754 AT.WorkPointer = oldworkpointer;
762 if ( wc && nwstore > 0 ) {
765 t = thewildcards + ntwa; r = AT.WildMask;
768 *m++ = *t++; *m++ = *t++; *m++ = *t++; *m++ = *t++; *r++ = *t++;
782 if ( funnycount == 1 ) {
783 funnycount = tcount - argcount;
784 for ( k = 0; k <= type; k++ ) {
786 p = params; t = fun + FUNHEAD;
787 while ( t < tstop ) *p++ = *t++;
790 p = params+tcount; t = fun + FUNHEAD;
791 while ( t < tstop ) *--p = *t++;
793 for ( i = 0; i < tcount; i++ ) {
794 p = pattern + FUNHEAD;
797 for ( j = 0; j < tcount; j++, p++, t++ ) {
798 if ( *t == *p )
continue;
799 if ( *p == FUNNYWILD ) {
802 if ( CheckWild(BHEAD *p,ARGTOARG,funnycount|EATTENSOR,t) )
break;
803 AddWild(BHEAD *p,ARGTOARG,funnycount|EATTENSOR);
804 j += funnycount-1; t += funnycount-1;
806 else if ( *p >= AM.OffsetIndex + WILDOFFSET
807 && *p < AM.OffsetIndex + 2*WILDOFFSET ) {
811 wc = *p - WILDOFFSET;
812 if ( CheckWild(BHEAD wc,INDTOIND,*t,&newvalue) )
break;
813 AddWild(BHEAD wc,INDTOIND,newvalue);
815 else if ( *t < MINSPEC && *p < MINSPEC
816 && *p >= AM.OffsetVector + WILDOFFSET ) {
820 wc = *p - WILDOFFSET;
821 if ( CheckWild(BHEAD wc,VECTOVEC,*t,&newvalue) )
break;
822 AddWild(BHEAD wc,VECTOVEC,newvalue);
830 AN.RepFunList[AN.RepFunNum++] = offset;
831 AN.RepFunList[AN.RepFunNum++] = 0;
832 newpat = pattern + pattern[1];
833 if ( newpat >= AN.patstop ) {
834 if ( AN.UseFindOnly == 0 ) {
835 if ( FindOnce(BHEAD AN.findTerm,AN.findPattern) ) {
836 AT.WorkPointer = oldworkpointer;
837 AN.UsedOtherFind = 1;
843 AT.WorkPointer = oldworkpointer;
847 else j = ScanFunctions(BHEAD newpat,inter,par);
849 AT.WorkPointer = oldworkpointer;
860 t = thewildcards + ntwa; r = AT.WildMask;
863 *m++ = *t++; *m++ = *t++; *m++ = *t++; *m++ = *t++; *r++ = *t++;
871 for ( j = 1; j < tcount; j++ ) { *t = t[1]; t++; }
882 sumeat = tcount - argcount;
891 for ( i = funnycount; i < ntwa; i++ ) thewildcards[i] = -1;
892 multiplicity = thewildcards + funnycount;
893 renum = multiplicity + funnycount;
895 while ( p < pstop ) {
896 if ( *p != FUNNYWILD ) { p++;
continue; }
898 if ( renum[*p] < 0 ) {
903 else multiplicity[renum[*p]]++;
909 for ( i = 1; i < AN.NumTotWildArgs; i++ ) {
910 if ( renum[i] < 0 )
continue;
911 for ( j = i+1; j <= AN.NumTotWildArgs; j++ ) {
912 if ( renum[j] < 0 )
continue;
913 if ( renum[i] < renum[j] )
continue;
914 k = multiplicity[renum[i]];
915 multiplicity[renum[i]] = multiplicity[renum[j]];
916 multiplicity[renum[j]] = k;
917 k = renum[i]; renum[i] = renum[j]; renum[j] = k;
920 for ( i = 0; i < funnycount; i++ ) thewildcards[i] = 0;
921 iraise = funnycount-1;
923 for ( i = 0, j = sumeat; i < iraise; i++ )
924 j -= thewildcards[i]*multiplicity[i];
925 if ( j < 0 || j % multiplicity[iraise] != 0 ) {
927 thewildcards[iraise-1]++;
931 while ( itop > 0 && j < 0 ) {
932 j += thewildcards[itop]*multiplicity[itop];
933 thewildcards[itop] = 0;
936 if ( itop <= 0 && j <= 0 )
break;
937 thewildcards[itop]++;
940 thewildcards[iraise] = j / multiplicity[iraise];
942 for ( k = 0; k <= type; k++ ) {
944 p = params; t = fun + FUNHEAD;
945 while ( t < tstop ) *p++ = *t++;
948 p = params+tcount; t = fun + FUNHEAD;
949 while ( t < tstop ) *--p = *t++;
951 for ( i = 0; i < tcount; i++ ) {
952 p = pattern + FUNHEAD;
955 for ( j = 0; j < tcount; j++, p++, t++ ) {
956 if ( *t == *p )
continue;
957 if ( *p == FUNNYWILD ) {
958 p++; wc = thewildcards[renum[*p]];
960 if ( CheckWild(BHEAD *p,ARGTOARG,wc|EATTENSOR,t) )
break;
961 AddWild(BHEAD *p,ARGTOARG,wc|EATTENSOR);
962 j += wc-1; t += wc-1; wc = 1;
964 else if ( *p >= AM.OffsetIndex + WILDOFFSET
965 && *p < AM.OffsetIndex + 2*WILDOFFSET ) {
969 wc = *p - WILDOFFSET;
970 if ( CheckWild(BHEAD wc,INDTOIND,*t,&newvalue) )
break;
971 AddWild(BHEAD wc,INDTOIND,newvalue);
973 else if ( *t < MINSPEC && *p < MINSPEC
974 && *p >= AM.OffsetVector + WILDOFFSET ) {
978 wc = *p - WILDOFFSET;
979 if ( CheckWild(BHEAD wc,VECTOVEC,*t,&newvalue) )
break;
980 AddWild(BHEAD wc,VECTOVEC,newvalue);
988 AN.RepFunList[AN.RepFunNum++] = offset;
989 AN.RepFunList[AN.RepFunNum++] = 0;
990 newpat = pattern + pattern[1];
991 if ( newpat >= AN.patstop ) {
992 if ( AN.UseFindOnly == 0 ) {
993 if ( FindOnce(BHEAD AN.findTerm,AN.findPattern) ) {
994 AT.WorkPointer = oldworkpointer;
995 AN.UsedOtherFind = 1;
1001 AT.WorkPointer = oldworkpointer;
1005 else j = ScanFunctions(BHEAD newpat,inter,par);
1007 AT.WorkPointer = oldworkpointer;
1018 t = thewildcards + ntwa; r = AT.WildMask;
1021 *m++ = *t++; *m++ = *t++; *m++ = *t++; *m++ = *t++; *r++ = *t++;
1022 }
while ( --j > 0 );
1029 for ( j = 1; j < tcount; j++ ) { *t = t[1]; t++; }
1033 (thewildcards[iraise-1])++;
1039 if ( oldwilval > 0 ) {
1044 t = lowlevel; r = AT.WildMask;
1047 *m++ = *t++; *m++ = *t++; *m++ = *t++; *m++ = *t++; *r++ = *t++;
1048 }
while ( --j > 0 );
1054 AT.WorkPointer = oldworkpointer;
1066 int FunMatchCy(PHEAD WORD *pattern, WORD *fun, WORD *inter, WORD par)
1069 WORD *t, *tstop, *p, *pstop, *m, *r, *oldworkpointer = AT.WorkPointer;
1070 WORD **a, *thewildcards, *multiplicity, *renum, wc, wcc, oldwilval = 0;
1071 LONG oww = AT.pWorkPointer;
1072 WORD newvalue, *lowlevel = 0;
1073 int argcount = 0, funnycount = 0, tcount = 0;
1074 int type = 0, pnum, i, j, k, nwstore, iraise, itop, sumeat;
1075 CBUF *C = cbuf+AT.ebufnum;
1076 int ntwa = 3*AN.NumTotWildArgs+1;
1078 WORD offset = fun-AN.terstart, *newpat;
1080 if ( (functions[fun[0]-FUNCTION].symmetric & ~REVERSEORDER) == RCYCLESYMMETRIC ) type = 1;
1082 nwstore = (AN.WildValue[-SUBEXPSIZE+1]-SUBEXPSIZE)/4;
1083 if ( pnum > FUNCTION + WILDOFFSET ) {
1085 if ( CheckWild(BHEAD pnum,FUNTOFUN,fun[0],&newvalue) )
return(0);
1087 t = lowlevel = oldworkpointer;
1093 *t++ = *m++; *t++ = *m++; *t++ = *m++; *t++ = *m++; *t++ = *r++;
1094 }
while ( --i > 0 );
1097 if ( t >= AT.WorkTop ) {
1098 MLOCK(ErrorMessageLock);
1100 MUNLOCK(ErrorMessageLock);
1104 AddWild(BHEAD pnum,FUNTOFUN,newvalue);
1106 if ( (functions[pnum-FUNCTION].symmetric & ~REVERSEORDER) == RCYCLESYMMETRIC ) type = 1;
1110 p = pattern + FUNHEAD;
1111 pstop = pattern + pattern[1];
1112 while ( p < pstop ) {
1113 if ( *p == -ARGWILD ) { p += 2; funnycount++; }
1114 else { NEXTARG(p); argcount++; }
1117 tstop = fun + fun[1];
1118 while ( t < tstop ) { NEXTARG(t); tcount++; }
1120 if ( argcount > tcount )
return(0);
1121 if ( argcount < tcount && funnycount == 0 )
return(0);
1122 if ( argcount == 0 && tcount == 0 && funnycount == 0 ) {
1123 AN.RepFunList[AN.RepFunNum++] = offset;
1124 AN.RepFunList[AN.RepFunNum++] = 0;
1125 newpat = pattern + pattern[1];
1126 if ( newpat >= AN.patstop ) {
1127 if ( AN.UseFindOnly == 0 ) {
1128 if ( FindOnce(BHEAD AN.findTerm,AN.findPattern) ) {
1129 AT.WorkPointer = oldworkpointer;
1130 AN.UsedOtherFind = 1;
1136 AT.WorkPointer = oldworkpointer;
1140 else j = ScanFunctions(BHEAD newpat,inter,par);
1147 WantAddPointers(tcount);
1148 AT.pWorkPointer += tcount;
1149 thewildcards = t = AT.WorkPointer;
1151 if ( oldwilval ) lowlevel = oldworkpointer;
1158 *t++ = *m++; *t++ = *m++; *t++ = *m++; *t++ = *m++; *t++ = *r++;
1159 }
while ( --i > 0 );
1162 if ( t >= AT.WorkTop ) {
1163 MLOCK(ErrorMessageLock);
1165 MUNLOCK(ErrorMessageLock);
1172 if ( argcount == tcount ) {
1173 if ( funnycount > 0 ) {
1174 p = pattern + FUNHEAD;
1176 while ( p < pstop ) {
1177 if ( *p != -ARGWILD ) { p++;
continue; }
1179 if ( CheckWild(BHEAD p[1],ARGTOARG,0,t) )
goto nomatch;
1180 AddWild(BHEAD p[1],ARGTOARG,0);
1185 for ( k = 0; k <= type; k++ ) {
1187 a = AT.pWorkSpace+oww; t = fun + FUNHEAD;
1188 while ( t < tstop ) { *a++ = t; NEXTARG(t); }
1191 a = AT.pWorkSpace+oww+tcount; t = fun + FUNHEAD;
1192 while ( t < tstop ) { *--a = t; NEXTARG(t); }
1194 for ( i = 0; i < tcount; i++ ) {
1195 p = pattern + FUNHEAD;
1197 for ( j = 0; j < tcount; j++ ) {
1198 while ( *p == -ARGWILD ) p += 2;
1199 t = AT.pWorkSpace[oww+((i+j)%tcount)];
1200 if ( ( wcc = MatchArgument(BHEAD t,p) ) == 0 )
break;
1201 if ( wcc > 1 ) wc = 1;
1204 if ( j >= tcount ) {
1208 AN.RepFunList[AN.RepFunNum++] = offset;
1209 AN.RepFunList[AN.RepFunNum++] = 0;
1211 if ( funnycount > 0 ) {
1212 p = pattern + FUNHEAD;
1214 while ( p < pstop ) {
1215 if ( *p != -ARGWILD ) { p++;
continue; }
1217 AddWild(BHEAD p[1],ARGTOARG,0);
1221 newpat = pattern + pattern[1];
1222 if ( newpat >= AN.patstop ) {
1223 if ( AN.UseFindOnly == 0 ) {
1224 if ( FindOnce(BHEAD AN.findTerm,AN.findPattern) ) {
1225 AT.WorkPointer = oldworkpointer;
1226 AT.pWorkPointer = oww;
1227 AN.UsedOtherFind = 1;
1233 AT.WorkPointer = oldworkpointer;
1234 AT.pWorkPointer = oww;
1238 else j = ScanFunctions(BHEAD newpat,inter,par);
1240 AT.WorkPointer = oldworkpointer;
1241 AT.pWorkPointer = oww;
1249 if ( wc && nwstore > 0 ) {
1252 t = thewildcards + ntwa; r = AT.WildMask;
1255 *m++ = *t++; *m++ = *t++; *m++ = *t++; *m++ = *t++; *r++ = *t++;
1256 }
while ( --j > 0 );
1269 if ( funnycount == 1 ) {
1270 funnycount = tcount - argcount;
1271 for ( k = 0; k <= type; k++ ) {
1273 a = AT.pWorkSpace+oww; t = fun + FUNHEAD;
1274 while ( t < tstop ) { *a++ = t; NEXTARG(t); }
1277 a = AT.pWorkSpace+oww+tcount; t = fun + FUNHEAD;
1278 while ( t < tstop ) { *--a = t; NEXTARG(t); }
1280 for ( i = 0; i < tcount; i++ ) {
1281 p = pattern + FUNHEAD;
1282 a = AT.pWorkSpace+oww;
1284 for ( j = 0; j < tcount; j++, a++ ) {
1286 if ( *p == -ARGWILD ) {
1288 AN.argaddress = (WORD *)a;
1289 if ( CheckWild(BHEAD p[1],ARLTOARL,funnycount,(WORD *)a) )
break;
1290 AddWild(BHEAD p[1],ARLTOARL,funnycount);
1291 j += funnycount-1; a += funnycount-1;
1293 else if ( MatchArgument(BHEAD t,p) == 0 )
break;
1296 if ( j >= tcount ) {
1300 AN.RepFunList[AN.RepFunNum++] = offset;
1301 AN.RepFunList[AN.RepFunNum++] = 0;
1302 newpat = pattern + pattern[1];
1303 if ( newpat >= AN.patstop ) {
1304 if ( AN.UseFindOnly == 0 ) {
1305 if ( FindOnce(BHEAD AN.findTerm,AN.findPattern) ) {
1306 AT.WorkPointer = oldworkpointer;
1307 AT.pWorkPointer = oww;
1308 AN.UsedOtherFind = 1;
1314 AT.WorkPointer = oldworkpointer;
1315 AT.pWorkPointer = oww;
1319 else j = ScanFunctions(BHEAD newpat,inter,par);
1321 AT.WorkPointer = oldworkpointer;
1322 AT.pWorkPointer = oww;
1333 t = thewildcards + ntwa; r = AT.WildMask;
1336 *m++ = *t++; *m++ = *t++; *m++ = *t++; *m++ = *t++; *r++ = *t++;
1337 }
while ( --j > 0 );
1342 a = AT.pWorkSpace+oww;
1344 for ( j = 1; j < tcount; j++ ) { *a = a[1]; a++; }
1355 sumeat = tcount - argcount;
1363 p = pattern+FUNHEAD;
1364 for ( i = funnycount; i < ntwa; i++ ) thewildcards[i] = -1;
1365 multiplicity = thewildcards + funnycount;
1366 renum = multiplicity + funnycount;
1368 while ( p < pstop ) {
1369 if ( *p != -ARGWILD ) { p++;
continue; }
1371 if ( renum[*p] < 0 ) {
1373 multiplicity[j] = 1;
1376 else multiplicity[renum[*p]]++;
1382 for ( i = 1; i < AN.NumTotWildArgs; i++ ) {
1383 if ( renum[i] < 0 )
continue;
1384 for ( j = i+1; j <= AN.NumTotWildArgs; j++ ) {
1385 if ( renum[j] < 0 )
continue;
1386 if ( renum[i] < renum[j] )
continue;
1387 k = multiplicity[renum[i]];
1388 multiplicity[renum[i]] = multiplicity[renum[j]];
1389 multiplicity[renum[j]] = k;
1390 k = renum[i]; renum[i] = renum[j]; renum[j] = k;
1393 for ( i = 0; i < funnycount; i++ ) thewildcards[i] = 0;
1394 iraise = funnycount-1;
1396 for ( i = 0, j = sumeat; i < iraise; i++ )
1397 j -= thewildcards[i]*multiplicity[i];
1398 if ( j < 0 || j % multiplicity[iraise] != 0 ) {
1400 thewildcards[iraise-1]++;
1404 while ( itop > 0 && j < 0 ) {
1405 j += thewildcards[itop]*multiplicity[itop];
1406 thewildcards[itop] = 0;
1409 if ( itop <= 0 && j <= 0 )
break;
1410 thewildcards[itop]++;
1413 thewildcards[iraise] = j / multiplicity[iraise];
1415 for ( k = 0; k <= type; k++ ) {
1417 a = AT.pWorkSpace+oww; t = fun + FUNHEAD;
1418 while ( t < tstop ) { *a++ = t; NEXTARG(t); }
1421 a = AT.pWorkSpace+oww+tcount; t = fun + FUNHEAD;
1422 while ( t < tstop ) { *--a = t; NEXTARG(t); }
1424 for ( i = 0; i < tcount; i++ ) {
1425 p = pattern + FUNHEAD;
1426 a = AT.pWorkSpace+oww;
1428 for ( j = 0; j < tcount; j++, a++ ) {
1430 if ( *p == -ARGWILD ) {
1431 wc = thewildcards[renum[p[1]]];
1432 AN.argaddress = (WORD *)a;
1433 if ( CheckWild(BHEAD p[1],ARLTOARL,wc,(WORD *)a) )
break;
1434 AddWild(BHEAD p[1],ARLTOARL,wc);
1435 j += wc-1; a += wc-1; wc = 1;
1437 else if ( MatchArgument(BHEAD t,p) == 0 )
break;
1440 if ( j >= tcount ) {
1444 AN.RepFunList[AN.RepFunNum++] = offset;
1445 AN.RepFunList[AN.RepFunNum++] = 0;
1446 newpat = pattern + pattern[1];
1447 if ( newpat >= AN.patstop ) {
1448 if ( AN.UseFindOnly == 0 ) {
1449 if ( FindOnce(BHEAD AN.findTerm,AN.findPattern) ) {
1450 AT.WorkPointer = oldworkpointer;
1451 AT.pWorkPointer = oww;
1452 AN.UsedOtherFind = 1;
1458 AT.WorkPointer = oldworkpointer;
1459 AT.pWorkPointer = oww;
1463 else j = ScanFunctions(BHEAD newpat,inter,par);
1465 AT.WorkPointer = oldworkpointer;
1466 AT.pWorkPointer = oww;
1477 t = thewildcards + ntwa; r = AT.WildMask;
1480 *m++ = *t++; *m++ = *t++; *m++ = *t++; *m++ = *t++; *r++ = *t++;
1481 }
while ( --j > 0 );
1486 a = AT.pWorkSpace+oww;
1488 for ( j = 1; j < tcount; j++ ) { *a = a[1]; a++; }
1492 (thewildcards[iraise-1])++;
1498 if ( oldwilval > 0 ) {
1502 t = lowlevel; r = AT.WildMask;
1505 *m++ = *t++; *m++ = *t++; *m++ = *t++; *m++ = *t++; *r++ = *t++;
1506 }
while ( --j > 0 );
1511 AT.WorkPointer = oldworkpointer;
1512 AT.pWorkPointer = oww;
1524 int FunMatchSy(PHEAD WORD *pattern, WORD *fun, WORD *inter, WORD par)
1527 WORD *t, *tstop, *p, *pstop, *m, *r, *oldworkpointer = AT.WorkPointer;
1528 WORD **a, *thewildcards, oldwilval = 0;
1529 WORD newvalue, *lowlevel = 0, num, assig;
1531 LONG oww = AT.pWorkPointer, lhpars, lhfunnies;
1532 int argcount = 0, funnycount = 0, tcount = 0, signs = 0, signfun = 0, signo;
1533 int type = 0, pnum, i, j, k, nwstore, iraise, cou2;
1534 CBUF *C = cbuf+AT.ebufnum;
1535 int ntwa = 3*AN.NumTotWildArgs+1;
1537 WORD offset = fun-AN.terstart, *newpat;
1539 if ( (functions[fun[0]-FUNCTION].symmetric & ~REVERSEORDER) == RCYCLESYMMETRIC ) type = 1;
1541 nwstore = (AN.WildValue[-SUBEXPSIZE+1]-SUBEXPSIZE)/4;
1542 if ( pnum > FUNCTION + WILDOFFSET ) {
1544 if ( CheckWild(BHEAD pnum,FUNTOFUN,fun[0],&newvalue) )
return(0);
1546 t = lowlevel = oldworkpointer;
1552 *t++ = *m++; *t++ = *m++; *t++ = *m++; *t++ = *m++; *t++ = *r++;
1553 }
while ( --i > 0 );
1556 if ( t >= AT.WorkTop ) {
1557 MLOCK(ErrorMessageLock);
1559 MUNLOCK(ErrorMessageLock);
1563 AddWild(BHEAD pnum,FUNTOFUN,newvalue);
1565 if ( (functions[pnum-FUNCTION].symmetric & ~REVERSEORDER) == RCYCLESYMMETRIC ) type = 1;
1569 if ( fun[1] == pattern[1] ) {
1570 i = fun[1]-FUNHEAD; p = pattern+FUNHEAD; t = fun + FUNHEAD;
1571 while ( --i >= 0 ) {
if ( *p++ != *t++ )
break; }
1572 if ( i < 0 )
goto quicky;
1577 p = pattern + FUNHEAD;
1578 pstop = pattern + pattern[1];
1579 while ( p < pstop ) {
1580 if ( *p == -ARGWILD ) { p += 2; funnycount++; }
1581 else { NEXTARG(p); argcount++; }
1584 tstop = fun + fun[1];
1585 while ( t < tstop ) { NEXTARG(t); tcount++; }
1587 if ( argcount > tcount )
return(0);
1588 if ( argcount < tcount && funnycount == 0 )
return(0);
1589 if ( argcount == 0 && tcount == 0 && funnycount == 0 ) {
1591 if ( AN.SignCheck && signs != AN.ExpectedSign )
goto NoSuccess;
1592 AN.RepFunList[AN.RepFunNum++] = offset;
1593 AN.RepFunList[AN.RepFunNum++] = signs;
1594 newpat = pattern + pattern[1];
1595 if ( newpat >= AN.patstop ) {
1596 if ( AN.UseFindOnly == 0 ) {
1597 if ( FindOnce(BHEAD AN.findTerm,AN.findPattern) ) {
1598 AT.WorkPointer = oldworkpointer;
1599 AN.UsedOtherFind = 1;
1605 AT.WorkPointer = oldworkpointer;
1609 else j = ScanFunctions(BHEAD newpat,inter,par);
1611 AT.WorkPointer = oldworkpointer;
1619 WantAddPointers(tcount+argcount+funnycount);
1620 AT.pWorkPointer += tcount+argcount+funnycount;
1621 thewildcards = t = AT.WorkPointer;
1623 if ( oldwilval ) lowlevel = oldworkpointer;
1626 i = nwstore; assig = 0;
1631 *t++ = *m++; *t++ = *m++; *t++ = *m++; *t++ = *m++; *t++ = *r++;
1632 }
while ( --i > 0 );
1635 if ( t >= AT.WorkTop ) {
1636 MLOCK(ErrorMessageLock);
1638 MUNLOCK(ErrorMessageLock);
1645 t = fun + FUNHEAD; a = AT.pWorkSpace+oww;
1646 while ( t < tstop ) { *a++ = t; NEXTARG(t) }
1647 lhpars = a-AT.pWorkSpace;
1648 t = pattern + FUNHEAD;
1649 while ( t < pstop ) {
1650 if ( *t != -ARGWILD ) *a++ = t;
1653 lhfunnies = a-AT.pWorkSpace;
1654 t = pattern + FUNHEAD; cou2 = 0;
1655 while ( t < pstop ) {
1657 if ( *t == -ARGWILD ) {
1664 signfun = ((argcount+funnycount-cou2)*(tcount-argcount)) & 1;
1669 if ( funnycount > 0 ) {
1670 if ( ( (functions[fun[0]-FUNCTION].symmetric & ~REVERSEORDER) == SYMMETRIC )
1671 || ( (functions[fun[0]-FUNCTION].symmetric & ~REVERSEORDER) == ANTISYMMETRIC )
1672 || ( (functions[pnum-FUNCTION].symmetric & ~REVERSEORDER) == SYMMETRIC )
1673 || ( (functions[pnum-FUNCTION].symmetric & ~REVERSEORDER) == ANTISYMMETRIC ) ) {
1674 AT.WorkPointer = oldworkpointer;
1675 AT.pWorkPointer = oww;
1676 MLOCK(ErrorMessageLock);
1677 MesPrint(
"Sorry: no argument field wildcards yet in (anti)symmetric functions");
1678 MUNLOCK(ErrorMessageLock);
1690 for ( i = 0; i < iraise; i++ ) {
1691 t = AT.pWorkSpace[i+lhpars];
1695 else if ( *t <= -FUNCTION ) {
1696 if ( *t > -FUNCTION - WILDOFFSET )
goto cat1;
1697 type = FUNTOFUN; num = -*t - WILDOFFSET;
1699 else if ( *t == -SYMBOL ) {
1700 if ( t[1] < 2*MAXPOWER )
goto cat1;
1701 type = SYMTOSYM; num = t[1] - 2*MAXPOWER;
1703 else if ( *t == -INDEX ) {
1704 if ( t[1] < AM.OffsetIndex + WILDOFFSET )
goto cat1;
1705 type = INDTOIND; num = t[1] - WILDOFFSET;
1707 else if ( *t == -VECTOR || *t == -MINVECTOR ) {
1708 if ( t[1] < AM.OffsetVector + WILDOFFSET )
goto cat1;
1709 type = VECTOVEC; num = t[1] - WILDOFFSET;
1718 while ( --j >= 0 ) {
1719 if ( m[2] == num && *r ) {
1720 if ( type == *m )
break;
1721 if ( type == SYMTOSYM ) {
1722 if ( *m == SYMTONUM || *m == SYMTOSUB )
break;
1724 else if ( type == INDTOIND ) {
1725 if ( *m == INDTOSUB )
break;
1727 else if ( type == VECTOVEC ) {
1728 if ( *m == VECTOMIN || *m == VECTOSUB )
break;
1734 a = AT.pWorkSpace+lhpars;
1736 if ( iraise != i ) signs++;
1742 for ( j = 0; j < tcount; j++ ) {
1743 if ( MatchArgument(BHEAD AT.pWorkSpace[oww+j],t) ) {
1747 while ( --k >= 0 ) num += *r++;
1748 if ( num == assig ) {
1754 if ( j >= tcount )
goto NoSuccess;
1757 t = thewildcards + ntwa; r = AT.WildMask;
1760 *m++ = *t++; *m++ = *t++; *m++ = *t++; *m++ = *t++; *r++ = *t++;
1761 }
while ( --j > 0 );
1767 for ( j = 0; j < tcount; j++ ) {
1768 m = AT.pWorkSpace[j+oww];
1769 if ( *t != *m )
continue;
1771 if ( *t <= -FUNCTION )
break;
1772 if ( t[1] == m[1] )
break;
1776 while ( --k >= 0 && *m++ == *r++ ) {}
1780 if ( j >= tcount )
goto NoSuccess;
1787 while ( j < tcount ) {
1788 AT.pWorkSpace[oww+j] = AT.pWorkSpace[oww+j+1]; j++;
1794 while ( j < argcount ) {
1795 AT.pWorkSpace[lhpars+j] = AT.pWorkSpace[lhpars+j+1]; j++;
1805 for ( i = 0; i < funnycount; i++ ) {
1806 k = AT.pWorkSpace[lhfunnies+i][1];
1810 while ( --j >= 0 ) {
1811 if ( *m == ARGTOARG && m[2] == k )
break;
1814 if ( *r == 0 )
continue;
1815 m = cbuf[AT.ebufnum].rhs[m[3]];
1818 if ( j > tcount - argcount )
goto NoSuccess;
1819 while ( --j >= 0 ) {
1821 if ( *m < 0 ) type = -VECTOR;
1822 else if ( *m < AM.OffsetIndex ) type = -SNUMBER;
1824 a = AT.pWorkSpace+oww;
1825 for ( k = 0; k < tcount; k++ ) {
1826 if ( a[k][0] != type || a[k][1] != *m )
continue;
1837 for ( k = 0; k < tcount; k++ ) {
1838 t = AT.pWorkSpace[oww+k];
1839 if ( *t != *m )
continue;
1842 if ( *r < -FUNCTION )
goto nextargw;
1843 else if ( r[1] == t[1] )
goto nextargw;
1847 while ( --j >= 0 && *r++ == *t++ ) {}
1848 if ( j < 0 )
goto nextargw;
1853 AT.pWorkSpace[oww+k] = AT.pWorkSpace[oww+(--tcount)];
1857 AT.pWorkSpace[lhfunnies+i] = AT.pWorkSpace[lhfunnies+(--funnycount)];
1859 if ( tcount == 0 ) {
1860 if ( argcount > 0 )
goto NoSuccess;
1861 for ( i = 0; i < funnycount; i++ ) {
1862 AddWild(BHEAD AT.pWorkSpace[lhfunnies+i][1],ARGTOARG,0);
1874 for ( i = 0; i < iraise; i++ ) {
1875 for ( j = 0; j < tcount; j++ ) {
1876 if ( MatchArgument(BHEAD AT.pWorkSpace[oww+j],AT.pWorkSpace[lhpars+i]) ) {
1880 while ( --k >= 0 ) num += *r++;
1881 if ( num == assig ) {
1883 AT.pWorkSpace[oww+j] = AT.pWorkSpace[oww+(--tcount)];
1884 if ( tcount > j ) signs += tcount-j-1;
1886 a = AT.pWorkSpace + lhpars;
1887 for ( j = i; j < argcount; j++ ) a[j] = a[j+1];
1894 t = thewildcards + ntwa; r = AT.WildMask;
1897 *m++ = *t++; *m++ = *t++; *m++ = *t++; *m++ = *t++; *r++ = *t++;
1898 }
while ( --j > 0 );
1920 cycles = AT.WorkPointer;
1921 for ( i = 0; i < tcount; i++ ) cycles[i] = tcount-i;
1922 AT.WorkPointer += tcount;
1926 WORD oRepFunNum = AN.RepFunNum;
1927 for ( j = 0; j < argcount; j++ ) {
1928 if ( MatchArgument(BHEAD AT.pWorkSpace[oww+j],AT.pWorkSpace[lhpars+j]) == 0 ) {
1932 if ( j >= argcount ) {
1937 AT.WorkPointer = oldworkpointer;
1938 AT.pWorkPointer = oww;
1939 MLOCK(ErrorMessageLock);
1940 MesPrint(
"Sorry: no argument field wildcards yet in (anti)symmetric functions");
1941 MUNLOCK(ErrorMessageLock);
1952 AN.RepFunList[AN.RepFunNum++] = offset;
1953 if ( ( (functions[fun[0]-FUNCTION].symmetric & ~REVERSEORDER) == ANTISYMMETRIC )
1954 || ( (functions[pnum-FUNCTION].symmetric & ~REVERSEORDER) == ANTISYMMETRIC ) ) {
1955 AN.RepFunList[AN.RepFunNum++] = ( signs + signo ) & 1;
1958 AN.RepFunList[AN.RepFunNum++] = 0;
1960 newpat = pattern + pattern[1];
1961 if ( newpat >= AN.patstop ) {
1962 WORD countsgn, sgn = 0;
1963 for ( countsgn = oRepFunNum+1; countsgn < AN.RepFunNum; countsgn += 2 ) {
1964 if ( AN.RepFunList[countsgn] ) sgn ^= 1;
1966 if ( AN.SignCheck == 0 || sgn == AN.ExpectedSign ) {
1967 AT.WorkPointer = oldworkpointer;
1968 AT.pWorkPointer = oww;
1971 if ( AN.UseFindOnly == 0 ) {
1972 if ( FindOnce(BHEAD AN.findTerm,AN.findPattern) ) {
1973 AT.WorkPointer = oldworkpointer;
1974 AT.pWorkPointer = oww;
1975 AN.UsedOtherFind = 1;
1981 else j = ScanFunctions(BHEAD newpat,inter,par);
1983 WORD countsgn, sgn = 0;
1984 for ( countsgn = oRepFunNum+1; countsgn < AN.RepFunNum; countsgn += 2 ) {
1985 if ( AN.RepFunList[countsgn] ) sgn ^= 1;
1987 if ( AN.SignCheck == 0 || sgn == AN.ExpectedSign ) {
1988 AT.WorkPointer = oldworkpointer;
1989 AT.pWorkPointer = oww;
1993 AN.RepFunNum = oRepFunNum;
1999 t = thewildcards + ntwa; r = AT.WildMask;
2002 *m++ = *t++; *m++ = *t++; *m++ = *t++; *m++ = *t++; *r++ = *t++;
2003 }
while ( --j > 0 );
2010 a = AT.pWorkSpace + oww;
2011 for ( j = i+1, t = a[i]; j < tcount; j++ ) a[j-1] = a[j];
2012 a[tcount-1] = t; cycles[i]--;
2013 signo += tcount - i - 1;
2014 while ( cycles[i] <= 0 ) {
2015 cycles[i] = tcount - i;
2017 if ( i < 0 )
goto NoSuccess;
2023 for ( j = i+1, t = a[i]; j < tcount; j++ ) a[j-1] = a[j];
2024 a[tcount-1] = t; cycles[i]--;
2025 signo += tcount - i - 1;
2029 if ( oldwilval > 0 ) {
2032 t = lowlevel; r = AT.WildMask;
2035 *m++ = *t++; *m++ = *t++; *m++ = *t++; *m++ = *t++; *r++ = *t++;
2036 }
while ( --j > 0 );
2041 AT.WorkPointer = oldworkpointer;
2042 AT.pWorkPointer = oww;
2051 int MatchArgument(PHEAD WORD *arg, WORD *pat)
2054 WORD *m = pat, *t = arg, i, j, newvalue;
2055 WORD *argmstop = pat, *argtstop = arg;
2056 WORD *cto, *cfrom, *csav, ci;
2057 WORD oRepFunNum, *oRepFunList;
2058 WORD *oterstart,*oterstop,*opatstop;
2059 WORD wildargs, wildeat;
2060 WORD *mtrmstop, *ttrmstop, *msubstop, msizcoef;
2069 if ( *m < 0 && *t < 0 ) {
2070 if ( *t <= -FUNCTION ) {
2072 else if ( *m <= -FUNCTION-WILDOFFSET
2073 && functions[-*t-FUNCTION].spec
2074 == functions[-*m-FUNCTION-WILDOFFSET].spec ) {
2075 i = -*m - WILDOFFSET; wc = 2;
2076 if ( CheckWild(BHEAD i,FUNTOFUN,-*t,&newvalue) ) {
2079 AddWild(BHEAD i,FUNTOFUN,newvalue);
2081 else if ( *m == -SYMBOL && m[1] >= 2*MAXPOWER ) {
2082 i = m[1] - 2*MAXPOWER;
2083 AN.argaddress = AT.FunArg;
2084 AT.FunArg[ARGHEAD+1] = -*t;
2085 if ( CheckWild(BHEAD i,SYMTOSUB,1,AN.argaddress) )
return(0);
2086 AddWild(BHEAD i,SYMTOSUB,0);
2090 else if ( *t == *m ) {
2091 if ( t[1] == m[1] ) {}
2092 else if ( *t == -SYMBOL ) {
2094 SymAll:
if ( ( i = m[1] - 2*MAXPOWER ) < 0 )
return(0);
2096 if ( CheckWild(BHEAD i,j,t[1],&newvalue) )
return(0);
2097 AddWild(BHEAD i,j,newvalue);
2099 else if ( *t == -INDEX ) {
2100 IndAll: i = m[1] - WILDOFFSET;
2101 if ( i < AM.OffsetIndex || i >= WILDOFFSET+AM.OffsetIndex )
2105 if ( CheckWild(BHEAD i,INDTOIND,t[1],&newvalue) )
return(0);
2106 AddWild(BHEAD i,INDTOIND,newvalue);
2108 else if ( *t == -VECTOR || *t == -MINVECTOR ) {
2109 i = m[1] - WILDOFFSET;
2110 if ( i < AM.OffsetVector )
return(0);
2112 if ( CheckWild(BHEAD i,VECTOVEC,t[1],&newvalue) )
return(0);
2113 AddWild(BHEAD i,VECTOVEC,newvalue);
2117 else if ( *m == -INDEX && m[1] >= AM.OffsetIndex+WILDOFFSET
2118 && m[1] < AM.OffsetIndex+(WILDOFFSET<<1) ) {
2119 if ( *t == -VECTOR )
goto IndAll;
2120 if ( *t == -SNUMBER && t[1] >= 0 && t[1] < AM.OffsetIndex )
goto IndAll;
2121 if ( *t == -MINVECTOR ) {
2122 i = m[1] - WILDOFFSET;
2123 AN.argaddress = AT.MinVecArg;
2124 AT.MinVecArg[ARGHEAD+3] = t[1];
2126 if ( CheckWild(BHEAD i,INDTOSUB,1,AN.argaddress) )
return(0);
2127 AddWild(BHEAD i,INDTOSUB,(WORD)0);
2131 else if ( *m == -SYMBOL && m[1] >= 2*MAXPOWER && *t == -SNUMBER ) {
2135 else if ( *m == -VECTOR && *t == -MINVECTOR &&
2136 ( i = m[1] - WILDOFFSET ) >= AM.OffsetVector ) {
2144 if ( CheckWild(BHEAD i,VECTOMIN,t[1],&newvalue) )
return(0);
2145 AddWild(BHEAD i,VECTOMIN,newvalue);
2148 else if ( *m == -MINVECTOR && *t == -VECTOR &&
2149 ( i = m[1] - WILDOFFSET ) >= AM.OffsetVector ) {
2157 if ( CheckWild(BHEAD i,VECTOMIN,t[1],&newvalue) )
return(0);
2158 AddWild(BHEAD i,VECTOMIN,newvalue);
2166 else if ( *m > 0 && *t <= -FUNCTION ) {
2167 if ( ( m[ARGHEAD]+ARGHEAD == *m ) && m[*m-1] == 3
2168 && m[*m-2] == 1 && m[*m-3] == 1 && m[ARGHEAD+1] >= FUNCTION
2169 && m[ARGHEAD+2] == *m-ARGHEAD-4 ) {
2170 WORD *mmmst, *mmm, mmmi;
2171 if ( m[ARGHEAD+1] >= FUNCTION+WILDOFFSET ) {
2172 mmmi = *m - WILDOFFSET;
2174 if ( CheckWild(BHEAD mmmi,FUNTOFUN,-*t,&newvalue) )
return(0);
2175 AddWild(BHEAD mmmi,FUNTOFUN,newvalue);
2177 else if ( m[ARGHEAD+1] != -*t )
return(0);
2182 mmm = m + ARGHEAD + FUNHEAD + 1;
2183 while ( mmm < mmmst ) {
2184 if ( *mmm != -ARGWILD )
return(0);
2186 AN.argaddress = t; wc = 2;
2187 if ( CheckWild(BHEAD mmm[1],ARGTOARG,mmmi,t) )
return(0);
2188 AddWild(BHEAD mmm[1],ARGTOARG,mmmi);
2198 else if ( *m < 0 && *t > 0 ) {
2199 if ( *m == -SYMBOL ) {
2200 if ( m[1] < 2*MAXPOWER )
return(0);
2201 i = m[1] - 2*MAXPOWER;
2202 AN.argaddress = t; wc = 2;
2203 if ( CheckWild(BHEAD i,SYMTOSUB,1,AN.argaddress) )
return(0);
2204 AddWild(BHEAD i,SYMTOSUB,0);
2206 else if ( *m == -VECTOR ) {
2207 if ( ( i = m[1] - WILDOFFSET ) < AM.OffsetVector )
return(0);
2208 AN.argaddress = t; wc = 2;
2209 if ( CheckWild(BHEAD i,VECTOSUB,1,t) )
return(0);
2210 AddWild(BHEAD i,VECTOSUB,(WORD)0);
2212 else if ( *m == -INDEX ) {
2213 if ( ( i = m[1] - WILDOFFSET ) < AM.OffsetIndex )
return(0);
2214 if ( i >= AM.OffsetIndex + WILDOFFSET )
return(0);
2215 AN.argaddress = t; wc = 2;
2216 if ( CheckWild(BHEAD i,INDTOSUB,1,AN.argaddress) )
return(0);
2217 AddWild(BHEAD i,INDTOSUB,(WORD)0);
2225 else if ( *m > 0 && *t > 0 ) {
2227 do {
if ( *m++ != *t++ )
break; }
while ( --i > 0 );
2234 m += ARGHEAD; t += ARGHEAD;
2237 if ( mtrmstop < argmstop )
return(0);
2238 msizcoef = mtrmstop[-1];
2239 if ( msizcoef < 0 ) msizcoef = -msizcoef;
2240 msubstop = mtrmstop - msizcoef;
2242 if ( m >= msubstop )
return(0);
2255 if ( argtstop > ttrmstop )
return(0);
2258 oterstart = AN.terstart;
2259 oterstop = AN.terstop;
2260 opatstop = AN.patstop;
2261 oRepFunList = AN.RepFunList;
2262 oRepFunNum = AN.RepFunNum;
2264 wildargtaken = AT.WorkPointer;
2265 AN.RepFunList = wildargtaken + AN.NumTotWildArgs;
2266 AT.WorkPointer = (WORD *)(((UBYTE *)(AN.RepFunList)) + AM.MaxTer/2);
2267 csav = cto = AT.WorkPointer;
2270 while ( --ci >= 0 ) *cto++ = *cfrom++;
2271 AT.WorkPointer = cto;
2274 while ( --ci >= 0 ) {
2275 if ( *--cfrom != *--cto ) {
2276 AT.WorkPointer = wildargtaken;
2277 AN.RepFunList = oRepFunList;
2278 AN.RepFunNum = oRepFunNum;
2279 AN.terstart = oterstart;
2280 AN.terstop = oterstop;
2281 AN.patstop = opatstop;
2286 wildargs = AN.WildArgs;
2287 wildeat = AN.WildEat;
2288 for ( i = 0; i < wildargs; i++ ) wildargtaken[i] = AT.WildArgTaken[i];
2289 AN.ForFindOnly = 0; AN.UseFindOnly = 1;
2291 if ( FindRest(BHEAD csav,m) && ( AN.UsedOtherFind || FindOnly(BHEAD csav,m) ) ) { }
2294 AT.WorkPointer = wildargtaken;
2295 AN.RepFunList = oRepFunList;
2296 AN.RepFunNum = oRepFunNum;
2297 AN.terstart = oterstart;
2298 AN.terstop = oterstop;
2299 AN.patstop = opatstop;
2300 AN.WildArgs = wildargs;
2301 AN.WildEat = wildeat;
2303 for ( i = 0; i < wildargs; i++ ) AT.WildArgTaken[i] = wildargtaken[i];
2307 AN.WildArgs = wildargs;
2308 AN.WildEat = wildeat;
2309 for ( i = 0; i < wildargs; i++ ) AT.WildArgTaken[i] = wildargtaken[i];
2310 Substitute(BHEAD csav,m,1);
2312 cfrom = cto + *cto - msizcoef;
2315 AT.WorkPointer = wildargtaken;
2316 AN.RepFunList = oRepFunList;
2317 AN.RepFunNum = oRepFunNum;
2318 AN.terstart = oterstart;
2319 AN.terstop = oterstop;
2320 AN.patstop = opatstop;
2321 if ( *cto != SUBEXPRESSION )
return(0);
2323 if ( cto < cfrom )
return(0);