• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

form-dev / form / 19064367933

04 Nov 2025 09:42AM UTC coverage: 57.102% (+0.05%) from 57.055%
19064367933

push

github

cbmarini
fix: the float_ functions are now protected from the statements argument, normalize, makeinteger, splitarg, factarg and argtoextrasymbol.
 - these functions make use of the same compiler function DoArgument and execarg during execution, so the fix is universal.
 - added a test for this.

8 of 12 new or added lines in 2 files covered. (66.67%)

845 existing lines in 2 files now uncovered.

47130 of 82537 relevant lines covered (57.1%)

5678695.64 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

76.87
/sources/function.c
1
/** @file function.c
2
 * 
3
 *  The file with the central routines for the pattern matching of
4
 *        functions and their arguments.
5
 *        The file also contains the routines for the execution of the
6
 *        Symmetrize statement and its variations (like antisymmetrize etc).
7
 */
8
/* #[ License : */
9
/*
10
 *   Copyright (C) 1984-2023 J.A.M. Vermaseren
11
 *   When using this file you are requested to refer to the publication
12
 *   J.A.M.Vermaseren "New features of FORM" math-ph/0010025
13
 *   This is considered a matter of courtesy as the development was paid
14
 *   for by FOM the Dutch physics granting agency and we would like to
15
 *   be able to track its scientific use to convince FOM of its value
16
 *   for the community.
17
 *
18
 *   This file is part of FORM.
19
 *
20
 *   FORM is free software: you can redistribute it and/or modify it under the
21
 *   terms of the GNU General Public License as published by the Free Software
22
 *   Foundation, either version 3 of the License, or (at your option) any later
23
 *   version.
24
 *
25
 *   FORM is distributed in the hope that it will be useful, but WITHOUT ANY
26
 *   WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
27
 *   FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
28
 *   details.
29
 *
30
 *   You should have received a copy of the GNU General Public License along
31
 *   with FORM.  If not, see <http://www.gnu.org/licenses/>.
32
 */
33
/* #] License : */ 
34
/*
35
          #[ Includes : function.c
36
*/
37

38
#include "form3.h"
39

40
/*
41
          #] Includes : 
42
         #[ Utilities :
43
                 #[ MakeDirty :
44

45
                Routine finds the function with the address x in it
46
                and mark all arguments that contain x as dirty.
47
                if par == 0 term is a full term, else term is the start of a 
48
                function
49
*/
50

51
int MakeDirty(WORD *term, WORD *x, WORD par)
24✔
52
{
53
        WORD *next, *n;
24✔
54
        if ( !par ) {
24✔
55
                next = term; next += *term;
×
56
                next -= ABS(next[-1]);
×
57
                term++;
×
58
                if ( x < term ) return(0);
×
59
                if ( x >= next ) return(0);
×
60
                while ( term < next ) {
×
61
                        n = term + term[1];
×
62
                        if ( x < n ) break;
×
63
                        term = n;
64
                }
65
/*                next = n; */
66
        }
67
        else {
68
                next = term + term[1];
24✔
69
                if ( x < term || x >= next ) return(0);
24✔
70
        }
71
        if ( *term < FUNCTION ) return(0);
24✔
72
        if ( functions[*term-FUNCTION].spec >= TENSORFUNCTION ) return(0);
24✔
73
        term += FUNHEAD;
24✔
74
        if ( x < term ) return(0);
24✔
75
        next = term; NEXTARG(next)
24✔
76
        while ( x >= next ) { term = next; NEXTARG(next) }
24✔
77
        if ( *term < 0 ) return(0);
24✔
78
        term[1] = 1;
×
79
        term += ARGHEAD;
×
80
        if ( x < term ) return(1);
×
81
        next = term + *term;
×
82
        while ( x >= next ) { term = next; next += *next; }
×
83
        MakeDirty(term,x,0);
×
84
        return(1);
×
85
}
86

87
/*
88
                 #] MakeDirty : 
89
                 #[ MarkDirty :
90

91
                Routine marks all functions dirty with the given flags.
92
                Is to be used when there is a possibility that symmetrization
93
                properties of functions may have changed. In that case we play
94
                it safe.
95
*/
96

97
void MarkDirty(WORD *term, WORD flags)
816✔
98
{
99
        WORD *t, *r, *m, *tstop;
816✔
100
        GETSTOP(term,tstop);
816✔
101
        t = term+1;
816✔
102
        while ( t < tstop ) {
1,788✔
103
                if ( *t < FUNCTION ) { t += t[1]; continue; }
972✔
104
                t[2] |= flags;
456✔
105
                if ( *t < FUNCTION+WILDOFFSET && functions[*t-FUNCTION].spec > 0 ) {
456✔
106
                        t += t[1]; continue;
48✔
107
                }
108
                if ( *t >= FUNCTION+WILDOFFSET && functions[*t-FUNCTION-WILDOFFSET].spec > 0 ) {
408✔
109
                        t += t[1]; continue;
×
110
                }
111
                r = t + FUNHEAD;
408✔
112
                t += t[1];
408✔
113
                while ( r < t ) {
1,146✔
114
                        if ( *r <= 0 ) {
738✔
115
                                if ( *r <= -FUNCTION ) r++;
618✔
116
                                else r += 2;
606✔
117
                                continue;
618✔
118
                        }
119
                        r[1] |= DIRTYFLAG;
120✔
120
                        m = r + ARGHEAD;
120✔
121
                        r += *r;
120✔
122
                        while ( m < r ) {
270✔
123
                                MarkDirty(m,flags);
150✔
124
                                m += *m;
150✔
125
                        }
126
                }
127
        }
128
}
816✔
129

130
/*
131
                 #] MarkDirty : 
132
                 #[ PolyFunDirty :
133

134
                Routine marks the PolyFun or the PolyRatFun dirty.
135
                This is used when there is modular calculus and the modulus
136
                has changed for the current module.
137
*/
138

139
void PolyFunDirty(PHEAD WORD *term)
757,710✔
140
{
141
        GETBIDENTITY
142
        WORD *t, *tstop, *endarg;
757,710✔
143
        tstop = term + *term;
757,710✔
144
        tstop -= ABS(tstop[-1]);
757,710✔
145
        t = term+1;
757,710✔
146
        while ( t < tstop ) {
2,249,730✔
147
                if ( *t == AR.PolyFun ) {
1,492,020✔
148
                        if ( AR.PolyFunType == 2 ) t[2] |= MUSTCLEANPRF;
34,038✔
149
                        endarg = t + t[1];
34,038✔
150
                        t[2] |= DIRTYFLAG;
34,038✔
151
                        t += FUNHEAD;
34,038✔
152
                        while ( t < endarg ) {
34,038✔
153
                                if ( *t > 0 ) {
52,800✔
154
                                        t[1] |= DIRTYFLAG;
50,646✔
155
                                }
156
                                NEXTARG(t);
139,638✔
157
                        }
158
                }
159
                else {
160
                        t += t[1];
1,457,982✔
161
                }
162
        }
163
}
757,710✔
164

165
/*
166
                 #] PolyFunDirty : 
167
                 #[ PolyFunClean :
168

169
                Routine marks the PolyFun or the PolyRatFun clean.
170
                This is used when there is modular calculus and the modulus
171
                has changed for the current module.
172
*/
173

174
void PolyFunClean(PHEAD WORD *term)
3,002,736✔
175
{
176
        GETBIDENTITY
177
        WORD *t, *tstop;
3,002,736✔
178
        tstop = term + *term;
3,002,736✔
179
        tstop -= ABS(tstop[-1]);
3,002,736✔
180
        t = term+1;
3,002,736✔
181
        while ( t < tstop ) {
14,860,914✔
182
                if ( *t == AR.PolyFun ) {
11,858,178✔
183
                        t[2] &= ~MUSTCLEANPRF;
2,996,742✔
184
                }
185
                t += t[1];
11,858,178✔
186
        }
187
}
3,002,736✔
188

189
/*
190
                 #] PolyFunClean : 
191
                 #[ Symmetrize :
192

193
                (Anti)Symmetrizes the arguments of a function. 
194
                Nlist tells of how many arguments are involved.
195
                Nlist == 0                All arguments must be sorted.
196
                Nlist > 0                Arguments mentioned are to be sorted, rest skipped.
197
                type = SYMMETRIC       Full symmetrization
198
                type = ANTISYMMETRIC:  Full symmetrization
199
                type = CYCLESYMMETRIC: Cyclic
200
                type = RCYCLESYMMETRIC:Cyclic or reverse
201
                Return value: OR of:
202
                        0 even, 1 odd
203
                        2 equal groups
204
                        4 there was a permutation.
205

206
                The information in Lijst tells what grouping is to be applied.
207
                The information is:
208
                ngroups number of groups
209
                gsize size of groups
210
                Lijst[0]....  The groups.
211
*/
212

213
WORD Symmetrize(PHEAD WORD *func, WORD *Lijst, WORD ngroups, WORD gsize,
260,868✔
214
                WORD type)
215
{
216
        GETBIDENTITY
217
        WORD **args,**arg,nargs;
260,868✔
218
        WORD *to, *r, *fstop;
260,868✔
219
        WORD i, j, k, ff, exch, nexch, neq;
260,868✔
220
        WORD *a1, *a2, *a3;
260,868✔
221
        WORD reverseorder;
260,868✔
222
        if ( ( type & REVERSEORDER ) != 0 ) reverseorder = -1;
260,868✔
223
        else                                reverseorder = 1;
260,868✔
224
        type &= ~REVERSEORDER;
260,868✔
225

226
        ff = ( *func > FUNCTION ) ? functions[*func-FUNCTION].spec: 0;
260,868✔
227

228
        if ( 2*func[1] > AN.arglistsize ) {
260,868✔
229
                if ( AN.arglist ) M_free(AN.arglist,"Symmetrize");
241✔
230
                AN.arglistsize = 2*func[1] + 8;
241✔
231
                AN.arglist = (WORD **)Malloc1(AN.arglistsize*sizeof(WORD *),"Symmetrize");
241✔
232
        }
233
        arg = args = AN.arglist;
260,868✔
234
        to = AT.WorkPointer;
260,868✔
235
        r = func;
260,868✔
236
        fstop = r + r[1];
260,868✔
237
        r += FUNHEAD;
260,868✔
238
        nargs = 0;
260,868✔
239
        while ( r < fstop ) {        /* Make list of arguments */
260,868✔
240
                *arg++ = r;
846,990✔
241
                nargs++;
846,990✔
242
                if ( ff ) {
846,990✔
243
                        if ( *r == FUNNYWILD ) r++;
205,446✔
244
                        r++;
205,446✔
245
                }
246
                else { NEXTARG(r); }
1,749,402✔
247
        }
248
        exch = 0;
260,868✔
249
        nexch = 0;
260,868✔
250
        neq = 0;
260,868✔
251
        a1 = Lijst;
260,868✔
252
        if ( type == SYMMETRIC || type == ANTISYMMETRIC ) {
260,868✔
253
        for ( i = 1; i < ngroups; i++ ) {
792,180✔
254
                a3 = a2 = a1 + gsize;
543,504✔
255
                k = reverseorder*CompGroup(BHEAD ff,args,a1,a2,gsize);
543,504✔
256
                if ( k < 0 ) {
543,504✔
257
                        j = i-1;
88,530✔
258
                        for(;;) {
203,394✔
259
                                for ( k = 0; k < gsize; k++ ) {
291,924✔
260
                                        r = args[a1[k]]; args[a1[k]] = args[a2[k]]; args[a2[k]] = r;
145,962✔
261
                                }
262
                                exch ^= 1;
145,962✔
263
                                nexch = 4;
145,962✔
264
                                if ( j <= 0 ) break;
145,962✔
265
                                a1 -= gsize;
81,585✔
266
                                a2 -= gsize;
81,585✔
267
                                k = reverseorder*CompGroup(BHEAD ff,args,a1,a2,gsize);
81,585✔
268
                                if ( k == 0 ) neq = 2;
81,585✔
269
                                if ( k >= 0 ) break;
81,273✔
270
                                j--;
57,432✔
271
                        }
272
                }
273
                else if ( k == 0 ) neq = 2;
454,974✔
274
                a1 = a3;
543,504✔
275
        }
276
        }
277
        else if ( type == CYCLESYMMETRIC || type == RCYCLESYMMETRIC ) {
12,192✔
278
                WORD rev = 0, jmin = 0, ii, iimin;
279
recycle:
12,192✔
280
                for ( j = 1; j < ngroups; j++ ) {
54,810✔
281
                        for ( i = 0; i < ngroups; i++ ) {
53,046✔
282
                                iimin = jmin + i;
51,636✔
283
                                if ( iimin >= ngroups ) iimin -= ngroups;
51,636✔
284
                                ii = j + i;
51,636✔
285
                                if ( ii >= ngroups ) ii -= ngroups;
51,636✔
286
                                k = reverseorder*CompGroup(BHEAD ff,args,Lijst+gsize*iimin,Lijst+gsize*ii,gsize);
51,636✔
287
                                if ( k > 0 ) break;
51,636✔
288
                                if ( k < 0 ) { jmin = j; nexch = 4; break; }
12,372✔
289
                        }
290
                }
291
                if ( type == RCYCLESYMMETRIC && rev == 0 && ngroups > 1 ) {
12,192✔
292
                        for ( j = 0; j < ngroups; j++ ) {
×
293
                                for ( i = 0; i < ngroups; i++ ) {
×
294
                                        iimin = jmin + i;
×
295
                                        if ( iimin >= ngroups ) iimin -= ngroups;
×
296
                                        ii = j - i;
×
297
                                        if ( ii < 0 ) ii += ngroups;
×
298
                                        k = reverseorder*CompGroup(BHEAD ff,args,Lijst+gsize*iimin,Lijst+gsize*ii,gsize);
×
299
                                        if ( k > 0 ) break;
×
300
                                        if ( k < 0 ) {
×
301
                                                nexch = 4;
×
302
                                                jmin = 0;
×
303
                                                a1 = Lijst;
×
304
                                                a2 = Lijst + gsize * (ngroups-1);
×
305
                                                while ( a2 > a1 ) {
×
306
                                                        for ( k = 0; k < gsize; k++ ) {
×
307
                                                                r = args[a1[k]];
×
308
                                                                args[a1[k]] = args[a2[k]];
×
309
                                                                args[a2[k]] = r;
×
310
                                                        }
311
                                                        a1 += gsize; a2 -= gsize;
×
312
                                                }
313
                                                rev = 1;
×
314
                                                goto recycle;
×
315
                                        }
316
                                }
317
                        }
318
                }
319
                if ( jmin != 0 ) {
12,192✔
320
                        arg = AN.arglist + func[1];
1,386✔
321
                        a1 = Lijst + gsize * jmin;
1,386✔
322
                        k = gsize * ngroups;
1,386✔
323
                        a2 = Lijst + k;
1,386✔
324
                        for ( i = 0; i < k; i++ ) {
7,344✔
325
                                if ( a1 >= a2 ) a1 = Lijst;
5,958✔
326
                                *arg++ = args[*a1++];
5,958✔
327
                        }
328
                        arg = AN.arglist + func[1];
1,386✔
329
                        a1 = Lijst;
1,386✔
330
                        for ( i = 0; i < k; i++ ) args[*a1++] = *arg++;
7,344✔
331
                }
332
        }
333
        r = func;
260,868✔
334
        i = FUNHEAD;
260,868✔
335
        NCOPY(to,r,i);
1,043,472✔
336
        for ( i = 0; i < nargs; i++ ) {
1,107,858✔
337
                if ( ff ) {
846,990✔
338
                        if ( *(args[i]) == FUNNYWILD ) {
205,446✔
339
                                *to++ = *(args[i]);
1,632✔
340
                                *to++ = args[i][1];
1,632✔
341
                        }
342
                        else *to++ = *(args[i]);
203,814✔
343
                }
344
                else if ( ( j = *args[i] ) < 0 ) {
641,544✔
345
                        *to++ = j;
641,424✔
346
                        if ( j > -FUNCTION ) *to++ = args[i][1];
641,424✔
347
                }
348
                else {
349
                        r = args[i];
350
                        NCOPY(to,r,j);
855,294✔
351
                }
352
        }
353
        i = func[1];
260,868✔
354
        to = func;
260,868✔
355
        r = AT.WorkPointer;
260,868✔
356
        NCOPY(to,r,i);
2,541,702✔
357
        return ( exch | nexch | neq );
260,868✔
358
}
359

