FORM 4.3
findpat.c
Go to the documentation of this file.
1
13/* #[ License : */
14/*
15 * Copyright (C) 1984-2022 J.A.M. Vermaseren
16 * When using this file you are requested to refer to the publication
17 * J.A.M.Vermaseren "New features of FORM" math-ph/0010025
18 * This is considered a matter of courtesy as the development was paid
19 * for by FOM the Dutch physics granting agency and we would like to
20 * be able to track its scientific use to convince FOM of its value
21 * for the community.
22 *
23 * This file is part of FORM.
24 *
25 * FORM is free software: you can redistribute it and/or modify it under the
26 * terms of the GNU General Public License as published by the Free Software
27 * Foundation, either version 3 of the License, or (at your option) any later
28 * version.
29 *
30 * FORM is distributed in the hope that it will be useful, but WITHOUT ANY
31 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
32 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
33 * details.
34 *
35 * You should have received a copy of the GNU General Public License along
36 * with FORM. If not, see <http://www.gnu.org/licenses/>.
37 */
38/* #] License : */
39/*
40 #[ Includes : findpat.c
41*/
42
43#include "form3.h"
44
45/*
46 #] Includes :
47 #[ Patterns :
48 #[ FindOnly : WORD FindOnly(term,pattern)
49
50 The current version doesn't scan function arguments yet. 10-Apr-1988
51
52 This routine searches for an exact match. This means in particular:
53 1: x^# must match exactly.
54 2: x^n? must have a single value for n that cannot be addapted.
55
56 When setp != 0 it points to a collection of sets
57 A match can occur only if no object will be left that belongs
58 to any of these sets.
59*/
60
61WORD FindOnly(PHEAD WORD *term, WORD *pattern)
62{
63 GETBIDENTITY
64 WORD *t, *m;
65 WORD *tstop, *mstop;
66 WORD *xstop, *ystop, *setp = AN.ForFindOnly;
67 WORD n, nt, *p, nq;
68 WORD older[NORMSIZE], *q, newval1, newval2, newval3;
69 AN.UsedOtherFind = 0;
70 m = pattern;
71 mstop = m + *m;
72 m++;
73 t = term;
74 t += *term - 1;
75 tstop = t - ABS(*t) + 1;
76 t = term;
77 t++;
78 while ( t < tstop && *t > DOTPRODUCT ) t += t[1];
79 while ( m < mstop && *m > DOTPRODUCT ) m += m[1];
80 if ( m < mstop ) { do {
81/*
82 #[ SYMBOLS :
83*/
84 if ( *m == SYMBOL ) {
85 ystop = m + m[1];
86 m += 2;
87 n = 0;
88 p = older;
89 if ( t < tstop ) while ( *t != SYMBOL ) {
90 t += t[1];
91 if ( t >= tstop ) {
92OnlyZer1:
93 do {
94 if ( *m >= 2*MAXPOWER ) return(0);
95 if ( m[1] >= 2*MAXPOWER ) nt = m[1];
96 else if ( m[1] <= -2*MAXPOWER ) nt = -m[1];
97 else return(0);
98 nt -= 2*MAXPOWER;
99 if ( CheckWild(BHEAD nt,SYMTONUM,0,&newval3) ) return(0);
100 AddWild(BHEAD nt,SYMTONUM,0);
101 m += 2;
102 } while ( m < ystop );
103 goto EndLoop;
104 }
105 }
106 else goto OnlyZer1;
107 xstop = t + t[1];
108 t += 2;
109 do {
110 if ( *m == *t && t < xstop ) {
111 if ( m[1] == t[1] ) { m += 2; t += 2; }
112 else if ( m[1] >= 2*MAXPOWER ) {
113 nt = t[1];
114 nq = m[1];
115 goto OnlyL2;
116 }
117 else if ( m[1] <= -2*MAXPOWER ) {
118 nt = -t[1];
119 nq = -m[1];
120OnlyL2: nq -= 2*MAXPOWER;
121 if ( CheckWild(BHEAD nq,SYMTONUM,nt,&newval3) ) return(0);
122 AddWild(BHEAD nq,SYMTONUM,nt);
123 m += 2;
124 t += 2;
125 }
126 else {
127 *p++ = *t++; *p++ = *t++; n += 2;
128 }
129 }
130 else if ( *m >= 2*MAXPOWER ) {
131 while ( t < xstop ) { *p++ = *t++; *p++ = *t++; n += 2; }
132 nq = n;
133 p = older;
134 while ( nq > 0 ) {
135 if ( !CheckWild(BHEAD *m-2*MAXPOWER,SYMTOSYM,*p,&newval1) ) {
136 if ( m[1] == p[1] ) {
137 AddWild(BHEAD *m-2*MAXPOWER,SYMTOSYM,newval1);
138 break;
139 }
140 else if ( m[1] >= 2*MAXPOWER && m[1] != *m ) {
141 if ( !CheckWild(BHEAD m[1]-2*MAXPOWER,SYMTONUM,p[1],&newval3) ) {
142 AddWild(BHEAD m[1]-2*MAXPOWER,SYMTONUM,p[1]);
143 AddWild(BHEAD *m-2*MAXPOWER,SYMTOSYM,newval1);
144 break;
145 }
146 }
147 else if ( m[1] <= -2*MAXPOWER && m[1] != -(*m) ) {
148 if ( !CheckWild(BHEAD -m[1]-2*MAXPOWER,SYMTONUM,-p[1],&newval3) ) {
149 AddWild(BHEAD -m[1]-2*MAXPOWER,SYMTONUM,-p[1]);
150 AddWild(BHEAD *m-2*MAXPOWER,SYMTOSYM,newval1);
151 break;
152 }
153 }
154 }
155 nq -= 2;
156 p += 2;
157 }
158 if ( nq <= 0 ) return(0);
159 nq -= 2;
160 n -= 2;
161 q = p + 2;
162 while ( --nq >= 0 ) *p++ = *q++;
163 m += 2;
164 }
165 else {
166 if ( t >= xstop || *m < *t ) {
167 if ( m[1] >= 2*MAXPOWER ) nt = m[1];
168 else if ( m[1] <= -2*MAXPOWER ) nt = -m[1];
169 else return(0);
170 nt -= 2*MAXPOWER;
171 if ( CheckWild(BHEAD nt,SYMTONUM,0,&newval3) ) return(0);
172 AddWild(BHEAD nt,SYMTONUM,0);
173 m += 2;
174 }
175 else {
176 *p++ = *t++; *p++ = *t++; n += 2;
177 }
178 }
179 } while ( m < ystop );
180 if ( setp ) {
181 while ( t < xstop ) { *p++ = *t++; *p++ = *t++; n+= 2; }
182 p = older;
183 while ( n > 0 ) {
184 nq = setp[1] - 2;
185 m = setp + 2;
186 while ( --nq >= 0 ) {
187 if ( Sets[*m].type != CSYMBOL ) { m++; continue; }
188 t = SetElements + Sets[*m].first;
189 tstop = SetElements + Sets[*m].last;
190 while ( t < tstop ) {
191 if ( *t++ == *p ) return(0);
192 }
193 m++;
194 }
195 n -= 2;
196 p += 2;
197 }
198 }
199 return(1);
200 }
201/*
202 #] SYMBOLS :
203 #[ DOTPRODUCTS :
204*/
205 else if ( *m == DOTPRODUCT ) {
206 ystop = m + m[1];
207 m += 2;
208 n = 0;
209 p = older;
210 if ( t < tstop ) {
211 if ( *t < DOTPRODUCT ) goto OnlyZer2;
212 while ( *t > DOTPRODUCT ) {
213 t += t[1];
214 if ( t >= tstop || *t < DOTPRODUCT ) {
215OnlyZer2:
216 do {
217 if ( *m >= (AM.OffsetVector+WILDOFFSET)
218 || m[1] >= (AM.OffsetVector+WILDOFFSET) ) return(0);
219 if ( m[2] >= 2*MAXPOWER ) nq = m[2];
220 else if ( m[2] <= -2*MAXPOWER ) nq = -m[2];
221 else return(0);
222 nq -= 2*MAXPOWER;
223 if ( CheckWild(BHEAD nq,SYMTONUM,0,&newval3) ) return(0);
224 AddWild(BHEAD nq,SYMTONUM,0);
225 m += 3;
226 } while ( m < ystop );
227 goto EndLoop;
228 }
229 }
230 }
231 else goto OnlyZer2;
232 xstop = t + t[1];
233 t += 2;
234 do {
235 if ( *m == *t && m[1] == t[1] && t < xstop ) {
236 if ( t[2] != m[2] ) {
237 if ( m[2] >= 2*MAXPOWER ) {
238 nq = m[2];
239 nt = t[2];
240 }
241 else if ( m[2] <= -2*MAXPOWER ) {
242 nq = -m[2];
243 nt = -t[2];
244 }
245 else return(0);
246 nq -= 2*MAXPOWER;
247 if ( CheckWild(BHEAD nq,SYMTONUM,nt,&newval3) ) return(0);
248 AddWild(BHEAD nq,SYMTONUM,nt);
249 }
250 t += 3; m += 3;
251 }
252 else if ( *m >= (AM.OffsetVector+WILDOFFSET) ) {
253 while ( t < xstop ) {
254 *p++ = *t++; *p++ = *t++; *p++ = *t++; n += 3;
255 }
256 nq = n;
257 p = older;
258 while ( nq > 0 ) {
259 if ( *m == m[1] ) {
260 if ( *p != p[1] ) goto NextInDot;
261 }
262 if ( !CheckWild(BHEAD *m-WILDOFFSET,VECTOVEC,*p,&newval1) &&
263 !CheckWild(BHEAD m[1]-WILDOFFSET,VECTOVEC,p[1],&newval2) ) {
264 if ( p[2] == m[2] ) {
265OnlyL9: AddWild(BHEAD m[1]-WILDOFFSET,VECTOVEC,newval2);
266 AddWild(BHEAD *m-WILDOFFSET,VECTOVEC,newval1);
267 break;
268 }
269 if ( m[2] >= 2*MAXPOWER ) {
270 if ( !CheckWild(BHEAD m[2]-2*MAXPOWER,SYMTONUM,p[2],&newval3) ) {
271 AddWild(BHEAD m[2]-2*MAXPOWER,SYMTONUM,newval3);
272 goto OnlyL9;
273 }
274 }
275 else if ( m[2] <= -2*MAXPOWER ) {
276 if ( !CheckWild(BHEAD -m[2]-2*MAXPOWER,SYMTONUM,-p[2],&newval3) ) {
277 AddWild(BHEAD -m[2]-2*MAXPOWER,SYMTONUM,-p[2]);
278 goto OnlyL9;
279 }
280 }
281 }
282 if ( !CheckWild(BHEAD *m-WILDOFFSET,VECTOVEC,p[1],&newval1) &&
283 !CheckWild(BHEAD m[1]-WILDOFFSET,VECTOVEC,*p,&newval2) ) {
284 if ( p[2] == m[2] ) {
285OnlyL10: AddWild(BHEAD *m-WILDOFFSET,VECTOVEC,newval1);
286 AddWild(BHEAD m[1]-WILDOFFSET,VECTOVEC,newval2);
287 break;
288 }
289 if ( m[2] >= 2*MAXPOWER ) {
290 if ( !CheckWild(BHEAD m[2]-2*MAXPOWER,SYMTONUM,p[2],&newval3) ) {
291 AddWild(BHEAD m[2]-2*MAXPOWER,SYMTONUM,p[2]);
292 goto OnlyL10;
293 }
294 }
295 else if ( m[2] <= -2*MAXPOWER ) {
296 if ( !CheckWild(BHEAD -m[2]-2*MAXPOWER,SYMTONUM,-p[2],&newval3) ) {
297 AddWild(BHEAD -m[2]-2*MAXPOWER,SYMTONUM,-p[2]);
298 goto OnlyL10;
299 }
300 }
301 }
302NextInDot:
303 p += 3; nq -= 3;
304 }
305 if ( nq <= 0 ) return(0);
306 q = p+3;
307 nq -= 3;
308 n -= 3;
309 while ( --nq >= 0 ) *p++ = *q++;
310 m += 3;
311 }
312 else if ( m[1] >= (AM.OffsetVector+WILDOFFSET) ) {
313 while ( *m >= *t && t < xstop ) {
314 *p++ = *t++; *p++ = *t++; *p++ = *t++; n += 3;
315 }
316 nq = n;
317 p = older;
318 while ( nq > 0 ) {
319 if ( *m == *p && !CheckWild(BHEAD m[1]-WILDOFFSET,VECTOVEC,p[1],&newval1) ) {
320 if ( p[2] == m[2] ) {
321 AddWild(BHEAD m[1]-WILDOFFSET,VECTOVEC,newval1);
322 break;
323 }
324 else if ( m[2] >= 2*MAXPOWER ) {
325 if ( !CheckWild(BHEAD m[2]-2*MAXPOWER,SYMTONUM,p[2],&newval3) ) {
326 AddWild(BHEAD m[2]-2*MAXPOWER,SYMTONUM,p[2]);
327 AddWild(BHEAD m[1]-WILDOFFSET,VECTOVEC,newval1);
328 break;
329 }
330 }
331 else if ( m[2] <= -2*MAXPOWER ) {
332 if ( !CheckWild(BHEAD -m[2]-2*MAXPOWER,SYMTONUM,-p[2],&newval3) ) {
333 AddWild(BHEAD -m[2]-2*MAXPOWER,SYMTONUM,-p[2]);
334 AddWild(BHEAD m[1]-WILDOFFSET,VECTOVEC,newval1);
335 break;
336 }
337 }
338 }
339 if ( *m == p[1] && !CheckWild(BHEAD m[1]-WILDOFFSET,VECTOVEC,*p,&newval1) ) {
340 if ( p[2] == m[2] ) {
341 AddWild(BHEAD m[1]-WILDOFFSET,VECTOVEC,newval1);
342 break;
343 }
344 if ( m[2] >= 2*MAXPOWER ) {
345 if ( !CheckWild(BHEAD m[2]-2*MAXPOWER,SYMTONUM,p[2],&newval3) ) {
346 AddWild(BHEAD m[2]-2*MAXPOWER,SYMTONUM,p[2]);
347 AddWild(BHEAD m[1]-WILDOFFSET,VECTOVEC,newval1);
348 break;
349 }
350 }
351 else if ( m[2] <= -2*MAXPOWER ) {
352 if ( !CheckWild(BHEAD -m[2]-2*MAXPOWER,SYMTONUM,-p[2],&newval3) ) {
353 AddWild(BHEAD -m[2]-2*MAXPOWER,SYMTONUM,-p[2]);
354 AddWild(BHEAD m[1]-WILDOFFSET,VECTOVEC,newval1);
355 break;
356 }
357 }
358 }
359 p += 3; nq -= 3;
360 }
361 if ( nq <= 0 ) return(0);
362 q = p+3;
363 nq -= 3;
364 n -= 3;
365 while ( --nq >= 0 ) *p++ = *q++;
366 m += 3;
367 }
368 else {
369 if ( t >= xstop || *m < *t || ( *m == *t && m[1] < t[1] ) ) {
370 if ( m[2] > 2*MAXPOWER ) nt = m[2];
371 else if ( m[2] <= -2*MAXPOWER ) nt = -m[2];
372 else return(0);
373 nt -= 2*MAXPOWER;
374 if ( CheckWild(BHEAD nt,SYMTONUM,0,&newval3) ) return(0);
375 AddWild(BHEAD nt,SYMTONUM,0);
376 m += 3;
377 }
378 else {
379 *p++ = *t++; *p++ = *t++; *p++ = *t++; n += 3;
380 }
381 }
382 } while ( m < ystop );
383 t = xstop;
384 }
385/*
386 #] DOTPRODUCTS :
387*/
388 else {
389 MLOCK(ErrorMessageLock);
390 MesPrint("Error in pattern(1)");
391 MUNLOCK(ErrorMessageLock);
392 Terminate(-1);
393 }
394EndLoop:;
395 } while ( m < mstop ); }
396 if ( setp ) {
397/*
398 while ( t < tstop && *t > SYMBOL ) t += t[1];
399 if ( t < tstop && setp[1] > 2 ) return(0);
400*/
401 /* There were nonempty sets */
402 /* Empty sets are rejected by the compiler */
403 }
404 return(1);
405}
406
407/*
408 #] FindOnly :
409 #[ FindOnce : WORD FindOnce(term,pattern)
410
411 Searches for a single match in term. The difference with multi
412 lies mainly in the fact that here functions may occur.
413 The functions have not been implemented yet. (10-Apr-1988)
414 Wildcard powers are adjustable. The value closer to zero is taken.
415 Positive and negative gives (o surprise) zero.
416
417*/
418
419WORD FindOnce(PHEAD WORD *term, WORD *pattern)
420{
421 GETBIDENTITY
422 WORD *t, *m;
423 WORD *tstop, *mstop;
424 WORD *xstop, *ystop;
425 WORD n, nt, *p, nq, mt, ch;
426 WORD older[2*NORMSIZE], *q, newval1, newval2, newval3;
427 AN.UsedOtherFind = 0;
428 m = pattern;
429 mstop = m + *m;
430 m++;
431 t = term;
432 t += *term - 1;
433 tstop = t - ABS(*t) + 1;
434 t = term;
435 t++;
436 while ( t < tstop && *t > DOTPRODUCT ) t += t[1];
437 while ( m < mstop && *m > DOTPRODUCT ) m += m[1];
438 if ( m < mstop ) { do {
439/*
440 #[ SYMBOLS :
441*/
442 if ( *m == SYMBOL ) {
443 ystop = m + m[1];
444 m += 2;
445 n = 0;
446 p = older;
447 if ( t < tstop ) while ( *t != SYMBOL ) {
448 t += t[1];
449 if ( t >= tstop ) {
450TryZero:
451 do {
452 if ( *m >= 2*MAXPOWER ) return(0);
453 if ( m[1] >= 2*MAXPOWER ) nt = m[1];
454 else if ( m[1] <= -2*MAXPOWER ) nt = -m[1];
455 else return(0);
456 nt -= 2*MAXPOWER;
457 if ( ( ch = CheckWild(BHEAD nt,SYMTONUM,0,&newval3) ) != 0 ) {
458 if ( ch > 1 ) return(0);
459 if ( AN.oldtype != SYMTONUM ) return(0);
460 if ( *AN.MaskPointer == 2 ) return(0);
461 }
462 AddWild(BHEAD nt,SYMTONUM,0);
463 m += 2;
464 } while ( m < ystop );
465 goto EndLoop;
466 }
467 }
468 else goto TryZero;
469 xstop = t + t[1];
470 t += 2;
471 do {
472 if ( *m == *t && t < xstop ) {
473 nt = t[1];
474 mt = m[1];
475 if ( ( mt > 0 && mt <= nt ) ||
476 ( mt < 0 && mt >= nt ) ) { m += 2; t += 2; }
477 else if ( mt >= 2*MAXPOWER ) goto OnceL2;
478 else if ( mt <= -2*MAXPOWER ) {
479 nt = -nt;
480 mt = -mt;
481OnceL2: mt -= 2*MAXPOWER;
482 if ( ( ch = CheckWild(BHEAD mt,SYMTONUM,nt,&newval3) ) != 0 ) {
483 if ( ch > 1 ) return(0);
484 if ( AN.oldtype != SYMTONUM ) return(0);
485 if ( AN.oldvalue <= 0 ) {
486 if ( nt < AN.oldvalue ) nt = AN.oldvalue;
487 else {
488 if ( *AN.MaskPointer == 2 ) return(0);
489 if ( nt > 0 ) nt = 0;
490 }
491 }
492 if ( AN.oldvalue >= 0 ) {
493 if ( nt > AN.oldvalue ) nt = AN.oldvalue;
494 else {
495 if ( *AN.MaskPointer == 2 ) return(0);
496 if ( nt < 0 ) nt = 0;
497 }
498 }
499 }
500 AddWild(BHEAD mt,SYMTONUM,nt);
501 m += 2;
502 t += 2;
503 }
504 else {
505 *p++ = *t++; *p++ = *t++; n += 2;
506 }
507 }
508 else if ( *m >= 2*MAXPOWER ) {
509 while ( t < xstop ) { *p++ = *t++; *p++ = *t++; n += 2; }
510 nq = n;
511 p = older;
512 while ( nq > 0 ) {
513 nt = p[1];
514 if ( !CheckWild(BHEAD *m-2*MAXPOWER,SYMTOSYM,*p,&newval1) ) {
515 mt = m[1];
516 if ( ( mt > 0 && mt <= nt ) ||
517 ( mt < 0 && mt >= nt ) ) {
518 AddWild(BHEAD *m-2*MAXPOWER,SYMTOSYM,newval1);
519 break;
520 }
521 else if ( mt >= 2*MAXPOWER && mt != *m ) {
522OnceL4a: mt -= 2*MAXPOWER;
523 if ( ( ch = CheckWild(BHEAD mt,SYMTONUM,nt,&newval3) ) != 0 ) {
524 if ( ch > 1 ) return(0);
525 if ( AN.oldtype == SYMTONUM ) {
526 if ( AN.oldvalue >= 0 ) {
527 if ( nt > AN.oldvalue ) nt = AN.oldvalue;
528 else {
529 if ( *AN.MaskPointer == 2 ) return(0);
530 if ( nt < 0 ) nt = 0;
531 }
532 }
533 else {
534 if ( nt < AN.oldvalue ) nt = AN.oldvalue;
535 else {
536 if ( *AN.MaskPointer == 2 ) return(0);
537 if ( nt > 0 ) nt = 0;
538 }
539 }
540 AddWild(BHEAD mt,SYMTONUM,nt);
541 AddWild(BHEAD *m-2*MAXPOWER,SYMTOSYM,newval1);
542 break;
543 }
544 }
545 else {
546 AddWild(BHEAD mt,SYMTONUM,nt);
547 AddWild(BHEAD *m-2*MAXPOWER,SYMTOSYM,newval1);
548 break;
549 }
550 }
551 else if ( mt <= -2*MAXPOWER && mt != -(*m) ) {
552 nt = -nt;
553 mt = -mt;
554 goto OnceL4a;
555 }
556 }
557 nq -= 2;
558 p += 2;
559 }
560 if ( nq <= 0 ) return(0);
561 nq -= 2;
562 n -= 2;
563 q = p + 2;
564 while ( --nq >= 0 ) *p++ = *q++;
565 m += 2;
566 }
567 else {
568 if ( t >= xstop || *m < *t ) {
569 if ( m[1] >= 2*MAXPOWER ) nt = m[1];
570 else if ( m[1] <= -2*MAXPOWER ) nt = -m[1];
571 else return(0);
572 nt -= 2*MAXPOWER;
573 if ( ( ch = CheckWild(BHEAD nt,SYMTONUM,0,&newval3) ) != 0 ) {
574 if ( ch > 1 ) return(0);
575 if ( AN.oldtype != SYMTONUM ) return(0);
576 if ( *AN.MaskPointer == 2 ) return(0);
577 }
578 AddWild(BHEAD nt,SYMTONUM,0);
579 m += 2;
580 }
581 else {
582 *p++ = *t++; *p++ = *t++; n += 2;
583 }
584 }
585 } while ( m < ystop );
586 }
587/*
588 #] SYMBOLS :
589 #[ DOTPRODUCTS :
590*/
591 else if ( *m == DOTPRODUCT ) {
592 ystop = m + m[1];
593 m += 2;
594 n = 0;
595 p = older;
596 if ( t < tstop ) {
597 if ( *t < DOTPRODUCT ) goto OnceOp;
598 while ( *t > DOTPRODUCT ) {
599 t += t[1];
600 if ( t >= tstop || *t < DOTPRODUCT ) {
601OnceOp:
602 do {
603 if ( *m >= (AM.OffsetVector+WILDOFFSET)
604 || m[1] >= (AM.OffsetVector+WILDOFFSET) ) return(0);
605 if ( m[2] >= 2*MAXPOWER ) {
606 nq = m[2] - 2*MAXPOWER;
607 }
608 else if ( m[2] <= -2*MAXPOWER ) {
609 nq = -m[2] - 2*MAXPOWER;
610 }
611 else return(0);
612 if ( CheckWild(BHEAD nq,SYMTONUM,(WORD)0,&newval3) ) {
613 if ( AN.oldtype != SYMTONUM ) return(0);
614 if ( *AN.MaskPointer == 2 ) return(0);
615 }
616 AddWild(BHEAD nq,SYMTONUM,(WORD)0);
617 m += 3;
618 } while ( m < ystop );
619 goto EndLoop;
620 }
621 }
622 }
623 else goto OnceOp;
624 xstop = t + t[1];
625 t += 2;
626 do {
627 if ( *m == *t && m[1] == t[1] && t < xstop ) {
628 nt = t[2];
629 mt = m[2];
630/*
631 if ( ( nt > 0 && nt < mt ) ||
632 ( nt < 0 && nt > mt ) ) {
633 if ( mt <= -2*MAXPOWER ) {
634 mt = -mt;
635 nt = -nt;
636 }
637 else if ( mt < 2*MAXPOWER ) return(0);
638 mt -= 2*MAXPOWER;
639 if ( CheckWild(BHEAD mt,SYMTONUM,nt,&newval3) ) {
640 if ( AN.oldtype != SYMTONUM ) return(0);
641 if ( AN.oldvalue <= 0 ) {
642 if ( nt < AN.oldvalue ) nt = AN.oldvalue;
643 else {
644 if ( *AN.MaskPointer == 2 ) return(0);
645 if ( nt > 0 ) nt = 0;
646 }
647 }
648 if ( AN.oldvalue >= 0 ) {
649 if ( nt > AN.oldvalue ) nt = AN.oldvalue;
650 else {
651 if ( *AN.MaskPointer == 2 ) return(0);
652 if ( nt < 0 ) nt = 0;
653 }
654 }
655 }
656 AddWild(BHEAD mt,SYMTONUM,nt);
657 m += 3; t += 3;
658 }
659 else if ( ( nt > 0 && nt >= mt && mt > -2*MAXPOWER )
660 || ( nt < 0 && nt <= mt && mt < 2*MAXPOWER ) ) {
661 m += 3; t += 3;
662 }
663*/
664 if ( ( mt > 0 && mt <= nt ) ||
665 ( mt < 0 && mt >= nt ) ) { m += 3; t += 3; }
666 else if ( mt >= 2*MAXPOWER ) goto OnceL7;
667 else if ( mt <= -2*MAXPOWER ) {
668 nt = -nt;
669 mt = -mt;
670OnceL7: mt -= 2*MAXPOWER;
671 if ( CheckWild(BHEAD mt,SYMTONUM,nt,&newval3) ) {
672 if ( AN.oldtype != SYMTONUM ) return(0);
673 if ( AN.oldvalue <= 0 ) {
674 if ( nt < AN.oldvalue ) nt = AN.oldvalue;
675 else {
676 if ( *AN.MaskPointer == 2 ) return(0);
677 if ( nt > 0 ) nt = 0;
678 }
679 }
680 if ( AN.oldvalue >= 0 ) {
681 if ( nt > AN.oldvalue ) nt = AN.oldvalue;
682 else {
683 if ( *AN.MaskPointer == 2 ) return(0);
684 if ( nt < 0 ) nt = 0;
685 }
686 }
687 }
688 AddWild(BHEAD mt,SYMTONUM,nt);
689 m += 3;
690 t += 3;
691 }
692 else {
693 *p++ = *t++; *p++ = *t++; *p++ = *t++; n += 3;
694 }
695 }
696 else if ( *m >= (AM.OffsetVector+WILDOFFSET) ) {
697 while ( t < xstop ) {
698 *p++ = *t++; *p++ = *t++; *p++ = *t++; n += 3;
699 }
700 nq = n;
701 p = older;
702 while ( nq > 0 ) {
703 if ( *m == m[1] ) {
704 if ( *p != p[1] ) goto NextInDot;
705 }
706 if ( !CheckWild(BHEAD *m-WILDOFFSET,VECTOVEC,*p,&newval1) &&
707 !CheckWild(BHEAD m[1]-WILDOFFSET,VECTOVEC,p[1],&newval2) ) {
708 nt = p[2];
709 mt = m[2];
710 if ( ( mt > 0 && nt >= mt ) ||
711 ( mt < 0 && nt <= mt ) ) {
712OnceL9: AddWild(BHEAD *m-WILDOFFSET,VECTOVEC,newval1);
713 AddWild(BHEAD m[1]-WILDOFFSET,VECTOVEC,newval2);
714 break;
715 }
716 if ( mt >= 2*MAXPOWER ) {
717OnceL9a: mt -= 2*MAXPOWER;
718 if ( CheckWild(BHEAD mt,SYMTONUM,nt,&newval3) ) {
719 if ( AN.oldtype == SYMTONUM ) {
720 if ( AN.oldvalue >= 0 ) {
721 if ( nt > AN.oldvalue ) nt = AN.oldvalue;
722 else {
723 if ( *AN.MaskPointer == 2 ) return(0);
724 if ( nt < 0 ) nt = 0;
725 }
726 }
727 else {
728 if ( nt < AN.oldvalue ) nt = AN.oldvalue;
729 else {
730 if ( *AN.MaskPointer == 2 ) return(0);
731 if ( nt > 0 ) nt = 0;
732 }
733 }
734 AddWild(BHEAD mt,SYMTONUM,nt);
735 goto OnceL9;
736 }
737 }
738 else {
739 AddWild(BHEAD mt,SYMTONUM,nt);
740 goto OnceL9;
741 }
742 }
743 else if ( mt <= -2*MAXPOWER ) {
744 mt = -mt;
745 nt = -nt;
746 goto OnceL9a;
747 }
748 }
749 if ( !CheckWild(BHEAD *m-WILDOFFSET,VECTOVEC,p[1],&newval1) &&
750 !CheckWild(BHEAD m[1]-WILDOFFSET,VECTOVEC,*p,&newval2) ) {
751 nt = p[2];
752 mt = m[2];
753 if ( ( mt > 0 && nt >= mt ) ||
754 ( mt < 0 && nt <= mt ) ) {
755OnceL10: AddWild(BHEAD *m-WILDOFFSET,VECTOVEC,newval1);
756 AddWild(BHEAD m[1]-WILDOFFSET,VECTOVEC,newval2);
757 break;
758 }
759 if ( mt >= 2*MAXPOWER ) {
760OnceL10a: mt -= 2*MAXPOWER;
761 if ( CheckWild(BHEAD mt,SYMTONUM,nt,&newval3) ) {
762 if ( AN.oldtype == SYMTONUM ) {
763 if ( AN.oldvalue >= 0 ) {
764 if ( nt > AN.oldvalue ) nt = AN.oldvalue;
765 else {
766 if ( *AN.MaskPointer == 2 ) return(0);
767 if ( nt < 0 ) nt = 0;
768 }
769 }
770 else {
771 if ( nt < AN.oldvalue ) nt = AN.oldvalue;
772 else {
773 if ( *AN.MaskPointer == 2 ) return(0);
774 if ( nt > 0 ) nt = 0;
775 }
776 }
777 AddWild(BHEAD mt,SYMTONUM,nt);
778 goto OnceL10;
779 }
780 }
781 else {
782 AddWild(BHEAD mt,SYMTONUM,nt);
783 goto OnceL10;
784 }
785 }
786 else if ( mt <= -2*MAXPOWER ) {
787 mt = -mt;
788 nt = -nt;
789 goto OnceL10a;
790 }
791 }
792NextInDot:
793 p += 3; nq -= 3;
794 }
795 if ( nq <= 0 ) return(0);
796 else {
797 q = p+3;
798 nq -= 3;
799 n -= 3;
800 while ( --nq >= 0 ) *p++ = *q++;
801 }
802 m += 3;
803 }
804 else if ( m[1] >= (AM.OffsetVector+WILDOFFSET) ) {
805 while ( *m >= *t && t < xstop ) {
806 *p++ = *t++; *p++ = *t++; *p++ = *t++; n += 3;
807 }
808 nq = n;
809 p = older;
810 while ( nq > 0 ) {
811 if ( *m == *p && !CheckWild(BHEAD m[1]-WILDOFFSET,
812 VECTOVEC,p[1],&newval1) ) {
813 nt = p[2];
814 mt = m[2];
815 if ( ( mt > 0 && nt >= mt ) ||
816 ( mt < 0 && nt <= mt ) ) {
817 AddWild(BHEAD m[1]-WILDOFFSET,VECTOVEC,newval1);
818 break;
819 }
820 else if ( mt >= 2*MAXPOWER ) {
821OnceL7a: mt -= 2*MAXPOWER;
822 if ( CheckWild(BHEAD mt,SYMTONUM,nt,&newval3) ) {
823 if ( AN.oldtype == SYMTONUM ) {
824 if ( AN.oldvalue >= 0 ) {
825 if ( nt > AN.oldvalue ) nt = AN.oldvalue;
826 else {
827 if ( *AN.MaskPointer == 2 ) return(0);
828 if ( nt < 0 ) nt = 0;
829 }
830 }
831 else {
832 if ( nt < AN.oldvalue ) nt = AN.oldvalue;
833 else {
834 if ( *AN.MaskPointer == 2 ) return(0);
835 if ( nt > 0 ) nt = 0;
836 }
837 }
838 AddWild(BHEAD mt,SYMTONUM,nt);
839 AddWild(BHEAD m[1]-WILDOFFSET,VECTOVEC,newval1);
840 break;
841 }
842 }
843 else {
844 AddWild(BHEAD mt,SYMTONUM,nt);
845 AddWild(BHEAD m[1]-WILDOFFSET,VECTOVEC,newval1);
846 break;
847 }
848 }
849 else if ( mt <= -2*MAXPOWER ) {
850 mt = -mt;
851 nt = -nt;
852 goto OnceL7a;
853 }
854 }
855 if ( *m == p[1] && !CheckWild(BHEAD m[1]-WILDOFFSET,
856 VECTOVEC,*p,&newval1) ) {
857 nt = p[2];
858 mt = m[2];
859 if ( ( mt > 0 && nt >= mt ) ||
860 ( mt < 0 && nt <= mt ) ) {
861 AddWild(BHEAD m[1]-WILDOFFSET,VECTOVEC,newval1);
862 break;
863 }
864 if ( mt >= 2*MAXPOWER ) {
865OnceL8a: mt -= 2*MAXPOWER;
866 if ( CheckWild(BHEAD mt,SYMTONUM,nt,&newval3) ) {
867 if ( AN.oldtype == SYMTONUM ) {
868 if ( AN.oldvalue >= 0 ) {
869 if ( nt > AN.oldvalue ) nt = AN.oldvalue;
870 else {
871 if ( *AN.MaskPointer == 2 ) return(0);
872 if ( nt < 0 ) nt = 0;
873 }
874 }
875 else {
876 if ( nt < AN.oldvalue ) nt = AN.oldvalue;
877 else {
878 if ( *AN.MaskPointer == 2 ) return(0);
879 if ( nt > 0 ) nt = 0;
880 }
881 }
882 AddWild(BHEAD mt,SYMTONUM,nt);
883 AddWild(BHEAD m[1]-WILDOFFSET,VECTOVEC,newval1);
884 break;
885 }
886 }
887 else {
888 AddWild(BHEAD mt,SYMTONUM,nt);
889 AddWild(BHEAD m[1]-WILDOFFSET,VECTOVEC,newval1);
890 break;
891 }
892 }
893 else if ( mt < -2*MAXPOWER ) {
894 mt = -mt;
895 nt = -nt;
896 goto OnceL8a;
897 }
898 }
899 p += 3; nq -= 3;
900 }
901 if ( nq <= 0 ) return(0);
902 q = p+3;
903 nq -= 3;
904 n -= 3;
905 while ( --nq >= 0 ) *p++ = *q++;
906 m += 3;
907 }
908 else {
909 if ( t >= xstop || *m < *t || ( *m == *t && m[1] < t[1] ) ) {
910 if ( m[2] >= 2*MAXPOWER ) nt = m[2];
911 else if ( m[2] <= -2*MAXPOWER ) nt = -m[2];
912 else return(0);
913 nt -= 2*MAXPOWER;
914 if ( CheckWild(BHEAD nt,SYMTONUM,0,&newval3) ) {
915 if ( AN.oldtype != SYMTONUM ) return(0);
916 if ( *AN.MaskPointer == 2 ) return(0);
917 }
918 AddWild(BHEAD nt,SYMTONUM,0);
919 m += 3;
920 }
921 else {
922 *p++ = *t++; *p++ = *t++; *p++ = *t++; n += 3;
923 }
924 }
925 } while ( m < ystop );
926 t = xstop;
927 }
928/*
929 #] DOTPRODUCTS :
930*/
931 else {
932 MLOCK(ErrorMessageLock);
933 MesPrint("Error in pattern(2)");
934 MUNLOCK(ErrorMessageLock);
935 Terminate(-1);
936 }
937EndLoop:;
938 } while ( m < mstop ); }
939 else {
940 return(-1);
941 }
942 return(1);
943}
944
945/*
946 #] FindOnce :
947 #[ FindMulti : WORD FindMulti(term,pattern)
948
949 Note that multi cannot deal with wildcards. Those patterns revert
950 to many which gives subsequent calls to once.
951
952*/
953
954WORD FindMulti(PHEAD WORD *term, WORD *pattern)
955{
956 GETBIDENTITY
957 WORD *t, *m, *p;
958 WORD *tstop, *mstop;
959 WORD *xstop, *ystop;
960 WORD mt, power, n, nq;
961 WORD older[2*NORMSIZE], *q, newval1;
962 AN.UsedOtherFind = 0;
963 m = pattern;
964 mstop = m + *m;
965 m++;
966 t = term;
967 t += *term - 1;
968 tstop = t - ABS(*t) + 1;
969 t = term;
970 t++;
971 while ( t < tstop && *t > DOTPRODUCT ) t += t[1];
972 while ( m < mstop && *m > DOTPRODUCT ) m += m[1];
973 power = -1; /* No power yet */
974 if ( m < mstop ) { do {
975/*
976 #[ SYMBOLS :
977*/
978 if ( *m == SYMBOL ) {
979 ystop = m + m[1];
980 m += 2;
981 if ( t >= tstop ) return(0);
982 while ( *t != SYMBOL ) { t += t[1]; if ( t >= tstop ) return(0); }
983 xstop = t + t[1];
984 t += 2;
985 p = older;
986 n = 0;
987 do {
988 if ( *m >= 2*MAXPOWER ) {
989 while ( t < xstop ) { *p++ = *t++; *p++ = *t++; n += 2; }
990 nq = n;
991 p = older;
992 while ( nq > 0 ) {
993 if ( !CheckWild(BHEAD *m-2*MAXPOWER,SYMTOSYM,*p,&newval1) ) {
994 mt = p[1]/m[1];
995 if ( mt > 0 ) {
996 if ( power < 0 || mt < power ) power = mt;
997 AddWild(BHEAD *m-2*MAXPOWER,SYMTOSYM,newval1);
998 break;
999 }
1000 }
1001 nq -= 2;
1002 p += 2;
1003 }
1004 if ( nq <= 0 ) return(0);
1005 nq -= 2;
1006 n -= 2;
1007 q = p + 2;
1008 while ( --nq >= 0 ) *p++ = *q++;
1009 m += 2;
1010 }
1011 else if ( t >= xstop ) return(0);
1012 else if ( *m == *t ) {
1013 if ( ( mt = t[1]/m[1] ) <= 0 ) return(0);
1014 if ( power < 0 || mt < power ) power = mt;
1015 m += 2;
1016 t += 2;
1017 }
1018 else if ( *m < *t ) return(0);
1019 else { *p++ = *t++; *p++ = *t++; n += 2; }
1020 } while ( m < ystop );
1021 }
1022/*
1023 #] SYMBOLS :
1024 #[ DOTPRODUCTS :
1025*/
1026 else if ( *m == DOTPRODUCT ) {
1027 ystop = m + m[1];
1028 m += 2;
1029 if ( t >= tstop ) return(0);
1030 while ( *t != DOTPRODUCT ) { t += t[1]; if ( t >= tstop ) return(0); }
1031 xstop = t + t[1];
1032 t += 2;
1033 do {
1034 if ( t >= xstop ) return(0);
1035 if ( *t == *m ) {
1036 if ( t[1] == m[1] ) {
1037 if ( ( mt = t[2]/m[2] ) <= 0 ) return(0);
1038 if ( power < 0 || mt < power ) power = mt;
1039 m += 3;
1040 }
1041 else if ( t[1] > m[1] ) return(0);
1042 }
1043 else if ( *t > *m ) return(0);
1044 t += 3;
1045 } while ( m < ystop );
1046 t = xstop;
1047 }
1048/*
1049 #] DOTPRODUCTS :
1050*/
1051 else {
1052 MLOCK(ErrorMessageLock);
1053 MesPrint("Error in pattern(3)");
1054 MUNLOCK(ErrorMessageLock);
1055 Terminate(-1);
1056 }
1057 } while ( m < mstop ); }
1058 if ( power < 0 ) power = 0;
1059 return(power);
1060}
1061
1062/*
1063 #] FindMulti :
1064 #[ FindRest : WORD FindRest(term,pattern)
1065
1066 This routine scans for anything but dotproducts and symbols.
1067
1068*/
1069
1070WORD FindRest(PHEAD WORD *term, WORD *pattern)
1071{
1072 GETBIDENTITY
1073 WORD *t, *m, *tt, wild, regular;
1074 WORD *tstop, *mstop;
1075 WORD *xstop, *ystop;
1076 WORD n, *p, nq;
1077 WORD older[NORMSIZE], *q, newval1, newval2;
1078 int i, ntwa;
1079 AN.UsedOtherFind = 0;
1080 AN.findTerm = term; AN.findPattern = pattern;
1081 m = AN.WildValue;
1082 i = (m[-SUBEXPSIZE+1]-SUBEXPSIZE)/4;
1083 ntwa = 0;
1084 while ( i > 0 ) {
1085 if ( m[0] == ARGTOARG ) ntwa++;
1086 m += m[1];
1087 i--;
1088 }
1089 t = term;
1090 t += *term - 1;
1091 tstop = t - ABS(*t) + 1;
1092 t = term;
1093 t++; p = t;
1094 while ( t < tstop && *t > DOTPRODUCT ) t += t[1];
1095 tstop = t;
1096 t = p;
1097 m = pattern;
1098 mstop = m + *m;
1099 m++;
1100 p = m;
1101 while ( m < mstop && *m > DOTPRODUCT ) m += m[1];
1102 mstop = m;
1103 m = p;
1104 if ( m < mstop ) {
1105 do {
1106/*
1107 #[ FUNCTIONS :
1108*/
1109 if ( *m >= FUNCTION ) {
1110 if ( *mstop > 5 && !MatchIsPossible(pattern,term) ) return(0);
1111 ystop = m;
1112 n = 0;
1113 do {
1114 m += m[1]; n++;
1115 } while ( m < mstop && *m >= FUNCTION );
1116 AT.WorkPointer += n;
1117 while ( t < tstop && *t == SUBEXPRESSION ) t += t[1];
1118 tt = xstop = t;
1119 nq = 0;
1120 while ( t < tstop && ( *t >= FUNCTION || *t == SUBEXPRESSION ) ) {
1121 if ( *t != SUBEXPRESSION ) {
1122 nq++;
1123 if ( functions[*t-FUNCTION].commute ) tt = t + t[1];
1124 }
1125 t += t[1];
1126 }
1127 if ( nq < n ) return(0);
1128 AN.terstart = term;
1129 AN.terstop = t;
1130 AN.terfirstcomm = tt;
1131 AN.patstop = m;
1132 AN.NumTotWildArgs = ntwa;
1133 if ( !ScanFunctions(BHEAD ystop,xstop,0) ) return(0);
1134 }
1135/*
1136 #] FUNCTIONS :
1137 #[ VECTORS :
1138*/
1139 else if ( *m == VECTOR ) {
1140 while ( t < tstop && *t != VECTOR ) t += t[1];
1141 if ( t >= tstop ) return(0);
1142 xstop = t + t[1];
1143 ystop = m + m[1];
1144 t += 2;
1145 m += 2;
1146 n = 0;
1147 p = older;
1148 do {
1149 if ( *m == *t && m[1] == t[1] && t < xstop ) {
1150 m += 2; t += 2;
1151 }
1152 else if ( *m >= (AM.OffsetVector+WILDOFFSET) ) {
1153 if ( t < xstop ) {
1154 p = older + n;
1155 do { *p++ = *t++; n++; } while ( t < xstop );
1156 }
1157 p = older;
1158 nq = n;
1159 if ( ( m[1] < (AM.OffsetIndex+WILDOFFSET) )
1160 || ( m[1] >= (AM.OffsetIndex+2*WILDOFFSET) ) ) {
1161 while ( nq > 0 ) {
1162 if ( m[1] == p[1] ) {
1163 if ( !CheckWild(BHEAD *m-WILDOFFSET,VECTOVEC,*p,&newval1) ) {
1164RestL11: AddWild(BHEAD *m-WILDOFFSET,VECTOVEC,newval1);
1165 break;
1166 }
1167 }
1168 p += 2;
1169 nq -= 2;
1170 }
1171 }
1172 else { /* Double wildcard */
1173 while ( nq > 0 ) {
1174 if ( !CheckWild(BHEAD *m-WILDOFFSET,VECTOVEC,*p,&newval1) &&
1175 !CheckWild(BHEAD m[1]-WILDOFFSET,INDTOIND,p[1],&newval2) ) {
1176 AddWild(BHEAD m[1]-WILDOFFSET,INDTOIND,newval2);
1177 goto RestL11;
1178 }
1179 p += 2;
1180 nq -= 2;
1181 }
1182 }
1183 if ( nq > 0 ) {
1184 nq -= 2; q = p + 2; n -= 2;
1185 while ( --nq >= 0 ) *p++ = *q++;
1186 }
1187 else return(0);
1188 m += 2;
1189 }
1190 else if ( ( *m <= *t )
1191 && ( m[1] >= (AM.OffsetIndex + WILDOFFSET) )
1192 && ( m[1] < (AM.OffsetIndex + 2*WILDOFFSET) ) ) {
1193 if ( *m == *t && t < xstop ) {
1194 p = older;
1195 p += n;
1196 *p++ = *t++;
1197 *p++ = *t++;
1198 n += 2;
1199 }
1200 p = older;
1201 nq = n;
1202 while ( nq > 0 ) {
1203 if ( *m == *p ) {
1204 if ( !CheckWild(BHEAD m[1]-WILDOFFSET,INDTOIND,p[1],&newval1) ) {
1205 AddWild(BHEAD m[1]-WILDOFFSET,INDTOIND,newval1);
1206 break;
1207 }
1208 }
1209 p += 2;
1210 nq -= 2;
1211 }
1212 if ( nq > 0 ) {
1213 nq -= 2; q = p + 2; n -= 2;
1214 while ( --nq >= 0 ) *p++ = *q++;
1215 }
1216 else return(0);
1217 m += 2;
1218 }
1219 else {
1220 if ( t >= xstop ) return(0);
1221 *p++ = *t++; *p++ = *t++; n += 2;
1222 }
1223 } while ( m < ystop );
1224 }
1225/*
1226 #] VECTORS :
1227 #[ INDICES :
1228*/
1229 else if ( *m == INDEX ) {
1230/*
1231 This needs only to say that there is a match, after matching
1232 a 'wildcard'. This has to be prepared in TestMatch. The C->rhs
1233 should provide the replacement inside the prototype!
1234 Next question: id,p=q/2+r/2
1235*/
1236 while ( *t != INDEX ) { t += t[1]; if ( t >= tstop ) return(0); }
1237 xstop = t + t[1];
1238 ystop = m + m[1];
1239 t += 2;
1240 m += 2;
1241 n = 0;
1242 p = older;
1243 do {
1244 if ( *m == *t && t < xstop && m < ystop ) {
1245 t++; m++;
1246 }
1247 else if ( ( *m >= (AM.OffsetIndex+WILDOFFSET) )
1248 && ( *m < (AM.OffsetIndex+2*WILDOFFSET) ) ) {
1249 while ( t < xstop ) {
1250 *p++ = *t++; n++;
1251 }
1252 if ( !n ) return(0);
1253 nq = n;
1254 q = older;
1255 do {
1256 if ( !CheckWild(BHEAD *m-WILDOFFSET,INDTOIND,*q,&newval1) ) {
1257 AddWild(BHEAD *m-WILDOFFSET,INDTOIND,newval1);
1258 break;
1259 }
1260 q++;
1261 nq--;
1262 } while ( nq > 0 );
1263 if ( nq <= 0 ) return (0);
1264 n--;
1265 nq--;
1266 p = q + 1;
1267 while ( nq > 0 ) { *q++ = *p++; nq--; }
1268 p--;
1269 m++;
1270 }
1271 else if ( ( *m >= (AM.OffsetVector+WILDOFFSET) )
1272 && ( *m < (AM.OffsetVector+2*WILDOFFSET) ) ) {
1273 while ( t < xstop ) {
1274 *p++ = *t++; n++;
1275 }
1276 if ( !n ) return(0);
1277 nq = n;
1278 q = older;
1279 do {
1280 if ( !CheckWild(BHEAD *m-WILDOFFSET,VECTOVEC,*q,&newval1) ) {
1281 AddWild(BHEAD *m-WILDOFFSET,VECTOVEC,newval1);
1282 break;
1283 }
1284 q++;
1285 nq--;
1286 } while ( nq > 0 );
1287 if ( nq <= 0 ) return (0);
1288 n--;
1289 nq--;
1290 p = q + 1;
1291 while ( nq > 0 ) { *q++ = *p++; nq--; }
1292 p--;
1293 m++;
1294 }
1295 else {
1296 if ( t >= xstop ) return(0);
1297 *p++ = *t++; n++;
1298 }
1299 } while ( m < ystop );
1300
1301/*
1302 return(0);
1303*/
1304 }
1305/*
1306 #] INDICES :
1307 #[ DELTAS :
1308*/
1309 else if ( *m == DELTA ) {
1310 while ( *t != DELTA ) { t += t[1]; if ( t >= tstop ) return(0); }
1311 xstop = t + t[1];
1312 ystop = m + m[1];
1313 t += 2;
1314 m += 2;
1315 n = 0;
1316 p = older;
1317 do {
1318 if ( *t == *m && t[1] == m[1] && t < xstop ) {
1319 m += 2;
1320 t += 2;
1321 }
1322 else if ( ( *m >= (AM.OffsetIndex+WILDOFFSET) )
1323 && ( *m < (AM.OffsetIndex+2*WILDOFFSET) )
1324 && ( m[1] >= (AM.OffsetIndex+WILDOFFSET) )
1325 && ( m[1] < (AM.OffsetIndex+2*WILDOFFSET) ) ) { /* Two dummies */
1326 while ( t < xstop ) {
1327 *p++ = *t++; *p++ = *t++; n += 2;
1328 }
1329 if ( !n ) return(0);
1330 nq = n;
1331 q = older;
1332 do {
1333 if ( !CheckWild(BHEAD *m-WILDOFFSET,INDTOIND,*q,&newval1) &&
1334 !CheckWild(BHEAD m[1]-WILDOFFSET,INDTOIND,q[1],&newval2) ) {
1335 AddWild(BHEAD *m-WILDOFFSET,INDTOIND,newval1);
1336 AddWild(BHEAD m[1]-WILDOFFSET,INDTOIND,newval2);
1337 break;
1338 }
1339 if ( !CheckWild(BHEAD *m-WILDOFFSET,INDTOIND,q[1],&newval1) &&
1340 !CheckWild(BHEAD m[1]-WILDOFFSET,INDTOIND,*q,&newval2) ) {
1341 AddWild(BHEAD *m-WILDOFFSET,INDTOIND,newval1);
1342 AddWild(BHEAD m[1]-WILDOFFSET,INDTOIND,newval2);
1343 break;
1344 }
1345 q += 2;
1346 nq -= 2;
1347 } while ( nq > 0 );
1348 if ( nq <= 0 ) return(0);
1349 n -= 2;
1350 nq -= 2;
1351 p = q + 2;
1352 while ( nq > 0 ) { *q++ = *p++; nq--; }
1353 p -= 2;
1354 m += 2;
1355 }
1356 else if ( ( m[1] >= (AM.OffsetIndex+WILDOFFSET) )
1357 && ( m[1] < (AM.OffsetIndex+2*WILDOFFSET) ) ) {
1358 wild = m[1]; regular = *m;
1359OneWild:
1360 while ( ( regular == *t || regular == t[1] ) && t < xstop ) {
1361 *p++ = *t++; *p++ = *t++; n += 2;
1362 }
1363 if ( !n ) return(0);
1364 nq = n;
1365 q = older;
1366 do {
1367 if ( regular == *q && !CheckWild(BHEAD wild-WILDOFFSET,INDTOIND,q[1],&newval1) ) {
1368 AddWild(BHEAD wild-WILDOFFSET,INDTOIND,newval1);
1369 break;
1370 }
1371 if ( regular == q[1] && !CheckWild(BHEAD wild-WILDOFFSET,INDTOIND,*q,&newval1) ) {
1372 AddWild(BHEAD wild-WILDOFFSET,INDTOIND,newval1);
1373 break;
1374 }
1375 q += 2;
1376 nq -= 2;
1377 } while ( nq > 0 );
1378 if ( nq <= 0 ) return(0);
1379 n -= 2;
1380 nq -= 2;
1381 p = q + 2;
1382 while ( nq > 0 ) { *q++ = *p++; nq--; }
1383 p -= 2;
1384 m += 2;
1385 }
1386 else if ( ( *m >= (AM.OffsetIndex+WILDOFFSET) )
1387 && ( *m < (AM.OffsetIndex+2*WILDOFFSET) ) ) {
1388 wild = *m; regular = m[1];
1389 goto OneWild;
1390 }
1391 else {
1392 if ( t >= tstop || *m < *t || ( *m == *t && m[1] < t[1] ) )
1393 return(0);
1394 *p++ = *t++; *p++ = *t++; n += 2;
1395 }
1396 } while ( m < ystop );
1397 }
1398/*
1399 #] DELTAS :
1400*/
1401 else {
1402 MLOCK(ErrorMessageLock);
1403 MesPrint("Pattern not yet implemented");
1404 MUNLOCK(ErrorMessageLock);
1405 Terminate(-1);
1406 }
1407 } while ( m < mstop );
1408 return(1);
1409 }
1410 else return(-1);
1411}
1412
1413/*
1414 #] FindRest :
1415 #] Patterns :
1416*/