62 int StudyPattern(WORD *lhs)
65 WORD *fullproto, *pat, *p, *p1, *p2, *pstop, *info, f, nn;
66 int numfun = 0, numsym = 0, allwilds = 0, i, j, k, nc;
67 FUN_INFO *finf, *fmin, *f1, *f2, funscratch;
69 fullproto = lhs + IDHEAD;
71 pat = fullproto + fullproto[1];
76 if ( *p >= FUNCTION ) {
79 if ( nn >= WILDOFFSET ) nn -= WILDOFFSET;
84 if ( ( functions[nn].symmetric == SYMMETRIC ) ||
85 ( functions[nn].symmetric == ANTISYMMETRIC ) ) {
86 p2 = p+p[1]; p1 = p+FUNHEAD;
87 if ( functions[nn].spec ) {
89 if ( *p1 == FUNNYWILD ) {
90 MesPrint(
"&Argument field wildcards are not allowed inside (anti)symmetric functions or tensors");
98 if ( *p1 == -ARGWILD ) {
99 MesPrint(
"&Argument field wildcards are not allowed inside (anti)symmetric functions or tensors");
109 if ( numfun == 0 )
return(0);
110 if ( ( lhs[2] & SUBMASK ) == SUBALL ) {
113 if ( *p == SYMBOL || *p == VECTOR || *p == DOTPRODUCT || *p == INDEX ) {
114 MesPrint(
"&id,all can have only functions and/or tensors in the lhs.");
123 if ( numfun > AN.numfuninfo ) {
124 if ( AN.FunInfo ) M_free(AN.FunInfo,
"funinfo");
125 AN.numfuninfo = numfun + 10;
133 if ( *p >= FUNCTION ) AN.FunInfo[i++].location = p;
136 for ( i = 0, finf = AN.FunInfo; i < numfun; i++, finf++ ) {
140 if ( f > FUNCTION+WILDOFFSET ) f -= WILDOFFSET;
141 finf->numargs = finf->numfunnies = finf->numwildcards = 0;
142 finf->symmet = functions[f-FUNCTION].symmetric;
143 finf->tensor = functions[f-FUNCTION].spec;
144 finf->commute = functions[f-FUNCTION].commute;
145 if ( finf->tensor >= TENSORFUNCTION ) {
147 while ( p < pstop ) {
148 if ( *p == FUNNYWILD ) {
149 finf->numfunnies++; p+= 2;
continue;
152 if ( *p >= AM.OffsetVector + WILDOFFSET && *p < MINSPEC ) {
153 finf->numwildcards++;
157 if ( *p >= AM.OffsetIndex + WILDOFFSET &&
158 *p <= AM.OffsetIndex + 2*WILDOFFSET ) finf->numwildcards++;
166 while ( p < pstop ) {
167 if ( *p > 0 ) { finf->numargs++; p += *p;
continue; }
168 if ( *p <= -FUNCTION ) {
169 if ( *p <= -FUNCTION - WILDOFFSET ) finf->numwildcards++;
172 else if ( *p == -SYMBOL ) {
173 if ( p[1] >= 2*MAXPOWER ) finf->numwildcards++;
176 else if ( *p == -INDEX ) {
177 if ( p[1] >= AM.OffsetIndex + WILDOFFSET &&
178 p[1] <= AM.OffsetIndex + 2*WILDOFFSET ) finf->numwildcards++;
181 else if ( *p == -VECTOR || *p == -MINVECTOR ) {
182 if ( p[1] >= AM.OffsetVector + WILDOFFSET && p[1] < MINSPEC ) {
183 finf->numwildcards++;
187 else if ( *p == -ARGWILD ) {
195 if ( finf->symmet ) {
197 allwilds += finf->numwildcards + finf->numfunnies;
200 if ( numsym == 0 )
return(0);
201 if ( allwilds == 0 )
return(0);
210 for ( nc = numfun-1; nc >= 0; nc-- ) {
if ( AN.FunInfo[nc].commute )
break; }
213 for ( i = nc+2; i < numfun; i++ ) {
215 if ( ( finf->symmet < fmin->symmet ) || (
216 ( finf->symmet == fmin->symmet ) &&
217 ( ( finf->numwildcards+finf->numfunnies < fmin->numwildcards+fmin->numfunnies )
218 || ( ( finf->numwildcards+finf->numfunnies == fmin->numwildcards+fmin->numfunnies )
219 && ( finf->numwildcards < fmin->numfunnies ) ) ) ) ) {
220 funscratch = AN.FunInfo[i];
221 AN.FunInfo[i] = AN.FunInfo[i-1];
222 AN.FunInfo[i-1] = funscratch;
223 for ( j = i-1; j > nc && j > 0; j-- ) {
226 if ( ( f1->symmet < f2->symmet ) || (
227 ( f1->symmet == f2->symmet ) &&
228 ( ( f1->numwildcards+f1->numfunnies < f2->numwildcards+f2->numfunnies )
229 || ( ( f1->numwildcards+f1->numfunnies == f2->numwildcards+f2->numfunnies )
230 && ( f1->numwildcards < f2->numfunnies ) ) ) ) ) {
231 funscratch = AN.FunInfo[j];
232 AN.FunInfo[j] = AN.FunInfo[j-1];
233 AN.FunInfo[j-1] = funscratch;
246 for ( i = 0; i < numfun; i++ ) {
248 for ( k = 0; k <= nc; k++ ) {
249 if ( AN.FunInfo[k].commute ) {
250 p1 = AN.FunInfo[k].location; j = p1[1];
255 else if ( AN.FunInfo[i].commute == 0 ) {
256 p1 = AN.FunInfo[i].location; j = p1[1];
260 p = pat + 1; p1 = info;
261 while ( p1 < p2 ) *p++ = *p1++;
266 for ( i = 0; i < numfun; i++ ) {
268 for ( k = 0; k <= nc; k++ ) {
269 if ( AN.FunInfo[k].commute ) {
270 finf = AN.FunInfo + k;
271 *p2++ = finf->numargs;
272 *p2++ = finf->numwildcards;
273 *p2++ = finf->numfunnies;
274 *p2++ = finf->symmet;
278 else if ( AN.FunInfo[i].commute == 0 ) {
279 finf = AN.FunInfo + i;
280 *p2++ = finf->numargs;
281 *p2++ = finf->numwildcards;
282 *p2++ = finf->numfunnies;
283 *p2++ = finf->symmet;
299 int MatchIsPossible(WORD *pattern, WORD *term)
302 WORD *info = pattern + *pattern;
303 WORD *t, *tstop, *tt, *inf, *p;
304 int numfun = 0, inpat, i, j, numargs;
311 while ( t < tstop ) {
312 if ( *t >= FUNCTION ) numfun++;
315 if ( numfun == 0 )
goto NotPossible;
316 if ( *info == SETSET ) info += info[1];
318 if ( inpat > numfun )
goto NotPossible;
322 if ( numfun > AN.numfuninfo ) {
323 if ( AN.FunInfo ) M_free(AN.FunInfo,
"funinfo");
324 AN.numfuninfo = numfun + 10;
327 t = term + 1; finf = AN.FunInfo;
328 while ( t < tstop ) {
329 if ( *t >= FUNCTION ) {
331 if ( functions[*t-FUNCTION].spec >= TENSORFUNCTION ) {
332 numargs = t[1]-FUNHEAD;
344 finf->numargs = numargs;
353 for ( i = 0, inf = info+1, p = pattern+1; i < inpat; i++, inf += 4, p+=p[1] ) {
354 if ( inf[2] )
continue;
355 if ( *p >= (FUNCTION+WILDOFFSET) )
continue;
356 for ( j = 0, finf = AN.FunInfo; j < numfun; j++, finf++ ) {
357 if ( *p == *(finf->location) && *inf == finf->numargs ) {
358 finf->numargs = -finf->numargs-1;
362 if ( j >= numfun )
goto NotPossible;
364 for ( i = 0, inf = info+1, p = pattern+1; i < inpat; i++, inf += 4, p+=p[1] ) {
365 if ( inf[2] )
continue;
366 if ( *p < (FUNCTION+WILDOFFSET) )
continue;
367 for ( j = 0, finf = AN.FunInfo; j < numfun; j++, finf++ ) {
368 if ( *inf == finf->numargs ) {
369 finf->numargs = -finf->numargs-1;
373 if ( j >= numfun )
goto NotPossible;
375 for ( i = 0, inf = info+1, p = pattern+1; i < inpat; i++, inf += 4, p+=p[1] ) {
376 if ( inf[2] == 0 )
continue;
377 if ( *p >= (FUNCTION+WILDOFFSET) )
continue;
378 for ( j = 0, finf = AN.FunInfo; j < numfun; j++, finf++ ) {
379 if ( *p == *(finf->location) && (*inf-inf[2]) <= finf->numargs ) {
380 finf->numargs = -finf->numargs-1;
384 if ( j >= numfun )
goto NotPossible;
386 for ( i = 0, inf = info+1, p = pattern+1; i < inpat; i++, inf += 4, p+=p[1] ) {
387 if ( inf[2] == 0 )
continue;
388 if ( *p < (FUNCTION+WILDOFFSET) )
continue;
389 for ( j = 0, finf = AN.FunInfo; j < numfun; j++, finf++ ) {
390 if ( (*inf-inf[2]) <= finf->numargs ) {
391 finf->numargs = -finf->numargs-1;
395 if ( j >= numfun )
goto NotPossible;