360
/*
361
                 #] Symmetrize : 
362
                 #[ CompGroup :
363

364
                        Routine compares two groups of arguments
365
                        The arguments are in args[a1[i]] and args[a2[i]]
366
                        for i = 0 to num
367
                        type indicates the type of function.
368
                        return value: -1 if there should be an exchange
369
                        0 if they are equal
370
                        1 if they are OK.
371
*/
372

373
int CompGroup(PHEAD WORD type, WORD **args, WORD *a1, WORD *a2, WORD num)
676,725✔
374
{
375
        GETBIDENTITY
376
        WORD *t1, *t2, i1, i2, n, k;
676,725✔
377

378
        for ( n = 0; n < num; n++ ) {
689,763✔
379
                t1 = args[a1[n]]; t2 = args[a2[n]];
676,725✔
380
                if ( type >= TENSORFUNCTION ) {
676,725✔
381
                        if ( AR.Eside == LHSIDE || AR.Eside == LHSIDEX ) {
162,336✔
382
                                if ( *t1 == FUNNYWILD ) {
47,682✔
383
                                        if ( *t2 == FUNNYWILD ) {
270✔
384
                                                if ( t1[1] < t2[1] ) return(1);
270✔
385
                                                if ( t1[1] > t2[1] ) return(-1);
×
386
                                        }
387
                                        return(-1);
388
                                }
389
                                else if ( *t2 == FUNNYWILD ) {
47,412✔
390
                                        return(1);
391
                                }
392
                                else {
393
                                        if ( *t1 < *t2 ) return(1);
45,186✔
394
                                        if ( *t1 > *t2 ) return(-1);
3,198✔
395
                                }
396
                        }
397
                        else {
398
                                if ( *t1 < *t2 ) return(1);
114,654✔
399
                                if ( *t1 > *t2 ) return(-1);
26,232✔
400
                        }
401
                }
402
                else if ( type == 0 ) {
514,389✔
403
                        if ( AC.properorderflag ) {
514,389✔
404
                                k = CompArg(t1,t2);
×
405
                                if ( k < 0 ) return(1);
×
406
                                if ( k > 0 ) return(-1);
×
407
                                NEXTARG(t1)
×
408
                                NEXTARG(t2)
13,038✔
409
                        }
410
                        else {
411
                                if ( *t1 > 0 ) {
514,389✔
412
                                        i1 = *t1 - ARGHEAD - 1;
1,455✔
413
                                        t1 += ARGHEAD + 1;
1,455✔
414
                                        if ( *t2 > 0 ) {
1,455✔
415
                                                i2 = *t2 - ARGHEAD - 1;
105✔
416
                                                t2 += ARGHEAD + 1;
105✔
417
                                                while ( i1 > 0 && i2 > 0 ) {
630✔
418
                                                        if ( *t1 > *t2 ) return(-1);
618✔
419
                                                        else if ( *t1 < *t2 ) return(1);
558✔
420
                                                        i1--; i2--; t1++; t2++;
525✔
421
                                                }
422
                                                if ( i1 > 0 ) return(-1);
12✔
423
                                                else if ( i2 > 0 ) return(1);
12✔
424
                                        }
425
/*
426
                                        This seems to be a bug. Reported by Aneesh Monahar, 28-sep-2005
427
                                        else return(1);
428
*/
429
                                        else return(-1);
430
                                }
431
                                else if ( *t2 > 0 ) return(1);
512,934✔
432
                                else {
433
                                        if ( *t1 != *t2 ) {
512,916✔
434
                                                if ( *t1 <= -FUNCTION && *t2 <= -FUNCTION ) {
4,260✔
435
                                                        if ( *t1 < *t2 ) return(-1);
×
436
                                                        return(1);
×
437
                                                }
438
                                                else {
439
                                                        if ( *t1 < *t2 ) return(1);
4,260✔
440
                                                        return(-1);
612✔
441
                                                }
442
                                        }
443
                                        if ( *t1 > -FUNCTION ) {
508,656✔
444
                                                if ( t1[1] != t2[1] ) {
508,656✔
445
                                                        if ( t1[1] < t2[1] ) return(1);
506,700✔
446
                                                        return(-1);
127,530✔
447
                                                }
448
                                        }
449
                                }
450
                        }
451
                }
452
        }
453
        return(0);
454
}
455

456
/*
457
                 #] CompGroup : 
458
                 #[ FullSymmetrize :
459

460
                Relay function for Normalize to execute a full symmetrization
461
                of a function fun. It hooks into Symmetrize according to the
462
                calling conventions for it.
463
                type = 0: Symmetrize
464
                type = 1: AntiSymmetrize
465
                type = 2: CycleSymmetrize
466
                type = 3: RCycleSymmetrize
467
                Return values:
468
                bit 0: odd permutation
469
                bit 1: identical arguments
470
                bit 2: there was a permutation.
471
*/
472

473
int FullSymmetrize(PHEAD WORD *fun, int type)
272,478✔
474
{
475
        GETBIDENTITY
476
        WORD *Lijst, count = 0;
272,478✔
477
        WORD *t, *funstop, i;
272,478✔
478
        int retval;
272,478✔
479

480
        if ( functions[*fun-FUNCTION].spec > 0 ) {
272,478✔
481
                count = fun[1] - FUNHEAD;
60,666✔
482
                for ( i = fun[1]-1; i >= FUNHEAD; i-- ) {
267,948✔
483
                        if ( fun[i] == FUNNYWILD ) count--;
207,282✔
484
                }
485
        }
486
        else {
487
                funstop = fun + fun[1];
211,812✔
488
                t = fun + FUNHEAD;
211,812✔
489
                while ( t < funstop ) { count++; NEXTARG(t) }
858,234✔
490
        }
491
        if ( count < 2 ) {
272,478✔
492
                fun[2] &= ~DIRTYSYMFLAG;
13,350✔
493
                return(0);
13,350✔
494
        }
495
        Lijst = AT.WorkPointer;
259,128✔
496
        for ( i = 0; i < count; i++ ) Lijst[i] = i;
1,098,948✔
497
        AT.WorkPointer += count;
259,128✔
498
        retval = Symmetrize(BHEAD fun,Lijst,count,1,type);
259,128✔
499
        fun[2] &= ~DIRTYSYMFLAG;
259,128✔
500
        AT.WorkPointer = Lijst;
259,128✔
501
        return(retval);
259,128✔
502
}
503

504
/*
505
                 #] FullSymmetrize : 
506
                 #[ SymGen :
507

508
                Routine does the outer work in the symmetrization.
509
                It locates the function(s) and loads up the parameters.
510
                It also studies the result.
511

512
                if params[4] = -1 and no extra -> all
513
                                      extra -> strip groups with elements too large
514
                               0  -> if group with element too large: nofun
515
                                           >0 -> must have right number of arguments
516
*/
517

518
int SymGen(PHEAD WORD *term, WORD *params, WORD num, WORD level)
240✔
519
{
520
        GETBIDENTITY
521
        WORD *t, *r, *m;
240✔
522
        WORD i, j, k, c1, c2, ngroup;
240✔
523
        WORD *rstop, Nlist, *inLijst, *Lijst, sign = 1, sumch = 0, count;
240✔
524
        DUMMYUSE(num);
240✔
525
        c1 = params[3];                /* function number */
240✔
526
        c2 = FUNCTION + WILDOFFSET;
240✔
527
        Nlist = params[4];
240✔
528
        if ( Nlist < 0 ) Nlist = 0;
240✔
529
        else Nlist = params[0] - 7;
240✔
530
        t = term;
240✔
531
        m = t + *t;
240✔
532
        m -= ABS(m[-1]);
240✔
533
        t++;
240✔
534
        while ( t < m ) {
7,440✔
535
                if ( *t == c1 || c1 > c2 ) {        /* Candidate function */
7,200✔
536
                        if ( *t >= FUNCTION && functions[*t-FUNCTION].spec
1,656✔
537
                        >= TENSORFUNCTION ) {
538
                                count = t[1] - FUNHEAD;
×
539
                        }
540
                        else {
541
                                count = 0;
1,656✔
542
                                r = t;
1,656✔
543
                                rstop = t + t[1];
1,656✔
544
                                r += FUNHEAD;
1,656✔
545
                                while ( r < rstop ) { count++; NEXTARG(r) }
8,256✔
546
                        }
547
                        if ( ( j = params[4] ) > 0 && j != count ) goto NextFun;
1,656✔
548
                        if ( j == 0 ) {
1,656✔
549
                                inLijst = params+7;
1,656✔
550
                                for ( i = 0; i < Nlist; i++ )
1,656✔
551
                                        if ( inLijst[i] > count-1 ) goto NextFun;
×
552
                        }
553

554
                        if ( Nlist > (params[0] - 7) ) Nlist = params[0] - 7;
1,656✔
555
                        Lijst = AT.WorkPointer;
1,656✔
556
                        inLijst = params + 7;
1,656✔
557
                        ngroup = params[5];
1,656✔
558
                        if ( Nlist > 0 && j < 0 ) {
1,656✔
559
                                k = 0;
560
                                for ( i = 0; i < ngroup; i++ ) {
×
561
                                        for ( j = 0; j < params[6]; j++ ) {
×
562
                                                if ( inLijst[j] > count+1 ) {
×
563
                                                        inLijst += params[6];
×
564
                                                        goto NextGroup;
×
565
                                                }
566
                                        }
567
                                        j = params[6];
568
                                        NCOPY(Lijst,inLijst,j);
×
569
                                        k++;
×
570
NextGroup:;
×
571
                                }
572
                                if ( k <= 1 ) goto NextFun;
×
573
                                ngroup = k;
×
574
                                inLijst = AT.WorkPointer;
×
575
                                AT.WorkPointer = Lijst;
×
576
                                Lijst = inLijst;
×
577
                        }
578
                        else if ( Nlist == 0 ) {
1,656✔
579
                                for ( i = 0; i < count; i++ ) Lijst[i] = i;
8,256✔
580
                                AT.WorkPointer += count;
1,656✔
581
                                ngroup = count;
1,656✔
582
                        }
583
                        else {
584
                                for ( i = 0; i < Nlist; i++ ) Lijst[i] = inLijst[i];
×
585
                                AT.WorkPointer += Nlist;
×
586
                        }
587
                        j = Symmetrize(BHEAD t,Lijst,ngroup,params[6],params[2]);
1,656✔
588
                        AT.WorkPointer = Lijst;
1,656✔
589
                        if ( params[2] == 4 ) { /* antisymmetric */
1,656✔
590
                                if ( ( j & 1 ) != 0 ) sign = -sign;
×
591
                                if ( ( j & 2 ) != 0 ) return(0); /* equal arguments */
×
592
                        }
593
                        if ( ( j & 4 ) != 0 ) sumch++;
1,656✔
594
                        t[2] &= ~DIRTYSYMFLAG;
1,656✔
595
                }
596
NextFun:
5,544✔
597
                t += t[1];
7,200✔
598
        }
599
        if ( sign < 0 ) {
240✔
600
                t = term;
×
601
                t += *t - 1;
×
602
                *t = -*t;
×
603
        }
604
        if ( sumch ) {
240✔
605
                if ( Normalize(BHEAD term) ) {
228✔
606
                        MLOCK(ErrorMessageLock);
×
607
                        MesCall("SymGen");
×
608
                        MUNLOCK(ErrorMessageLock);
×
609
                        return(-1);
×
610
                }
611
                if ( !*term ) return(0);
228✔
612
                *AN.RepPoint = 1;
228✔
613
                AR.expchanged = 1;
228✔
614
                if ( AR.CurDum > AM.IndDum && AR.sLevel <= 0 ) ReNumber(BHEAD term);
228✔
615
        }
616
        return(Generator(BHEAD term,level));
240✔
617
}
618

