FORM  4.1
findpat.c
Go to the documentation of this file.
1 
13 /* #[ License : */
14 /*
15  * Copyright (C) 1984-2013 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 
61 WORD 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 ) {
92 OnlyZer1:
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];
120 OnlyL2: 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 ) {
215 OnlyZer2:
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] ) {
265 OnlyL9: 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] ) {
285 OnlyL10: 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  }
302 NextInDot:
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");
391  MUNLOCK(ErrorMessageLock);
392  Terminate(-1);
393  }
394 EndLoop:;
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 
419 WORD 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 ) {
450 TryZero:
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;
481 OnceL2: 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 ) {
522 OnceL4a: 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 ) {
601 OnceOp:
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;
670 OnceL7: 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 ) ) {
712 OnceL9: AddWild(BHEAD *m-WILDOFFSET,VECTOVEC,newval1);
713  AddWild(BHEAD m[1]-WILDOFFSET,VECTOVEC,newval2);
714  break;
715  }
716  if ( mt >= 2*MAXPOWER ) {
717 OnceL9a: 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 ) ) {
755 OnceL10: AddWild(BHEAD *m-WILDOFFSET,VECTOVEC,newval1);
756  AddWild(BHEAD m[1]-WILDOFFSET,VECTOVEC,newval2);
757  break;
758  }
759  if ( mt >= 2*MAXPOWER ) {
760 OnceL10a: 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  }
792 NextInDot:
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 ) {
821 OnceL7a: 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 ) {
865 OnceL8a: 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");
934  MUNLOCK(ErrorMessageLock);
935  Terminate(-1);
936  }
937 EndLoop:;
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 
954 WORD 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");
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 
1070 WORD 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) ) {
1164 RestL11: 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;
1359 OneWild:
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 */
1417 
#define PHEAD
Definition: ftypes.h:56