619
/*
620
                 #] SymGen : 
621
                 #[ SymFind :
622

623
                There is a certain amount of double work here, as this routine
624
                finds the function to be treated, while the SymGen routine has
625
                to find it again. Note however that this way things remain
626
                uniform and simple. Moreover this avoids problems with actions
627
                on more than one function simultaneously.
628
                Output in AT.TMout:
629
                Number,sym/anti,fun,lenpar,ngroups,gsize,fields
630

631
*/
632

633
int SymFind(PHEAD WORD *term, WORD *params)
780✔
634
{
635
        GETBIDENTITY
636
        WORD *t, *r, *m;
780✔
637
        WORD j, c1, c2, count;
780✔
638
        WORD *rstop;
780✔
639
        c1 = params[4];                /* function number */
780✔
640
        c2 = FUNCTION + WILDOFFSET;
780✔
641
        t = term;
780✔
642
        m = t + *t;
780✔
643
        m -= ABS(m[-1]);
780✔
644
        t++;
780✔
645
        while ( t < m ) {
5,952✔
646
                if ( *t == c1 || c1 > c2 ) {        /* Candidate function */
5,412✔
647
                        if ( *t >= FUNCTION && functions[*t-FUNCTION].spec
240✔
648
                                >= TENSORFUNCTION ) { count = t[1] - FUNHEAD; }
×
649
                        else {
650
                                count = 0;
240✔
651
                                r = t;
240✔
652
                                rstop = t + t[1];
240✔
653
                                r += FUNHEAD;
240✔
654
                                while ( r < rstop ) { count++; NEXTARG(r) }
1,152✔
655
                        }
656
                        if ( ( j = params[5] ) > 0 && j != count ) goto NextFun;
240✔
657
                        if ( j == 0 ) {
240✔
658
                                r = params + 8;
240✔
659
                                rstop = params + params[1];
240✔
660
                                while ( r < rstop ) {
240✔
661
                                        if ( *r > count + 1 ) goto NextFun;
×
662
                                        r++;
×
663
                                }
664
                        }
665
                        
666
                        t = AT.TMout;
240✔
667
                        r = params;
240✔
668
                        j = r[1] - 1;
240✔
669
                        *t++ = j;
240✔
670
                        *t++ = SYMMETRIZE;
240✔
671
                        r += 3;
240✔
672
                        j--;
240✔
673
                        NCOPY(t,r,j);
1,680✔
674
                        return(1);
675
                }
676
NextFun:
5,172✔
677
                t += t[1];
5,172✔
678
        }
679
        return(0);
680
}
681

682
/*
683
                 #] SymFind : 
684
                 #[ ChainIn :
685

686
                Equivalent to repeat id f(?a)*f(?b) = f(?a,?b);
687

688
                This one always takes less space.
689
*/
690

691
int ChainIn(PHEAD WORD *term, WORD funnum)
258✔
692
{
693
        GETBIDENTITY
694
        WORD *t, *tend, *m, *tt, *ts;
258✔
695
        int action, normFlag = 0;
258✔
696
        if ( funnum < 0 ) {        /* Dollar to be expanded */
258✔
697
                funnum = DolToFunction(BHEAD -funnum);
×
698
                if ( AN.ErrorInDollar || funnum <= 0 ) {
×
699
                        MLOCK(ErrorMessageLock);
×
700
                        MesPrint("Dollar variable does not evaluate to function in ChainIn statement");
×
701
                        MUNLOCK(ErrorMessageLock);
×
702
                        return(-1);
×
703
                }
704
        }
705
        do {
444✔
706
                action = 0;
444✔
707
                tend = term+*term;
444✔
708
                tend -= ABS(tend[-1]);
444✔
709
                t = term+1;
444✔
710
                while ( t < tend ) {
942✔
711
                        if ( *t != funnum ) { t += t[1]; continue; }
684✔
712
                        m = t;
438✔
713
                        t += t[1];
438✔
714
                        tt = t;
438✔
715
                        if ( t >= tend || *t != funnum ) continue;
438✔
716
                        action = 1;
444✔
717
                        normFlag = 1;
444✔
718
                        while ( t < tend && *t == funnum ) {
444✔
719
                                ts = t + t[1];
258✔
720
                                t += FUNHEAD;
258✔
721
                                while ( t < ts ) *tt++ = *t++;
774✔
722
                        }
723
                        m[1] = tt - m;
186✔
724
                        ts = term + *term;
186✔
725
                        while ( t < ts ) *tt++ = *t++;
2,724✔
726
                        *term = tt - term;
186✔
727
                        break;
186✔
728
                }
729
        } while ( action );
444✔
730

731
        if ( normFlag ) {
258✔
732
                /* We need to check the newly-constructed arguments w.r.t symmetry properties */
733
                MarkDirty(term, DIRTYSYMFLAG);
186✔
734
                AT.WorkPointer = term + *term;
186✔
735
                Normalize(BHEAD term);
186✔
736
        }
737

738
        return(0);
739
}
740

741
/*
742
                 #] ChainIn : 
743
                 #[ ChainOut :
744

745
                Equivalent to repeat id f(x1?,x2?,?a) = f(x1)*f(x2,?a);
746
*/
747

748
int ChainOut(PHEAD WORD *term, WORD funnum)
1,548✔
749
{
750
        GETBIDENTITY
751
        WORD *t, *tend, *tt, *ts, *w, *ws;
1,548✔
752
        int flag = 0, i;
1,548✔
753
        if ( funnum < 0 ) {        /* Dollar to be expanded */
1,548✔
754
                funnum = DolToFunction(BHEAD -funnum);
×
755
                if ( AN.ErrorInDollar || funnum <= 0 ) {
×
756
                        MLOCK(ErrorMessageLock);
×
757
                        MesPrint("Dollar variable does not evaluate to function in ChainOut statement");
×
758
                        MUNLOCK(ErrorMessageLock);
×
759
                        return(-1);
×
760
                }
761
        }
762
        tend = term+*term;
1,548✔
763
        if ( AT.WorkPointer < tend ) AT.WorkPointer = tend;
1,548✔
764
        tend -= ABS(tend[-1]);
1,548✔
765
        t = term+1; tt = term; w = AT.WorkPointer;
1,548✔
766
        while ( t < tend ) {
3,096✔
767
                if ( *t != funnum || t[1] == FUNHEAD ) { t += t[1]; continue; }
1,548✔
768
                flag = 1;
36✔
769
                while ( tt < t ) *w++ = *tt++;
36✔
770
                ts = t + t[1];
18✔
771
                t += FUNHEAD;
18✔
772
                while ( t < ts ) {
414✔
773
                        ws = w;
774
                        for ( i = 0; i < FUNHEAD; i++ ) *w++ = tt[i];
1,584✔
775
                        if ( functions[*tt-FUNCTION].spec >= TENSORFUNCTION ) {
396✔
776
                                *w++ = *t++;
×
777
                        }
778
                        else if ( *t < 0 ) {
396✔
779
                                if ( *t <= -FUNCTION ) *w++ = *t++;
342✔
780
                                else { *w++ = *t++; *w++ = *t++; }
342✔
781
                        }
782
                        else {
783
                                i = *t; NCOPY(w,t,i);
3,738✔
784
                        }
785
                        ws[1] = w - ws;
396✔
786
                }
787
                tt = t;
788
        }
789
        if ( flag == 1 ) {
1,548✔
790
                ts = term + *term;
18✔
791
                while ( tt < ts ) *w++ = *tt++;
72✔
792
                *AT.WorkPointer = w - AT.WorkPointer;
18✔
793
                t = term; w = AT.WorkPointer; i = *w;
18✔
794
                NCOPY(t,w,i)
5,646✔
795
                AT.WorkPointer = term + *term;
18✔
796
                Normalize(BHEAD term);
18✔
797
        }
798
        return(0);
799
}
800

801
/*
802
                 #] ChainOut : 
803
          #] Utilities : 
804
        #[ Patterns :
805
                 #[ MatchFunction :                        WORD MatchFunction(pattern,interm,wilds)
806

807
                The routine assumes that the function numbers are the same.
808
                The contents are compared and a possible wildcard assignment
809
                is made. Note that it may be necessary to use a wildcard
810
                assignment stack to do things right.
811
                The routine can become arbitrarily complicated as there is
812
                no end to the possible wildcarding.
813
                Examples:
814
                -        a:        No wildcarding -> straight match
815
                -        b:        Individual arguments (object -> object)
816
                -        c:        whole arguments (object to subexpression)
817
                -        d:        any argumentlist
818
                        e:        part of an argument (object inside subexpression)
819

820
                The ones with a minus sign in front have been implemented.
821

822
                Note: the argument wilds allows backtracking when multiple
823
                ?a,?b give a match that later turns out to be useless.
824
*/
825

826
int MatchFunction(PHEAD WORD *pattern, WORD *interm, WORD *wilds)
33,764,094✔
827
{
828
        GETBIDENTITY
829
        WORD *m, *t, *r, i;
33,764,094✔
830
        WORD *mstop = 0, *tstop = 0;
33,764,094✔
831
        WORD *argmstop, *argtstop;
33,764,094✔
832
        WORD *mtrmstop, *ttrmstop;
33,764,094✔
833
        WORD *msubstop, *mnextsub;
33,764,094✔
834
        WORD msizcoef, mcount, tcount, newvalue, j;
33,764,094✔
835
        WORD *oldm, *oldt;
33,764,094✔
836
        WORD *OldWork, numofwildarg;
33,764,094✔
837
        WORD nwstore, tobeeaten, reservevalue = 0, resernum = 0, withwild;
33,764,094✔
838
        WORD *wildargtaken;
33,764,094✔
839
        CBUF *C = cbuf+AT.ebufnum;
33,764,094✔
840
        int ntwa = AN.NumTotWildArgs;
33,764,094✔
841
        LONG oldcpointer = C->Pointer - C->Buffer;
33,764,094✔
842
#ifdef WITHFLOAT
843
        // Pattern matching against float_ functions is currently disabled.
844
        // To relax this in the future, move this early return down to where gamma
845
        // functions and tensors are handled specially. 
846
        if ( *interm == FLOATFUN ) return(0);
33,764,094✔
847
#endif
848
/*
849
        Test first for a straight match
850
*/
851
        AN.RepFunList[AN.RepFunNum+1] = 0;
33,763,998✔
852
        if ( *wilds == 0 ) {
33,763,998✔
853
                m = pattern; t = interm;
33,758,454✔
854

855
                if ( *m != *t ) {
33,758,454✔
856
                        if ( *m < (FUNCTION + WILDOFFSET) ) return(0);
8,568✔
857
                        if ( *t < FUNCTION ) return(0);
8,568✔
858
                        if ( functions[*t-FUNCTION].spec !=
8,568✔
859
                        functions[*m-FUNCTION-WILDOFFSET].spec ) return(0);
8,568✔
860
                }
861
                i = m[1];
33,758,256✔
862
                if ( *m >= (FUNCTION + WILDOFFSET) ) { i--; m++; t++; }
33,758,256✔
863
                do { if ( *m++ != *t++ ) break; } while ( --i > 0 );
110,855,568✔
864
                if ( i <= 0 ) {                        /* Arguments match */
33,758,256✔
865
                        if ( AN.SignCheck && AN.ExpectedSign ) return(0);
147,018✔
866
                        i = *pattern - WILDOFFSET;
147,018✔
867
                        if ( i >= FUNCTION ) {
147,018✔
868
                                if ( *interm != GAMMA
×
869
                                && !CheckWild(BHEAD i,FUNTOFUN,*interm,&newvalue) ) {
×
UNCOV
870
                                        AddWild(BHEAD i,FUNTOFUN,newvalue);
×
871
                                        return(1);
×
872
                                }
UNCOV
873
                                return(0);
×
874
                        }
875
                        else return(1);
876
                }
877
        }
878
/*
879
        Store the current Wildcard assignments
880
*/
881
        t = wildargtaken = OldWork = AT.WorkPointer;
33,616,782✔
882
        t += ntwa;
33,616,782✔
883
        m = AN.WildValue;
33,616,782✔
884
        nwstore = i = (m[-SUBEXPSIZE+1]-SUBEXPSIZE)/4;
33,616,782✔
885
        if ( i > 0 ) {
33,616,782✔
886
                r = AT.WildMask;
33,486,600✔
887
                do {
109,437,816✔
888
                        *t++ = *m++; *t++ = *m++; *t++ = *m++; *t++ = *m++; *t++ = *r++;
109,437,816✔
889
                } while ( --i > 0 );
109,437,816✔
890
                *t++ = C->numrhs;
33,486,600✔
891
        }
892
        if ( t >= AT.WorkTop ) {
33,616,782✔
893
                MLOCK(ErrorMessageLock);
×
894
                MesWork();
×
UNCOV
895
                MUNLOCK(ErrorMessageLock);
×
UNCOV
896
                Terminate(-1);
×
897
        }
898
        AT.WorkPointer = t;
33,616,782✔
899

900
        if ( *wilds ) {
33,616,782✔
901
                if ( *wilds == 1 ) goto endoloop;
5,544✔
UNCOV
902
                else               goto enloop;                        /* tensors = 2 */
×
903
        }
904
        m = pattern; t = interm;
33,611,238✔
905
/*
906
        Single out the specials
907
*/
908
        if ( *t == GAMMA ) {
33,611,238✔
909
/*
910
                 #[ GAMMA :
911

912
                For the gamma's we need to do two things:
913
                a:        Find that there is a match
914
                b:        Find where the match occurs in the string
915
                This last thing cannot be stored in the current conventions,
916
                but once the wildcard assignments have been made it is much
917
                easier to find it back.
918
                Alternative: replace the function number in the term temporarily
919
                by the offset inside the string. This makes things maybe easier.
920
*/
921
                if ( *m != GAMMA ) goto NoCaseB;
72✔
922
                i = t[1] - m[1];
72✔
923
                if ( m[1] == FUNHEAD+1 ) {
72✔
924
                        if ( i ) goto NoCaseB;
×
UNCOV
925
                        if ( m[FUNHEAD] < (AM.OffsetIndex+WILDOFFSET) ||
×
926
                        t[FUNHEAD] >= (AM.OffsetIndex+WILDOFFSET) ) goto NoCaseB;
×
927

UNCOV
928
                        if ( CheckWild(BHEAD m[FUNHEAD]-WILDOFFSET,INDTOIND,t[FUNHEAD],&newvalue) ) goto NoCaseB;
×
929
                        AddWild(BHEAD m[FUNHEAD]-WILDOFFSET,INDTOIND,newvalue);
×
930
                        
931
                        AT.WorkPointer = OldWork;
×
UNCOV
932
                        if ( AN.SignCheck && AN.ExpectedSign ) return(0);
×
UNCOV
933
                        return(1);                /* m was eaten. we have a match! */
×
934
                }
935
                if ( i < 0 ) goto NoCaseB;        /* Pattern longer than target */
72✔
936
                mstop = m + m[1];
72✔
937
                tstop = t + t[1];
72✔
938
                m += FUNHEAD; t += FUNHEAD;
72✔
939
                if ( *m >= (AM.OffsetIndex+WILDOFFSET) && *t < (AM.OffsetIndex+WILDOFFSET) ) {
72✔
940
                        if ( CheckWild(BHEAD *m-WILDOFFSET,INDTOIND,*t,&newvalue) ) goto NoCaseB;
72✔
941
                        reservevalue = newvalue;
72✔
942
                        withwild = 1;
72✔
943
                        resernum = *m-WILDOFFSET;
72✔
944
                        AddWild(BHEAD *m-WILDOFFSET,INDTOIND,newvalue);
72✔
945
                }
UNCOV
946
                else if ( *m != *t ) goto NoCaseB;
×
947
                else withwild = 0;
948
                m++; t++;
72✔
949
                oldm = m; argtstop = oldt = t;
72✔
950
                j = 0;                                        /* No wildcard assignments yet */
72✔
951
                while ( i >= 0 ) {
936✔
952
                        if ( *m == *t ) {
864✔
953
WithGamma:                m++; t++;
×
954
                                if ( m >= mstop ) {
×
955
                                        if ( t < tstop && mstop < AN.patstop ) {
×
956
                                                WORD k;
×
957
                                                mnextsub = pattern + pattern[1];
×
958
                                                k = *mnextsub;
×
959
                                                while ( k == GAMMA && mnextsub[FUNHEAD]
×
960
                                                != pattern[FUNHEAD] ) {
×
961
                                                        mnextsub += mnextsub[1];
×
UNCOV
962
                                                        if ( mnextsub >= AN.patstop ) goto FullOK;
×
963
                                                        k = *mnextsub;
×
964
                                                }
965
                                                if ( k >= FUNCTION ) {
×
UNCOV
966
                                                        if ( k > (FUNCTION + WILDOFFSET) ) k -= WILDOFFSET;
×
UNCOV
967
                                                        if ( functions[k-FUNCTION].commute ) goto NoGamma;
×
968
                                                }
969
                                        }
970
FullOK:                                if ( AN.SignCheck && AN.ExpectedSign ) goto NoGamma;
×
UNCOV
971
                                        AN.RepFunList[AN.RepFunNum+1] = WORDDIF(oldt,argtstop);
×
972
                                        return(1);
×
973
                                }
UNCOV
974
                                if ( t >= tstop ) goto NoCaseB;
×
975
                        }
976
                        else if ( *m >= (AM.OffsetIndex+WILDOFFSET)
864✔
977
                        && *m < (AM.OffsetIndex + (WILDOFFSET<<1)) && ( *t >= 0 ||
×
978
                        *t < MINSPEC ) ) {                        /* Wildcard index */
979
                                if ( !CheckWild(BHEAD *m-WILDOFFSET,INDTOIND,*t,&newvalue) ) {
×
980
                                        AddWild(BHEAD *m-WILDOFFSET,INDTOIND,newvalue);
×
UNCOV
981
                                        j = 1;
×
982
                                        goto WithGamma;
×
983
                                }
UNCOV
984
                                else goto NoGamma;
×
985
                        }
986
                        else if ( *m < MINSPEC && *m >= (AM.OffsetVector+WILDOFFSET)
864✔
987
                        && *t < MINSPEC ) {                        /* Wildcard vector */
×
988
                                if ( !CheckWild(BHEAD *m-WILDOFFSET,VECTOVEC,*t,&newvalue) ) {
×
989
                                        AddWild(BHEAD *m-WILDOFFSET,VECTOVEC,newvalue);
×
UNCOV
990
                                        j = 1;
×
991
                                        goto WithGamma;
×
992
                                }
UNCOV
993
                                else goto NoGamma;
×
994
                        }
995
                        else {
996
NoGamma:
864✔
997
                                if ( j ) {                /* Undo wildcards */
864✔
998
                                        m = AN.WildValue;
×
999
                                        t = OldWork + AN.NumTotWildArgs; r = AT.WildMask; j = nwstore;
×
1000
                                        if ( j > 0 ) {
×
1001
                                                do {
×
1002
                                                        *m++ = *t++; *m++ = *t++;
×
1003
                                                        *m++ = *t++; *m++ = *t++; *r++ = *t++;
×
1004
                                                } while ( --j > 0 );
×
UNCOV
1005
                                                C->numrhs = *t++;
×
UNCOV
1006
                                                C->Pointer = C->Buffer + oldcpointer;
×
1007
                                        }
1008
                                        j = 0;
1009
                                }
1010
                                m = oldm; t = ++oldt; i--;
864✔
1011
                                if ( withwild ) {
864✔
1012
                                        AddWild(BHEAD resernum,INDTOIND,reservevalue);
864✔
1013
                                }
1014
                        }
1015
                }
1016
                goto NoCaseB;
72✔
1017
/*
1018
                 #] GAMMA : 
1019
                 #[ Tensors :
1020
*/
1021
        }
1022
        else if ( *t >= FUNCTION && functions[*t-FUNCTION].spec >= TENSORFUNCTION ) {
33,611,166✔
1023
                mstop = m + m[1];
87,702✔
1024
                tstop = t + t[1];
87,702✔
1025
                mcount = 0;
87,702✔
1026
                m += FUNHEAD;
87,702✔
1027
                t += FUNHEAD;
87,702✔
1028
                AN.WildArgs = 0;
87,702✔
1029
                tcount = WORDDIF(tstop,t);
87,702✔
1030
                while ( m < mstop ) {
192,624✔
1031
                        if ( *m == FUNNYWILD ) { m++; AN.WildArgs++; }
104,922✔
1032
                        m++; mcount++;
104,922✔
1033
                }
1034
                tobeeaten = tcount - mcount + AN.WildArgs;
87,702✔
1035
                if ( tobeeaten ) {
87,702✔
1036
                        if ( tobeeaten < 0 || AN.WildArgs == 0 ) {
34,062✔
1037
                                AT.WorkPointer = OldWork;
11,664✔
1038
                                return(0);        /* Cannot match */
11,664✔
1039
                        }
1040
                }
1041
                AT.WildArgTaken[0] = AN.WildEat = tobeeaten;
76,038✔
1042
                for ( i = 1; i < AN.WildArgs; i++ ) AT.WildArgTaken[i] = 0;
76,038✔
1043
toploop:
76,038✔
1044
                numofwildarg = 0;
76,038✔
1045

1046
                m = pattern; t = interm;
76,038✔
1047
                mstop = m + m[1];
76,038✔
1048
                if ( *m != *t ) {
76,038✔
1049
                        i = *m - WILDOFFSET;
×
UNCOV
1050
                        if ( CheckWild(BHEAD i,FUNTOFUN,*t,&newvalue) ) goto NoCaseB;
×
UNCOV
1051
                        AddWild(BHEAD i,FUNTOFUN,newvalue);
×
1052
                }
1053
                m += FUNHEAD;
76,038✔
1054
                t += FUNHEAD;
76,038✔
1055
                while ( m < mstop ) {
165,408✔
1056
/*
1057
                        First test for an exact match
1058
*/
1059
                        if ( *m == *t ) { m++; t++; continue; }
89,490✔
1060
/*
1061
                        No exact match. Try ARGWILD
1062
*/
1063
                        AN.argaddress = t;
89,490✔
1064
                        if ( *m == FUNNYWILD ) {
89,490✔
1065
                                tobeeaten = AT.WildArgTaken[numofwildarg++];
29,442✔
1066
                                if ( CheckWild(BHEAD m[1],ARGTOARG|EATTENSOR,tobeeaten,t) ) goto endloop;
29,442✔
1067
                                AddWild(BHEAD m[1],ARGTOARG|EATTENSOR,tobeeaten);
29,442✔
1068
                                m += 2;
29,442✔
1069
                                t += tobeeaten;
29,442✔
1070
                                continue;
29,442✔
1071
                        }
1072
/*
1073
                        Now the various cases:
1074
*/
1075
                        i = *m;
60,048✔
1076
                        if ( i < MINSPEC ) {
60,048✔
1077
                                if ( *t != i ) {
×
1078
                                        if ( *t >= MINSPEC ) goto endloop;
×
1079
                                        i -= WILDOFFSET;
×
1080
                                        if ( i < AM.OffsetVector ) goto endloop;
×
1081
                                        if ( CheckWild(BHEAD i,VECTOVEC,*t,&newvalue) )
×
UNCOV
1082
                                                goto endloop;
×
UNCOV
1083
                                        AddWild(BHEAD i,VECTOVEC,newvalue);
×
1084
                                }
1085
                        }
1086
                        else if ( i >= AM.OffsetIndex ) {                        /* Index */
60,048✔
1087
                                if ( i < ( AM.OffsetIndex + WILDOFFSET ) ) goto endloop;
60,048✔
1088
                                if ( i >= ( AM.OffsetIndex + (WILDOFFSET<<1) ) ) {
60,048✔
1089
                                                                                                /* Summed over index */
UNCOV
1090
                                        goto endloop;                                /* For the moment */
×
1091
                                }
1092
                                i -= WILDOFFSET;
60,048✔
1093
                                if ( CheckWild(BHEAD i,INDTOIND,*t,&newvalue) )
60,048✔
1094
                                        goto endloop;                /* Assignment not allowed */
120✔
1095
                                AddWild(BHEAD i,INDTOIND,newvalue);
59,928✔
1096
                        }
UNCOV
1097
                        else goto endloop;
×
1098
                        m++; t++;
59,928✔
1099
                }
1100
                if ( AN.SignCheck && AN.ExpectedSign ) goto endloop;
75,918✔
1101
                AT.WorkPointer = OldWork;
75,918✔
1102
                if ( AN.WildArgs > 1 ) *wilds = 2;
75,918✔
1103
                return(1);                /* m was eaten. we have a match! */
75,918✔
1104

1105
endloop:;
120✔
1106
/*
1107
        restore the current Wildcard assignments
1108
*/
1109
                i = nwstore;
120✔
1110
                if ( i > 0 ) {
120✔
1111
                        m = AN.WildValue;
120✔
1112
                        t = OldWork + ntwa; r = AT.WildMask;
120✔
1113
                        do {
600✔
1114
                                *m++ = *t++; *m++ = *t++; *m++ = *t++; *m++ = *t++; *r++ = *t++;
600✔
1115
                        } while ( --i > 0 );
600✔
1116
                        C->numrhs = *t++;
120✔
1117
                        C->Pointer = C->Buffer + oldcpointer;
120✔
1118
                }
UNCOV
1119
enloop:;
×
1120
                i = AN.WildArgs - 1;
120✔
1121
                if ( i <= 0 ) {
120✔
1122
                        AT.WorkPointer = OldWork;
120✔
1123
                        return(0);
120✔
1124
                }
1125
                while ( --i >= 0 ) {
×
1126
                        if ( AT.WildArgTaken[i] == 0 ) {
×
1127
                                if ( i == 0 ) {
×
1128
                                        AT.WorkPointer = OldWork;
×
UNCOV
1129
                                        *wilds = 0;
×
UNCOV
1130
                                        return(0);
×
1131
                                }
1132
                        }
1133
                        else {
1134
                                (AT.WildArgTaken[i])--;
×
1135
                                numofwildarg = 0;
×
UNCOV
1136
                                for ( j = 0; j <= i; j++ ) {
×
1137
                                        numofwildarg += AT.WildArgTaken[j];
×
1138
                                }
UNCOV
1139
                                AT.WildArgTaken[j] = AN.WildEat-numofwildarg;
×
UNCOV
1140
                                for ( j++; j < AN.WildArgs; j++ ) AT.WildArgTaken[j] = 0;
×
1141
                                break;
1142
                        }
1143
                }
UNCOV
1144
                goto toploop;
×
1145
/*
1146
                 #] Tensors : 
1147
*/
1148
        }
1149
/*
1150
        Count the number of arguments. Either equal or an argument wildcard.
1151
*/
1152
        mstop = m + m[1];
33,523,464✔
1153
        tstop = t + t[1];
33,523,464✔
1154
        mcount = 0; tcount = 0;
33,523,464✔
1155
        m += FUNHEAD; t += FUNHEAD;
33,523,464✔
1156
        while ( t < tstop ) { tcount++; NEXTARG(t) }
91,898,706✔
1157
        AN.WildArgs = 0;
33,523,464✔
1158
        while ( m < mstop ) {
87,088,530✔
1159
                mcount++;
53,565,066✔
1160
                if ( *m == -ARGWILD ) AN.WildArgs++;
53,565,066✔
1161
                NEXTARG(m)
53,565,066✔
1162
        }
1163
        tobeeaten = tcount - mcount + AN.WildArgs;
33,523,464✔
1164
        if ( tobeeaten ) {
33,523,464✔
1165
                if ( tobeeaten < 0 || AN.WildArgs == 0 ) {
2,800,638✔
1166
                        AT.WorkPointer = OldWork;
10,242✔
1167
                        return(0);        /* Cannot match */
10,242✔
1168
                }
1169
        }
1170
/*
1171
        Set up the array AT.WildArgTaken for the number of arguments that each
1172
        wildarg eats.
1173
*/
1174
        AT.WildArgTaken[0] = AN.WildEat = tobeeaten;
33,513,222✔
1175
        for ( i = 1; i < AN.WildArgs; i++ ) AT.WildArgTaken[i] = 0;
33,881,424✔
1176
topofloop:
33,513,222✔
1177
        numofwildarg = 0;
39,938,250✔
1178
/*
1179
        Test for single wildcard object/argument
1180
*/
1181
        m = pattern; t = interm;
39,938,250✔
1182
        if ( *m != *t ) {
39,938,250✔
1183
                i = *m - WILDOFFSET;
8,154✔
1184
                if ( CheckWild(BHEAD i,FUNTOFUN,*t,&newvalue) ) goto NoCaseB;
8,154✔
1185
                AddWild(BHEAD i,FUNTOFUN,newvalue);
8,154✔
1186
        }
1187
        mstop = m + m[1];
39,938,250✔
1188
/*        tstop = t + t[1];  */
1189
        m += FUNHEAD;
39,938,250✔
1190
        t += FUNHEAD;
39,938,250✔
1191
        while ( m < mstop ) {
78,466,944✔
1192
                argmstop = oldm = m;
61,861,452✔
1193
                argtstop = oldt = t;
61,861,452✔
1194
                NEXTARG(argmstop)
61,861,452✔
1195
                NEXTARG(argtstop)
61,861,452✔
1196
                if ( t == tstop ) { /* This concerns a very rare bug */
61,861,452✔
1197
                        if ( *m == -ARGWILD ) goto ArgAll;
51,010✔
UNCOV
1198
                        goto endofloop;
×
1199
                }
1200
                if ( *m < 0 && *t < 0 ) {
61,810,442✔
1201
                        if ( *t <= -FUNCTION ) {
47,809,376✔
1202
                                if ( *t == *m ) {}
13,356✔
1203
                                else if ( *m <= -FUNCTION-WILDOFFSET
13,356✔
1204
                                && functions[-*t-FUNCTION].spec
×
1205
                                == functions[-*m-FUNCTION-WILDOFFSET].spec ) {
×
1206
                                        i = -*m - WILDOFFSET;
×
UNCOV
1207
                                        if ( CheckWild(BHEAD i,FUNTOFUN,-*t,&newvalue) ) goto endofloop;
×
UNCOV
1208
                                        AddWild(BHEAD i,FUNTOFUN,newvalue);
×
1209
                                }
1210
                                else if ( *m == -SYMBOL && m[1] >= 2*MAXPOWER ) {
13,356✔
1211
                                        i = m[1] - 2*MAXPOWER;
13,344✔
1212
                                        AN.argaddress = AT.FunArg;
13,344✔
1213
                                        AT.FunArg[ARGHEAD+1] = -*t;
13,344✔
1214
                                        if ( CheckWild(BHEAD i,SYMTOSUB,1,AN.argaddress) ) goto endofloop;
13,344✔
1215
                                        AddWild(BHEAD i,SYMTOSUB,0);
13,344✔
1216
                                }
1217
                                else if ( *m == -ARGWILD ) {
12✔
1218
ArgAll:                                i = AT.WildArgTaken[numofwildarg++];
12✔
1219
                                        AN.argaddress = t;
14,894,526✔
1220
                                        if ( CheckWild(BHEAD m[1],ARGTOARG,i,t) ) goto endofloop;
14,894,526✔
1221
                                        AddWild(BHEAD m[1],ARGTOARG,i);
14,893,014✔
1222
/*                                        m += 2; */
1223
                                        while ( --i >= 0 ) { NEXTARG(t) }
329,049,506✔
1224
                                        argtstop = t;
1225
                                }
UNCOV
1226
                                else goto endofloop;
×
1227
                        }
1228
                        else if ( *t == *m ) {
47,796,020✔
1229
                                if ( t[1] == m[1] ) {}
23,847,738✔
1230
                                else if ( *t == -SYMBOL ) {
22,982,322✔
1231
                                        j = SYMTOSYM;
1232
SymAll:
8,847,552✔
1233
                                        if ( ( i = m[1] - 2*MAXPOWER ) < 0 ) goto endofloop;
8,847,552✔
1234
                                        if ( CheckWild(BHEAD i,j,t[1],&newvalue) ) goto endofloop;
8,827,260✔
1235
                                        AddWild(BHEAD i,j,newvalue);
5,127,186✔
1236
                                }
1237
                                else if ( *t == -INDEX ) {
22,443,498✔
1238
IndAll:                                i = m[1] - WILDOFFSET;
4,140✔
1239
                                        if ( i < AM.OffsetIndex || i >= WILDOFFSET+AM.OffsetIndex )
7,074✔
UNCOV
1240
                                                                                                                        goto endofloop;
×
1241
                                                                /* We kill the summed over indices here */
1242
                                        if ( CheckWild(BHEAD i,INDTOIND,t[1],&newvalue) ) goto endofloop;
7,074✔
1243
                                        AddWild(BHEAD i,INDTOIND,newvalue);
5,154✔
1244
                                }
1245
                                else if ( *t == -VECTOR || *t == -MINVECTOR ) {
22,439,358✔
1246
                                        i = m[1] - WILDOFFSET;
11,561,934✔
1247
                                        if ( i < AM.OffsetVector ) goto endofloop;
11,561,934✔
1248
                                        if ( CheckWild(BHEAD i,VECTOVEC,t[1],&newvalue) ) goto endofloop;
11,557,098✔
1249
                                        AddWild(BHEAD i,VECTOVEC,newvalue);
5,848,638✔
1250
                                }
1251
                                else goto endofloop;
10,877,424✔
1252
                        }
1253
                        else if ( *m == -ARGWILD ) goto ArgAll;
23,948,282✔
1254
                        else if ( *m == -INDEX && m[1] >= AM.OffsetIndex+WILDOFFSET
9,111,462✔
1255
                        && m[1] < AM.OffsetIndex+(WILDOFFSET<<1) ) {
3,096✔
1256
                                if ( *t == -VECTOR ) goto IndAll;
3,096✔
1257
                                if ( *t == -SNUMBER && t[1] >= 0 && t[1] < AM.OffsetIndex ) goto IndAll;
1,860✔
1258
                                if ( *t == -MINVECTOR ) {
162✔
1259
                                        i = m[1] - WILDOFFSET;
×
1260
                                        AN.argaddress = AT.MinVecArg;
×
1261
                                        AT.MinVecArg[ARGHEAD+3] = t[1];
×
UNCOV
1262
                                        if ( CheckWild(BHEAD i,INDTOSUB,1,AN.argaddress) ) goto endofloop;
×
UNCOV
1263
                                        AddWild(BHEAD i,INDTOSUB,(WORD)0);
×
1264
                                }
1265
                                else goto endofloop;
162✔
1266
                        }
1267
                        else if ( *m == -SYMBOL && m[1] >= 2*MAXPOWER && *t == -SNUMBER ) {
9,108,366✔
1268
                                j = SYMTONUM;
8,308,728✔
1269
                                goto SymAll;
8,308,728✔
1270
                        }
1271
                        else if ( *m == -VECTOR && *t == -MINVECTOR &&
799,638✔
1272
                        ( i = m[1] - WILDOFFSET ) >= AM.OffsetVector ) {
14,232✔
1273
/*
1274
================================
1275
                                AN.argaddress = AT.MinVecArg;
1276
                                AT.MinVecArg[ARGHEAD+3] = t[1];
1277
                                if ( CheckWild(BHEAD i,VECTOSUB,1,AN.argaddress) ) goto endofloop;
1278
                                AddWild(BHEAD i,VECTOSUB,(WORD)0);
1279
================================
1280
*/
1281
                                if ( CheckWild(BHEAD i,VECTOMIN,t[1],&newvalue) ) goto endofloop;
14,232✔
1282
                                AddWild(BHEAD i,VECTOMIN,newvalue);
6,618✔
1283

1284
                        }
1285
                        else if ( *m == -MINVECTOR && *t == -VECTOR &&
785,406✔
1286
                        ( i = m[1] - WILDOFFSET ) >= AM.OffsetVector ) {
752,112✔
1287
/*
1288
================================
1289
                                AN.argaddress = AT.MinVecArg;
1290
                                AT.MinVecArg[ARGHEAD+3] = t[1];
1291
                                if ( CheckWild(BHEAD i,VECTOSUB,1,AN.argaddress) ) goto endofloop;
1292
                                AddWild(BHEAD i,VECTOSUB,(WORD)0);
1293
================================
1294
*/
1295
                                if ( CheckWild(BHEAD i,VECTOMIN,t[1],&newvalue) ) goto endofloop;
752,112✔
1296
                                AddWild(BHEAD i,VECTOMIN,newvalue);
7,818✔
1297
                        }
1298
                        else goto endofloop;
33,294✔
1299
                }
1300
                else if ( *t <= -FUNCTION && *m > 0 ) {
14,001,066✔
1301
                        if ( ( m[ARGHEAD]+ARGHEAD == *m ) && m[*m-1] == 3
228✔
1302
                        && m[*m-2] == 1 && m[*m-3] == 1 && m[ARGHEAD+1] >= FUNCTION
228✔
1303
                        && m[ARGHEAD+2] == *m-ARGHEAD-4 ) { /* Check for f(?a) etc */
228✔
1304
                                WORD *mmmst, *mmm;
228✔
1305
                                if ( m[ARGHEAD+1] >= FUNCTION+WILDOFFSET ) {
228✔
1306
/*                                        i = *m - WILDOFFSET; */
1307
                                        i = m[ARGHEAD+1] - WILDOFFSET;
228✔
1308
                                        if ( CheckWild(BHEAD i,FUNTOFUN,-*t,&newvalue) ) goto endofloop;
228✔
1309
                                        AddWild(BHEAD i,FUNTOFUN,newvalue);
228✔
1310
                                }
UNCOV
1311
                                else if ( m[ARGHEAD+1] != -*t ) goto endofloop;
×
1312
/*
1313
                                        Only arguments allowed are ?a etc.
1314
*/
1315
                                mmmst = m+*m-3;
228✔
1316
                                mmm = m + ARGHEAD + FUNHEAD + 1;
228✔
1317
                                while ( mmm < mmmst ) {
456✔
1318
                                        if ( *mmm != -ARGWILD ) goto endofloop;
228✔
1319
                                        i = 0;
228✔
1320
                                        AN.argaddress = t;
228✔
1321
                                        if ( CheckWild(BHEAD mmm[1],ARGTOARG,i,t) ) goto endofloop;
228✔
1322
                                        AddWild(BHEAD mmm[1],ARGTOARG,i);
228✔
1323
                                        mmm += 2;
228✔
1324
                                }
1325
                        }
UNCOV
1326
                        else goto endofloop;
×
1327
                }
1328
                else if ( *m < 0 && *t > 0 ) {
14,000,838✔
1329
                        if ( *m == -SYMBOL ) {                        /* SYMTOSUB */
13,986,360✔
1330
                                if ( m[1] < 2*MAXPOWER ) goto endofloop;
13,978,506✔
1331
                                i = m[1] - 2*MAXPOWER;
13,978,488✔
1332
                                AN.argaddress = t;
13,978,488✔
1333
                                if ( CheckWild(BHEAD i,SYMTOSUB,1,AN.argaddress) ) goto endofloop;
13,978,488✔
1334
                                AddWild(BHEAD i,SYMTOSUB,0);
11,752,290✔
1335
                        }
1336
                        else if ( *m == -VECTOR ) {
7,854✔
1337
                                if ( ( i = m[1] - WILDOFFSET ) < AM.OffsetVector )
×
1338
                                                                                                                        goto endofloop;
×
1339
                                AN.argaddress = t;
×
UNCOV
1340
                                if ( CheckWild(BHEAD i,VECTOSUB,1,t) ) goto endofloop;
×
UNCOV
1341
                                AddWild(BHEAD i,VECTOSUB,(WORD)0);
×
1342
                        }
1343
                        else if ( *m == -INDEX ) {
7,854✔
1344
                                if ( ( i = m[1] - WILDOFFSET ) < AM.OffsetIndex ) goto endofloop;
966✔
1345
                                if ( i >= AM.OffsetIndex + WILDOFFSET ) goto endofloop;
966✔
1346
                                AN.argaddress = t;
966✔
1347
                                if ( CheckWild(BHEAD i,INDTOSUB,1,AN.argaddress) ) goto endofloop;
966✔
UNCOV
1348
                                AddWild(BHEAD i,INDTOSUB,(WORD)0);
×
1349
                        }
1350
                        else if ( *m == -ARGWILD ) goto ArgAll;
6,888✔
1351
                        else goto endofloop;
204✔
1352
                }
1353
                else if ( *m > 0 && *t > 0 ) {
14,478✔
1354
                        WORD ii = *t-*m;
1355
                        i = *m;
16,530✔
1356
                        do { if ( *m++ != *t++ ) break; } while ( --i > 0 );
16,530✔
1357
                        if ( i == 1 && ii == 0 ) {        /* sign difference */
14,478✔
1358
                                goto endofloop;
6✔
1359
                        }
1360
                        else if ( i > 0 ) {
14,472✔
1361
                                WORD *cto, *cfrom, *csav, ci;
14,472✔
1362
                                WORD oRepFunNum;
14,472✔
1363
                                WORD *oRepFunList;
14,472✔
1364
                                WORD *oterstart,*oterstop,*opatstop;
14,472✔
1365
                                WORD oExpectedSign;
14,472✔
1366
                                WORD wildargs, wildeat;
14,472✔
1367
/*
1368
                                Not an exact match here.
1369
                                We have to hope that the pattern contains a composite wildcard.
1370
*/
1371
                                m = oldm; t = oldt;
14,472✔
1372
                                m += ARGHEAD; t += ARGHEAD;                        /* Point at (first?) term */
14,472✔
1373
                                mtrmstop = m + *m;
14,472✔
1374
                                ttrmstop = t + *t;
14,472✔
1375
                                if ( mtrmstop < argmstop ) goto endofloop;/* More than one term */
14,472✔
1376
                                msizcoef = mtrmstop[-1];
14,472✔
1377
                                if ( msizcoef < 0 ) msizcoef = -msizcoef;
14,472✔
1378
                                msubstop = mtrmstop - msizcoef;
14,472✔
1379
                                m++;
14,472✔
1380
                                if ( m >= msubstop ) goto endofloop;        /* Only coefficient */
14,472✔
1381
/*
1382
                                Here we have a composite term. It can match provided it
1383
                                matches the entire argument. This argument must be a
1384
                                single term also and the coefficients should match
1385
                                (more or less).
1386
                                The matching takes:
1387
                                1:        Match the functions etc. Nothing can be left.
1388
                                2:        Match dotproducts and symbols. ONLY must match
1389
                                        and nothing may be left.
1390
                                For safety it is best to take the term out and put it
1391
                                in workspace.
1392
*/
1393

1394
                                if ( argtstop > ttrmstop ) goto endofloop;
14,472✔
1395
                                m--;
9,168✔
1396
                                oterstart = AN.terstart;
9,168✔
1397
                                oterstop = AN.terstop;
9,168✔
1398
                                opatstop = AN.patstop;
9,168✔
1399
                                oRepFunList = AN.RepFunList;
9,168✔
1400
                                oRepFunNum = AN.RepFunNum;
9,168✔
1401
                                AN.RepFunNum = 0;
9,168✔
1402
                                AN.RepFunList = AT.WorkPointer;
9,168✔
1403
                        AT.WorkPointer = (WORD *)(((UBYTE *)(AT.WorkPointer)) + AM.MaxTer);
9,168✔
1404
                                if ( AT.WorkPointer+*t+5 > AT.WorkTop ) {
9,168✔
1405
                                        MLOCK(ErrorMessageLock);
×
1406
                                        MesWork();
×
UNCOV
1407
                                        MUNLOCK(ErrorMessageLock);
×
UNCOV
1408
                                        return(-1);
×
1409
                                }
1410
                                csav = cto = AT.WorkPointer;
1411
                                cfrom = t;
1412
                                ci = *t;
1413
                                while ( --ci >= 0 ) *cto++ = *cfrom++;
202,170✔
1414
                                AT.WorkPointer = cto;
9,168✔
1415
                                ci = msizcoef;
9,168✔
1416
                                cfrom = mtrmstop;
9,168✔
1417
                                --ci;
9,168✔
1418
                                if ( abs(*--cfrom) != abs(*--cto) ) {
9,168✔
1419
                                        AT.WorkPointer = csav;
×
1420
                                        AN.RepFunList = oRepFunList;
×
1421
                                        AN.RepFunNum = oRepFunNum;
×
1422
                                        AN.terstart = oterstart;
×
1423
                                        AN.terstop = oterstop;
×
UNCOV
1424
                                        AN.patstop = opatstop;
×
UNCOV
1425
                                        goto endofloop;
×
1426
                                }
1427
                                i = (*cfrom != *cto) ? 1 : 0; /* buffer AN.ExpectedSign until we are beyond the goto */
9,168✔
1428
                                while ( --ci >= 0 ) {
27,504✔
1429
                                        if ( *--cfrom != *--cto ) {
18,336✔
1430
                                                AT.WorkPointer = csav;
×
1431
                                                AN.RepFunList = oRepFunList;
×
1432
                                                AN.RepFunNum = oRepFunNum;
×
1433
                                                AN.terstart = oterstart;
×
1434
                                                AN.terstop = oterstop;
×
UNCOV
1435
                                                AN.patstop = opatstop;
×
UNCOV
1436
                                                goto endofloop;
×
1437
                                        }
1438
                                }
1439
                                oExpectedSign =  AN.ExpectedSign; /* buffer AN.ExpectedSign until we are beyond FindRest/FindOnly */
9,168✔
1440
                                AN.ExpectedSign = i;
9,168✔
1441
                                *m -= msizcoef;
9,168✔
1442
                                wildargs = AN.WildArgs;
9,168✔
1443
                                wildeat = AN.WildEat;
9,168✔
1444
                                for ( i = 0; i < wildargs; i++ ) wildargtaken[i] = AT.WildArgTaken[i];
9,168✔
1445
                                AN.ForFindOnly = 0; AN.UseFindOnly = 1;
9,168✔
1446
                                AN.nogroundlevel++;
9,168✔
1447
                                if ( FindRest(BHEAD csav,m) && ( AN.UsedOtherFind || FindOnly(BHEAD csav,m) ) ) {}
9,168✔
1448
                                else {
1449
nomatch:
180✔
1450
                                        *m += msizcoef;
180✔
1451
                                        AT.WorkPointer = csav;
180✔
1452
                                        AN.RepFunList = oRepFunList;
180✔
1453
                                        AN.RepFunNum = oRepFunNum;
180✔
1454
                                        AN.terstart = oterstart;
180✔
1455
                                        AN.terstop = oterstop;
180✔
1456
                                        AN.patstop = opatstop;
180✔
1457
                                        AN.WildArgs = wildargs;
180✔
1458
                                        AN.WildEat = wildeat;
180✔
1459
                                        AN.ExpectedSign = oExpectedSign;
180✔
1460
                                        AN.nogroundlevel--;
180✔
1461
                                        for ( i = 0; i < wildargs; i++ ) AT.WildArgTaken[i] = wildargtaken[i];
180✔
1462
                                        goto endofloop;
180✔
1463
                                }
1464
/*                                if ( *m == 1 || m[1] < FUNCTION || functions[m[1]-FUNCTION].spec >= TENSORFUNCTION ) { */
1465
                                if ( *m == 1 || m[1] < FUNCTION ) {
8,988✔
UNCOV
1466
                                        if ( AN.ExpectedSign ) goto nomatch;
×
1467
                                }
1468
                                else {
1469
                                        if ( m[1] > FUNCTION + WILDOFFSET ) {
8,988✔
1470
                                                if ( functions[m[1]-FUNCTION-WILDOFFSET].spec >= TENSORFUNCTION ) {
7,248✔
UNCOV
1471
                                                        if ( AN.ExpectedSign != AN.RepFunList[AN.RepFunNum-1] ) goto nomatch;
×
1472
                                                }
1473
                                        }
1474
                             else {
1475
                                                if ( AN.ExpectedSign != AN.RepFunList[AN.RepFunNum-1] ) goto nomatch;
1,740✔
1476
/*
1477
                                                if ( functions[m[1]-FUNCTION].spec >= TENSORFUNCTION ) {
1478
                                                        if ( AN.ExpectedSign != AN.RepFunList[AN.RepFunNum-1] ) goto nomatch;
1479
                                                }
1480
*/
1481
                                        }
1482
                                }
1483
                                AN.nogroundlevel--;
8,988✔
1484
                                AN.ExpectedSign = oExpectedSign;
8,988✔
1485
                                AN.WildArgs = wildargs;
8,988✔
1486
                                AN.WildEat = wildeat;
8,988✔
1487
                                for ( i = 0; i < wildargs; i++ ) AT.WildArgTaken[i] = wildargtaken[i];
8,988✔
1488
                                Substitute(BHEAD csav,m,1);
8,988✔
1489
                                cto = csav;
8,988✔
1490
                                cfrom = cto + *cto - msizcoef;
8,988✔
1491
                                cto++;
8,988✔
1492
                                *m += msizcoef;
8,988✔
1493
                                AT.WorkPointer = csav;
8,988✔
1494
                                AN.RepFunList = oRepFunList;
8,988✔
1495
                                AN.RepFunNum = oRepFunNum;
8,988✔
1496
                                AN.terstart = oterstart;
8,988✔
1497
                                AN.terstop = oterstop;
8,988✔
1498
                                AN.patstop = opatstop;
8,988✔
1499
                                if ( *cto != SUBEXPRESSION ) goto endofloop;
8,988✔
1500
                                cto += cto[1];
8,988✔
1501
                                if ( cto < cfrom ) goto endofloop;
8,988✔
1502
                        }
1503
                }
UNCOV
1504
                else goto endofloop;
×
1505

1506
                t = argtstop;                                                /* Next argument */
1507
                m = argmstop;
1508
        }
1509
        if ( AN.SignCheck && AN.ExpectedSign ) goto endofloop;
16,605,492✔
1510
        AT.WorkPointer = OldWork;
16,605,492✔
1511
        if ( AN.WildArgs > 1 ) *wilds = 1;
16,605,492✔
1512
        if ( AN.SignCheck && AN.ExpectedSign ) return(0);
16,605,492✔
1513
        return(1);                /* m was eaten. we have a match! */
1514

1515
endofloop:;
23,332,758✔
1516
/*
1517
        restore the current Wildcard assignments
1518
*/
1519
        i = nwstore;
23,332,758✔
1520
        if ( i > 0 ) {
23,332,758✔
1521
                m = AN.WildValue;
23,210,148✔
1522
                t = OldWork + ntwa; r = AT.WildMask;
23,210,148✔
1523
                do {
85,610,556✔
1524
                        *m++ = *t++; *m++ = *t++; *m++ = *t++; *m++ = *t++; *r++ = *t++;
85,610,556✔
1525
                } while ( --i > 0 );
85,610,556✔
1526
                C->numrhs = *t++;
23,210,148✔
1527
                C->Pointer = C->Buffer + oldcpointer;
23,210,148✔
1528
        }
1529

1530
endoloop:;
122,610✔
1531
        i = AN.WildArgs-1;
23,338,302✔
1532
        if ( i <= 0 ) {
23,338,302✔
1533
                AT.WorkPointer = OldWork;
16,688,796✔
1534
                return(0);
16,688,796✔
1535
        }
1536
        while ( --i >= 0 ) {
6,904,816✔
1537
                if ( AT.WildArgTaken[i] == 0 ) {
6,904,816✔
1538
                        if ( i == 0 ) {
479,788✔
1539
                                AT.WorkPointer = OldWork;
224,478✔
1540
                                return(0);
224,478✔
1541
                        }
1542
                }
1543
                else {
1544
                        (AT.WildArgTaken[i])--;
6,425,028✔
1545
                        numofwildarg = 0;
6,425,028✔
1546
                        for ( j = 0; j <= i; j++ ) {
18,297,626✔
1547
                                numofwildarg += AT.WildArgTaken[j];
11,872,598✔
1548
                        }
1549
                        AT.WildArgTaken[j] = AN.WildEat-numofwildarg;
6,425,028✔
1550
/* ----> bug to be replaced in other source code */
1551
                        for ( j++; j < AN.WildArgs; j++ ) AT.WildArgTaken[j] = 0;
6,677,830✔
1552
                        break;
1553
                }
1554
        }
1555
        goto topofloop;
6,425,028✔
1556
NoCaseB:
72✔
1557
/*
1558
        Restore the old Wildcard assignments
1559
*/
1560
        i = nwstore;
72✔
1561
        if ( i > 0 ) {
72✔
1562
                m = AN.WildValue;
72✔
1563
                t = OldWork + ntwa; r = AT.WildMask;
72✔
1564
                do {
72✔
1565
                        *m++ = *t++; *m++ = *t++; *m++ = *t++; *m++ = *t++; *r++ = *t++;
72✔
1566
                } while ( --i > 0 );
72✔
1567
                C->numrhs = *t++;
72✔
1568
                C->Pointer = C->Buffer + oldcpointer;
72✔
1569
        }
1570
        AT.WorkPointer = OldWork;
72✔
1571
        return(0);                /* no match */
72✔
1572
}
1573

1574
/*
1575
                 #] MatchFunction : 
1576
                 #[ ScanFunctions :                        WORD ScanFunctions(inpat,inter,par)
1577

1578
                Finds in which functions to look for a match.
1579
                inpat is the start of the pattern still to be matched.
1580
                inter is the start of the term still to be matched.
1581
                par gives information about commutativity.
1582
                        par = 0: nothing special
1583
                        par = 1: regular noncommuting function
1584
                        par = 2: GAMMA function
1585

1586
                AN.patstop: end of the functions field in the search pattern
1587
                AN.terstop: end of the functions field in the target pattern
1588
                AN.terstart: address of entire term;
1589

1590
                The actual matching of the functions and their arguments is done
1591
                in a number of different routines. Mainly MatchFunction when there
1592
                are no symmetry properties.
1593
                Also: MatchE
1594
                      MatchCy
1595
                      FunMatchSy
1596
                      FunMatchCy
1597

1598
                The main problem here is backtracking, ie continuing with wildcard
1599
                possibilities when a first assignment doesn't work.
1600
                Important note: this was completely forgotten in the symmetric
1601
                functions till 6-jan-2009. As of the moment this still has to
1602
                be fixed.  ??????21-mar-2023????? Is this still unfixed?????
1603

1604
                Functions inside functions can cause problems when antisymmetric
1605
                functions are involved. The sign of the term may be at stake.
1606
                At the lowest level this is no problem but in f(-fas(n2,n1)) this
1607
                plays a role. Next is when we have a product of functions inside
1608
                an argument. The strategy must be that we test the sign only at the
1609
                last function. Hence, when inpat+inpat[1] >= AN.patstop.
1610
                We might relax that to the last antisymmetric function at a later stage.
1611

1612
        New scheme to be implemented for non-commuting objects:
1613
        When we are matching a second (or higher) function, any match can only
1614
        be directly after the last matched non-commuting function or a commuting
1615
        function. This will take care of whatever happens in MatchE etc.
1616
*/
1617

1618
int ScanFunctions(PHEAD WORD *inpat, WORD *inter, WORD par)
40,480,440✔
1619
{
1620
        GETBIDENTITY
1621
        WORD i, *m, *t, *r, sym, psym;
40,480,440✔
1622
        WORD *newpat, *newter, *instart, *oinpat = 0, *ointer = 0;
40,480,440✔
1623
        WORD nwstore, offset, *OldWork, SetStop = 0, oRepFunNum = AN.RepFunNum;
40,480,440✔
1624
        WORD wilds, wildargs = 0, wildeat = 0, *wildargtaken;
40,480,440✔
1625
        WORD *Oterfirstcomm = AN.terfirstcomm;
40,480,440✔
1626
        CBUF *C = cbuf+AT.ebufnum;
40,480,440✔
1627
        int ntwa = AN.NumTotWildArgs;
40,480,440✔
1628
        LONG oldcpointer = C->Pointer - C->Buffer;
40,480,440✔
1629
        WORD oldSignCheck = AN.SignCheck;
40,480,440✔
1630
        instart = inter;
40,480,440✔
1631
/*
1632
        Only active for the last function in the pattern.
1633
        The actual test on the sign is in MatchFunction or the symmetric functions
1634
*/
1635
        if ( AN.nogroundlevel ) {
40,480,440✔
1636
                AN.SignCheck = ( inpat + inpat[1] >= AN.patstop ) ? 1 : 0;
8,988✔
1637
        }
1638
        else {
1639
                AN.SignCheck = 0;
40,471,452✔
1640
        }
1641
/*
1642
                        Store the current Wildcard assignments
1643
*/
1644
        t = wildargtaken = OldWork = AT.WorkPointer;
40,480,440✔
1645
        t += ntwa;
40,480,440✔
1646
        m = AN.WildValue;
40,480,440✔
1647
        nwstore = i = (m[-SUBEXPSIZE+1]-SUBEXPSIZE)/4;
40,480,440✔
1648
        if ( i > 0 ) {
40,480,440✔
1649
                r = AT.WildMask;
40,135,392✔
1650
                do {
135,209,994✔
1651
                        *t++ = *m++; *t++ = *m++; *t++ = *m++; *t++ = *m++; *t++ = *r++;
135,209,994✔
1652
                } while ( --i > 0 );
135,209,994✔
1653
                *t++ = C->numrhs;
40,135,392✔
1654
        }
1655
        if ( t >= AT.WorkTop ) {
40,480,440✔
1656
                MLOCK(ErrorMessageLock);
×
1657
                MesWork();
×
UNCOV
1658
                MUNLOCK(ErrorMessageLock);
×
UNCOV
1659
                Terminate(-1);
×
1660
        }
1661
        AT.WorkPointer = t;
40,480,440✔
1662
        do {
254,609,958✔
1663
#ifndef NEWCOMMUTE
1664
/*
1665
                Find an eligible unsubstituted function
1666
*/
1667
                if ( AN.RepFunNum > 0 ) {
254,609,958✔
1668
/*
1669
                        First try a non-commuting function, just after the last
1670
                        substituted non-commuting function.
1671
*/
1672
                        if ( *inter >= FUNCTION && functions[*inter-FUNCTION].commute ) {
80,524,728✔
1673
                                do {
6✔
1674
                                        offset = WORDDIF(inter,AN.terstart);
6✔
1675
                                        for ( i = 0; i < AN.RepFunNum; i += 2 ) {
12✔
1676
                                                if ( AN.RepFunList[i] >= offset ) break;
6✔
1677
                                        }
1678
                                        if ( i >= AN.RepFunNum ) break;
6✔
UNCOV
1679
                                        inter += inter[1];
×
UNCOV
1680
                                } while ( inter < AN.terfirstcomm );
×
1681
                                if ( inter < AN.terfirstcomm ) { /* Check that it is directly after */
6✔
1682
                                        for ( i = 0; i < AN.RepFunNum; i += 2 ) {
6✔
1683
                                                if ( functions[AN.terstart[AN.RepFunList[i]]-FUNCTION].commute
6✔
1684
                                                && AN.RepFunList[i]+AN.terstart[AN.RepFunList[i]+1] == offset ) break;
6✔
1685
                                        }
1686
                                        if ( i < AN.RepFunNum ) goto trythis;
6✔
1687
                                }
1688
                                inter = AN.terfirstcomm;
1689
                        }
1690
/*
1691
                        Now try one of the commuting functions
1692
*/
1693
                        while ( inter < AN.terstop ) {
92,657,742✔
1694
                                offset = WORDDIF(inter,AN.terstart);
92,532,246✔
1695
                                for ( i = 0; i < AN.RepFunNum; i += 2 ) {
176,966,082✔
1696
                                        if ( AN.RepFunList[i] == offset ) break;
96,566,856✔
1697
                                }
1698
                                if ( i >= AN.RepFunNum ) break;
92,532,246✔
1699
                                inter += inter[1];
12,133,020✔
1700
                        }
1701
                        if ( inter >= AN.terstop ) goto Failure;
80,524,722✔
1702
trythis:;
80,399,226✔
1703
                }
1704
                else {
1705
/*
1706
                        The first function can be anywhere. We have no problems.
1707
*/
1708
                        offset = WORDDIF(inter,AN.terstart);
174,085,230✔
1709
                }
1710
#else
1711
                /* first find an unsubstituted function */
1712
                do {
1713
                        offset = WORDDIF(inter,AN.terstart);
1714
                        for ( i = 0; i < AN.RepFunNum; i += 2 ) {
1715
                                if ( AN.RepFunList[i] == offset ) break;
1716
                        }
1717
                        if ( i >= AN.RepFunNum ) break;
1718
                        inter += inter[1];
1719
                } while ( inter < AN.terstop );
1720
                if ( inter >= AN.terstop ) goto Failure;
1721
#endif
1722
                wilds = 0;
254,484,462✔
1723
                /* We found one */
1724
                if ( *inter >= FUNCTION && *inpat >= FUNCTION ) {
254,484,462✔
1725
                        if ( *inpat == *inter || *inpat >= FUNCTION + WILDOFFSET ) {
249,788,172✔
1726
/*
1727
                                if ( inter[1] == FUNHEAD ) goto rewild;
1728
*/
1729
                                if ( functions[*inter-FUNCTION].spec >= TENSORFUNCTION
35,025,642✔
1730
                                && ( *inter == *inpat ||
137,058✔
1731
                                functions[*inpat-FUNCTION-WILDOFFSET].spec >= TENSORFUNCTION ) ) {
420✔
1732
                                        sym = functions[*inter-FUNCTION].symmetric & ~REVERSEORDER;
137,058✔
1733
                                        if ( *inpat == *inter ) psym = sym;
137,058✔
1734
                                        else psym = functions[*inpat-FUNCTION-WILDOFFSET].symmetric & ~REVERSEORDER;
420✔
1735
                                        if ( sym == ANTISYMMETRIC || sym == SYMMETRIC
137,058✔
1736
                                        || psym == SYMMETRIC || psym == ANTISYMMETRIC ) {
107,208✔
1737
                                                if ( sym == ANTISYMMETRIC && psym == SYMMETRIC ) goto rewild;
29,850✔
1738
                                                if ( sym == SYMMETRIC && psym == ANTISYMMETRIC ) goto rewild;
29,634✔
1739
/*
1740
                                                Special function call for (anti)symmetric tensors
1741
*/
1742
                                                if ( MatchE(BHEAD inpat,inter,instart,par) ) goto OnSuccess;
29,634✔
1743
                                        }
1744
                                        else if ( sym == CYCLESYMMETRIC || sym == RCYCLESYMMETRIC
107,208✔
1745
                                        || psym == CYCLESYMMETRIC || psym == RCYCLESYMMETRIC ) {
87,558✔
1746
/*
1747
                                                Special function call for (r)cyclic tensors
1748
*/
1749
                                                if ( MatchCy(BHEAD inpat,inter,instart,par) ) goto OnSuccess;
19,650✔
1750
                                        }
1751
                                        else goto rewild;
87,558✔
1752
                                }
1753
                                else if ( functions[*inter-FUNCTION].spec <= 0
34,888,584✔
1754
                                && ( *inter == *inpat ||
34,888,584✔
1755
                                functions[*inpat-FUNCTION-WILDOFFSET].spec <= 0 ) ) {
11,022✔
1756
                                        sym = functions[*inter-FUNCTION].symmetric & ~REVERSEORDER;
34,888,386✔
1757
                                        if ( *inpat == *inter ) psym = sym;
34,888,386✔
1758
                                        else psym = functions[*inpat-FUNCTION-WILDOFFSET].symmetric & ~REVERSEORDER;
10,824✔
1759
                                        if ( psym == SYMMETRIC || sym == SYMMETRIC
34,888,386✔
1760
/*
1761
                                        The next statement was commented out. Why????
1762
                                        Werkt nog niet. Teken wordt nog niet bijgehouden.
1763
                                        5-nov-2001
1764
*/
1765
                                        || psym == ANTISYMMETRIC || sym == ANTISYMMETRIC
33,654,528✔
1766
                                        ) {
1767
                                                if ( sym == ANTISYMMETRIC && psym == SYMMETRIC ) goto rewild;
1,233,948✔
1768
                                                if ( sym == SYMMETRIC && psym == ANTISYMMETRIC ) goto rewild;
1,233,066✔
1769
                                                if ( FunMatchSy(BHEAD inpat,inter,instart,par) ) goto OnSuccess;
1,233,066✔
1770
                                        }
1771
                                        else
1772
                                                if ( sym == CYCLESYMMETRIC || sym == RCYCLESYMMETRIC
33,654,438✔
1773
                                        || psym == CYCLESYMMETRIC || psym == RCYCLESYMMETRIC ) {
33,654,438✔
UNCOV
1774
                                                if ( FunMatchCy(BHEAD inpat,inter,instart,par) ) goto OnSuccess;
×
1775
                                        }
1776
                                        else goto rewild;
33,654,438✔
1777
                                }
1778
                                else goto rewild;
198✔
1779
                                AN.terfirstcomm = Oterfirstcomm;
1,275,246✔
1780
                        }
1781
                        else if ( par > 0 ) { SetStop = 1; goto maybenext; }
214,762,530✔
1782
                }
1783
                else {
1784
rewild:
4,696,290✔
1785
                AN.terfirstcomm = Oterfirstcomm;
38,445,126✔
1786
                if ( *inter != SUBEXPRESSION && MatchFunction(BHEAD inpat,inter,&wilds) ) {
38,445,126✔
1787
                        AN.terfirstcomm = Oterfirstcomm;
16,813,170✔
1788
                        if ( wilds ) {
16,813,170✔
1789
/*
1790
                                Store wildcards to continue in MatchFunction if the current
1791
                                wildcards do not work out.
1792
*/
1793
                                wildargs = AN.WildArgs;
140,724✔
1794
                                wildeat = AN.WildEat;
140,724✔
1795
                                for ( i = 0; i < wildargs; i++ ) wildargtaken[i] = AT.WildArgTaken[i];
428,208✔
1796
                                oinpat = inpat; ointer = inter;
1797
                        }
1798
                        if ( par && *inter == GAMMA && AN.RepFunList[AN.RepFunNum+1] ) {
16,813,170✔
UNCOV
1799
                                SetStop = 1; goto NoMat;
×
1800
                        }
1801
                        if ( par == 2 ) {
12✔
UNCOV
1802
                                if ( *inter < FUNCTION || functions[*inter-FUNCTION].commute ) {
×
UNCOV
1803
                                        goto NoMat;
×
1804
                                }
1805
                                par = 1;
1806
                        }
1807
                        AN.RepFunList[AN.RepFunNum] = offset;
16,813,170✔
1808
                        AN.RepFunNum += 2;
16,813,170✔
1809
                        newpat = inpat + inpat[1];
16,813,170✔
1810
                        if ( newpat >= AN.patstop ) {
16,813,170✔
1811
                                if ( AN.UseFindOnly == 0 ) {
5,478,708✔
1812
                                        if ( FindOnce(BHEAD AN.findTerm,AN.findPattern) ) {
28,908✔
1813
                                                AN.UsedOtherFind = 1;
28,908✔
1814
                                                goto OnSuccess;
28,908✔
1815
                                        }
UNCOV
1816
                                        AN.RepFunNum -= 2;
×
UNCOV
1817
                                        goto NoMat;
×
1818
                                }
1819
                                goto OnSuccess;
5,449,800✔
1820
                        }
1821
                        if ( *inter < FUNCTION || functions[*inter-FUNCTION].commute ) {
11,334,462✔
1822
                                newter = inter + inter[1];
12✔
1823
                                if ( newter >= AN.terstop ) goto Failure;
12✔
1824
                                if ( *inter == GAMMA && inpat[1] <
12✔
1825
                                inter[1] - AN.RepFunList[AN.RepFunNum-1] ) {
×
UNCOV
1826
                                        if ( ScanFunctions(BHEAD newpat,newter,2) ) goto OnSuccess;
×
UNCOV
1827
                                        AN.terfirstcomm = Oterfirstcomm;
×
1828
                                }
1829
                                else if ( *newter ==  SUBEXPRESSION ) {}
12✔
1830
                                else if ( functions[*inter-FUNCTION].commute ) {
12✔
1831
                                        if ( ScanFunctions(BHEAD newpat,newter,1) ) goto OnSuccess;
12✔
1832
                                        AN.terfirstcomm = Oterfirstcomm;
×
UNCOV
1833
                                        if ( ( *newpat < (FUNCTION+WILDOFFSET)
×
1834
                                                && ( functions[*newpat-FUNCTION].commute == 0 ) ) ||
×
1835
                                                ( *newpat >= (FUNCTION+WILDOFFSET)
1836
                                                && ( functions[*newpat-FUNCTION-WILDOFFSET].commute == 0 ) ) ) {
×
UNCOV
1837
                                                newter = AN.terfirstcomm;
×
UNCOV
1838
                                                if ( newter < AN.terstop && ScanFunctions(BHEAD newpat,newter,1) ) goto OnSuccess;
×
1839
                                        }
1840
                                }
1841
                                else {
UNCOV
1842
                                        if ( ScanFunctions(BHEAD newpat,instart,1) ) goto OnSuccess;
×
UNCOV
1843
                                        AN.terfirstcomm = Oterfirstcomm;
×
1844
                                }
1845
                                SetStop = par;
1846
                        }
1847
                        else {
1848
/*
1849
                                Shouldn't this be newpat instead of inpat?????
1850
*/
1851
                                if ( par && inter > instart && ( ( *newpat < (FUNCTION+WILDOFFSET)
11,334,450✔
1852
                                && functions[*newpat-FUNCTION].commute ) ||
×
1853
                                ( *newpat >= (FUNCTION+WILDOFFSET)
UNCOV
1854
                                && functions[*newpat-FUNCTION-WILDOFFSET].commute ) ) ) {
×
1855
                                        SetStop = 1;
1856
                                }
1857
                                else {
1858
                                        newter = instart;
11,334,450✔
1859
                                        if ( ScanFunctions(BHEAD newpat,newter,par) ) goto OnSuccess;
11,334,450✔
1860
                                        AN.terfirstcomm = Oterfirstcomm;
11,211,834✔
1861
                                }
1862
                        }
1863
/*
1864
                        Restore the old Wildcard assignments
1865
*/
1866
NoMat:
11,211,870✔
1867
                        i = nwstore;
11,211,870✔
1868
                        if ( i > 0 ) {
11,211,870✔
1869
                                m = AN.WildValue;
11,071,602✔
1870
                                t = OldWork + ntwa; r = AT.WildMask;
11,071,602✔
1871
                                do {
41,026,278✔
1872
                                        *m++ = *t++; *m++ = *t++; *m++ = *t++; *m++ = *t++; *r++ = *t++;
41,026,278✔
1873
                                } while ( --i > 0 );
41,026,278✔
1874
                                C->numrhs = *t++;
11,071,602✔
1875
                                C->Pointer = C->Buffer + oldcpointer;
11,071,602✔
1876
                        }
1877
/*                        AN.RepFunNum -= 2; */
1878
                        AN.RepFunNum = oRepFunNum;
11,211,870✔
1879
                        if ( wilds ) {
11,211,870✔
1880
                                inter = ointer; inpat = oinpat;
5,544✔
1881
                                AN.WildArgs = wildargs;
5,544✔
1882
                                AN.WildEat = wildeat;
5,544✔
1883
                                for ( i = 0; i < wildargs; i++ ) AT.WildArgTaken[i] = wildargtaken[i];
16,632✔
1884
                                goto rewild;
5,544✔
1885
                        }
1886
                        if ( SetStop ) break;
11,206,326✔
1887
                }
1888
                else if ( par ) {
21,631,956✔
1889
maybenext:
×
1890
                        if ( *inpat < (FUNCTION+WILDOFFSET) ) {
×
UNCOV
1891
                                if ( *inpat < FUNCTION ||
×
UNCOV
1892
                                functions[*inpat-FUNCTION].commute ) break;
×
1893
                        }
1894
                        else {
UNCOV
1895
                                if ( functions[*inpat-FUNCTION-WILDOFFSET].commute ) break;
×
1896
                        }
1897
                }}
1898
                inter += inter[1];
248,876,058✔
1899
        } while ( inter < AN.terstop );
248,876,058✔
1900
Failure:
34,746,540✔
1901
    AN.SignCheck = oldSignCheck;
34,872,036✔
1902
        AT.WorkPointer = OldWork;
34,872,036✔
1903
        return(0);
34,872,036✔
1904
OnSuccess:
5,608,440✔
1905
        if ( AT.idallflag && AN.nogroundlevel <= 0 ) {
5,608,440✔
1906
                if ( AT.idallmaxnum > 0 && AT.idallnum >= AT.idallmaxnum ) {
36✔
1907
                        AN.terfirstcomm = Oterfirstcomm;
×
1908
                    AN.SignCheck = oldSignCheck;
×
UNCOV
1909
                        AT.WorkPointer = OldWork;
×
UNCOV
1910
                        return(0);
×
1911
                }
1912
                SubsInAll(BHEAD0);
36✔
1913
                AT.idallnum++;
36✔
1914
                if ( AT.idallmaxnum == 0 || AT.idallnum < AT.idallmaxnum ) goto NoMat;
36✔
1915
        }
1916
        AN.terfirstcomm = Oterfirstcomm;
5,608,404✔
1917
    AN.SignCheck = oldSignCheck;
5,608,404✔
1918
/*
1919
        Now the disorder test
1920
*/
1921
        if ( AN.DisOrderFlag && AN.RepFunNum >= 4 ) {
5,608,404✔
1922
                WORD k, kk;
UNCOV
1923
                for ( i = 2; i < AN.RepFunNum; i += 2 ) {
×
1924
/*
1925
------------> We still have to copy the code from Normalize wrt properorderflag
1926
*/
1927
                        m = AN.terstart + AN.RepFunList[i-2];
×
1928
                        t = AN.terstart + AN.RepFunList[i];
×
1929
                        if ( *m != *t ) {
×
UNCOV
1930
                                if ( *m > *t ) continue;
×
1931
                                goto doesmatch;
×
1932
                        }
1933
                        if ( *m >= FUNCTION && functions[*m-FUNCTION].spec >=
×
1934
                                TENSORFUNCTION ) {
1935
                                k = m[1] - FUNHEAD;
×
1936
                                kk = t[1] - FUNHEAD;
×
UNCOV
1937
                                m += FUNHEAD;
×
UNCOV
1938
                                t += FUNHEAD;
×
1939
                        }
1940
                        else {
1941
                                k = m[1] - FUNHEAD;
×
1942
                                kk = t[1] - FUNHEAD;
×
UNCOV
1943
                                m += FUNHEAD;
×
1944
                                t += FUNHEAD;
×
1945
                        }
1946
                        while ( k > 0 && kk > 0 ) {
×
1947
                                if ( *m < *t ) goto NextFor;
×
UNCOV
1948
                                else if ( *m++ > *t++ ) goto doesmatch;
×
1949
                                k--; kk--;
×
1950
                        }
UNCOV
1951
                        if ( k > 0 ) goto doesmatch;
×
1952
NextFor:;
×
1953
                }
UNCOV
1954
                SetStop = 1;
×
UNCOV
1955
                goto NoMat;
×
1956
        }
1957
doesmatch:
5,608,404✔
1958
        AT.WorkPointer = OldWork;
5,608,404✔
1959
        return(1);
5,608,404✔
1960
}
1961

1962
/*
1963
                 #] ScanFunctions : 
1964
        #] Patterns :
1965
*/
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc