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

vermaseren / form / 9364948935

04 Jun 2024 09:49AM UTC coverage: 49.979% (-0.02%) from 49.999%
9364948935

Pull #526

github

web-flow
Merge 7062bd769 into 83e3d4185
Pull Request #526: RFC: better debugging

52 of 415 new or added lines in 46 files covered. (12.53%)

32 existing lines in 2 files now uncovered.

41391 of 82816 relevant lines covered (49.98%)

878690.77 hits per line

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

48.26
/sources/normal.c
1
/** @file normal.c
2
 * 
3
 *  Mainly the routine Normalize. This routine brings terms to standard
4
 *        FORM. Currently it has one serious drawback. Its buffers are all
5
 *        in the stack. This means these buffers have a fixed size (NORMSIZE).
6
 *        In the past this has caused problems and NORMSIZE had to be increased.
7
 *
8
 *        It is not clear whether Normalize can be called recursively.
9
 */
10
/* #[ License : */
11
/*
12
 *   Copyright (C) 1984-2023 J.A.M. Vermaseren
13
 *   When using this file you are requested to refer to the publication
14
 *   J.A.M.Vermaseren "New features of FORM" math-ph/0010025
15
 *   This is considered a matter of courtesy as the development was paid
16
 *   for by FOM the Dutch physics granting agency and we would like to
17
 *   be able to track its scientific use to convince FOM of its value
18
 *   for the community.
19
 *
20
 *   This file is part of FORM.
21
 *
22
 *   FORM is free software: you can redistribute it and/or modify it under the
23
 *   terms of the GNU General Public License as published by the Free Software
24
 *   Foundation, either version 3 of the License, or (at your option) any later
25
 *   version.
26
 *
27
 *   FORM is distributed in the hope that it will be useful, but WITHOUT ANY
28
 *   WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
29
 *   FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
30
 *   details.
31
 *
32
 *   You should have received a copy of the GNU General Public License along
33
 *   with FORM.  If not, see <http://www.gnu.org/licenses/>.
34
 */
35
/* #] License : */ 
36
/*
37
          #[ Includes : normal.c
38
*/
39

40
#include "form3.h"
41
#ifdef WITHFLOAT
42
#include <gmp.h>
43

44
int PackFloat(WORD *,mpf_t);
45
int UnpackFloat(mpf_t, WORD *);
46
void RatToFloat(mpf_t result, UWORD *formrat, int ratsize);
47
#endif
48
/*
49
          #] Includes : 
50
         #[ Normalize :
51
                 #[ CompareFunctions :
52
*/
53

54
WORD CompareFunctions(WORD *fleft,WORD *fright)
24✔
55
{
56
        WORD k, kk;
24✔
57
        if ( AC.properorderflag ) {
24✔
58
                if ( ( *fleft >= (FUNCTION+WILDOFFSET)
×
59
                && functions[*fleft-FUNCTION-WILDOFFSET].spec >= TENSORFUNCTION )
×
60
                || ( *fleft >= FUNCTION && *fleft < (FUNCTION + WILDOFFSET)
×
61
                && functions[*fleft-FUNCTION].spec >= TENSORFUNCTION ) ) {}
×
62
                else {
63
                        WORD *s1, *s2, *ss1, *ss2;
×
64
                        s1 = fleft+FUNHEAD; s2 = fright+FUNHEAD;
×
65
                        ss1 = fleft + fleft[1]; ss2 = fright + fright[1];
×
66
                        while ( s1 < ss1 && s2 < ss2 ) {
×
67
                                k = CompArg(s1,s2);
×
68
                                if ( k > 0 ) return(1);
×
69
                                if ( k < 0 ) return(0);
×
70
                                NEXTARG(s1)
×
71
                                NEXTARG(s2)
×
72
                        }
73
                        if ( s1 < ss1 ) return(1);
×
74
                        return(0);
×
75
                }
76
                k = fleft[1] - FUNHEAD;
×
77
                kk = fright[1] - FUNHEAD;
×
78
                fleft += FUNHEAD;
×
79
                fright += FUNHEAD;
×
80
                while ( k > 0 && kk > 0 ) {
×
81
                        if ( *fleft < *fright ) return(0);
×
82
                        else if ( *fleft++ > *fright++ ) return(1);
×
83
                        k--; kk--;
×
84
                }
85
                if ( k > 0 ) return(1);
×
86
                return(0);
×
87
        }
88
        else {
89
                k = fleft[1] - FUNHEAD;
24✔
90
                kk = fright[1] - FUNHEAD;
24✔
91
                fleft += FUNHEAD;
24✔
92
                fright += FUNHEAD;
24✔
93
                while ( k > 0 && kk > 0 ) {
40✔
94
                        if ( *fleft < *fright ) return(0);
32✔
95
                        else if ( *fleft++ > *fright++ ) return(1);
20✔
96
                        k--; kk--;
16✔
97
                }
98
                if ( k > 0 ) return(1);
8✔
99
                return(0);
8✔
100
        }
101
}
102

103
/*
104
                 #] CompareFunctions : 
105
                 #[ Commute :
106

107
        This function gets two adjacent function pointers and decides
108
        whether these two functions should be exchanged to obtain a
109
        natural ordering.
110

111
        Currently there is only an ordering of gamma matrices belonging
112
        to different spin lines.
113

114
        Note that we skip for now the cases of (F)^(3/2) or 1/F and a few more
115
        of such funny functions.
116
*/
117

118
WORD Commute(WORD *fleft, WORD *fright)
2,347✔
119
{
120
        WORD fun1, fun2;
2,347✔
121
        if ( *fleft == DOLLAREXPRESSION || *fright == DOLLAREXPRESSION ) return(0);
2,347✔
122
        fun1 = ABS(*fleft); fun2 = ABS(*fright);
2,347✔
123
        if ( *fleft >= GAMMA && *fleft <= GAMMASEVEN
2,347✔
124
            && *fright >= GAMMA && *fright <= GAMMASEVEN ) {
48✔
125
                if ( fleft[FUNHEAD] < AM.OffsetIndex && fleft[FUNHEAD] > fright[FUNHEAD] )
36✔
126
                        return(1);
127
                return(0);
12✔
128
        }
129
        if ( fun1 >= WILDOFFSET ) fun1 -= WILDOFFSET;
2,311✔
130
        if ( fun2 >= WILDOFFSET ) fun2 -= WILDOFFSET;
2,311✔
131
        if ( ( ( functions[fun1-FUNCTION].flags & COULDCOMMUTE ) == 0 )
2,311✔
132
          || ( ( functions[fun2-FUNCTION].flags & COULDCOMMUTE ) == 0 ) ) return(0);
156✔
133
/*
134
        if other conditions will come here, keep in mind that if *fleft < 0
135
        or *fright < 0 they are arguments in the exponent function as in f^(3/2)
136
*/
137
        if ( AC.CommuteInSet == 0 ) return(0);
152✔
138
/*
139
        The code for CompareFunctions can be stolen from the commuting case.
140

141
        We need the syntax:
142
                Commute Fun1,Fun2,...,Fun`n';
143
        For this Fun1,...,Fun`n' need to be noncommuting functions.
144
        These functions will commute with all members of the group.
145
        In the AC.paircommute buffer the representation is
146
                `n'+1,element1,...,element`n',`m'+1,element1,...,element`m',0
147
        A function can belong to more than one group.
148
        If a function commutes with itself, it is most efficient to make a separate
149
        group of two elements for it as in
150
                Commute T,T;   -> 3,T,T
151
*/
152
    if ( fun1 >= fun2 ) {
152✔
153
                WORD *group = AC.CommuteInSet, *g1, *g2, *g3;
154
                while ( *group > 0 ) {
316✔
155
                        g3 = group + *group;
276✔
156
                        g1 = group+1;
276✔
157
                        while ( g1 < g3 ) {
580✔
158
                                if ( *g1 == fun1 || ( fun1 <= GAMMASEVEN && fun1 >= GAMMA 
500✔
159
                                 && *g1 <= GAMMASEVEN && *g1 >= GAMMA ) ) {
×
160
                                        g2 = group+1;
161
                                        while ( g2 < g3 ) {
548✔
162
                                                if ( g1 != g2 && ( *g2 == fun2 ||
440✔
163
                                                 ( fun2 <= GAMMASEVEN && fun2 >= GAMMA 
212✔
164
                                                 && *g2 <= GAMMASEVEN && *g2 >= GAMMA ) ) ) {
60✔
165
                                                        if ( fun1 != fun2 ) return(1);
88✔
166
                                                        if ( *fleft < 0 ) return(0);
24✔
167
                                                        if ( *fright < 0 ) return(1);
24✔
168
                                                        return(CompareFunctions(fleft,fright));
24✔
169
                                                }
170
                                                g2++;
352✔
171
                                        }
172
                                        break;
173
                                }
174
                                g1++;
304✔
175
                        }
176
                        group = g3;
177
                }
178
        }
179
        return(0);
180
}
181

182
/*
183
                 #] Commute : 
184
                 #[ Normalize :
185

186
        This is the big normalization routine. It has a great need
187
        to be economical.
188
        There is a fixed limit to the number of objects coming in.
189
        Something should be done about it.
190

191
*/
192

193
WORD Normalize(PHEAD WORD *term)
32,392,070✔
194
{
195
/*
196
          #[ Declarations :
197
*/
198
        GETBIDENTITY
199
        WORD *t, *m, *r, i, j, k, l, nsym, *ss, *tt, *u;
32,392,070✔
200
        WORD shortnum, stype;
32,392,070✔
201
        WORD *stop, *to = 0, *from = 0;
32,392,070✔
202
/*
203
        The next variables could be better off in the AT.WorkSpace (?)
204
        Now they make stackallocations rather bothersome.
205
*/
206
        WORD psym[7*NORMSIZE],*ppsym;
32,392,070✔
207
        WORD pvec[NORMSIZE],*ppvec,nvec;
32,392,070✔
208
        WORD pdot[3*NORMSIZE],*ppdot,ndot;
32,392,070✔
209
        WORD pdel[2*NORMSIZE],*ppdel,ndel;
32,392,070✔
210
        WORD pind[NORMSIZE],nind;
32,392,070✔
211
        WORD *peps[NORMSIZE/3],neps;
32,392,070✔
212
        WORD *pden[NORMSIZE/3],nden;
32,392,070✔
213
        WORD *pcom[NORMSIZE],ncom;
32,392,070✔
214
        WORD *pnco[NORMSIZE],nnco;
32,392,070✔
215
        WORD *pcon[2*NORMSIZE],ncon;                /* Pointer to contractable indices */
32,392,070✔
216
        WORD *n_coef, ncoef;                                /* Accumulator for the coefficient */
32,392,070✔
217
        WORD *n_llnum, *lnum, nnum;
32,392,070✔
218
        WORD *termout, oldtoprhs = 0, subtype;
32,392,070✔
219
        WORD ReplaceType, ReplaceVeto = 0, didcontr, regval = 0;
32,392,070✔
220
        WORD *ReplaceSub;
32,392,070✔
221
        WORD *fillsetexp;
32,392,070✔
222
        CBUF *C = cbuf+AT.ebufnum;
32,392,070✔
223
        WORD *ANsc = 0, *ANsm = 0, *ANsr = 0, PolyFunMode;
32,392,070✔
224
#ifdef WITHFLOAT
225
        WORD withfloat = 0;
32,392,070✔
226
        WORD *firstfloat = 0;
32,392,070✔
227
#endif
228
        LONG oldcpointer = 0, x;
32,392,070✔
229
        n_coef = TermMalloc("NormCoef");
32,392,070✔
230
        n_llnum = TermMalloc("n_llnum");
32,392,070✔
231
        lnum = n_llnum+1;
32,392,070✔
232
/*
233
        int termflag;
234
*/
235
/*
236
          #] Declarations : 
237
          #[ Setup :
238
PrintTerm(term,"Normalize");
239
*/
240

241
Restart:
33✔
242
        didcontr = 0;
32,392,100✔
243
        ReplaceType = -1;
32,392,100✔
244
        t = term;
32,392,100✔
245
        if ( !*t ) { TermFree(n_coef,"NormCoef"); TermFree(n_llnum,"n_llnum"); return(regval); }
32,392,100✔
246
        r = t + *t;
32,391,640✔
247
        ncoef = r[-1];
32,391,640✔
248
        i = ABS(ncoef);
32,391,640✔
249
        r -= i;
32,391,640✔
250
        m = r;
32,391,640✔
251
        t = n_coef;
32,391,640✔
252
        NCOPY(t,r,i);
132,307,500✔
253
        termout = AT.WorkPointer;
32,391,640✔
254
    AT.WorkPointer = (WORD *)(((UBYTE *)(AT.WorkPointer)) + AM.MaxTer);
32,391,640✔
255
        fillsetexp = termout+1;
32,391,640✔
256
        AN.PolyNormFlag = 0; PolyFunMode = AN.PolyFunTodo;
32,391,640✔
257
/*
258
        termflag = 0;
259
*/
260
/*
261
          #] Setup : 
262
          #[ First scan :
263
*/
264
        nsym = nvec = ndot = ndel = neps = nden = 
32,391,640✔
265
        nind = ncom = nnco = ncon = 0;
32,391,640✔
266
        ppsym = psym;
32,391,640✔
267
        ppvec = pvec;
32,391,640✔
268
        ppdot = pdot;
32,391,640✔
269
        ppdel = pdel;
32,391,640✔
270
        t = term + 1;
32,391,640✔
271
conscan:;
32,391,680✔
272
        if ( t < m ) do {
32,391,680✔
273
                r = t + t[1];
57,423,500✔
274
                switch ( *t ) {
57,423,500✔
275
                        case SYMBOL :
9,148,090✔
276
                                t += 2;
9,148,090✔
277
                                from = m;
9,148,090✔
278
                                do {
10,807,180✔
279
                                        if ( t[1] == 0 ) {
10,807,180✔
280
/*                                                if ( *t == 0 || *t == MAXPOWER ) goto NormZZ; */
281
                                                t += 2;
4,119✔
282
                                                goto NextSymbol;
4,119✔
283
                                        }
284
                                        if ( *t <= DENOMINATORSYMBOL && *t >= COEFFSYMBOL ) {
10,803,080✔
285
/*
286
                                                if ( AN.NoScrat2 == 0 ) {
287
                                                        AN.NoScrat2 = (UWORD *)Malloc1((AM.MaxTal+2)*sizeof(UWORD),"Normalize");
288
                                                }
289
*/
290
                                                if ( AN.cTerm ) m = AN.cTerm;
×
291
                                                else m = term;
292
                                                m += *m;
×
293
                                                ncoef = REDLENG(ncoef);
×
294
                                                if ( *t == COEFFSYMBOL ) {
×
295
                                                  i = t[1];
×
296
                                                  nnum = REDLENG(m[-1]);
×
297
                                                  m -= ABS(m[-1]);
×
298
                                                  if ( i > 0 ) {
×
299
                                                        while ( i > 0 ) {
×
300
                                                                if ( MulRat(BHEAD (UWORD *)n_coef,ncoef,(UWORD *)m,nnum,
×
301
                                                                (UWORD *)n_coef,&ncoef) ) goto FromNorm;
×
302
                                                                i--;
×
303
                                                        }
304
                                                  }
305
                                                  else if ( i < 0 ) {
×
306
                                                        while ( i < 0 ) {
×
307
                                                                if ( DivRat(BHEAD (UWORD *)n_coef,ncoef,(UWORD *)m,nnum,
×
308
                                                                (UWORD *)n_coef,&ncoef) ) goto FromNorm;
×
309
                                                                i++;
×
310
                                                        }
311
                                                  }
312
                                                }
313
                                                else {
314
                                                  i = m[-1];
×
315
                                                  nnum = (ABS(i)-1)/2;
×
316
                                                  if ( *t == NUMERATORSYMBOL ) { m -= nnum + 1; }
×
317
                                                  else { m--; }
×
318
                                                  while ( *m == 0 && nnum > 1 ) { m--; nnum--; }
×
319
                                                  m -= nnum;
×
320
                                                  if ( i < 0 && *t == NUMERATORSYMBOL ) nnum = -nnum;
×
321
                                                  i = t[1];
×
322
                                                  if ( i > 0 ) {
×
323
                                                        while ( i > 0 ) {
×
324
                                                                if ( Mully(BHEAD (UWORD *)n_coef,&ncoef,(UWORD *)m,nnum) )
×
325
                                                                                goto FromNorm;
×
326
                                                                i--;
×
327
                                                        }
328
                                                  }
329
                                                  else if ( i < 0 ) {
×
330
                                                        while ( i < 0 ) {
×
331
                                                                if ( Divvy(BHEAD (UWORD *)n_coef,&ncoef,(UWORD *)m,nnum) )
×
332
                                                                                goto FromNorm;
×
333
                                                                i++;
×
334
                                                        }
335
                                                  }
336
                                                }
337
                                                ncoef = INCLENG(ncoef);
×
338
                                                t += 2;
×
339
                                                goto NextSymbol;
×
340
                                        }
341
                                        else if ( *t == DIMENSIONSYMBOL ) {
10,803,080✔
342
                                                if ( AN.cTerm ) m = AN.cTerm;
×
343
                                                else m = term;
344
                                                k = DimensionTerm(m);
×
345
                                                if ( k == 0 ) goto NormZero;
×
346
                                                if ( k == MAXPOSITIVE ) {
×
347
                                                        MLOCK(ErrorMessageLock);
×
348
                                                        MesPrint("Dimension_ is undefined in term %t");
×
349
                                                        MUNLOCK(ErrorMessageLock);
×
350
                                                        goto NormMin;
×
351
                                                }
352
                                                if ( k == -MAXPOSITIVE ) {
×
353
                                                        MLOCK(ErrorMessageLock);
×
354
                                                        MesPrint("Dimension_ out of range in term %t");
×
355
                                                        MUNLOCK(ErrorMessageLock);
×
356
                                                        goto NormMin;
×
357
                                                }
358
                                                if ( k > 0 ) { *((UWORD *)lnum) = k; nnum = 1; }
×
359
                                                else { *((UWORD *)lnum) = -k; nnum = -1; }
×
360
                                                ncoef = REDLENG(ncoef);        
×
361
                                                if ( Mully(BHEAD (UWORD *)n_coef,&ncoef,(UWORD *)lnum,nnum) ) goto FromNorm;
×
362
                                                ncoef = INCLENG(ncoef);
×
363
                                                t += 2;
×
364
                                                goto NextSymbol;
×
365
                                        }
366
                                        if ( ( *t >= MAXPOWER && *t < 2*MAXPOWER )
10,803,080✔
367
                                                || ( *t < -MAXPOWER && *t > -2*MAXPOWER ) ) {
10,803,080✔
368
/*
369
                        #[ TO SNUMBER :
370
*/
371
                                if ( *t < 0 ) {
×
372
                                        *t += MAXPOWER;
×
373
                                        *t = -*t;
×
374
                                        if ( t[1] & 1 ) ncoef = -ncoef;
×
375
                                }
376
                                else if ( *t == MAXPOWER ) {
×
377
                                        if ( t[1] > 0 ) goto NormZero;
×
378
                                        goto NormInf;
×
379
                                }
380
                                else {
381
                                        *t -= MAXPOWER;
×
382
                                }
383
                                lnum[0] = *t;
×
384
                                nnum = 1;
×
385
                                if ( t[1] && RaisPow(BHEAD (UWORD *)lnum,&nnum,(UWORD)(ABS(t[1]))) )
×
386
                                        goto FromNorm;
×
387
                                ncoef = REDLENG(ncoef);
×
388
                                if ( t[1] < 0 ) {
×
389
                                        if ( Divvy(BHEAD (UWORD *)n_coef,&ncoef,(UWORD *)lnum,nnum) )
×
390
                                                goto FromNorm;
×
391
                                }
392
                                else if ( t[1] > 0 ) {
×
393
                                        if ( Mully(BHEAD (UWORD *)n_coef,&ncoef,(UWORD *)lnum,nnum) )
×
394
                                                goto FromNorm;
×
395
                                }
396
                                ncoef = INCLENG(ncoef);
×
397
/*
398
                        #] TO SNUMBER : 
399
*/
400
                                                t += 2;
×
401
                                                goto NextSymbol;
×
402
                                        }
403
                                        if ( ( *t <= NumSymbols && *t > -MAXPOWER )
10,803,080✔
404
                                         && ( symbols[*t].complex & VARTYPEROOTOFUNITY ) == VARTYPEROOTOFUNITY ) {
10,796,920✔
405
                                                if ( t[1] <= 2*MAXPOWER && t[1] >= -2*MAXPOWER ) {
×
406
                                                t[1] %= symbols[*t].maxpower;
×
407
                                                if ( t[1] < 0 ) t[1] += symbols[*t].maxpower;
×
408
                                                if ( ( symbols[*t].complex & VARTYPEMINUS ) == VARTYPEMINUS ) {
×
409
                                                        if ( ( ( symbols[*t].maxpower & 1 ) == 0 ) &&
×
410
                                                        ( t[1] >= symbols[*t].maxpower/2 ) ) {
×
411
                                                                t[1] -= symbols[*t].maxpower/2; ncoef = -ncoef;
×
412
                                                        }
413
                                                }
414
                                                if ( t[1] == 0 ) { t += 2; goto NextSymbol; }
×
415
                                                }
416
                                        }
417
                                        i = nsym;
10,803,080✔
418
                                        m = ppsym;
10,803,080✔
419
                                        if ( i > 0 ) do {
10,803,080✔
420
                                                m -= 2;
5,813,720✔
421
                                                if        ( *t == *m ) {
5,813,720✔
422
                                                        t++; m++;
3,280,777✔
423
                                                        if        ( *t > 2*MAXPOWER || *t < -2*MAXPOWER
3,280,777✔
424
                                                        ||        *m > 2*MAXPOWER || *m < -2*MAXPOWER ) {
3,280,777✔
425
                                                                MLOCK(ErrorMessageLock);
×
426
                                                                MesPrint("Illegal wildcard power combination.");
×
427
                                                                MUNLOCK(ErrorMessageLock);
×
428
                                                                goto NormMin;
×
429
                                                        }
430
                                                        *m += *t;
3,280,777✔
431
                                                        if ( ( t[-1] <= NumSymbols && t[-1] > -MAXPOWER )
3,280,777✔
432
                                                         && ( symbols[t[-1]].complex & VARTYPEROOTOFUNITY ) == VARTYPEROOTOFUNITY ) {
3,280,777✔
433
                                                                *m %= symbols[t[-1]].maxpower;
×
434
                                                                if ( *m < 0 ) *m += symbols[t[-1]].maxpower;
×
435
                                                                if ( ( symbols[t[-1]].complex & VARTYPEMINUS ) == VARTYPEMINUS ) {
×
436
                                                                        if ( ( ( symbols[t[-1]].maxpower & 1 ) == 0 ) &&
×
437
                                                                        ( *m >= symbols[t[-1]].maxpower/2 ) ) {
×
438
                                                                                *m -= symbols[t[-1]].maxpower/2; ncoef = -ncoef;
×
439
                                                                        }
440
                                                                }
441
                                                        }
442
                                                        if        ( *m >= 2*MAXPOWER || *m <= -2*MAXPOWER ) {
3,280,777✔
443
                                                                MLOCK(ErrorMessageLock);
×
444
                                                                MesPrint("Power overflow during normalization");
×
445
                                                                MUNLOCK(ErrorMessageLock);
×
446
                                                                goto NormMin;
×
447
                                                        }
448
                                                        if ( !*m ) {
3,280,777✔
449
                                                                m--;
450
                                                                while ( i < nsym )
15,347✔
451
                                                                        { *m = m[2]; m++; *m = m[2]; m++; i++; }
5,516✔
452
                                                                ppsym -= 2;
9,831✔
453
                                                                nsym--;
9,831✔
454
                                                        }
455
                                                        t++;
3,280,777✔
456
                                                        goto NextSymbol;
3,280,777✔
457
                                                }
458
                                        } while ( *t < *m && --i > 0 );
2,532,938✔
459
                                        m = ppsym;
460
                                        while ( i < nsym )
7,749,310✔
461
                                                { m--; m[2] = *m; m--; m[2] = *m; i++; }
227,010✔
462
                                        *m++ = *t++;
7,522,310✔
463
                                        *m = *t++;
7,522,310✔
464
                                        ppsym += 2;
7,522,310✔
465
                                        nsym++;
7,522,310✔
466
NextSymbol:;
10,807,220✔
467
                                } while ( t < r );
10,807,220✔
468
                                m = from;
469
                                break;
470
                        case VECTOR :
116✔
471
                                t += 2;
116✔
472
                                do {
116✔
473
                                        if ( t[0] == AM.vectorzero ) goto NormZero;
116✔
474
                                        if ( t[1] == FUNNYVEC ) {
116✔
475
                                                pind[nind++] = *t;
×
476
                                                t += 2;
×
477
                                        }
478
                                        else if ( t[1] < 0 ) {
116✔
479
                                                if ( *t == NOINDEX && t[1] == NOINDEX ) t += 2;
8✔
480
                                                else {
481
                                                        if ( t[1] == AM.vectorzero ) goto NormZero;
8✔
482
                                                        *ppdot++ = *t++; *ppdot++ = *t++; *ppdot++ = 1; ndot++; 
8✔
483
                                                }
484
                                        }
485
                                        else { *ppvec++ = *t++; *ppvec++ = *t++; nvec += 2; }
108✔
486
                                } while ( t < r );
116✔
487
                                break;
488
                        case DOTPRODUCT :
669✔
489
                                t += 2;
669✔
490
                                do {
777✔
491
                                        if ( t[2] == 0 ) t += 3;
777✔
492
                                        else if ( ndot > 0 && t[0] == ppdot[-3]
769✔
493
                                                && t[1] == ppdot[-2] ) {
92✔
494
                                                ppdot[-1] += t[2];
×
495
                                                t += 3;
×
496
                                                if ( ppdot[-1] == 0 ) { ppdot -= 3; ndot--; }
×
497
                                        }
498
                                        else if ( t[0] == AM.vectorzero || t[1] == AM.vectorzero ) {
769✔
499
                                                if ( t[2] > 0 ) goto NormZero;
×
500
                                                goto NormInf;
×
501
                                        }
502
                                        else {
503
                                                *ppdot++ = *t++; *ppdot++ = *t++;
769✔
504
                                                *ppdot++ = *t++; ndot++;
769✔
505
                                        }
506
                                } while ( t < r );
777✔
507
                                break;
508
                        case HAAKJE :
509
                                break;
510
                        case SETSET:
×
511
                                if ( WildFill(BHEAD termout,term,AT.dummysubexp) < 0 ) goto FromNorm;
×
512
                                i = *termout;
×
513
                                t = termout; m = term;
×
514
                                NCOPY(m,t,i);
×
515
                                goto Restart;
×
516
                        case DOLLAREXPRESSION :
33✔
517
/*
518
                                We have DOLLAREXPRESSION,4,number,power
519
                                Replace by SUBEXPRESSION and exit elegantly to let
520
                                TestSub pick it up. Of course look for special cases first.
521
                                Note that we have a special compiler buffer for the values.
522
*/
523
                                if ( AR.Eside != LHSIDE ) {
33✔
524
                                DOLLARS d = Dollars + t[2];
12✔
525
#ifdef WITHPTHREADS
526
                                int nummodopt, ptype = -1;
6✔
527
                                if ( AS.MultiThreaded ) {
6✔
528
                                        for ( nummodopt = 0; nummodopt < NumModOptdollars; nummodopt++ ) {
4✔
529
                                                if ( t[2] == ModOptdollars[nummodopt].number ) break;
530
                                        }
531
                                        if ( nummodopt < NumModOptdollars ) {
4✔
532
                                                ptype = ModOptdollars[nummodopt].type;
533
                                                if ( ptype == MODLOCAL ) {
534
                                                        d = ModOptdollars[nummodopt].dstruct+AT.identity;
535
                                                }
536
                                                else {
537
                                                        LOCK(d->pthreadslockread);
538
                                                }
539
                                        }
540
                                }
541
#endif
542
                                if ( d->type == DOLZERO ) {
12✔
543
#ifdef WITHPTHREADS
544
                                        if ( ptype > 0 && ptype != MODLOCAL ) { UNLOCK(d->pthreadslockread); }
545
#endif
546
                                        if ( t[3] == 0 ) goto NormZZ;
×
547
                                        if ( t[3] < 0 ) goto NormInf;
×
548
                                        goto NormZero;
×
549
                                }
550
                                else if ( d->type == DOLNUMBER ) {
12✔
551
                                        nnum = d->where[0];
×
552
                                        if ( nnum > 0 ) {
×
553
                                                nnum = d->where[nnum-1];
×
554
                                                if ( nnum < 0 ) { ncoef = -ncoef; nnum = -nnum; }
×
555
                                                nnum = (nnum-1)/2;
×
556
                                                for ( i = 1; i <= nnum; i++ ) lnum[i-1] = d->where[i];
×
557
                                        }
558
                                        if ( nnum == 0 || ( nnum == 1 && lnum[0] == 0 ) ) {
×
559
#ifdef WITHPTHREADS
560
                                                if ( ptype > 0 && ptype != MODLOCAL ) { UNLOCK(d->pthreadslockread); }
561
#endif
562
                                                if ( t[3] < 0 ) goto NormInf;
×
563
                                                else if ( t[3] == 0 ) goto NormZZ;
×
564
                                                goto NormZero;
×
565
                                        }
566
                                        if ( t[3] && RaisPow(BHEAD (UWORD *)lnum,&nnum,(UWORD)(ABS(t[3]))) ) goto FromNorm;
×
567
                                        ncoef = REDLENG(ncoef);
×
568
                                        if ( t[3] < 0 ) {
×
569
                                                if ( Divvy(BHEAD (UWORD *)n_coef,&ncoef,(UWORD *)lnum,nnum) ) {
×
570
#ifdef WITHPTHREADS
571
                                                        if ( ptype > 0 && ptype != MODLOCAL ) { UNLOCK(d->pthreadslockread); }
572
#endif
573
                                                        goto FromNorm;
×
574
                                                }
575
                                        }
576
                                        else if ( t[3] > 0 ) {
×
577
                                                if ( Mully(BHEAD (UWORD *)n_coef,&ncoef,(UWORD *)lnum,nnum) ) {
×
578
#ifdef WITHPTHREADS
579
                                                        if ( ptype > 0 && ptype != MODLOCAL ) { UNLOCK(d->pthreadslockread); }
580
#endif
581
                                                        goto FromNorm;
×
582
                                                }
583
                                        }
584
                                        ncoef = INCLENG(ncoef);
×
585
                                }
586
                                else if ( d->type == DOLINDEX ) {
12✔
587
                                        if ( d->index == 0 ) {
×
588
#ifdef WITHPTHREADS
589
                                                if ( ptype > 0 && ptype != MODLOCAL ) { UNLOCK(d->pthreadslockread); }
590
#endif
591
                                                goto NormZero;
×
592
                                        }
593
                                        if ( d->index != NOINDEX ) pind[nind++] = d->index;
×
594
                                }
595
                                else if ( d->type == DOLTERMS ) {
12✔
596
                                        if ( t[3] >= MAXPOWER || t[3] <= -MAXPOWER ) {
12✔
597
                                                if ( d->where[0] == 0 ) goto NormZero;
8✔
598
                                                if ( d->where[d->where[0]] != 0 ) {
8✔
599
IllDollarExp:
×
600
                                                        MLOCK(ErrorMessageLock);
×
601
                                                        MesPrint("!!!Illegal $ expansion with wildcard power!!!");
×
602
                                                        MUNLOCK(ErrorMessageLock);
×
603
                                                        goto FromNorm;
×
604
                                                }
605
/*
606
                                                At this point we should only admit symbols and dotproducts
607
                                                We expand the dollar directly and do not send it back.
608
*/
609
                                                {        WORD *td, *tdstop, dj;
8✔
610
                                                        td = d->where+1;
8✔
611
                                                        tdstop = d->where+d->where[0];
8✔
612
                                                        if ( tdstop[-1] != 3 || tdstop[-2] != 1
8✔
613
                                                                || tdstop[-3] != 1 ) goto IllDollarExp;
8✔
614
                                                        tdstop -= 3;
8✔
615
                                                        if ( td >= tdstop ) goto IllDollarExp;
8✔
616
                                                        while ( td < tdstop ) {
20✔
617
                                                                if ( *td == SYMBOL ) {
12✔
618
                                                                        for ( dj = 2; dj < td[1]; dj += 2 ) {
20✔
619
                                                                                if ( td[dj+1] == 1 ) {
12✔
620
                                                                                        *ppsym++ = td[dj];
12✔
621
                                                                                        *ppsym++ = t[3];
12✔
622
                                                                                        nsym++;
12✔
623
                                                                                }
624
                                                                                else if ( td[dj+1] == -1 ) {
×
625
                                                                                        *ppsym++ = td[dj];
×
626
                                                                                        *ppsym++ = -t[3];
×
627
                                                                                        nsym++;
×
628
                                                                                }
629
                                                                                else goto IllDollarExp;
×
630
                                                                        }
631
                                                                }
632
                                                                else if ( *td == DOTPRODUCT ) {
4✔
633
                                                                        for ( dj = 2; dj < td[1]; dj += 3 ) {
8✔
634
                                                                                if ( td[dj+2] == 1 ) {
4✔
635
                                                                                        *ppdot++ = td[dj];
4✔
636
                                                                                        *ppdot++ = td[dj+1];
4✔
637
                                                                                        *ppdot++ = t[3];
4✔
638
                                                                                        ndot++;
4✔
639
                                                                                }
640
                                                                                else if ( td[dj+2] == -1 ) {
×
641
                                                                                        *ppdot++ = td[dj];
×
642
                                                                                        *ppdot++ = td[dj+1];
×
643
                                                                                        *ppdot++ = -t[3];
×
644
                                                                                        ndot++;
×
645
                                                                                }
646
                                                                                else goto IllDollarExp;
×
647
                                                                        }
648
                                                                }
649
                                                                else goto IllDollarExp;
×
650
                                                                td += td[1];
12✔
651
                                                        }
652
                                                        regval = 2;
653
                                                        break;
654
                                                }
655
                                        }
656
                                        t[0] = SUBEXPRESSION;
4✔
657
                                        t[4] = AM.dbufnum;
4✔
658
                                        if ( t[3] == 0 ) {
4✔
659
#ifdef WITHPTHREADS
660
                                                if ( ptype > 0 && ptype != MODLOCAL ) { UNLOCK(d->pthreadslockread); }
661
#endif
662
                                                break;
663
                                        }
664
                                        regval = 2;
8✔
665
                                        t = r;
666
                                        while ( t < m ) {
8✔
667
                                                if ( *t == DOLLAREXPRESSION ) {
4✔
668
#ifdef WITHPTHREADS
669
                                                        if ( ptype > 0 && ptype != MODLOCAL ) { UNLOCK(d->pthreadslockread); }
670
#endif
671
                                                        d = Dollars + t[2];
×
672
#ifdef WITHPTHREADS
673
                                                        if ( AS.MultiThreaded ) {
674
                                                                for ( nummodopt = 0; nummodopt < NumModOptdollars; nummodopt++ ) {
675
                                                                        if ( t[2] == ModOptdollars[nummodopt].number ) break;
676
                                                                }
677
                                                                if ( nummodopt < NumModOptdollars ) {
678
                                                                        ptype = ModOptdollars[nummodopt].type;
679
                                                                        if ( ptype == MODLOCAL ) {
680
                                                                                d = ModOptdollars[nummodopt].dstruct+AT.identity;
681
                                                                        }
682
                                                                        else {
683
                                                                                LOCK(d->pthreadslockread);
684
                                                                        }
685
                                                                }
686
                                                        }
687
#endif
688
                                                        if ( d->type == DOLTERMS ) {
×
689
                                                                t[0] = SUBEXPRESSION;
×
690
                                                                t[4] = AM.dbufnum;
×
691
                                                        }
692
                                                }
693
                                                t += t[1];
4✔
694
                                        }
695
#ifdef WITHPTHREADS
696
                                        if ( ptype > 0 && ptype != MODLOCAL ) { UNLOCK(d->pthreadslockread); }
2✔
697
#endif
698
                                        goto RegEnd;
4✔
699
                                }
700
                                else {
701
#ifdef WITHPTHREADS
702
                                        if ( ptype > 0 && ptype != MODLOCAL ) { UNLOCK(d->pthreadslockread); }
703
#endif
704
                                        MLOCK(ErrorMessageLock);
×
705
                                        MesPrint("!!!This $ variation has not been implemented yet!!!");
×
706
                                        MUNLOCK(ErrorMessageLock);
×
707
                                        goto NormMin;
×
708
                                }
709
#ifdef WITHPTHREADS
710
                                if ( ptype > 0 && ptype != MODLOCAL ) { UNLOCK(d->pthreadslockread); }
711
#endif
712
                                }
713
                                else {
714
                                        pnco[nnco++] = t;
21✔
715
/*
716
                                        The next statement should be safe as the value is used
717
                                        only by the compiler (ie the master).
718
*/
719
                                        AC.lhdollarflag = 1;
21✔
720
                                }
721
                                break;
722
                        case DELTA :
16,429,200✔
723
                                t += 2;
16,429,200✔
724
                                do {
130,580,000✔
725
                                        if ( *t < 0 ) {
130,580,000✔
726
                                                if ( *t == SUMMEDIND ) {
400✔
727
                                                        if ( t[1] < -NMIN4SHIFT ) {
×
728
                                                                k = -t[1]-NMIN4SHIFT;
×
729
                                                                k = ExtraSymbol(k,1,nsym,ppsym,&ncoef);
×
730
                                                                nsym += k;
×
731
                                                                ppsym += (k * 2);
×
732
                                                        }
733
                                                        else if ( t[1] == 0 ) goto NormZero;
×
734
                                                        else {
735
                                                                if ( t[1] < 0 ) {
×
736
                                                                        lnum[0] = -t[1];
×
737
                                                                        nnum = -1;
×
738
                                                                }
739
                                                                else {
740
                                                                        lnum[0] = t[1];
×
741
                                                                        nnum = 1;
×
742
                                                                }
743
                                                                ncoef = REDLENG(ncoef);
×
744
                                                                if ( Mully(BHEAD (UWORD *)n_coef,&ncoef,(UWORD *)lnum,nnum) )
×
745
                                                                        goto FromNorm;
×
746
                                                                ncoef = INCLENG(ncoef);
×
747
                                                        }
748
                                                        t += 2;
×
749
                                                }
750
                                                else if ( *t == NOINDEX && t[1] == NOINDEX ) t += 2;
400✔
751
                                                else if ( *t == EMPTYINDEX && t[1] == EMPTYINDEX ) {
400✔
752
                                                        *ppdel++ = *t++; *ppdel++ = *t++; ndel += 2;
×
753
                                                }
754
                                                else
755
                                                if ( t[1] < 0 ) {
400✔
756
                                                        *ppdot++ = *t++; *ppdot++ = *t++; *ppdot++ = 1; ndot++; 
396✔
757
                                                }
758
                                                else {
759
                                                        *ppvec++ = *t++; *ppvec++ = *t++; nvec += 2;
4✔
760
                                                }
761
                                        }
762
                                        else {
763
                                                if ( t[1] < 0 ) {
130,579,600✔
764
                                                        *ppvec++ = t[1]; *ppvec++ = *t; t+=2; nvec += 2;
×
765
                                                }
766
                                                else { *ppdel++ = *t++; *ppdel++ = *t++; ndel += 2; }
130,579,600✔
767
                                        }
768
                                } while ( t < r );
130,580,000✔
769
                                break;
770
                        case FACTORIAL :
×
771
/*
772
                                (FACTORIAL,FUNHEAD+2,..,-SNUMBER,number)
773
*/
774
                                if ( t[FUNHEAD] == -SNUMBER && t[1] == FUNHEAD+2
×
775
                                                                                        && t[FUNHEAD+1] >= 0 ) {
×
776
                                        if ( Factorial(BHEAD t[FUNHEAD+1],(UWORD *)lnum,&nnum) )
×
777
                                                goto FromNorm;
×
778
MulIn:
×
779
                                        ncoef = REDLENG(ncoef);        
7,135✔
780
                                        if ( Mully(BHEAD (UWORD *)n_coef,&ncoef,(UWORD *)lnum,nnum) ) goto FromNorm;
7,135✔
781
                                        ncoef = INCLENG(ncoef);
7,135✔
782
                                }
783
                                else pcom[ncom++] = t;
×
784
                                break;
785
                        case BERNOULLIFUNCTION :
×
786
/*
787
                                (BERNOULLIFUNCTION,FUNHEAD+2,..,-SNUMBER,number)
788
*/
789
                                if ( ( t[FUNHEAD] == -SNUMBER && t[FUNHEAD+1] >= 0 )
×
790
                                && ( t[1] == FUNHEAD+2 || ( t[1] == FUNHEAD+4 &&
×
791
                                t[FUNHEAD+2] == -SNUMBER && ABS(t[FUNHEAD+3]) == 1 ) ) ) {
×
792
                                        WORD inum, mnum;
×
793
                                        if ( Bernoulli(t[FUNHEAD+1],(UWORD *)lnum,&nnum) )
×
794
                                                goto FromNorm;
×
795
                                        if ( nnum == 0 ) goto NormZero;
×
796
                                        inum = nnum; if ( inum < 0 ) inum = -inum;
×
797
                                        inum--; inum /= 2;
×
798
                                        mnum = inum;
×
799
                                        while ( lnum[mnum-1] == 0 ) mnum--;
×
800
                                        if ( nnum < 0 ) mnum = -mnum;
×
801
                                        ncoef = REDLENG(ncoef);        
×
802
                                        if ( Mully(BHEAD (UWORD *)n_coef,&ncoef,(UWORD *)lnum,mnum) ) goto FromNorm;
×
803
                                        mnum = inum;
804
                                        while ( lnum[inum+mnum-1] == 0 ) mnum--;
×
805
                                        if ( Divvy(BHEAD (UWORD *)n_coef,&ncoef,(UWORD *)(lnum+inum),mnum) ) goto FromNorm;
×
806
                                        ncoef = INCLENG(ncoef);
×
807
                                        if ( t[1] == FUNHEAD+4 && t[FUNHEAD+1] == 1
×
808
                                         && t[FUNHEAD+3] == -1 ) ncoef = -ncoef; 
×
809
                                }
810
                                else pcom[ncom++] = t;
×
811
                                break;
812
                        case NUMARGSFUN:
20✔
813
/*
814
                                Numerical function giving the number of arguments.
815
*/
816
                                k = 0;
20✔
817
                                t += FUNHEAD;
20✔
818
                                while ( t < r ) {
20✔
819
                                        k++;
40,140✔
820
                                        NEXTARG(t);
40,160✔
821
                                }
822
                                if ( k == 0 ) goto NormZero;
20✔
823
                                *((UWORD *)lnum) = k;
20✔
824
                                nnum = 1;
20✔
825
                                goto MulIn;
20✔
826
                        case NUMFACTORS:
28✔
827
/*
828
                                Numerical function giving the number of factors in an expression.
829
*/
830
                                t += FUNHEAD;
28✔
831
                                if ( *t == -EXPRESSION ) {
28✔
832
                                        k = AS.OldNumFactors[t[1]];
24✔
833
                                }
834
                                else if ( *t == -DOLLAREXPRESSION ) {
4✔
835
                                        k = Dollars[t[1]].nfactors;
4✔
836
                                }
837
                                else {
838
                                        pcom[ncom++] = t;
×
839
                                        break;
×
840
                                }
841
                                if ( k == 0 ) goto NormZero;
28✔
842
                                *((UWORD *)lnum) = k;
24✔
843
                                nnum = 1;
24✔
844
                                goto MulIn;
24✔
845
                        case NUMTERMSFUN:
×
846
/*
847
                                Numerical function giving the number of terms in the single argument.
848
*/
849
                                if ( t[FUNHEAD] < 0 ) {
×
850
                                        if ( t[FUNHEAD] <= -FUNCTION && t[1] == FUNHEAD+1 ) break;
×
851
                                        if ( t[FUNHEAD] > -FUNCTION && t[1] == FUNHEAD+2 ) {
×
852
                                                if ( t[FUNHEAD] == -SNUMBER && t[FUNHEAD+1] == 0 ) goto NormZero;
×
853
                                                break;
854
                                        }
855
                                        pcom[ncom++] = t;
×
856
                                        break;
×
857
                                }
858
                                if ( t[FUNHEAD] > 0 && t[FUNHEAD] == t[1]-FUNHEAD ) {
×
859
                                        k = 0;
×
860
                                        t += FUNHEAD+ARGHEAD;
×
861
                                        while ( t < r ) {
×
862
                                                k++;
×
863
                                                t += *t;
×
864
                                        }
865
                                        if ( k == 0 ) goto NormZero;
×
866
                                        *((UWORD *)lnum) = k;
×
867
                                        nnum = 1;
×
868
                                        goto MulIn;
×
869
                                }
870
                                else pcom[ncom++] = t;
×
871
                                break;
×
872
                        case COUNTFUNCTION:
9,251✔
873
                                if ( AN.cTerm ) {
9,251✔
874
                                        k = CountFun(AN.cTerm,t);
9,239✔
875
                                }
876
                                else {
877
                                        k = CountFun(term,t);
12✔
878
                                }
879
                                if ( k == 0 ) goto NormZero;
9,251✔
880
                                if ( k > 0 ) { *((UWORD *)lnum) = k; nnum = 1; }
7,083✔
881
                                else { *((UWORD *)lnum) = -k; nnum = -1; }
2,127✔
882
                                goto MulIn;
7,083✔
883
                                break;
4✔
884
                        case MAKERATIONAL:
4✔
885
                                if ( t[FUNHEAD] == -SNUMBER && t[FUNHEAD+2] == -SNUMBER
4✔
886
                                        && t[1] == FUNHEAD+4 && t[FUNHEAD+3] > 1 ) {
4✔
887
                                        WORD x1[2], sgn;
4✔
888
                                        if ( t[FUNHEAD+1] == 0 ) goto NormZero;
4✔
889
                                        if ( t[FUNHEAD+1] < 0 ) { t[FUNHEAD+1] = -t[FUNHEAD+1]; sgn = -1; }
4✔
890
                                        else sgn = 1;
891
                                        if ( MakeRational(t[FUNHEAD+1],t[FUNHEAD+3],x1,x1+1) ) {
4✔
892
                                                static int warnflag = 1;
×
893
                                                if ( warnflag ) {
×
894
                                                        MesPrint("%w Warning: fraction could not be reconstructed in MakeRational_");
×
895
                                                        warnflag = 0;
×
896
                                                }
897
                                                x1[0] = t[FUNHEAD+1]; x1[1] = 1;
×
898
                                        }
899
                                        if ( sgn < 0 ) { t[FUNHEAD+1] = -t[FUNHEAD+1]; x1[0] = -x1[0]; }
4✔
900
                                        if ( x1[0] < 0 ) { sgn = -1; x1[0] = -x1[0]; }
4✔
901
                                        else sgn = 1;
902
                                        ncoef = REDLENG(ncoef);
4✔
903
                                        if ( MulRat(BHEAD (UWORD *)n_coef,ncoef,(UWORD *)x1,sgn,
4✔
904
                                        (UWORD *)n_coef,&ncoef) ) goto FromNorm;
×
905
                                        ncoef = INCLENG(ncoef);
4✔
906
                                }
907
                                else {
908
                                        WORD narg = 0, *tt, *ttstop, *arg1 = 0, *arg2 = 0;
×
909
                                        UWORD *x1, *x2, *xx;
×
910
                                        WORD nx1,nx2,nxx;
×
911
                                        ttstop = t + t[1]; tt = t+FUNHEAD;
×
912
                                        while ( tt < ttstop ) {
×
913
                                                narg++;
×
914
                                                if ( narg == 1 ) arg1 = tt;
×
915
                                                else arg2 = tt;
916
                                                NEXTARG(tt);
×
917
                                        }
918
                                        if ( narg != 2 ) goto defaultcase;
×
919
                                        if ( *arg2 == -SNUMBER && arg2[1] <= 1 ) goto defaultcase;
×
920
                                        else if ( *arg2 > 0 && ttstop[-1] < 0 ) goto defaultcase;
×
921
                                        x1 = NumberMalloc("Norm-MakeRational");
×
922
                                        if ( *arg1 == -SNUMBER ) {
×
923
                                                if ( arg1[1] == 0 ) {
×
924
                                                        NumberFree(x1,"Norm-MakeRational");
×
925
                                                        goto NormZero;
×
926
                                                }
927
                                                if ( arg1[1] < 0 ) { x1[0] = -arg1[1]; nx1 = -1; }
×
928
                                                else { x1[0] = arg1[1]; nx1 = 1; }
×
929
                                        }
930
                                        else if ( *arg1 > 0 ) {
×
931
                                                WORD *tc;
×
932
                                                nx1 = (ABS(arg2[-1])-1)/2;
×
933
                                                tc = arg1+ARGHEAD+1+nx1;
×
934
                                                if ( tc[0] != 1 ) {
×
935
                                                        NumberFree(x1,"Norm-MakeRational");
×
936
                                                        goto defaultcase;
×
937
                                                }
938
                                                for ( i = 1; i < nx1; i++ ) if ( tc[i] != 0 ) {
×
939
                                                        NumberFree(x1,"Norm-MakeRational");
×
940
                                                        goto defaultcase;
×
941
                                                }
942
                                                tc = arg1+ARGHEAD+1;
×
943
                                                for ( i = 0; i < nx1; i++ ) x1[i] = tc[i];
×
944
                                                if ( arg2[-1] < 0 ) nx1 = -nx1;
×
945
                                        }
946
                                        else {
947
                                                NumberFree(x1,"Norm-MakeRational");
×
948
                                                goto defaultcase;
×
949
                                        }
950
                                        x2 = NumberMalloc("Norm-MakeRational");
×
951
                                        if ( *arg2 == -SNUMBER ) {
×
952
                                                if ( arg2[1] <= 1 ) {
×
953
                                                        NumberFree(x2,"Norm-MakeRational");
×
954
                                                        NumberFree(x1,"Norm-MakeRational");
×
955
                                                        goto defaultcase;
×
956
                                                }
957
                                                else { x2[0] = arg2[1]; nx2 = 1; }
×
958
                                        }
959
                                        else if ( *arg2 > 0 ) {
×
960
                                                WORD *tc;
×
961
                                                nx2 = (ttstop[-1]-1)/2;
×
962
                                                tc = arg2+ARGHEAD+1+nx2;
×
963
                                                if ( tc[0] != 1 ) {
×
964
                                                        NumberFree(x2,"Norm-MakeRational");
×
965
                                                        NumberFree(x1,"Norm-MakeRational");
×
966
                                                        goto defaultcase;
×
967
                                                }
968
                                                for ( i = 1; i < nx2; i++ ) if ( tc[i] != 0 ) {
×
969
                                                        NumberFree(x2,"Norm-MakeRational");
×
970
                                                        NumberFree(x1,"Norm-MakeRational");
×
971
                                                        goto defaultcase;
×
972
                                                }
973
                                                tc = arg2+ARGHEAD+1;
×
974
                                                for ( i = 0; i < nx2; i++ ) x2[i] = tc[i];
×
975
                                        }
976
                                        else {
977
                                                NumberFree(x2,"Norm-MakeRational");
×
978
                                                NumberFree(x1,"Norm-MakeRational");
×
979
                                                goto defaultcase;
×
980
                                        }
981
                                        if ( BigLong(x1,ABS(nx1),x2,nx2) >= 0 ) {
×
982
                                                UWORD *x3 = NumberMalloc("Norm-MakeRational");
×
983
                                                UWORD *x4 = NumberMalloc("Norm-MakeRational");
×
984
                                                WORD nx3, nx4;
×
985
                                                DivLong(x1,nx1,x2,nx2,x3,&nx3,x4,&nx4);
×
986
                                                for ( i = 0; i < ABS(nx4); i++ ) x1[i] = x4[i];
×
987
                                                nx1 = nx4;
×
988
                                                NumberFree(x4,"Norm-MakeRational");
×
989
                                                NumberFree(x3,"Norm-MakeRational");
×
990
                                        }
991
                                        xx = (UWORD *)(TermMalloc("Norm-MakeRational"));
×
992
                                        if ( MakeLongRational(BHEAD x1,nx1,x2,nx2,xx,&nxx) ) {
×
993
                                                static int warnflag = 1;
×
994
                                                if ( warnflag ) {
×
995
                                                        MesPrint("%w Warning: fraction could not be reconstructed in MakeRational_");
×
996
                                                        warnflag = 0;
×
997
                                                }
998
                                                ncoef = REDLENG(ncoef);
×
999
                                                if ( Mully(BHEAD (UWORD *)n_coef,&ncoef,x1,nx1) )
×
1000
                                                        goto FromNorm;
×
1001
                                        }
1002
                                        else {
1003
                                                ncoef = REDLENG(ncoef);
×
1004
                                                if ( MulRat(BHEAD (UWORD *)n_coef,ncoef,xx,nxx,
×
1005
                                                (UWORD *)n_coef,&ncoef) ) goto FromNorm;
×
1006
                                        }
1007
                                        ncoef = INCLENG(ncoef);
×
1008
                                        TermFree(xx,"Norm-MakeRational");
×
1009
                                        NumberFree(x2,"Norm-MakeRational");
×
1010
                                        NumberFree(x1,"Norm-MakeRational");
×
1011
                                }
1012
                                break;
1013
                        case TERMFUNCTION:
44✔
1014
                                if ( t[1] == FUNHEAD && AN.cTerm ) {
44✔
1015
                                        ANsr = r; ANsm = m; ANsc = AN.cTerm;
44✔
1016
                                        AN.cTerm = 0;
44✔
1017
                                        t = ANsc + 1;
44✔
1018
                                        m = ANsc + *ANsc;
44✔
1019
                                        ncoef = REDLENG(ncoef);
44✔
1020
                                        nnum = REDLENG(m[-1]);        
44✔
1021
                                        m -= ABS(m[-1]);
44✔
1022
                                        if ( MulRat(BHEAD (UWORD *)n_coef,ncoef,(UWORD *)m,nnum,
44✔
1023
                                        (UWORD *)n_coef,&ncoef) ) goto FromNorm;
×
1024
                                        ncoef = INCLENG(ncoef);
44✔
1025
                                        r = t;
44✔
1026
                                }
1027
                                break;
1028
                        case FIRSTBRACKET:
×
1029
                                if ( ( t[1] == FUNHEAD+2 ) && t[FUNHEAD] == -EXPRESSION ) {
×
1030
                                        if ( GetFirstBracket(termout,t[FUNHEAD+1]) < 0 ) goto FromNorm;
×
1031
                                        if ( *termout == 0 ) goto NormZero;
×
1032
                                        if ( *termout > 4 ) {
×
1033
                                                WORD *r1, *r2, *r3;
1034
                                                while ( r < m ) *t++ = *r++;
×
1035
                                                r1 = term + *term;
×
1036
                                                r2 = termout + *termout; r2 -= ABS(r2[-1]);
×
1037
                                                while ( r < r1 ) *r2++ = *r++;
×
1038
                                                r3 = termout + 1;
1039
                                                while ( r3 < r2 ) *t++ = *r3++;
×
1040
                                                *term = t - term;
×
1041
                                                if ( AT.WorkPointer > term && AT.WorkPointer < t )
×
1042
                                                        AT.WorkPointer = t;
×
1043
                                                goto Restart;
×
1044
                                        }
1045
                                }
1046
                                break;
1047
                        case FIRSTTERM:
21✔
1048
                        case CONTENTTERM:
1049
                                if ( ( t[1] == FUNHEAD+2 ) && t[FUNHEAD] == -EXPRESSION ) {
21✔
1050
                                        {
1051
                                                EXPRESSIONS e = Expressions+t[FUNHEAD+1];
×
1052
                                                POSITION oldondisk = AS.OldOnFile[t[FUNHEAD+1]];
×
1053
                                                if ( e->replace == NEWLYDEFINEDEXPRESSION ) {
×
1054
                                                        AS.OldOnFile[t[FUNHEAD+1]] = e->onfile;
×
1055
                                                }
1056
                                                if ( *t == FIRSTTERM ) {
×
1057
                                                        if ( GetFirstTerm(termout,t[FUNHEAD+1]) < 0 ) goto FromNorm;
×
1058
                                                }
1059
                                                else if ( *t == CONTENTTERM ) {
×
1060
                                                        if ( GetContent(termout,t[FUNHEAD+1]) < 0 ) goto FromNorm;
×
1061
                                                }
1062
                                                AS.OldOnFile[t[FUNHEAD+1]] = oldondisk;
×
1063
                                                if ( *termout == 0 ) goto NormZero;
×
1064
                                        }
1065
PasteIn:;
21✔
1066
                                        {
1067
                                                WORD *r1, *r2, *r3, *r4, *r5, nr1, *rterm;
21✔
1068
                                                r2 = termout + *termout; lnum = r2 - ABS(r2[-1]);
21✔
1069
                                                nnum = REDLENG(r2[-1]);
21✔
1070

1071
                                                r1 = term + *term; r3 = r1 - ABS(r1[-1]);
21✔
1072
                                                nr1 = REDLENG(r1[-1]);
21✔
1073
                                                if ( Mully(BHEAD (UWORD *)lnum,&nnum,(UWORD *)r3,nr1) ) goto FromNorm;
21✔
1074
                                                nnum = INCLENG(nnum); nr1 = ABS(nnum); lnum[nr1-1] = nnum;
21✔
1075
                                                rterm = TermMalloc("FirstTerm/ContentTerm");
21✔
1076
                                                r4 = rterm+1; r5 = term+1; while ( r5 < t ) *r4++ = *r5++;
21✔
1077
                                                r5 = termout+1; while ( r5 < lnum ) *r4++ = *r5++;
119✔
1078
                                                r5 = r; while ( r5 < r3 ) *r4++ = *r5++;
49✔
1079
                                                r5 = lnum; NCOPY(r4,r5,nr1);
84✔
1080
                                                *rterm = r4-rterm;
21✔
1081
                                                nr1 = *rterm; r1 = term; r2 = rterm; NCOPY(r1,r2,nr1);
231✔
1082
                                                TermFree(rterm,"FirstTerm/ContentTerm");
21✔
1083
                                                if ( AT.WorkPointer > term && AT.WorkPointer < r1 )
21✔
1084
                                                        AT.WorkPointer = r1;
×
1085
                                                goto Restart;
21✔
1086
                                        }
1087
                                }
1088
                                else if ( ( t[1] == FUNHEAD+2 ) && t[FUNHEAD] == -DOLLAREXPRESSION ) {
21✔
1089
                                        DOLLARS d = Dollars + t[FUNHEAD+1], newd = 0;
21✔
1090
                                        int idol, ido;
21✔
1091
#ifdef WITHPTHREADS
1092
                                        int nummodopt, dtype = -1;
6✔
1093
                                        if ( AS.MultiThreaded && ( AC.mparallelflag == PARALLELFLAG ) ) {
6✔
1094
                                                for ( nummodopt = 0; nummodopt < NumModOptdollars; nummodopt++ ) {
6✔
1095
                                                        if ( t[FUNHEAD+1] == ModOptdollars[nummodopt].number ) break;
1096
                                                }
1097
                                                if ( nummodopt < NumModOptdollars ) {
6✔
1098
                                                        dtype = ModOptdollars[nummodopt].type;
1099
                                                        if ( dtype == MODLOCAL ) {
1100
                                                                d = ModOptdollars[nummodopt].dstruct+AT.identity;
1101
                                                        }
1102
                                                }
1103
                                        }
1104
#endif
1105
                                        if ( d->where && ( d->type == DOLTERMS || d->type == DOLNUMBER ) ) {
21✔
1106
                                                newd = d;
1107
                                        }
1108
                                        else {
1109
                                                if ( ( newd = DolToTerms(BHEAD t[FUNHEAD+1]) ) == 0 )
×
1110
                                                        goto NormZero;
×
1111
                                        }
1112
                                        if ( newd->where[0] == 0 ) {
21✔
1113
                                                M_free(newd,"Copy of dollar variable");
×
1114
                                                goto NormZero;
×
1115
                                        }
1116
                                        if ( *t == FIRSTTERM ) {
21✔
1117
                                                idol = newd->where[0];
×
1118
                                                for ( ido = 0; ido < idol; ido++ ) termout[ido] = newd->where[ido];
×
1119
                                        }
1120
                                        else if ( *t == CONTENTTERM ) {
21✔
1121
                                                WORD *tterm;
1122
                                                tterm = newd->where;
175✔
1123
                                                idol = tterm[0];
175✔
1124
                                                for ( ido = 0; ido < idol; ido++ ) termout[ido] = tterm[ido];
175✔
1125
                                                tterm += *tterm;
21✔
1126
                                                while ( *tterm ) {
49✔
1127
                                                        if ( ContentMerge(BHEAD termout,tterm) < 0 ) goto FromNorm;
28✔
1128
                                                        tterm += *tterm;
28✔
1129
                                                }
1130
                                        }
1131
                                        if ( newd != d ) {
21✔
1132
                                                if ( newd->factors ) M_free(newd->factors,"Dollar factors");
×
1133
                                                M_free(newd,"Copy of dollar variable");
×
1134
                                                newd = 0;
×
1135
                                        }
1136
                                        goto PasteIn;
21✔
1137
                                }
1138
                                break;
1139
                        case TERMSINEXPR:
48✔
1140
                                {
1141
                                if ( ( t[1] == FUNHEAD+2 ) && t[FUNHEAD] == -EXPRESSION ) {
48✔
1142
                                        x = TermsInExpression(t[FUNHEAD+1]);
8✔
1143
multermnum:                        if ( x == 0 ) goto NormZero;
48✔
1144
                                        if ( x < 0 ) {
48✔
1145
                                                x = -x;
×
1146
                                                if ( x > (LONG)WORDMASK ) { lnum[0] = x & WORDMASK;
×
1147
                                                        lnum[1] = x >> BITSINWORD; nnum = -2;
×
1148
                                                }
1149
                                                else { lnum[0] = x; nnum = -1; }
×
1150
                                        }
1151
                                        else if ( x > (LONG)WORDMASK ) {
48✔
1152
                                                lnum[0] = x & WORDMASK;
×
1153
                                                lnum[1] = x >> BITSINWORD;
×
1154
                                                nnum = 2;
×
1155
                                        }
1156
                                        else { lnum[0] = x; nnum = 1; }
48✔
1157
                                        ncoef = REDLENG(ncoef);
48✔
1158
                                        if ( Mully(BHEAD (UWORD *)n_coef,&ncoef,(UWORD *)lnum,nnum) )
48✔
1159
                                                goto FromNorm;
×
1160
                                        ncoef = INCLENG(ncoef);
48✔
1161
                                }
1162
                                else if ( ( t[1] == FUNHEAD+2 ) && t[FUNHEAD] == -DOLLAREXPRESSION ) {
40✔
1163
                                        x = TermsInDollar(t[FUNHEAD+1]);
40✔
1164
                                        goto multermnum;
40✔
1165
                                }
1166
                                else { pcom[ncom++] = t; }
×
1167
                                }
1168
                                break;
1169
                        case SIZEOFFUNCTION:
×
1170
                                {
1171
                                if ( ( t[1] == FUNHEAD+2 ) && t[FUNHEAD] == -EXPRESSION ) {
×
1172
                                        x = SizeOfExpression(t[FUNHEAD+1]);
×
1173
                                        goto multermnum;
×
1174
                                }
1175
                                else if ( ( t[1] == FUNHEAD+2 ) && t[FUNHEAD] == -DOLLAREXPRESSION ) {
×
1176
                                        x = SizeOfDollar(t[FUNHEAD+1]);
×
1177
                                        goto multermnum;
×
1178
                                }
1179
                                else { pcom[ncom++] = t; }
×
1180
                                }
1181
                                break;
×
1182
                        case MATCHFUNCTION:
1183
                        case PATTERNFUNCTION:
1184
                                break;
1185
                        case BINOMIAL:
×
1186
/*
1187
                                Binomial function for internal use for the moment.
1188
                                The routine in reken.c should be more efficient.
1189
*/
1190
                                if ( t[1] == FUNHEAD+4 && t[FUNHEAD] == -SNUMBER
×
1191
                                && t[FUNHEAD+1] >= 0 && t[FUNHEAD+2] == -SNUMBER
×
1192
                                && t[FUNHEAD+3] >= 0 && t[FUNHEAD+1] >= t[FUNHEAD+3] ) {
×
1193
                                        if ( t[FUNHEAD+1] > t[FUNHEAD+3] ) {
×
1194
                                                if ( GetBinom((UWORD *)lnum,&nnum,
×
1195
                                                t[FUNHEAD+1],t[FUNHEAD+3]) ) goto FromNorm;
×
1196
                                                if ( nnum == 0 ) goto NormZero;
×
1197
                                                goto MulIn;
×
1198
                                        }
1199
                                }
1200
                                else pcom[ncom++] = t;
×
1201
                                break;
1202
                        case SIGNFUN:
×
1203
/*
1204
                                Numerical function giving (-1)^arg
1205
*/
1206
                                if ( t[1] == FUNHEAD+2 && t[FUNHEAD] == -SNUMBER ) {
×
1207
                                        if ( ( t[FUNHEAD+1] & 1 ) != 0 ) ncoef = -ncoef;
×
1208
                                }
1209
                                else if ( ( t[FUNHEAD] > 0 ) && ( t[1] == FUNHEAD+t[FUNHEAD] )
×
1210
                                && ( t[FUNHEAD] == ARGHEAD+1+abs(t[t[1]-1]) ) ) {
×
1211
                                        UWORD *numer1,*denom1;
×
1212
                                        WORD nsize = abs(t[t[1]-1]), nnsize, isize;
×
1213
                                        nnsize = (nsize-1)/2;
×
1214
                                        numer1 = (UWORD *)(t + FUNHEAD+ARGHEAD+1);
×
1215
                                        denom1 = numer1 + nnsize;
×
1216
                                        for ( isize = 1; isize < nnsize; isize++ ) {
×
1217
                                                if ( denom1[isize] ) break;
×
1218
                                        }
1219
                                        if ( ( denom1[0] != 1 ) || isize < nnsize ) {
×
1220
                                                pcom[ncom++] = t;
×
1221
                                        }
1222
                                        else {
1223
                                                if ( ( numer1[0] & 1 ) != 0 ) ncoef = -ncoef;
×
1224
                                        }
1225
                                }
1226
                                else {
1227
                                        goto doflags;
×
1228
/*                                        pcom[ncom++] = t; */
1229
                                }
1230
                                break;
1231
                        case SIGFUNCTION:
52✔
1232
/*
1233
                                Numerical function giving the sign of the numerical argument
1234
                                The sign of zero is 1.
1235
                                If there are roots of unity they are part of the sign.
1236
*/
1237
                                if ( t[1] == FUNHEAD+2 && t[FUNHEAD] == -SNUMBER ) {
52✔
1238
                                        if ( t[FUNHEAD+1] < 0 ) ncoef = -ncoef;
52✔
1239
                                }
1240
                                else if ( ( t[1] == FUNHEAD+2 ) && ( t[FUNHEAD] == -SYMBOL )
×
1241
                                        && ( ( t[FUNHEAD+1] <= NumSymbols && t[FUNHEAD+1] > -MAXPOWER )
×
1242
                                        && ( symbols[t[FUNHEAD+1]].complex & VARTYPEROOTOFUNITY ) == VARTYPEROOTOFUNITY ) ) {
×
1243
                                        k = t[FUNHEAD+1];
×
1244
                                        from = m;
×
1245
                                        i = nsym;
×
1246
                                        m = ppsym;
×
1247
                                        if ( i > 0 ) do {
×
1248
                                                m -= 2;
×
1249
                                                if        ( k == *m ) {
×
1250
                                                        m++;
×
1251
                                                        *m = *m + 1;
×
1252
                                                        *m %= symbols[k].maxpower;
×
1253
                                                        if ( ( symbols[k].complex & VARTYPEMINUS ) == VARTYPEMINUS ) {
×
1254
                                                                if ( ( ( symbols[k].maxpower & 1 ) == 0 ) &&
×
1255
                                                                ( *m >= symbols[k].maxpower/2 ) ) {
×
1256
                                                                        *m -= symbols[k].maxpower/2; ncoef = -ncoef;
×
1257
                                                                }
1258
                                                        }
1259
                                                        if ( !*m ) {
×
1260
                                                                m--;
1261
                                                                while ( i < nsym )
×
1262
                                                                        { *m = m[2]; m++; *m = m[2]; m++; i++; }
×
1263
                                                                ppsym -= 2;
×
1264
                                                                nsym--;
×
1265
                                                        }
1266
                                                        goto sigDoneSymbol;
×
1267
                                                }
1268
                                        } while ( k < *m && --i > 0 );
×
1269
                                        m = ppsym;
1270
                                        while ( i < nsym )
×
1271
                                                { m--; m[2] = *m; m--; m[2] = *m; i++; }
×
1272
                                        *m++ = k;
×
1273
                                        *m = 1;
×
1274
                                        ppsym += 2;
×
1275
                                        nsym++;
×
1276
sigDoneSymbol:;
1277
                                        m = from;
1278
                                }
1279
                                else if ( ( t[FUNHEAD] > 0 ) && ( t[1] == FUNHEAD+t[FUNHEAD] ) ) {
×
1280
                                        if ( t[FUNHEAD] == ARGHEAD+1+abs(t[t[1]-1]) ) {
×
1281
                                                if ( t[t[1]-1] < 0 ) ncoef = -ncoef;
×
1282
                                        }
1283
/*
1284
                                        Now we should fish out the roots of unity
1285
*/
1286
                                        else if ( ( t[FUNHEAD+ARGHEAD]+FUNHEAD+ARGHEAD == t[1] )
×
1287
                                        && ( t[FUNHEAD+ARGHEAD+1] == SYMBOL ) ) {
×
1288
                                                WORD *ts = t + FUNHEAD+ARGHEAD+3;
×
1289
                                                WORD its = ts[-1]-2;
×
1290
                                                while ( its > 0 ) {
×
1291
                                                        if ( ( *ts != 0 ) && ( ( *ts > NumSymbols || *ts <= -MAXPOWER )
×
1292
                                                         || ( symbols[*ts].complex & VARTYPEROOTOFUNITY ) != VARTYPEROOTOFUNITY ) ) {
×
1293
                                                                goto signogood;
×
1294
                                                        }
1295
                                                        ts += 2; its -= 2;
×
1296
                                                }
1297
/*
1298
                                                Now we have only roots of unity which should be
1299
                                                registered in the list of symbols.
1300
*/
1301
                                                if ( t[t[1]-1] < 0 ) ncoef = -ncoef;
×
1302
                                                ts = t + FUNHEAD+ARGHEAD+3;
1303
                                                its = ts[-1]-2;
1304
                                                from = m;
×
1305
                                                while ( its > 0 ) {
×
1306
                                                        i = nsym;
×
1307
                                                        m = ppsym;
×
1308
                                                        if ( i > 0 ) do {
×
1309
                                                                m -= 2;
×
1310
                                                                if        ( *ts == *m ) {
×
1311
                                                                        ts++; m++;
×
1312
                                                                        *m += *ts;
×
1313
                                                                        if ( ( ts[-1] <= NumSymbols && ts[-1] > -MAXPOWER ) &&
×
1314
                                                                         ( symbols[ts[-1]].complex & VARTYPEROOTOFUNITY ) == VARTYPEROOTOFUNITY ) {
×
1315
                                                                                *m %= symbols[ts[-1]].maxpower;
×
1316
                                                                                if ( *m < 0 ) *m += symbols[ts[-1]].maxpower;
×
1317
                                                                                if ( ( symbols[ts[-1]].complex & VARTYPEMINUS ) == VARTYPEMINUS ) {
×
1318
                                                                                        if ( ( ( symbols[ts[-1]].maxpower & 1 ) == 0 ) &&
×
1319
                                                                                        ( *m >= symbols[ts[-1]].maxpower/2 ) ) {
×
1320
                                                                                                *m -= symbols[ts[-1]].maxpower/2; ncoef = -ncoef;
×
1321
                                                                                        }
1322
                                                                                }
1323
                                                                        }
1324
                                                                        if ( !*m ) {
×
1325
                                                                                m--;
1326
                                                                                while ( i < nsym )
×
1327
                                                                                        { *m = m[2]; m++; *m = m[2]; m++; i++; }
×
1328
                                                                                ppsym -= 2;
×
1329
                                                                                nsym--;
×
1330
                                                                        }
1331
                                                                        ts++; its -= 2;
×
1332
                                                                        goto sigNextSymbol;
×
1333
                                                                }
1334
                                                        } while ( *ts < *m && --i > 0 );
×
1335
                                                        m = ppsym;
1336
                                                        while ( i < nsym )
×
1337
                                                                { m--; m[2] = *m; m--; m[2] = *m; i++; }
×
1338
                                                        *m++ = *ts++;
×
1339
                                                        *m = *ts++;
×
1340
                                                        ppsym += 2;
×
1341
                                                        nsym++; its -= 2;
×
1342
sigNextSymbol:;
×
1343
                                                }
1344
                                                m = from;
1345
                                        }
1346
                                        else {
1347
signogood:                                pcom[ncom++] = t;
×
1348
                                        }
1349
                                }
1350
                                else pcom[ncom++] = t;
×
1351
                                break;
1352
                        case ABSFUNCTION:
×
1353
/*
1354
                                Numerical function giving the absolute value of the
1355
                                numerical argument. Or roots of unity.
1356
*/
1357
                                if ( t[1] == FUNHEAD+2 && t[FUNHEAD] == -SNUMBER ) {
×
1358
                                        k = t[FUNHEAD+1];
×
1359
                                        if ( k < 0 ) k = -k;
×
1360
                                        if ( k == 0 ) goto NormZero;
×
1361
                                        *((UWORD *)lnum) = k; nnum = 1;
×
1362
                                        goto MulIn;
×
1363

1364
                                }
1365
                                else if ( t[1] == FUNHEAD+2 && t[FUNHEAD] == -SYMBOL ) {
×
1366
                                        k = t[FUNHEAD+1];
×
1367
                                        if ( ( k > NumSymbols || k <= -MAXPOWER )
×
1368
                                         || ( symbols[k].complex & VARTYPEROOTOFUNITY ) != VARTYPEROOTOFUNITY )
×
1369
                                                goto absnogood;
×
1370
                                }
1371
                                else if ( ( t[FUNHEAD] > 0 ) && ( t[1] == FUNHEAD+t[FUNHEAD] )
×
1372
                                && ( t[1] == FUNHEAD+ARGHEAD+t[FUNHEAD+ARGHEAD] ) ) {
×
1373
                                        if ( t[FUNHEAD] == ARGHEAD+1+abs(t[t[1]-1]) ) {
×
1374
                                                WORD *ts;
×
1375
absnosymbols:                        ts = t + t[1] -1;
×
1376
                                                ncoef = REDLENG(ncoef);
×
1377
                                                nnum = REDLENG(*ts);        
×
1378
                                                if ( nnum < 0 ) nnum = -nnum;
×
1379
                                                if ( MulRat(BHEAD (UWORD *)n_coef,ncoef,
×
1380
                                                (UWORD *)(ts-ABS(*ts)+1),nnum,
×
1381
                                                (UWORD *)n_coef,&ncoef) ) goto FromNorm;
×
1382
                                                ncoef = INCLENG(ncoef);
×
1383
                                        }
1384
/*
1385
                                        Now get rid of the roots of unity. This includes i_
1386
*/
1387
                                        else if ( t[FUNHEAD+ARGHEAD+1] == SYMBOL ) {
×
1388
                                                WORD *ts = t+FUNHEAD+ARGHEAD+1;
×
1389
                                                WORD its = ts[1] - 2;
×
1390
                                                ts += 2;
×
1391
                                                while ( its > 0 ) {
×
1392
                                                        if ( *ts == 0 ) { }
×
1393
                                                        else if ( ( *ts > NumSymbols || *ts <= -MAXPOWER )
×
1394
                                                         || ( symbols[*ts].complex & VARTYPEROOTOFUNITY )
×
1395
                                                                != VARTYPEROOTOFUNITY ) goto absnogood;
×
1396
                                                        its -= 2; ts += 2;
×
1397
                                                }
1398
                                                goto absnosymbols;
×
1399
                                        }
1400
                                        else {
1401
absnogood:                                        pcom[ncom++] = t;
×
1402
                                        }
1403
                                }
1404
                                else pcom[ncom++] = t;
×
1405
                                break;
1406
                        case MODFUNCTION:
8✔
1407
                        case MOD2FUNCTION:
1408
/*
1409
                                Mod function. Does work if two arguments and the
1410
                                second argument is a positive short number
1411
*/
1412
                                if ( t[1] == FUNHEAD+4 && t[FUNHEAD] == -SNUMBER
8✔
1413
                                        && t[FUNHEAD+2] == -SNUMBER && t[FUNHEAD+3] > 1 ) {
×
1414
                                        WORD tmod;
×
1415
                                        tmod = (t[FUNHEAD+1]%t[FUNHEAD+3]);
×
1416
                                        if ( tmod < 0 ) tmod += t[FUNHEAD+3];
×
1417
                                        if ( *t == MOD2FUNCTION && tmod > t[FUNHEAD+3]/2 )
×
1418
                                                        tmod -= t[FUNHEAD+3];
×
1419
                                        if ( tmod < 0 ) {
×
1420
                                                *((UWORD *)lnum) = -tmod;
×
1421
                                                nnum = -1;
×
1422
                                        }
1423
                                        else if ( tmod > 0 ) {
×
1424
                                                *((UWORD *)lnum) = tmod;
×
1425
                                                nnum = 1;
×
1426
                                        }
1427
                                        else goto NormZero;
×
1428
                                        goto MulIn;
×
1429
                                }
1430
                                else if ( t[1] > t[FUNHEAD+2] && t[FUNHEAD] > 0
8✔
1431
                                && t[FUNHEAD+t[FUNHEAD]] == -SNUMBER
8✔
1432
                                && t[FUNHEAD+t[FUNHEAD]+1] > 1
8✔
1433
                                && t[1] == FUNHEAD+2+t[FUNHEAD] ) {
8✔
1434
                                        WORD *ttt = t+FUNHEAD, iii;
8✔
1435
                                        iii = ttt[*ttt-1];
8✔
1436
                                        if ( *ttt == ttt[ARGHEAD]+ARGHEAD &&
8✔
1437
                                                ttt[ARGHEAD] == ABS(iii)+1 ) {
8✔
1438
                                                WORD ncmod = 1;
8✔
1439
                                                WORD cmod = ttt[*ttt+1];
8✔
1440
                                                iii = REDLENG(iii);
8✔
1441
                                                if ( *t == MODFUNCTION ) {
8✔
1442
                                                        if ( TakeModulus((UWORD *)(ttt+ARGHEAD+1)
×
1443
                                                        ,&iii,(UWORD *)(&cmod),ncmod,UNPACK|NOINVERSES) )
1444
                                                                goto FromNorm;
×
1445
                                                }
1446
                                                else {
1447
                                                        if ( TakeModulus((UWORD *)(ttt+ARGHEAD+1)
8✔
1448
                                                        ,&iii,(UWORD *)(&cmod),ncmod,UNPACK|POSNEG|NOINVERSES) )
1449
                                                                goto FromNorm;
×
1450
                                                }
1451
                                                if ( *t == MOD2FUNCTION && ttt[ARGHEAD+1] > cmod/2 && iii > 0 ) {
8✔
1452
                                                        ttt[ARGHEAD+1] -= cmod;
4✔
1453
                                                }
1454
                                                if ( ttt[ARGHEAD+1] < 0 ) {
8✔
1455
                                                        *((UWORD *)lnum) = -ttt[ARGHEAD+1];
4✔
1456
                                                        nnum = -1;
4✔
1457
                                                }
1458
                                                else if ( ttt[ARGHEAD+1] > 0 ) {
4✔
1459
                                                        *((UWORD *)lnum) = ttt[ARGHEAD+1];
4✔
1460
                                                        nnum = 1;
4✔
1461
                                                }
1462
                                                else goto NormZero;
×
1463
                                                goto MulIn;
8✔
1464
                                        }                                                
1465
                                }
1466
                                else if ( t[1] == FUNHEAD+2 && t[FUNHEAD] == -SNUMBER ) {
×
1467
                                        *((UWORD *)lnum) = t[FUNHEAD+1];
×
1468
                                        if ( *lnum == 0 ) goto NormZero;
×
1469
                                        nnum = 1;
×
1470
                                        goto MulIn;
×
1471
                                }
1472
                                else if ( ( ( t[FUNHEAD] < 0 ) && ( t[FUNHEAD] == -SNUMBER )
×
1473
                                && ( t[1] >= ( FUNHEAD+6+ARGHEAD ) )
×
1474
                                && ( t[FUNHEAD+2] >= 4+ARGHEAD )
×
1475
                                && ( t[t[1]-1] == t[FUNHEAD+2+ARGHEAD]-1 ) ) ||
×
1476
                                ( ( t[FUNHEAD] > 0 )
1477
                                && ( t[FUNHEAD]-ARGHEAD-1 == ABS(t[FUNHEAD+t[FUNHEAD]-1]) )
×
1478
                                && ( t[FUNHEAD+t[FUNHEAD]]-ARGHEAD-1 == t[t[1]-1] ) ) ) {
×
1479
/*
1480
                                        Check that the last (long) number is integer
1481
*/
1482
                                        WORD *ttt = t + t[1], iii, iii1;
×
1483
                                        UWORD coefbuf[2], *coef2, ncoef2;
×
1484
                                        iii = (ttt[-1]-1)/2;
×
1485
                                        ttt -= iii;
×
1486
                                        if ( ttt[-1] != 1 ) {
×
1487
exitfromhere:
×
1488
                                                pcom[ncom++] = t;
×
1489
                                                break;
×
1490
                                        }
1491
                                        iii--;
×
1492
                                        for ( iii1 = 0; iii1 < iii; iii1++ ) {
×
1493
                                                if ( ttt[iii1] != 0 ) goto exitfromhere;
×
1494
                                        }
1495
/*
1496
                                        Now we have a hit!
1497
                                        The first argument will be put in lnum.
1498
                                        It will be a rational.
1499
                                        The second argument will be a long integer in coef2.
1500
*/
1501
                                        ttt = t + FUNHEAD;
×
1502
                                        if ( *ttt < 0 ) {
×
1503
                                                if ( ttt[1] < 0 ) {
×
1504
                                                        nnum = -1; lnum[0] = -ttt[1]; lnum[1] = 1;
×
1505
                                                }
1506
                                                else {
1507
                                                        nnum = 1; lnum[0] = ttt[1]; lnum[1] = 1;
×
1508
                                                }
1509
                                        }
1510
                                        else {
1511
                                                nnum = ABS(ttt[ttt[0]-1] - 1);
×
1512
                                                for ( iii = 0; iii < nnum; iii++ ) {
×
1513
                                                        lnum[iii] = ttt[ARGHEAD+1+iii];
×
1514
                                                }
1515
                                                nnum = nnum/2;
×
1516
                                                if ( ttt[ttt[0]-1] < 0 ) nnum = -nnum;
×
1517
                                        }
1518
                                        NEXTARG(ttt);
×
1519
                                        if ( *ttt < 0 ) {
×
1520
                                                coef2 = coefbuf;
×
1521
                                                ncoef2 = 3; *coef2 = (UWORD)(ttt[1]);
×
1522
                                                coef2[1] = 1;
×
1523
                                        }
1524
                                        else {
1525
                                                coef2 = (UWORD *)(ttt+ARGHEAD+1);
×
1526
                                                ncoef2 = (ttt[ttt[0]-1]-1)/2;
×
1527
                                        }
1528
                                        if ( TakeModulus((UWORD *)lnum,&nnum,(UWORD *)coef2,ncoef2,
×
1529
                                                                        UNPACK|NOINVERSES|FROMFUNCTION) ) {
1530
                                                goto FromNorm;
×
1531
                                        }
1532
                                        if ( *t == MOD2FUNCTION && nnum > 0 ) {
×
1533
                                                UWORD *coef3 = NumberMalloc("Mod2Function"), two = 2;
×
1534
                                                WORD ncoef3;
×
1535
                                                if ( MulLong((UWORD *)lnum,nnum,&two,1,coef3,&ncoef3) )
×
1536
                                                        goto FromNorm;
×
1537
                                                if ( BigLong(coef3,ncoef3,(UWORD *)coef2,ncoef2) > 0 ) {
×
1538
                                                        nnum = -nnum;
×
1539
                                                        AddLong((UWORD *)lnum,nnum,(UWORD *)coef2,ncoef2
×
1540
                                                                        ,(UWORD *)lnum,&nnum);
1541
                                                        nnum = -nnum;
×
1542
                                                }
1543
                                                NumberFree(coef3,"Mod2Function");
×
1544
                                        }
1545
/*
1546
                                        Do we have to pack? No, because the answer is not a fraction
1547
*/
1548
                                        ncoef = REDLENG(ncoef);
×
1549
                                        if ( Mully(BHEAD (UWORD *)n_coef,&ncoef,(UWORD *)lnum,nnum) )
×
1550
                                                        goto FromNorm;
×
1551
                                        ncoef = INCLENG(ncoef);
×
1552
                                }
1553
                                else pcom[ncom++] = t;
×
1554
                                break;
1555
                        case EXTEUCLIDEAN:
38✔
1556
                                {
1557
                                        WORD argcount = 0, *tc, *ts, xc, xs, *tcc;
38✔
1558
                                        UWORD *Num1, *Num2, *Num3, *Num4;
38✔
1559
                                        WORD size1, size2, size3, size4, space;
38✔
1560
                                        tc = t+FUNHEAD; ts = t + t[1];
38✔
1561
                                        while ( argcount < 3 && tc < ts ) { NEXTARG(tc); argcount++; }
144✔
1562
                                        if ( argcount != 2 ) goto defaultcase;
38✔
1563
                                        if ( t[FUNHEAD] == -SNUMBER ) {
8✔
1564
                                                if ( t[FUNHEAD+1] <= 1 ) goto defaultcase;
8✔
1565
                                                if ( t[FUNHEAD+2] == -SNUMBER ) {
8✔
1566
                                                        if ( t[FUNHEAD+3] <= 1 ) goto defaultcase;
8✔
1567
                                                        Num2 = NumberMalloc("modinverses");
8✔
1568
                                                        *Num2 = t[FUNHEAD+3]; size2 = 1;
8✔
1569
                                                }
1570
                                                else {
1571
                                                        if ( ts[-1] < 0 ) goto defaultcase;
×
1572
                                                        if ( ts[-1] != t[FUNHEAD+2]-ARGHEAD-1 ) goto defaultcase;
×
1573
                                                        xs = (ts[-1]-1)/2;
×
1574
                                                        tcc = ts-xs-1;
×
1575
                                                        if ( *tcc != 1 ) goto defaultcase;
×
1576
                                                        for ( i = 1; i < xs; i++ ) {
×
1577
                                                                if ( tcc[i] != 0 ) goto defaultcase;
×
1578
                                                        }
1579
                                                        Num2 = NumberMalloc("modinverses");
×
1580
                                                        size2 = xs;
×
1581
                                                        for ( i = 0; i < xs; i++ ) Num2[i] = t[FUNHEAD+ARGHEAD+3+i];
×
1582
                                                }
1583
                                                Num1 = NumberMalloc("modinverses");
8✔
1584
                                                *Num1 = t[FUNHEAD+1]; size1 = 1;
8✔
1585
                                        }
1586
                                        else {
1587
                                                tc = t + FUNHEAD + t[FUNHEAD];
×
1588
                                                if ( tc[-1] < 0 ) goto defaultcase;
×
1589
                                                if ( tc[-1] != t[FUNHEAD]-ARGHEAD-1 ) goto defaultcase;
×
1590
                                                xc = (tc[-1]-1)/2;
×
1591
                                                tcc = tc-xc-1;
×
1592
                                                if ( *tcc != 1 ) goto defaultcase;
×
1593
                                                for ( i = 1; i < xc; i++ ) {
×
1594
                                                        if ( tcc[i] != 0 ) goto defaultcase;
×
1595
                                                }
1596
                                                if ( *tc == -SNUMBER ) {
×
1597
                                                        if ( tc[1] <= 1 ) goto defaultcase;
×
1598
                                                        Num2 = NumberMalloc("modinverses");
×
1599
                                                        *Num2 = tc[1]; size2 = 1;
×
1600
                                                }
1601
                                                else {
1602
                                                        if ( ts[-1] < 0 ) goto defaultcase;
×
1603
                                                        if ( ts[-1] != t[FUNHEAD+2]-ARGHEAD-1 ) goto defaultcase;
×
1604
                                                        xs = (ts[-1]-1)/2;
×
1605
                                                        tcc = ts-xs-1;
×
1606
                                                        if ( *tcc != 1 ) goto defaultcase;
×
1607
                                                        for ( i = 1; i < xs; i++ ) {
×
1608
                                                                if ( tcc[i] != 0 ) goto defaultcase;
×
1609
                                                        }
1610
                                                        Num2 = NumberMalloc("modinverses");
×
1611
                                                        size2 = xs;
×
1612
                                                        for ( i = 0; i < xs; i++ ) Num2[i] = tc[ARGHEAD+1+i];
×
1613
                                                }
1614
                                                Num1 = NumberMalloc("modinverses");
×
1615
                                                size1 = xc;
×
1616
                                                for ( i = 0; i < xc; i++ ) Num1[i] = t[FUNHEAD+ARGHEAD+1+i];
×
1617
                                        }
1618
                                        Num3 = NumberMalloc("modinverses");
8✔
1619
                                        Num4 = NumberMalloc("modinverses");
8✔
1620
                                        GetLongModInverses(BHEAD Num1,size1,Num2,size2
8✔
1621
                                                                ,Num3,&size3,Num4,&size4);
1622
/*
1623
                                        Now we have to compose the answer. This needs more space
1624
                                        and hence we have to put this inside the term.
1625
                                        Compute first how much extra space we need.
1626
                                        Then move the trailing part of the term upwards.
1627
                                        Do not forget relevant pointers!!! (r, m, termout, AT.WorkPointer)
1628
*/
1629
                                        space = 0;
8✔
1630
                                        if ( ( size3 == 1 || size3 == -1 ) && (*Num3&TOPBITONLY) == 0 ) space += 2;
8✔
1631
                                        else space += ARGHEAD + 2*ABS(size3) + 2;
×
1632
                                        if ( ( size4 == 1 || size4 == -1 ) && (*Num4&TOPBITONLY) == 0 ) space += 2;
8✔
1633
                                        else space += ARGHEAD + 2*ABS(size4) + 2;
×
1634
                                        tt = term + *term; u = tt + space;
8✔
1635
                                        while ( tt >= ts ) *--u = *--tt;
40✔
1636
                                        m += space; r += space;
8✔
1637
                                        *term += space;
8✔
1638
                                        t[1] += space;
8✔
1639
                                        if ( ( size3 == 1 || size3 == -1 ) && (*Num3&TOPBITONLY) == 0 ) {
8✔
1640
                                                *ts++ = -SNUMBER; *ts = (WORD)(*Num3);
8✔
1641
                                                if ( size3 < 0 ) *ts = -*ts;
8✔
1642
                                                ts++;
8✔
1643
                                        }
1644
                                        else {
1645
                                                *ts++ = 2*ABS(size3)+ARGHEAD+2;
×
1646
                                                *ts++ = 0; FILLARG(ts)
×
1647
                                                *ts++ = 2*ABS(size3)+1;
×
1648
                                                for ( i = 0; i < ABS(size3); i++ ) *ts++ = Num3[i];
×
1649
                                                *ts++ = 1;
×
1650
                                                for ( i = 1; i < ABS(size3); i++ ) *ts++ = 0;
×
1651
                                                if ( size3 < 0 ) *ts++ = 2*size3-1;
×
1652
                                                else             *ts++ = 2*size3+1;
×
1653
                                        }
1654
                                        if ( ( size4 == 1 || size4 == -1 ) && (*Num4&TOPBITONLY) == 0 ) {
8✔
1655
                                                *ts++ = -SNUMBER; *ts = *Num4;
8✔
1656
                                                if ( size4 < 0 ) *ts = -*ts;
8✔
1657
                                                ts++;
8✔
1658
                                        }
1659
                                        else {
1660
                                                *ts++ = 2*ABS(size4)+ARGHEAD+2;
×
1661
                                                *ts++ = 0; FILLARG(ts)
×
1662
                                                *ts++ = 2*ABS(size4)+2;
×
1663
                                                for ( i = 0; i < ABS(size4); i++ ) *ts++ = Num4[i];
×
1664
                                                *ts++ = 1;
×
1665
                                                for ( i = 1; i < ABS(size4); i++ ) *ts++ = 0;
×
1666
                                                if ( size4 < 0 ) *ts++ = 2*size4-1;
×
1667
                                                else             *ts++ = 2*size4+1;
×
1668
                                        }
1669
                                        NumberFree(Num4,"modinverses");
8✔
1670
                                        NumberFree(Num3,"modinverses");
8✔
1671
                                        NumberFree(Num1,"modinverses");
8✔
1672
                                        NumberFree(Num2,"modinverses");
8✔
1673
                                        t[2] = 0; /* mark function as clean. */
8✔
1674
                                        goto Restart;
8✔
1675
                                }
1676
                                break;
×
1677
                        case GCDFUNCTION:
×
1678
#ifdef EVALUATEGCD
1679
#ifdef NEWGCDFUNCTION
1680
                                {
1681
/*
1682
                                Has two integer arguments
1683
                                Four cases: S,S, S,L, L,S, L,L
1684
*/
1685
                                WORD *num1, *num2, size1, size2, stor1, stor2, *ttt, ti;
1686
                                if ( t[1] == FUNHEAD+4 && t[FUNHEAD] == -SNUMBER
1687
                                && t[FUNHEAD+2] == -SNUMBER && t[FUNHEAD+1] != 0
1688
                                && t[FUNHEAD+3] != 0 ) {        /* Short,Short */
1689
                                        stor1 = t[FUNHEAD+1];
1690
                                        stor2 = t[FUNHEAD+3];
1691
                                        if ( stor1 < 0 ) stor1 = -stor1;
1692
                                        if ( stor2 < 0 ) stor2 = -stor2;
1693
                                        num1 = &stor1; num2 = &stor2;
1694
                                        size1 = size2 = 1;
1695
                                        goto gcdcalc;
1696
                                }
1697
                                else if ( t[1] > FUNHEAD+4 ) {
1698
                                        if ( t[FUNHEAD] == -SNUMBER && t[FUNHEAD+1] != 0
1699
                                        && t[FUNHEAD+2] == t[1]-FUNHEAD-2 &&
1700
                                        ABS(t[t[1]-1]) == t[FUNHEAD+2]-1-ARGHEAD ) { /* Short,Long */
1701
                                                num2 = t + t[1];
1702
                                                size2 = ABS(num2[-1]);
1703
                                                ttt = num2-1;
1704
                                                num2 -= size2;
1705
                                                size2 = (size2-1)/2;
1706
                                                ti = size2;
1707
                                                while ( ti > 1 && ttt[-1] == 0 ) { ttt--; ti--; }
1708
                                                if ( ti == 1 && ttt[-1] == 1 ) {
1709
                                                        stor1 = t[FUNHEAD+1];
1710
                                                        if ( stor1 < 0 ) stor1 = -stor1;
1711
                                                        num1 = &stor1;
1712
                                                        size1 = 1;
1713
                                                        goto gcdcalc;
1714
                                                }
1715
                                                else pcom[ncom++] = t;
1716
                                        }
1717
                                        else if ( t[FUNHEAD] > 0 &&
1718
                                        t[FUNHEAD]-1-ARGHEAD == ABS(t[t[FUNHEAD]+FUNHEAD-1]) ) {
1719
                                                num1 = t + FUNHEAD + t[FUNHEAD];
1720
                                                size1 = ABS(num1[-1]);
1721
                                                ttt = num1-1;
1722
                                                num1 -= size1;
1723
                                                size1 = (size1-1)/2;
1724
                                                ti = size1;
1725
                                                while ( ti > 1 && ttt[-1] == 0 ) { ttt--; ti--; }
1726
                                                if ( ti == 1 && ttt[-1] == 1 ) {
1727
                                                 if ( t[1]-FUNHEAD == t[FUNHEAD]+2 && t[t[1]-2] == -SNUMBER
1728
                                                 && t[t[1]-1] != 0 ) { /* Long,Short */
1729
                                                        stor2 = t[t[1]-1];
1730
                                                        if ( stor2 < 0 ) stor2 = -stor2;
1731
                                                        num2 = &stor2;
1732
                                                        size2 = 1;
1733
                                                        goto gcdcalc;
1734
                                                 }
1735
                                                 else if ( t[1]-FUNHEAD == t[FUNHEAD]+t[FUNHEAD+t[FUNHEAD]]
1736
                                                 && ABS(t[t[1]-1]) == t[FUNHEAD+t[FUNHEAD]] - ARGHEAD-1 ) {
1737
                                                  num2 = t + t[1];
1738
                                                  size2 = ABS(num2[-1]);
1739
                                                  ttt = num2-1;
1740
                                                  num2 -= size2;
1741
                                                  size2 = (size2-1)/2;
1742
                                                  ti = size2;
1743
                                                  while ( ti > 1 && ttt[-1] == 0 ) { ttt--; ti--; }
1744
                                                  if ( ti == 1 && ttt[-1] == 1 ) {
1745
gcdcalc:                                        if ( GcdLong(BHEAD (UWORD *)num1,size1,(UWORD *)num2,size2
1746
                                                                ,(UWORD *)lnum,&nnum) ) goto FromNorm;
1747
                                                        goto MulIn;
1748
                                                  }
1749
                                                  else pcom[ncom++] = t;
1750
                                                 }
1751
                                                 else pcom[ncom++] = t;
1752
                                                }
1753
                                                else pcom[ncom++] = t;
1754
                                        }
1755
                                        else pcom[ncom++] = t;
1756
                                }
1757
                                else pcom[ncom++] = t;
1758
                                }
1759
#else
1760
                                {
1761
                                        WORD *gcd = AT.WorkPointer;
1762
                                        if ( ( gcd = EvaluateGcd(BHEAD t) ) == 0 ) goto FromNorm;
1763
                                        if ( *gcd == 4 && gcd[1] == 1 && gcd[2] == 1 && gcd[4] == 0 ) {
1764
                                                AT.WorkPointer = gcd;
1765
                                        }
1766
                                        else if ( gcd[*gcd] == 0 ) {
1767
                                                WORD *t1, iii, change, *num, *den, numsize, densize;
1768
                                                if ( gcd[*gcd-1] < *gcd-1 ) {
1769
                                                        t1 = gcd+1;
1770
                                                        for ( iii = 2; iii < t1[1]; iii += 2 ) {
1771
                                                                change = ExtraSymbol(t1[iii],t1[iii+1],nsym,ppsym,&ncoef);
1772
                                                                nsym += change;
1773
                                                                ppsym += change * 2;
1774
                                                        }
1775
                                                }
1776
                                                t1 = gcd + *gcd;
1777
                                                iii = t1[-1]; num = t1-iii; numsize = (iii-1)/2;
1778
                                                den = num + numsize; densize = numsize;
1779
                                                while ( numsize > 1 && num[numsize-1] == 0 ) numsize--;
1780
                                                while ( densize > 1 && den[densize-1] == 0 ) densize--;
1781
                                                if ( numsize > 1 || num[0] != 1 ) {
1782
                                                        ncoef = REDLENG(ncoef);
1783
                                                        if ( Mully(BHEAD (UWORD *)n_coef,&ncoef,(UWORD *)num,numsize) ) goto FromNorm;
1784
                                                        ncoef = INCLENG(ncoef);
1785
                                                }
1786
                                                if ( densize > 1 || den[0] != 1 ) {
1787
                                                        ncoef = REDLENG(ncoef);
1788
                                                        if ( Divvy(BHEAD (UWORD *)n_coef,&ncoef,(UWORD *)den,densize) ) goto FromNorm;
1789
                                                        ncoef = INCLENG(ncoef);
1790
                                                }
1791
                                                AT.WorkPointer = gcd;
1792
                                        }
1793
                                        else {        /* a whole expression */
1794
/*
1795
                                                Action: Put the expression in a compiler buffer.
1796
                                                Insert a SUBEXPRESSION subterm
1797
                                                Set the return value of the routine such that in
1798
                                                Generator the term gets sent again to TestSub.
1799

1800
                                                1: put in C (ebufnum)
1801
                                                2: after that the WorkSpace is free again.
1802
                                                3: insert the SUBEXPRESSION
1803
                                                4: copy the top part of the term down
1804
*/
1805
                                                LONG size = AT.WorkPointer - gcd;
1806

1807
                                                ss = AddRHS(AT.ebufnum,1);
1808
                                                while ( (ss + size + 10) > C->Top ) ss = DoubleCbuffer(AT.ebufnum,ss,13);
1809
                                                tt = gcd;
1810
                                                NCOPY(ss,tt,size);
1811
                                                C->rhs[C->numrhs+1] = ss;
1812
                                                C->Pointer = ss;
1813

1814
                                                t[0] = SUBEXPRESSION;
1815
                                                t[1] = SUBEXPSIZE;
1816
                                                t[2] = C->numrhs;
1817
                                                t[3] = 1;
1818
                                                t[4] = AT.ebufnum;
1819
                                                t += 5;
1820
                                                tt = term + *term;
1821
                                                while ( r < tt ) *t++ = *r++;
1822
                                                *term = t - term;
1823

1824
                                                regval = 1;
1825
                                                goto RegEnd;
1826
                                        }
1827
                                }
1828
#endif
1829
#else
1830
                                MesPrint(" Unexpected call to EvaluateGCD");
×
NEW
1831
                                TERMINATE(-1);
×
1832
#endif
1833
                                break;
×
1834
                        case MINFUNCTION:
×
1835
                        case MAXFUNCTION:
1836
                                if ( t[1] == FUNHEAD ) break;
×
1837
                                {
1838
                                        WORD *ttt = t + FUNHEAD;
×
1839
                                        WORD *tttstop = t + t[1];
×
1840
                                        WORD tterm[4], iii;
×
1841
                                        while ( ttt < tttstop ) {
×
1842
                                                if ( *ttt > 0 ) {
×
1843
                                                        if ( ttt[ARGHEAD]-1 > ABS(ttt[*ttt-1]) ) goto nospec;
×
1844
                                                        ttt += *ttt;
×
1845
                                                }
1846
                                                else {
1847
                                                        if ( *ttt != -SNUMBER ) goto nospec;
×
1848
                                                        ttt += 2;
×
1849
                                                }
1850
                                        }
1851
/*
1852
                                        Function has only numerical arguments
1853
                                        Pick up the first argument.
1854
*/
1855
                                        ttt = t + FUNHEAD;
×
1856
                                        if ( *ttt > 0 ) {
×
1857
loadnew1:
×
1858
                                                for ( iii = 0; iii < ttt[ARGHEAD]; iii++ )
×
1859
                                                        n_llnum[iii] = ttt[ARGHEAD+iii];
×
1860
                                                ttt += *ttt;
×
1861
                                        }
1862
                                        else {
1863
loadnew2:
×
1864
                                                if ( ttt[1] == 0 ) {
×
1865
                                                        n_llnum[0] = n_llnum[1] = n_llnum[2] = n_llnum[3] = 0;
×
1866
                                                }
1867
                                                else {
1868
                                                        n_llnum[0] = 4;
×
1869
                                                        if ( ttt[1] > 0 ) { n_llnum[1] = ttt[1]; n_llnum[3] = 3; }
×
1870
                                                        else { n_llnum[1] = -ttt[1]; n_llnum[3] = -3; }
×
1871
                                                        n_llnum[2] = 1;
×
1872
                                                }
1873
                                                ttt += 2;
×
1874
                                        }
1875
/*
1876
                                        Now loop over the other arguments
1877
*/
1878
                                        while ( ttt < tttstop ) {
×
1879
                                                if ( *ttt > 0 ) {
×
1880
                                                        if ( n_llnum[0] == 0 ) {
×
1881
                                                                if ( ( *t == MINFUNCTION && ttt[*ttt-1] < 0 )
×
1882
                                                                || ( *t == MAXFUNCTION && ttt[*ttt-1] > 0 ) )
×
1883
                                                                        goto loadnew1;
×
1884
                                                        }
1885
                                                        else {
1886
                                                                ttt += ARGHEAD;
×
1887
                                                                iii = CompCoef(n_llnum,ttt);
×
1888
                                                                if ( ( iii > 0 && *t == MINFUNCTION )
×
1889
                                                                || ( iii < 0 && *t == MAXFUNCTION ) ) {
×
1890
                                                                        for ( iii = 0; iii < ttt[0]; iii++ )
×
1891
                                                                                n_llnum[iii] = ttt[iii];
×
1892
                                                                }
1893
                                                        }
1894
                                                        ttt += *ttt;
×
1895
                                                }
1896
                                                else {
1897
                                                        if ( n_llnum[0] == 0 ) {
×
1898
                                                                if ( ( *t == MINFUNCTION && ttt[1] < 0 )
×
1899
                                                                || ( *t == MAXFUNCTION && ttt[1] > 0 ) )
×
1900
                                                                        goto loadnew2;
×
1901
                                                        }
1902
                                                        else if ( ttt[1] == 0 ) {
×
1903
                                                                if ( ( *t == MINFUNCTION && n_llnum[*n_llnum-1] > 0 )
×
1904
                                                                || ( *t == MAXFUNCTION && n_llnum[*n_llnum-1] < 0 ) ) {
×
1905
                                                                        n_llnum[0] = 0;
×
1906
                                                                }
1907
                                                        }
1908
                                                        else {
1909
                                                                tterm[0] = 4; tterm[2] = 1;
×
1910
                                                                if ( ttt[1] < 0 ) { tterm[1] = -ttt[1]; tterm[3] = -3; }
×
1911
                                                                else { tterm[1] = ttt[1]; tterm[3] = 3; }
×
1912
                                                                iii = CompCoef(n_llnum,tterm);
×
1913
                                                                if ( ( iii > 0 && *t == MINFUNCTION )
×
1914
                                                                || ( iii < 0 && *t == MAXFUNCTION ) ) {
×
1915
                                                                        for ( iii = 0; iii < 4; iii++ )
×
1916
                                                                                n_llnum[iii] = tterm[iii];
×
1917
                                                                }
1918
                                                        }
1919
                                                        ttt += 2;
×
1920
                                                }
1921
                                        }
1922
                                        if ( n_llnum[0] == 0 ) goto NormZero;
×
1923
                                        ncoef = REDLENG(ncoef);
×
1924
                                        nnum = REDLENG(n_llnum[*n_llnum-1]);        
×
1925
                                        if ( MulRat(BHEAD (UWORD *)n_coef,ncoef,(UWORD *)lnum,nnum,
×
1926
                                        (UWORD *)n_coef,&ncoef) ) goto FromNorm;
×
1927
                                        ncoef = INCLENG(ncoef);
×
1928
                                }
1929
                                break;
×
1930
                        case INVERSEFACTORIAL:
×
1931
                                if ( t[FUNHEAD] == -SNUMBER && t[FUNHEAD+1] >= 0 ) {
×
1932
                                        if ( Factorial(BHEAD t[FUNHEAD+1],(UWORD *)lnum,&nnum) )
×
1933
                                                goto FromNorm;
×
1934
                                        ncoef = REDLENG(ncoef);        
×
1935
                                        if ( Divvy(BHEAD (UWORD *)n_coef,&ncoef,(UWORD *)lnum,nnum) ) goto FromNorm;
×
1936
                                        ncoef = INCLENG(ncoef);
×
1937
                                }
1938
                                else {
1939
nospec:                                pcom[ncom++] = t;
×
1940
                                }
1941
                                break;
1942
                        case MAXPOWEROF:
×
1943
                                if ( ( t[FUNHEAD] == -SYMBOL )
×
1944
                                         && ( t[FUNHEAD+1] > 0 ) && ( t[1] == FUNHEAD+2 ) ) {
×
1945
                                        *((UWORD *)lnum) = symbols[t[FUNHEAD+1]].maxpower;
×
1946
                                        nnum = 1;
×
1947
                                        goto MulIn;
×
1948
                                }
1949
                                else { pcom[ncom++] = t; }
×
1950
                                break;
×
1951
                        case MINPOWEROF:
1952
                                if ( ( t[FUNHEAD] == -SYMBOL )
×
1953
                                         && ( t[FUNHEAD] > 0 ) && ( t[1] == FUNHEAD+2 ) ) {
1954
                                        *((UWORD *)lnum) = symbols[t[FUNHEAD+1]].minpower;
1955
                                        nnum = 1;
1956
                                        goto MulIn;
1957
                                }
1958
                                else { pcom[ncom++] = t; }
×
1959
                                break;
×
1960
                        case PRIMENUMBER :
23✔
1961
                                if ( t[1] == FUNHEAD+2 && t[FUNHEAD] == -SNUMBER
23✔
1962
                                         && t[FUNHEAD+1] > 0 ) {
23✔
1963
                                        UWORD xp = (UWORD)(NextPrime(BHEAD t[FUNHEAD+1]));
23✔
1964
                                        ncoef = REDLENG(ncoef);
23✔
1965
                                        if ( Mully(BHEAD (UWORD *)n_coef,&ncoef,&xp,1) ) goto FromNorm;
23✔
1966
                                        ncoef = INCLENG(ncoef);
23✔
1967
                                }
1968
                                else goto defaultcase;
×
1969
                                break;
1970
                        case MOEBIUS:
1,538✔
1971
/*
1972
                                Numerical function giving -1,0,1 or no evaluation
1973
*/
1974
                                if ( t[1] == FUNHEAD+2 && t[FUNHEAD] == -SNUMBER
1,538✔
1975
                                        && t[FUNHEAD+1] > 0 ) {
1,538✔
1976
                                        WORD val = Moebius(BHEAD t[FUNHEAD+1]);
1,538✔
1977
                                        if ( val == 0 ) goto NormZero;
1,538✔
1978
                                        if ( val < 0 ) ncoef = -ncoef;
1,044✔
1979
                                }
1980
                                else {
1981
                                        pcom[ncom++] = t;
×
1982
                                }
1983
                                break;
1984
                        case LNUMBER :
×
1985
                                ncoef = REDLENG(ncoef);
×
1986
                                if ( Mully(BHEAD (UWORD *)n_coef,&ncoef,(UWORD *)(t+3),t[2]) ) goto FromNorm;
×
1987
                                ncoef = INCLENG(ncoef);
×
1988
                                break;
×
1989
                        case SNUMBER :
17,012,050✔
1990
                                if ( t[2] < 0 ) {
17,012,050✔
1991
                                        t[2] = -t[2];
136✔
1992
                                        if ( t[3] & 1 ) ncoef = -ncoef;
136✔
1993
                                }
1994
                                else if ( t[2] == 0 ) {
17,011,920✔
1995
                                        if ( t[3] < 0 ) goto NormInf;
2,144✔
1996
                                        goto NormZero;
2,144✔
1997
                                }
1998
                                lnum[0] = t[2];
17,009,890✔
1999
                                nnum = 1;
17,009,890✔
2000
                                if ( t[3] && RaisPow(BHEAD (UWORD *)lnum,&nnum,(UWORD)(ABS(t[3]))) ) goto FromNorm;
17,009,890✔
2001
                                ncoef = REDLENG(ncoef);
17,009,890✔
2002
                                if ( t[3] < 0 ) {
17,009,890✔
2003
                                        if ( Divvy(BHEAD (UWORD *)n_coef,&ncoef,(UWORD *)lnum,nnum) )
13,300✔
2004
                                                goto FromNorm;
×
2005
                                }
2006
                                else if ( t[3] > 0 ) {
16,996,610✔
2007
                                        if ( Mully(BHEAD (UWORD *)n_coef,&ncoef,(UWORD *)lnum,nnum) )
8,676,400✔
2008
                                                goto FromNorm;
×
2009
                                }
2010
                                ncoef = INCLENG(ncoef);
17,009,890✔
2011
                                break;
17,009,890✔
2012
                        case GAMMA :
2,099✔
2013
                        case GAMMAI :
2014
                        case GAMMAFIVE :
2015
                        case GAMMASIX :
2016
                        case GAMMASEVEN :
2017
                                if ( t[1] == FUNHEAD ) {
2,099✔
2018
                                        MLOCK(ErrorMessageLock);
3✔
2019
                                        MesPrint("Gamma matrix without spin line encountered.");
3✔
2020
                                        MUNLOCK(ErrorMessageLock);
3✔
2021
                                        goto NormMin;
3✔
2022
                                }
2023
                                pnco[nnco++] = t;
2,096✔
2024
                                t += FUNHEAD+1;
2,096✔
2025
                                goto ScanCont;
2,096✔
2026
                        case LEVICIVITA :
216,380✔
2027
                                peps[neps++] = t;
216,380✔
2028
                                if ( ( t[2] & DIRTYFLAG ) == DIRTYFLAG ) {
216,380✔
2029
                                        t[2] &= ~DIRTYFLAG;
6,472✔
2030
                                        t[2] |= DIRTYSYMFLAG;
6,472✔
2031
                                }
2032
                                t += FUNHEAD;
216,380✔
2033
ScanCont:                while ( t < r ) {
1,099,900✔
2034
                                        if ( *t >= AM.OffsetIndex &&
881,424✔
2035
                                                ( *t >= AM.DumInd || ( *t < AM.WilInd &&
880,684✔
2036
                                                indices[*t-AM.OffsetIndex].dimension ) ) )
880,604✔
2037
                                                pcon[ncon++] = t;
880,660✔
2038
                                        t++;
881,424✔
2039
                                }
2040
                                break;
2041
                        case EXPONENT :
216✔
2042
                                {
2043
                                        WORD *rr;
216✔
2044
                                        k = 1;
216✔
2045
                                        rr = t + FUNHEAD;
216✔
2046
                                        if ( *rr == ARGHEAD || ( *rr == -SNUMBER && rr[1] == 0 ) )
216✔
2047
                                                k = 0;
×
2048
                                        if ( *rr == -SNUMBER && rr[1] == 1 ) break;
216✔
2049
                                        if ( *rr <= -FUNCTION ) k = *rr;
216✔
2050
                                        NEXTARG(rr)
216✔
2051
                                        if ( *rr == ARGHEAD || ( *rr == -SNUMBER && rr[1] == 0 ) ) {
216✔
2052
                                                if ( k == 0 ) goto NormZZ;
×
2053
                                                break;
2054
                                        }
2055
                                        if ( *rr == -SNUMBER && rr[1] > 0 && rr[1] < MAXPOWER && k < 0 ) {
216✔
2056
                                                k = -k;
×
2057
                                                if ( functions[k-FUNCTION].commute ) {
×
2058
                                                        for ( i = 0; i < rr[1]; i++ ) pnco[nnco++] = rr-1;
×
2059
                                                }
2060
                                                else {
2061
                                                        for ( i = 0; i < rr[1]; i++ ) pcom[ncom++] = rr-1;
×
2062
                                                }
2063
                                                break;
2064
                                        }
2065
                                        if ( k == 0 ) goto NormZero;
216✔
2066
                                        if ( t[FUNHEAD] == -SYMBOL && *rr == -SNUMBER && t[1] == FUNHEAD+4 ) {
216✔
2067
                                                if ( rr[1] < MAXPOWER ) {
12✔
2068
                                                        t[FUNHEAD+2] = t[FUNHEAD+1]; t += FUNHEAD+2;
12✔
2069
                                                        from = m;
12✔
2070
                                                        goto NextSymbol;
12✔
2071
                                                }
2072
                                        }
2073
/*
2074
                                        if ( ( t[FUNHEAD] > 0 && t[FUNHEAD+1] != 0 )
2075
                                        || ( *rr > 0 && rr[1] != 0 ) ) {}
2076
                                        else 
2077
*/
2078
                                        t[2] &= ~DIRTYSYMFLAG;
204✔
2079

2080
                                        pnco[nnco++] = t;
204✔
2081
                                }
2082
                                break;
204✔
2083
                        case DENOMINATOR :
3,029✔
2084
                                t[2] &= ~DIRTYSYMFLAG;
3,029✔
2085
                                pden[nden++] = t;
3,029✔
2086
                                pnco[nnco++] = t;
3,029✔
2087
                                break;
3,029✔
2088
                        case INDEX :
3,109✔
2089
                                t += 2;
3,109✔
2090
                                do {
3,109✔
2091
                                        if ( *t == 0 || *t == AM.vectorzero ) goto NormZero;
3,109✔
2092
                                        if ( *t > 0 && *t < AM.OffsetIndex ) {
3,089✔
2093
                                                lnum[0] = *t++;
2,560✔
2094
                                                nnum = 1;
2,560✔
2095
                                                ncoef = REDLENG(ncoef);
2,560✔
2096
                                                if ( Mully(BHEAD (UWORD *)n_coef,&ncoef,(UWORD *)lnum,nnum) )
2,560✔
2097
                                                        goto FromNorm;
×
2098
                                                ncoef = INCLENG(ncoef);
2,560✔
2099
                                        }
2100
                                        else if ( *t == NOINDEX ) t++;
529✔
2101
                                        else pind[nind++] = *t++;
529✔
2102
                                } while ( t < r );
3,089✔
2103
                                break;
2104
                        case SUBEXPRESSION :
×
2105
                                if ( t[3] == 0 ) break;
×
2106
                        case EXPRESSION :
2107
                                goto RegEnd;
×
2108
                        case ROOTFUNCTION :
×
2109
/*
2110
                                Tries to take the n-th root inside the rationals
2111
                                If this is not possible, it clears all flags and
2112
                                hence tries no more.
2113
                                Notation:
2114
                                root_(power(=integer),(rational)number)
2115
*/
2116
                                { WORD nc;
×
2117
                                if ( t[2] == 0 ) goto defaultcase;
×
2118
                                if ( t[FUNHEAD] != -SNUMBER || t[FUNHEAD+1] < 0 ) goto defaultcase;
×
2119
                                if ( t[FUNHEAD+2] == -SNUMBER ) {
×
2120
                                        if ( t[FUNHEAD+1] == 0 && t[FUNHEAD+3] == 0 ) goto NormZZ;
×
2121
                                        if ( t[FUNHEAD+1] == 0 ) break;
×
2122
                                        if ( t[FUNHEAD+3] < 0 ) {
×
2123
                                                AT.WorkPointer[0] = -t[FUNHEAD+3];
×
2124
                                                nc = -1;
×
2125
                                        }
2126
                                        else {
2127
                                                AT.WorkPointer[0] = t[FUNHEAD+3];
×
2128
                                                nc = 1;
×
2129
                                        }
2130
                                        AT.WorkPointer[1] = 1;
×
2131
                                }
2132
                                else if ( t[FUNHEAD+2] == t[1]-FUNHEAD-2
×
2133
                                && t[FUNHEAD+2] == t[FUNHEAD+2+ARGHEAD]+ARGHEAD
×
2134
                                && ABS(t[t[1]-1]) == t[FUNHEAD+2+ARGHEAD] - 1 ) {
×
2135
                                        WORD *r1, *r2;
×
2136
                                        if ( t[FUNHEAD+1] == 0 ) break;
×
2137
                                        i = t[t[1]-1]; r1 = t + FUNHEAD+ARGHEAD+3;
×
2138
                                        nc = REDLENG(i);
×
2139
                                        i = ABS(i) - 1;
×
2140
                                        r2 = AT.WorkPointer;
×
2141
                                        while ( --i >= 0 ) *r2++ = *r1++;
×
2142
                                }
2143
                                else goto defaultcase;
×
2144
                                if ( TakeRatRoot((UWORD *)AT.WorkPointer,&nc,t[FUNHEAD+1]) ) {
×
2145
                                        t[2] = 0;
×
2146
                                        goto defaultcase;
×
2147
                                }
2148
                                ncoef = REDLENG(ncoef);
×
2149
                                if ( Mully(BHEAD (UWORD *)n_coef,&ncoef,(UWORD *)AT.WorkPointer,nc) )
×
2150
                                                goto FromNorm;
×
2151
                                if ( nc < 0 ) nc = -nc;
×
2152
                                if ( Divvy(BHEAD (UWORD *)n_coef,&ncoef,(UWORD *)(AT.WorkPointer+nc),nc) )
×
2153
                                                goto FromNorm;
×
2154
                                ncoef = INCLENG(ncoef);
×
2155
                                }
2156
                                break;
×
2157
                        case RANDOMFUNCTION :
×
2158
                                {
2159
                                WORD nnc, nc, nca, nr;
×
2160
                                UWORD xx;
×
2161
/*
2162
                                Needs one positive integer argument.
2163
                                returns (wranf()%argument)+1.
2164
                                We may call wranf several times to paste UWORDS together
2165
                                when we need long numbers.
2166
                                We make little errors when taking the % operator
2167
                                (not 100% uniform). We correct for that by redoing the
2168
                                calculation in the (unlikely) case that we are in leftover area
2169
*/
2170
                                if ( t[1] == FUNHEAD ) goto defaultcase;
×
2171
                                if ( t[1] == FUNHEAD+2 && t[FUNHEAD] == -SNUMBER &&
×
2172
                                        t[FUNHEAD+1] > 0 ) {
×
2173
                                        if ( t[FUNHEAD+1] == 1 ) break;
×
2174
redoshort:
×
2175
                                        ((UWORD *)AT.WorkPointer)[0] = wranf(BHEAD0);
×
2176
                                        ((UWORD *)AT.WorkPointer)[1] = wranf(BHEAD0);
×
2177
                                        nr = 2;
×
2178
                                        if ( ((UWORD *)AT.WorkPointer)[1] == 0 ) {
×
2179
                                                nr = 1;
×
2180
                                                if ( ((UWORD *)AT.WorkPointer)[0] == 0 ) {
×
2181
                                                        nr = 0;
×
2182
                                                }
2183
                                        }
2184
                                        xx = (UWORD)(t[FUNHEAD+1]);
×
2185
                                        if ( nr ) {
×
2186
                                        DivLong((UWORD *)AT.WorkPointer,nr
×
2187
                                                        ,&xx,1
2188
                                                        ,((UWORD *)AT.WorkPointer)+4,&nnc
2189
                                                        ,((UWORD *)AT.WorkPointer)+2,&nc);
2190
                                        ((UWORD *)AT.WorkPointer)[4] = 0;
×
2191
                                        ((UWORD *)AT.WorkPointer)[5] = 0;
×
2192
                                        ((UWORD *)AT.WorkPointer)[6] = 1;
×
2193
                                        DivLong((UWORD *)AT.WorkPointer+4,3
×
2194
                                                        ,&xx,1
2195
                                                        ,((UWORD *)AT.WorkPointer)+9,&nnc
2196
                                                        ,((UWORD *)AT.WorkPointer)+7,&nca);
×
2197
                                        AddLong((UWORD *)AT.WorkPointer+4,3
×
2198
                                                        ,((UWORD *)AT.WorkPointer)+7,-nca
2199
                                                        ,((UWORD *)AT.WorkPointer)+9,&nnc);
×
2200
                                        if ( BigLong((UWORD *)AT.WorkPointer,nr
×
2201
                                                        ,((UWORD *)AT.WorkPointer)+9,nnc) >= 0 ) goto redoshort;
×
2202
                                        }
2203
                                        else nc = 0;
×
2204
                                        if ( nc == 0 ) {
×
2205
                                                AT.WorkPointer[2] = (WORD)xx;
×
2206
                                                nc = 1;
×
2207
                                        }
2208
                                        ncoef = REDLENG(ncoef);
×
2209
                                        if ( Mully(BHEAD (UWORD *)n_coef,&ncoef,((UWORD *)(AT.WorkPointer))+2,nc) )
×
2210
                                                        goto FromNorm;
×
2211
                                        ncoef = INCLENG(ncoef);
×
2212
                                }
2213
                                else if ( t[FUNHEAD] > 0 && t[1] == t[FUNHEAD]+FUNHEAD
×
2214
                                && ABS(t[t[1]-1]) == t[FUNHEAD]-1-ARGHEAD && t[t[1]-1] > 0 ) {
×
2215
                                        WORD nna, nnb, nni, nnb2, nnb2a;
×
2216
                                        UWORD *nnt;
×
2217
                                        nna = t[t[1]-1];
×
2218
                                        nnb2 = nna-1;
×
2219
                                        nnb = nnb2/2;
×
2220
                                        nnt = (UWORD *)(t+t[1]-1-nnb);  /* start of denominator */
×
2221
                                        if ( *nnt != 1 ) goto defaultcase;
×
2222
                                        for ( nni = 1; nni < nnb; nni++ ) {
×
2223
                                                if ( nnt[nni] != 0 ) goto defaultcase;
×
2224
                                        }
2225
                                        nnt = (UWORD *)(t + FUNHEAD + ARGHEAD + 1);
×
2226

2227
                                        for ( nni = 0; nni < nnb2; nni++ ) {
×
2228
                                                ((UWORD *)AT.WorkPointer)[nni] = wranf(BHEAD0);
×
2229
                                        }
2230
                                        nnb2a = nnb2;
2231
                                        while ( nnb2a > 0 && ((UWORD *)AT.WorkPointer)[nnb2a-1] == 0 ) nnb2a--;
×
2232
                                        if ( nnb2a > 0 ) {
×
2233
                                        DivLong((UWORD *)AT.WorkPointer,nnb2a
×
2234
                                                        ,nnt,nnb
2235
                                                        ,((UWORD *)AT.WorkPointer)+2*nnb2,&nnc
×
2236
                                                        ,((UWORD *)AT.WorkPointer)+nnb2,&nc);
×
2237
                                        for ( nni = 0; nni < nnb2; nni++ ) {
×
2238
                                                ((UWORD *)AT.WorkPointer)[nni+2*nnb2] = 0;
×
2239
                                        }
2240
                                        ((UWORD *)AT.WorkPointer)[3*nnb2] = 1;
×
2241
                                        DivLong((UWORD *)AT.WorkPointer+2*nnb2,nnb2+1
×
2242
                                                        ,nnt,nnb
2243
                                                        ,((UWORD *)AT.WorkPointer)+4*nnb2+1,&nnc
×
2244
                                                        ,((UWORD *)AT.WorkPointer)+3*nnb2+1,&nca);
×
2245
                                        AddLong((UWORD *)AT.WorkPointer+2*nnb2,nnb2+1
×
2246
                                                        ,((UWORD *)AT.WorkPointer)+3*nnb2+1,-nca
2247
                                                        ,((UWORD *)AT.WorkPointer)+4*nnb2+1,&nnc);
×
2248
                                        if ( BigLong((UWORD *)AT.WorkPointer,nnb2a
×
2249
                                                        ,((UWORD *)AT.WorkPointer)+4*nnb2+1,nnc) >= 0 ) goto redoshort;
×
2250
                                        }
2251
                                        else nc = 0;
×
2252
                                        if ( nc == 0 ) {
×
2253
                                                for ( nni = 0; nni < nnb; nni++ ) {
×
2254
                                                        ((UWORD *)AT.WorkPointer)[nnb2+nni] = nnt[nni];
×
2255
                                                }
2256
                                                nc = nnb;
×
2257
                                        }
2258
                                        ncoef = REDLENG(ncoef);
×
2259
                                        if ( Mully(BHEAD (UWORD *)n_coef,&ncoef,((UWORD *)(AT.WorkPointer))+nnb2,nc) )
×
2260
                                                        goto FromNorm;
×
2261
                                        ncoef = INCLENG(ncoef);
×
2262
                                }
2263
                                else goto defaultcase;
×
2264
                                }
2265
                                break;
×
2266
                        case RANPERM :
88✔
2267
                                if ( *t == RANPERM && t[1] > FUNHEAD && t[FUNHEAD] <= -FUNCTION ) {
88✔
2268
                                        WORD **pwork;
88✔
2269
                                        WORD *mm, *ww, *ow = AT.WorkPointer;
88✔
2270
                                        WORD *Array, *targ, *argstop, narg = 0, itot;
88✔
2271
                                        int ie;
88✔
2272
                                        argstop = t+t[1];
88✔
2273
                                        targ = t+FUNHEAD+1;
88✔
2274
                                        while ( targ < argstop ) {
88✔
2275
                                                narg++; NEXTARG(targ);
8,132✔
2276
                                        }
2277
                                        WantAddPointers(narg);
96✔
2278
                                        pwork = AT.pWorkSpace + AT.pWorkPointer;
88✔
2279
                                        targ = t+FUNHEAD+1; narg = 0;
88✔
2280
                                        while ( targ < argstop ) {
88✔
2281
                                                pwork[narg++] = targ;
8,044✔
2282
                                                NEXTARG(targ);
8,132✔
2283
                                        }
2284
/*
2285
                                        Make a random permutation of the numbers 0,...,narg-1
2286
                                        The following code works also for narg == 0 and narg == 1
2287
*/
2288
                                        ow = AT.WorkPointer;
88✔
2289
                                        Array = AT.WorkPointer;
88✔
2290
                                        AT.WorkPointer += narg;
88✔
2291
                                        for ( i = 0; i < narg; i++ ) Array[i] = i;
8,132✔
2292
                                        for ( i = 2; i <= narg; i++ ) {
8,044✔
2293
                                                itot = (WORD)(iranf(BHEAD i));
7,956✔
2294
                                                for ( j = 0; j < itot; j++ ) CYCLE1(WORD,Array,i)
13,429,190✔
2295
                                        }
2296
                                        mm = AT.WorkPointer;
88✔
2297
                                        *mm++ = -t[FUNHEAD];
88✔
2298
                                        *mm++ = t[1] - 1;
88✔
2299
                                        for ( ie = 2; ie < FUNHEAD; ie++ ) *mm++ = t[ie];
176✔
2300
                                        for ( i = 0; i < narg; i++ ) {
8,132✔
2301
                                                ww = pwork[Array[i]];
8,044✔
2302
                                                CopyArg(mm,ww);
8,116✔
2303
                                        }
2304
                                        mm = AT.WorkPointer; t++; ww = t;
88✔
2305
                                        i = mm[1]; NCOPY(ww,mm,i)
16,504✔
2306
                                        AT.WorkPointer = ow;
88✔
2307
                                        goto TryAgain;
88✔
2308
                                }
2309
                                pnco[nnco++] = t;
×
2310
                                break;
×
2311
                        case PUTFIRST : /* First argument should be a function, second a number */
4✔
2312
                                if ( ( t[2] & DIRTYFLAG ) != 0 && t[FUNHEAD] <= -FUNCTION
4✔
2313
                                && t[FUNHEAD+1] == -SNUMBER && t[FUNHEAD+2] > 0 ) {
4✔
2314
                                        WORD *rr = t+t[1], *mm = t+FUNHEAD+3, *tt, *tt1, *tt2, num = 0;
4✔
2315
/*
2316
                                        now count the arguments. If not enough: no action.
2317
*/
2318
                                        while ( mm < rr ) { num++; NEXTARG(mm); }
48✔
2319
                                        if ( num < t[FUNHEAD+2] ) { pnco[nnco++] = t; break; }
4✔
2320
                                        *t = -t[FUNHEAD]; mm = t+FUNHEAD+3;
4✔
2321
                                        i = t[FUNHEAD+2];
4✔
2322
                                        while ( --i > 0 ) { NEXTARG(mm); }
16✔
2323
                                        tt = TermMalloc("Select_"); /* Move selected out of the way */
4✔
2324
                    tt1 = tt;
4✔
2325
                                        if ( *mm > 0 ) {
4✔
2326
                                                for ( i = 0; i < *mm; i++ ) *tt1++ = mm[i];
×
2327
                                        }
2328
                                        else if ( *mm <= -FUNCTION ) { *tt1++ = *mm; }
4✔
2329
                                        else { *tt1++ = mm[0]; *tt1++ = mm[1]; }
4✔
2330
                                        tt2 = t+FUNHEAD+3;
2331
                                        while ( tt2 < mm ) *tt1++ = *tt2++;
28✔
2332
                                        i = tt1-tt; tt1 = tt; tt2 = t+FUNHEAD;
4✔
2333
                                        NCOPY(tt2,tt1,i);
36✔
2334
                                        TermFree(tt,"Select_");
4✔
2335
                                        NEXTARG(mm);
4✔
2336
                                        while ( mm < rr ) *tt2++ = *mm++;
60✔
2337
                                        t[1] = tt2 - t;
4✔
2338
                                        rr = term + *term;
4✔
2339
                                        while ( mm < rr ) *tt2++ = *mm++;
16✔
2340
                                        *term = tt2-term;
4✔
2341
                                        goto Restart;
4✔
2342
                                }
2343
                                else pnco[nnco++] = t;
×
2344
                                break;
×
2345
#ifdef WITHFLOAT
2346
                        case FLOATFUN :
×
2347
/*
2348
                                If it is a proper float_ we give it special treatment.
2349
                                If it is not proper, we treat it as a regular commuting function.
2350
*/
2351
                                if ( withfloat == 0 ) {
×
2352
                                        if ( TestFloat(t) == 0 ) goto defaultcase;
×
2353
                                        firstfloat = t;
2354
                                        withfloat = 1;
2355
                                }
2356
                                else { /* There are now at least two float_'s. Time for action. */
2357
                                        if ( TestFloat(t) == 0 ) goto defaultcase;
×
2358
                                        if ( withfloat == 1 ) UnpackFloat(aux4,firstfloat);
×
2359
                                        withfloat++;
×
2360
                                        UnpackFloat(aux5,t);
×
2361
                                        mpf_mul(aux4,aux4,aux5);
×
2362
                                }
2363
                                break;
2364
#endif
2365
                        case INTFUNCTION :
×
2366
/*
2367
                                Can be resolved if the first argument is a number
2368
                                and the second argument either doesn't exist or has
2369
                                the value +1, 0, -1
2370
                                +1 : rounding up
2371
                                0  : rounding towards zero
2372
                                -1 : rounding down (same as no argument)
2373
*/
2374
                                if ( t[1] <= FUNHEAD ) break;
×
2375
                                {
2376
                                        WORD *rr, den, num;
×
2377
                                        to = t + FUNHEAD;
×
2378
                                        if ( *to > 0 ) {
×
2379
                                                if ( *to == ARGHEAD ) goto NormZero;
×
2380
                                                rr = to + *to;
×
2381
                                                i = rr[-1];
×
2382
                                                j = ABS(i);
×
2383
                                                if ( to[ARGHEAD] != j+1 ) goto NoInteg;
×
2384
                                                if ( rr >= r ) k = -1;
×
2385
                                                else if ( *rr == ARGHEAD ) { k = 0; rr += ARGHEAD; }
×
2386
                                                else if ( *rr == -SNUMBER ) { k = rr[1]; rr += 2; }
×
2387
                                                else goto NoInteg;
×
2388
                                                if ( rr != r ) goto NoInteg;
×
2389
                                                if ( k > 1 || k < -1 ) goto NoInteg;
×
2390
                                                to += ARGHEAD+1;
×
2391
                                                j = (j-1) >> 1;
×
2392
                                                i = ( i < 0 ) ? -j: j;
×
2393
                                                UnPack((UWORD *)to,i,&den,&num);
×
2394
/*
2395
                                                Potentially the use of NoScrat2 is unsafe.
2396
                                                It makes the routine not reentrant, but because it is
2397
                                                used only locally and because we only call the
2398
                                                low level routines DivLong and AddLong which never
2399
                                                make calls involving Normalize, things are OK after all
2400
*/
2401
                                                if ( AN.NoScrat2 == 0 ) {
×
2402
                                                        AN.NoScrat2 = (UWORD *)Malloc1((AM.MaxTal+2)*sizeof(UWORD),"Normalize");
×
2403
                                                }
2404
                                                if ( DivLong((UWORD *)to,num,(UWORD *)(to+j),den
×
2405
                                                ,(UWORD *)AT.WorkPointer,&num,AN.NoScrat2,&den) ) goto FromNorm;
×
2406
                                                if ( k < 0 && den < 0 ) {
×
2407
                                                        *AN.NoScrat2 = 1;
×
2408
                                                        den = -1;
×
2409
                                                        if ( AddLong((UWORD *)AT.WorkPointer,num
×
2410
                                                        ,AN.NoScrat2,den,(UWORD *)AT.WorkPointer,&num) )
×
2411
                                                                goto FromNorm;
×
2412
                                                }
2413
                                                else if ( k > 0 && den > 0 ) {
×
2414
                                                        *AN.NoScrat2 = 1;
×
2415
                                                        den = 1;
×
2416
                                                        if ( AddLong((UWORD *)AT.WorkPointer,num,
×
2417
                                                        AN.NoScrat2,den,(UWORD *)AT.WorkPointer,&num) )
×
2418
                                                                goto FromNorm;
×
2419
                                                }
2420

2421
                                        }
2422
                                        else if ( *to == -SNUMBER ) {        /* No rounding needed */
×
2423
                                                if ( to[1] < 0 ) { *AT.WorkPointer = -to[1]; num = -1; }
×
2424
                                                else if ( to[1] == 0 ) goto NormZero;
×
2425
                                                else { *AT.WorkPointer = to[1]; num = 1; }
×
2426
                                        }
2427
                                        else goto NoInteg;
×
2428
                                        if ( num == 0 ) goto NormZero;
×
2429
                                        ncoef = REDLENG(ncoef);
×
2430
                                        if ( Mully(BHEAD (UWORD *)n_coef,&ncoef,(UWORD *)AT.WorkPointer,num) )
×
2431
                                                goto FromNorm;
×
2432
                                        ncoef = INCLENG(ncoef);
×
2433
                                        break;
×
2434
                                }
2435
NoInteg:;
11,566,460✔
2436
/*
2437
                                Fall through if it cannot be resolved
2438
*/
2439
                        default :
2440
defaultcase:;
11,566,460✔
2441
                                if ( *t < FUNCTION ) {
11,566,460✔
2442
                                        MLOCK(ErrorMessageLock);
×
2443
                                        MesPrint("Illegal code in Norm");
×
2444
#ifdef DEBUGON
2445
                                        {
2446
                                                UBYTE OutBuf[140];
2447
                                                AO.OutFill = AO.OutputLine = OutBuf;
2448
                                                t = term;
2449
                                                AO.OutSkip = 3;
2450
                                                FiniLine();
2451
                                                i = *t;
2452
                                                while ( --i >= 0 ) {
2453
                                                        TalToLine((UWORD)(*t++));
2454
                                                        TokenToLine((UBYTE *)"  ");
2455
                                                }
2456
                                                AO.OutSkip = 0;
2457
                                                FiniLine();
2458
                                        }
2459
#endif
2460
                                        MUNLOCK(ErrorMessageLock);
×
2461
                                        goto NormMin;
×
2462
                                }
2463
                                if ( *t == REPLACEMENT ) {
11,566,460✔
2464
                                        if ( AR.Eside != LHSIDE ) ReplaceVeto--;
4,554✔
2465
                                        pcom[ncom++] = t;
4,554✔
2466
                                        break;
4,554✔
2467
                                }
2468
/*
2469
                                if ( *t == AM.termfunnum && t[1] == FUNHEAD+2
2470
                                && t[FUNHEAD] == -DOLLAREXPRESSION ) termflag++;
2471
*/
2472
                                if ( *t == DUMMYFUN || *t == DUMMYTEN ) {}
11,561,890✔
2473
                                else {
2474
                                        if ( *t < (FUNCTION + WILDOFFSET) ) {
11,561,770✔
2475
                                                if ( ( ( functions[*t-FUNCTION].maxnumargs > 0 )
11,561,410✔
2476
                                                || ( functions[*t-FUNCTION].minnumargs > 0 ) )
11,561,410✔
2477
                                                 && ( ( t[2] & DIRTYFLAG ) != 0 ) ) {
×
2478
/*
2479
                                                        Number of arguments is bounded. And we have not checked.
2480
*/
2481
                                                        WORD *ta = t + FUNHEAD, *tb = t + t[1];
×
2482
                                                        int numarg = 0;
×
2483
                                                        while ( ta < tb ) { numarg++; NEXTARG(ta) }
×
2484
                                                        if ( ( functions[*t-FUNCTION].maxnumargs > 0 )
×
2485
                                                        && ( numarg >= functions[*t-FUNCTION].maxnumargs ) )
×
2486
                                                                goto NormZero;
×
2487
                                                        if ( ( functions[*t-FUNCTION].minnumargs > 0 )
×
2488
                                                        && ( numarg < functions[*t-FUNCTION].minnumargs ) )
×
2489
                                                                goto NormZero;
×
2490
                                                }
2491
doflags:
11,561,410✔
2492
                                                if ( ( ( t[2] & DIRTYFLAG ) != 0 ) && ( functions[*t-FUNCTION].tabl == 0 ) ) {
11,561,410✔
2493
                                                        t[2] &= ~DIRTYFLAG;
2,678,667✔
2494
                                                        t[2] |= DIRTYSYMFLAG;
2,678,667✔
2495
                                                }
2496
                                                if ( functions[*t-FUNCTION].commute ) { pnco[nnco++] = t; }
11,561,410✔
2497
                                                else { pcom[ncom++] = t; }
11,555,040✔
2498
                                        }
2499
                                        else {
2500
                                                if ( ( ( t[2] & DIRTYFLAG ) != 0 ) && ( functions[*t-FUNCTION-WILDOFFSET].tabl == 0 ) ) {
364✔
2501
                                                        t[2] &= ~DIRTYFLAG;
182✔
2502
                                                        t[2] |= DIRTYSYMFLAG;
182✔
2503
                                                }
2504
                                                if ( functions[*t-FUNCTION-WILDOFFSET].commute ) {
364✔
2505
                                                        pnco[nnco++] = t;
14✔
2506
                                                }
2507
                                                else { pcom[ncom++] = t; }
350✔
2508
                                        }
2509
                                }
2510

2511
                                /* Now hunt for contractible indices */
2512

2513
                                if ( ( *t < (FUNCTION + WILDOFFSET)
11,561,890✔
2514
                                 && functions[*t-FUNCTION].spec >= TENSORFUNCTION ) || (
11,561,890✔
2515
                                 *t >= (FUNCTION + WILDOFFSET)
2516
                                 && functions[*t-FUNCTION-WILDOFFSET].spec >= TENSORFUNCTION ) ) {
364✔
2517
                                        if ( *t >= GAMMA && *t <= GAMMASEVEN ) t++;
590✔
2518
                                        t += FUNHEAD;
590✔
2519
                                        while ( t < r ) {
2,760✔
2520
                                                if ( *t == AM.vectorzero ) goto NormZero;
2,170✔
2521
                                                if ( *t >= AM.OffsetIndex && ( *t >= AM.DumInd
2,170✔
2522
                                                || ( *t < AM.WilInd && indices[*t-AM.OffsetIndex].dimension ) ) ) {
276✔
2523
                                                        pcon[ncon++] = t;
596✔
2524
                                                }
2525
                                                else if ( *t == FUNNYWILD ) { t++; }
1,574✔
2526
                                                t++;
2,170✔
2527
                                        }
2528
                                }
2529
                                else {
2530
                                        t += FUNHEAD;
11,561,310✔
2531
                                        while ( t < r ) {
24,768,550✔
2532
                                                if ( *t > 0 ) {
13,207,250✔
2533
/*
2534
                                                        Here we should worry about a recursion
2535
                                                        A problem is the possibility of a construct
2536
                                                        like  f(mu+nu)
2537
*/
2538
                                                        t += *t;
4,367,540✔
2539
                                                }
2540
                                                else if ( *t <= -FUNCTION ) t++;
8,839,702✔
2541
                                                else if ( *t == -INDEX ) {
8,839,340✔
2542
                                                        if ( t[1] >= AM.OffsetIndex &&
41,582✔
2543
                                                                ( t[1] >= AM.DumInd || ( t[1] < AM.WilInd
41,574✔
2544
                                                                && indices[t[1]-AM.OffsetIndex].dimension ) ) )
40,917✔
2545
                                                                pcon[ncon++] = t+1;
41,434✔
2546
                                                        t += 2;
41,582✔
2547
                                                }
2548
                                                else if ( *t == -SYMBOL ) {
8,797,758✔
2549
                                                        if ( t[1] >= MAXPOWER && t[1] < 2*MAXPOWER ) {
384,559✔
2550
                                                                *t = -SNUMBER;
×
2551
                                                                t[1] -= MAXPOWER;
×
2552
                                                        }
2553
                                                        else if ( t[1] < -MAXPOWER && t[1] > -2*MAXPOWER  ) {
384,559✔
2554
                                                                *t = -SNUMBER;
×
2555
                                                                t[1] += MAXPOWER;
×
2556
                                                        }
2557
                                                        else t += 2;
384,559✔
2558
                                                }
2559
                                                else t += 2;
8,413,196✔
2560
                                        }
2561
                                }
2562
                                break;
2563
                }
2564
                t = r;
×
2565
TryAgain:;
57,418,700✔
2566
        } while ( t < m );
57,418,700✔
2567
        if ( ANsc ) {
32,386,820✔
2568
                AN.cTerm = ANsc;
44✔
2569
                r = t = ANsr; m = ANsm;
44✔
2570
                ANsc = ANsm = ANsr = 0;
44✔
2571
                goto conscan;
44✔
2572
        }
2573
/*
2574
          #] First scan : 
2575
          #[ Easy denominators :
2576

2577
        Easy denominators are denominators that can be replaced by
2578
        negative powers of individual subterms. This may add to all
2579
        our sublists.
2580

2581
*/
2582
        if ( nden ) {
32,386,770✔
2583
                for ( k = 0, i = 0; i < nden; i++ ) {
6,058✔
2584
                        t = pden[i];
3,029✔
2585
                        if ( ( t[2] & DIRTYFLAG ) == 0 ) continue;
3,029✔
2586
                        r = t + t[1]; m = t + FUNHEAD;
2,941✔
2587
                        if ( m >= r ) {
2,941✔
2588
                                for ( j = i+1; j < nden; j++ ) pden[j-1] = pden[j];
×
2589
                                nden--;
×
2590
                                for ( j = 0; j < nnco; j++ ) if ( pnco[j] == t ) break;
×
2591
                                for ( j++; j < nnco; j++ ) pnco[j-1] = pnco[j];
×
2592
                                nnco--;
×
2593
                                i--;
×
2594
                        }
2595
                        else {
2596
                                NEXTARG(m);
2,941✔
2597
                                if ( m >= r ) continue;
2,941✔
2598
/*
2599
                                We have more than one argument. Split the function.
2600
*/
2601
                                if ( k == 0 ) {
×
2602
                                        k = 1; to = termout; from = term;
×
2603
                                }
2604
                                while ( from < t ) *to++ = *from++;
×
2605
                                m = t + FUNHEAD;
2606
                                while ( m < r ) {
×
2607
                                        stop = to;
×
2608
                                        *to++ = DENOMINATOR;
×
2609
                                        for ( j = 1; j < FUNHEAD; j++ ) *to++ = 0;
×
2610
                                        if ( *m < -FUNCTION ) *to++ = *m++;
×
2611
                                        else if ( *m < 0 ) { *to++ = *m++; *to++ = *m++; }
×
2612
                                        else {
2613
                                                j = *m; while ( --j >= 0 ) *to++ = *m++;
×
2614
                                        }
2615
                                        stop[1] = WORDDIF(to,stop);
×
2616
                                }
2617
                                from = r;
×
2618
                                if ( i == nden - 1 ) {
×
2619
                                        stop = term + *term;
×
2620
                                        while ( from < stop ) *to++ = *from++;
×
2621
                                        i = *termout = WORDDIF(to,termout);
×
2622
                                        to = term; from = termout;
×
2623
                                        while ( --i >= 0 ) *to++ = *from++;
×
2624
                                        goto Restart;
×
2625
                                }
2626
                        }
2627
                }
2628
                for ( i = 0; i < nden; i++ ) {
6,058✔
2629
                        t = pden[i];
3,029✔
2630
                        if ( ( t[2] & DIRTYFLAG ) == 0 ) continue;
3,029✔
2631
                        t[2] = 0;
2,941✔
2632
                        if ( t[FUNHEAD] == -SYMBOL ) {
2,941✔
2633
                                WORD change;
×
2634
                                t += FUNHEAD+1;
×
2635
                                change = ExtraSymbol(*t,-1,nsym,ppsym,&ncoef);
×
2636
                                nsym += change;
×
2637
                                ppsym += change * 2;
×
2638
                                goto DropDen;
×
2639
                        }
2640
                        else if ( t[FUNHEAD] == -SNUMBER ) {
2,941✔
2641
                                t += FUNHEAD+1;
1,652✔
2642
                                if ( *t == 0 ) goto NormInf;
1,652✔
2643
                                if ( *t < 0 ) { *AT.WorkPointer = -*t; j = -1; }
1,652✔
2644
                                else { *AT.WorkPointer = *t; j = 1; }
1,652✔
2645
                                ncoef = REDLENG(ncoef);
1,652✔
2646
                                if ( Divvy(BHEAD (UWORD *)n_coef,&ncoef,(UWORD *)AT.WorkPointer,j) )
1,652✔
2647
                                        goto FromNorm;
×
2648
                                ncoef = INCLENG(ncoef);
1,652✔
2649
                                goto DropDen;
1,652✔
2650
                        }
2651
                        else if ( t[FUNHEAD] == ARGHEAD ) goto NormInf;
1,289✔
2652
                        else if ( t[FUNHEAD] > 0 && t[FUNHEAD+ARGHEAD] == 
1,289✔
2653
                        t[FUNHEAD]-ARGHEAD ) {
1,289✔
2654
                                /* Only one term */
2655
                                r = t + t[1] - 1;
1,249✔
2656
                                t += FUNHEAD + ARGHEAD + 1;
1,249✔
2657
                                j = *r;
1,249✔
2658
                                m = r - ABS(*r) + 1;
1,249✔
2659
                                if ( j != 3 || ( ( *m != 1 ) || ( m[1] != 1 ) ) ) {
1,249✔
2660
                                        ncoef = REDLENG(ncoef);
1,221✔
2661
                                        if ( DivRat(BHEAD (UWORD *)n_coef,ncoef,(UWORD *)m,REDLENG(j),(UWORD *)n_coef,&ncoef) ) goto FromNorm;
1,221✔
2662
                                        ncoef = INCLENG(ncoef);
1,221✔
2663
                                        j = ABS(j) - 3;
1,221✔
2664
                                        t[-FUNHEAD-ARGHEAD] -= j;
1,221✔
2665
                                        t[-ARGHEAD-1] -= j;
1,221✔
2666
                                        t[-1] -= j;
1,221✔
2667
                                        m[0] = m[1] = 1;
1,221✔
2668
                                        m[2] = 3;
1,221✔
2669
                                }
2670
                                while ( t < m ) {
1,298✔
2671
                                        r = t + t[1];
49✔
2672
                                        if ( *t == SYMBOL || *t == DOTPRODUCT ) {
49✔
2673
                                                k = t[1];
49✔
2674
                                                pden[i][1] -= k;
49✔
2675
                                                pden[i][FUNHEAD] -= k;
49✔
2676
                                                pden[i][FUNHEAD+ARGHEAD] -= k;
49✔
2677
                                                m -= k;
49✔
2678
                                                stop = m + 3;
49✔
2679
                                                tt = to = t;
49✔
2680
                                                from = r;
49✔
2681
                                                if ( *t == SYMBOL ) {
49✔
2682
                                                        t += 2;
49✔
2683
                                                        while ( t < r ) {
98✔
2684
                                                                WORD change;
49✔
2685
                                                                change = ExtraSymbol(*t,-t[1],nsym,ppsym,&ncoef);
49✔
2686
                                                                nsym += change;
49✔
2687
                                                                ppsym += change * 2;
49✔
2688
                                                                t += 2;
49✔
2689
                                                        }
2690
                                                }
2691
                                                else {
2692
                                                        t += 2;
×
2693
                                                        while ( t < r ) {
×
2694
                                                                *ppdot++ = *t++;
×
2695
                                                                *ppdot++ = *t++;
×
2696
                                                                *ppdot++ = -*t++;
×
2697
                                                                ndot++;
×
2698
                                                        }
2699
                                                }
2700
                                                while ( to < stop ) *to++ = *from++;
196✔
2701
                                                r = tt;
2702
                                        }
2703
#ifdef WITHFLOAT
2704
                                        else if ( *t == FLOATFUN && TestFloat(t) ) {
×
2705
                                                k = t[1];
×
2706
                                                pden[i][1] -= k;
×
2707
                                                pden[i][FUNHEAD] -= k;
×
2708
                                                pden[i][FUNHEAD+ARGHEAD] -= k;
×
2709
                                                UnpackFloat(aux5,t);
×
2710
                                                if ( withfloat == 0 ) {
×
2711
                                                        mpf_ui_div(aux4,1,aux5);
×
2712
                                                        withfloat = 2;
×
2713
                                                }
2714
                                                else {
2715
                                                        if ( withfloat == 1 ) UnpackFloat(aux4,firstfloat);
×
2716
                                                        mpf_div(aux4,aux4,aux5);
×
2717
                                                        withfloat++;
×
2718
                                                }
2719
                                                tt = to = t;
×
2720
                                                while ( r < m ) *to++ = *r++;
×
2721
                                                *to++ = 1; *to++ = 1; *to++ = 3;
×
2722
                                                if ( ncoef < 0 ) t[-1] = -t[-1];
×
2723
                                                m -= k;
×
2724
                                                stop = m + 3;
×
2725
                                                r = tt;
×
2726
                                        }
2727
#endif
2728
                                        t = r;
2729
                                }
2730
                                if ( pden[i][1] == 4+FUNHEAD+ARGHEAD ) {
1,249✔
2731
DropDen:
1,249✔
2732
                                        for ( j = 0; j < nnco; j++ ) {
2,901✔
2733
                                                if ( pden[i] == pnco[j] ) {
2,901✔
2734
                                                        --nnco;
2,901✔
2735
                                                        while ( j < nnco ) {
2,901✔
2736
                                                                pnco[j] = pnco[j+1];
×
2737
                                                                j++;
×
2738
                                                        }
2739
                                                        break;
2740
                                                }
2741
                                        }
2742
                                        pden[i--] = pden[--nden];
2,901✔
2743
                                }
2744
                        }
2745
                }
2746
        }
2747
/*
2748
          #] Easy denominators : 
2749
          #[ Index Contractions :
2750
*/
2751
        if ( ndel ) {
32,386,770✔
2752
                t = pdel;
2753
                for ( i = 0; i < ndel; i += 2 ) {
147,008,000✔
2754
                        if ( t[0] == t[1] ) {
130,579,200✔
2755
                                if ( t[0] == EMPTYINDEX ) {}
668✔
2756
                                else if ( *t < AM.OffsetIndex ) {
668✔
2757
                                        k = AC.FixIndices[*t];
484✔
2758
                                        if ( k < 0 ) { j = -1; k = -k; }
484✔
2759
                                        else if ( k > 0 ) j = 1;
324✔
2760
                                        else goto NormZero;
×
2761
                                        goto WithFix;
484✔
2762
                                }
2763
                                else if ( *t >= AM.DumInd ) {
184✔
2764
                                        k = AC.lDefDim;
×
2765
                                        if ( k ) goto docontract;
×
2766
                                }
2767
                                else if ( *t >= AM.WilInd ) {
184✔
2768
                                        k = indices[*t-AM.OffsetIndex-WILDOFFSET].dimension;
×
2769
                                        if ( k ) goto docontract;
×
2770
                                }
2771
                                else if ( ( k = indices[*t-AM.OffsetIndex].dimension ) != 0 ) {
184✔
2772
docontract:
8✔
2773
                                        if ( k > 0 ) {
8✔
2774
                                                j = 1;
2775
WithFix:                                shortnum = k;
484✔
2776
                                                ncoef = REDLENG(ncoef);
484✔
2777
                                                if ( Mully(BHEAD (UWORD *)n_coef,&ncoef,(UWORD *)(&shortnum),j) )
484✔
2778
                                                        goto FromNorm;
×
2779
                                                ncoef = INCLENG(ncoef);
484✔
2780
                                        }
2781
                                        else {
2782
                                                WORD change;
8✔
2783
                                                change = ExtraSymbol((WORD)(-k),(WORD)1,nsym,ppsym,&ncoef);
8✔
2784
                                                nsym += change;
8✔
2785
                                                ppsym += change * 2;
8✔
2786
                                           }
2787
                                        t[1] = pdel[ndel-1];
492✔
2788
                                        t[0] = pdel[ndel-2];
492✔
2789
HaveCon:
496✔
2790
                                        ndel -= 2;
496✔
2791
                                        i -= 2;
496✔
2792
                                }
2793
                        }
2794
                        else {
2795
                                if ( *t < AM.OffsetIndex && t[1] < AM.OffsetIndex ) goto NormZero;
130,578,800✔
2796
                                j = *t - AM.OffsetIndex;
130,578,400✔
2797
                                if ( j >= 0 && ( ( *t >= AM.DumInd && AC.lDefDim )
130,578,400✔
2798
                                || ( *t < AM.WilInd && indices[j].dimension ) ) ) {
130,578,400✔
2799
                                        for ( j = i + 2, m = pdel+j; j < ndel; j += 2, m += 2 ) {
585,904,000✔
2800
                                                if ( *t == *m ) {
455,328,000✔
2801
                                                        *t = m[1];
4✔
2802
                                                        *m++ = pdel[ndel-2];
4✔
2803
                                                        *m = pdel[ndel-1];
4✔
2804
                                                        goto HaveCon;
4✔
2805
                                                }
2806
                                                else if ( *t == m[1] ) {
455,328,000✔
2807
                                                        *t = *m;
×
2808
                                                        *m++ = pdel[ndel-2];
×
2809
                                                        *m   = pdel[ndel-1];
×
2810
                                                        goto HaveCon;
×
2811
                                                }
2812
                                        }
2813
                                }
2814
                                j = t[1]-AM.OffsetIndex;
130,578,400✔
2815
                                if ( j >= 0 && ( ( t[1] >= AM.DumInd && AC.lDefDim )
130,578,400✔
2816
                                || ( t[1] < AM.WilInd && indices[j].dimension ) ) ) {
130,578,400✔
2817
                                        for ( j = i + 2, m = pdel+j; j < ndel; j += 2, m += 2 ) {
585,904,000✔
2818
                                                if ( t[1] == *m ) {
455,328,000✔
2819
                                                        t[1] = m[1];
×
2820
                                                        *m++ = pdel[ndel-2];
×
2821
                                                        *m   = pdel[ndel-1];
×
2822
                                                        goto HaveCon;
×
2823
                                                }
2824
                                                else if ( t[1] == m[1] ) {
455,328,000✔
2825
                                                        t[1] = *m;
×
2826
                                                        *m++ = pdel[ndel-2];
×
2827
                                                        *m   = pdel[ndel-1];
×
2828
                                                        goto HaveCon;
×
2829
                                                }
2830
                                        }
2831
                                }
2832
                                t += 2;
130,578,400✔
2833
                        }
2834
                }
2835
                if ( ndel > 0 ) {
16,428,800✔
2836
                        if ( nvec ) {        
16,428,560✔
2837
                                t = pdel;
2838
                                for ( i = 0; i < ndel; i++ ) {
×
2839
                                        if ( *t >= AM.OffsetIndex && ( ( *t >= AM.DumInd && AC.lDefDim ) ||
×
2840
                                        ( *t < AM.WilInd && indices[*t-AM.OffsetIndex].dimension ) ) ) {
×
2841
                                                r = pvec + 1;
2842
                                                for ( j = 1; j < nvec; j += 2 ) {
×
2843
                                                        if ( *r == *t ) {
×
2844
                                                                if ( i & 1 ) {
×
2845
                                                                        *r = t[-1];
×
2846
                                                                        *t-- = pdel[--ndel];
×
2847
                                                                        i -= 2;
×
2848
                                                                }
2849
                                                                else {
2850
                                                                        *r = t[1];
×
2851
                                                                        t[1] = pdel[--ndel];
×
2852
                                                                        i--;
×
2853
                                                                }
2854
                                                                *t-- = pdel[--ndel];
×
2855
                                                                break;
×
2856
                                                        }
2857
                                                        r += 2;
×
2858
                                                }
2859
                                        }
2860
                                        t++;
×
2861
                                }
2862
                        }
2863
                        if ( ndel > 0 && ncon ) {
16,428,560✔
2864
                                t = pdel;
2865
                                for ( i = 0; i < ndel; i++ ) {
1,909,104✔
2866
                                        if ( *t >= AM.OffsetIndex && ( ( *t >= AM.DumInd && AC.lDefDim ) ||
1,696,968✔
2867
                                        ( *t < AM.WilInd && indices[*t-AM.OffsetIndex].dimension ) ) ) {
1,696,968✔
2868
                                                for ( j = 0; j < ncon; j++ ) {
8,484,680✔
2869
                                                        if ( *pcon[j] == *t ) {
6,787,800✔
2870
                                                                if ( i & 1 ) {
72✔
2871
                                                                        *pcon[j] = t[-1];
×
2872
                                                                        *t-- = pdel[--ndel];
×
2873
                                                                        i -= 2;
×
2874
                                                                }
2875
                                                                else {
2876
                                                                        *pcon[j] = t[1];
72✔
2877
                                                                        t[1] = pdel[--ndel];
72✔
2878
                                                                        i--;
72✔
2879
                                                                }
2880
                                                                *t-- = pdel[--ndel];
72✔
2881
                                                                didcontr++;
72✔
2882
                                                                r = pcon[j];
72✔
2883
                                                                for ( j = 0; j < nnco; j++ ) {
72✔
2884
                                                                        m = pnco[j];
×
2885
                                                                        if ( r > m && r < m+m[1] ) {
×
2886
                                                                                m[2] |= DIRTYSYMFLAG;
×
2887
                                                                                break;
×
2888
                                                                        }
2889
                                                                }
2890
                                                                for ( j = 0; j < ncom; j++ ) {
144✔
2891
                                                                        m = pcom[j];
144✔
2892
                                                                        if ( r > m && r < m+m[1] ) {
144✔
2893
                                                                                m[2] |= DIRTYSYMFLAG;
72✔
2894
                                                                                break;
72✔
2895
                                                                        }
2896
                                                                }
2897
                                                                for ( j = 0; j < neps; j++ ) {
72✔
2898
                                                                        m = peps[j];
×
2899
                                                                        if ( r > m && r < m+m[1] ) {
×
2900
                                                                                m[2] |= DIRTYSYMFLAG;
×
2901
                                                                                break;
×
2902
                                                                        }
2903
                                                                }
2904
                                                                break;
2905
                                                        }
2906
                                                }
2907
                                        }
2908
                                        t++;
1,696,968✔
2909
                                }
2910
                        }
2911
                }
2912
        }
2913
        if ( nvec ) {
32,386,550✔
2914
                t = pvec + 1;
2915
                for ( i = 3; i < nvec; i += 2 ) {
112✔
2916
                        k = *t - AM.OffsetIndex;
12✔
2917
                        if ( k >= 0 && ( ( *t > AM.DumInd && AC.lDefDim )
12✔
2918
                        || ( *t < AM.WilInd && indices[k].dimension ) ) ) {
×
2919
                                r = t + 2;
12✔
2920
                                for ( j = i; j < nvec; j += 2 ) {
16✔
2921
                                        if ( *r == *t ) {        /* Another dotproduct */
12✔
2922
                                                *ppdot++ = t[-1];
8✔
2923
                                                *ppdot++ = r[-1];
8✔
2924
                                                *ppdot++ = 1;
8✔
2925
                                                ndot++;
8✔
2926
                                                *r-- = pvec[--nvec];
8✔
2927
                                                *r   = pvec[--nvec];
8✔
2928
                                                *t-- = pvec[--nvec];
8✔
2929
                                                *t-- = pvec[--nvec];
8✔
2930
                                                i -= 2;
8✔
2931
                                                break;
8✔
2932
                                        }
2933
                                        r += 2;
4✔
2934
                                }
2935
                        }
2936
                        t += 2;
12✔
2937
                }
2938
                if ( nvec > 0 && ncon ) {
100✔
2939
                        t = pvec + 1;
2940
                        for ( i = 1; i < nvec; i += 2 ) {
12✔
2941
                                k = *t - AM.OffsetIndex;
8✔
2942
                                if ( k >= 0 && ( ( *t >= AM.DumInd && AC.lDefDim )
8✔
2943
                                || ( *t < AM.WilInd && indices[k].dimension ) ) ) {
×
2944
                                        for ( j = 0; j < ncon; j++ ) {
8✔
2945
                                                if ( *pcon[j] == *t ) {
8✔
2946
                                                        *pcon[j] = t[-1];
8✔
2947
                                                        *t-- = pvec[--nvec];
8✔
2948
                                                        *t-- = pvec[--nvec];
8✔
2949
                                                        r = pcon[j];
8✔
2950
                                                        pcon[j] = pcon[--ncon];
8✔
2951
                                                        i -= 2;
8✔
2952
                                                        for ( j = 0; j < nnco; j++ ) {
8✔
2953
                                                                m = pnco[j];
×
2954
                                                                if ( r > m && r < m+m[1] ) {
×
2955
                                                                        m[2] |= DIRTYSYMFLAG;
×
2956
                                                                        break;
×
2957
                                                                }
2958
                                                        }
2959
                                                        for ( j = 0; j < ncom; j++ ) {
12✔
2960
                                                                m = pcom[j];
12✔
2961
                                                                if ( r > m && r < m+m[1] ) {
12✔
2962
                                                                        m[2] |= DIRTYSYMFLAG;
8✔
2963
                                                                        break;
8✔
2964
                                                                }
2965
                                                        }
2966
                                                        for ( j = 0; j < neps; j++ ) {
8✔
2967
                                                                m = peps[j];
×
2968
                                                                if ( r > m && r < m+m[1] ) {
×
2969
                                                                        m[2] |= DIRTYSYMFLAG;
×
2970
                                                                        break;
×
2971
                                                                }
2972
                                                        }
2973
                                                        break;
2974
                                                }
2975
                                        }
2976
                                }
2977
                                t += 2;
8✔
2978
                        }
2979
                }
2980
        }
2981
/*
2982
          #] Index Contractions : 
2983
          #[ NonCommuting Functions :
2984
*/
2985
        m = fillsetexp;
32,386,550✔
2986
        if ( nnco ) {
32,386,550✔
2987
                for ( i = 0; i < nnco; i++ ) {
15,431✔
2988
                        t = pnco[i];
8,831✔
2989
                        if ( ( *t >= (FUNCTION+WILDOFFSET)
8,831✔
2990
                        && functions[*t-FUNCTION-WILDOFFSET].spec <= 0 )
14✔
2991
                        || ( *t >= FUNCTION && *t < (FUNCTION + WILDOFFSET)
8,817✔
2992
                        && functions[*t-FUNCTION].spec <= 0 ) ) {
8,796✔
2993
                                DoRevert(t,m);
6,714✔
2994
                                if ( didcontr ) {
6,714✔
2995
                                        r = t + FUNHEAD;
×
2996
                                        t += t[1];
×
2997
                                        while ( r < t ) {
×
2998
                                                if ( *r == -INDEX && r[1] >= 0 && r[1] < AM.OffsetIndex ) {
×
2999
                                                        *r = -SNUMBER;
×
3000
                                                        didcontr--;
×
3001
                                                        pnco[i][2] |= DIRTYSYMFLAG;
×
3002
                                                }
3003
                                                NEXTARG(r)
×
3004
                                        }
3005
                                }
3006
                        }
3007
                }
3008

3009
                /* First should come the code for function properties. */
3010
 
3011
                /* First we test for symmetric properties and the DIRTYSYMFLAG */
3012

3013
                for ( i = 0; i < nnco; i++ ) {
15,431✔
3014
                        t = pnco[i];
8,831✔
3015
                        if ( *t > 0 && ( t[2] & DIRTYSYMFLAG ) && *t != DOLLAREXPRESSION ) {
8,831✔
3016
                                l = 0; /* to make the compiler happy */
4,230✔
3017
                                if ( ( *t >= (FUNCTION+WILDOFFSET)
4,230✔
3018
                                && ( l = functions[*t-FUNCTION-WILDOFFSET].symmetric ) > 0 )
14✔
3019
                                || ( *t >= FUNCTION && *t < (FUNCTION + WILDOFFSET)
4,230✔
3020
                                && ( l = functions[*t-FUNCTION].symmetric ) > 0 ) ) {
4,216✔
3021
                                        if ( *t >= (FUNCTION+WILDOFFSET) ) {
44✔
3022
                                                *t -= WILDOFFSET;
×
3023
                                                j = FullSymmetrize(BHEAD t,l);
×
3024
                                                *t += WILDOFFSET;
×
3025
                                        }
3026
                                        else j = FullSymmetrize(BHEAD t,l);
44✔
3027
                                        if ( (l & ~REVERSEORDER) == ANTISYMMETRIC ) {
44✔
3028
                                                if ( ( j & 2 ) != 0 ) goto NormZero;
36✔
3029
                                                if ( ( j & 1 ) != 0 ) ncoef = -ncoef;
36✔
3030
                                        }
3031
                                }
3032
                                else t[2] &= ~DIRTYSYMFLAG;
4,186✔
3033
                        }
3034
                }
3035

3036
                /* Non commuting functions are then tested for commutation
3037
                   rules. If needed their order is exchanged. */
3038

3039
                k = nnco - 1;
6,600✔
3040
                for ( i = 0; i < k; i++ ) {
8,831✔
3041
                        j = i;
3042
                        while ( Commute(pnco[j],pnco[j+1]) ) {
2,263✔
3043
                                t = pnco[j]; pnco[j] = pnco[j+1]; pnco[j+1] = t;
36✔
3044
                                l = j-1;
36✔
3045
                                while ( l >= 0 && Commute(pnco[l],pnco[l+1]) ) {
92✔
3046
                                        t = pnco[l]; pnco[l] = pnco[l+1]; pnco[l+1] = t;
56✔
3047
                                        l--;
56✔
3048
                                }
3049
                                if ( ++j >= k ) break;
36✔
3050
                        }
3051
                }
3052

3053
                /* Finally they are written to output. gamma matrices
3054
                   are bundled if possible */
3055

3056
                for ( i = 0; i < nnco; i++ ) {
15,419✔
3057
                        t = pnco[i];
8,819✔
3058
                        if ( *t == IDFUNCTION ) AN.idfunctionflag = 1;
8,819✔
3059
                        if ( *t >= GAMMA && *t <= GAMMASEVEN ) {
8,819✔
3060
                                WORD gtype;
2,084✔
3061
                                to = m;
2,084✔
3062
                                *m++ = GAMMA;
2,084✔
3063
                                m++;
2,084✔
3064
                                FILLFUN(m)
2,084✔
3065
                                *m++ = stype = t[FUNHEAD];                /* type of string */
2,084✔
3066
                                j = 0;
2,084✔
3067
                                nnum = 0;
2,084✔
3068
                                do {
2,096✔
3069
                                        r = t + t[1];
2,096✔
3070
                                        if ( *t == GAMMAFIVE ) {
2,096✔
3071
                                                gtype = GAMMA5; t += FUNHEAD; goto onegammamatrix; }
16✔
3072
                                        else if ( *t == GAMMASIX ) {
2,080✔
3073
                                                gtype = GAMMA6; t += FUNHEAD; goto onegammamatrix; }
×
3074
                                        else if ( *t == GAMMASEVEN ) {
2,080✔
3075
                                                gtype = GAMMA7; t += FUNHEAD; goto onegammamatrix; }
×
3076
                                        t += FUNHEAD+1;
2,080✔
3077
                                        while ( t < r ) {
18,272✔
3078
                                                gtype = *t;
16,176✔
3079
onegammamatrix:
16,192✔
3080
                                                if ( gtype == GAMMA5 ) {
16,192✔
3081
                                                        if ( j == GAMMA1 ) j = GAMMA5;
44✔
3082
                                                        else if ( j == GAMMA5 ) j = GAMMA1;
4✔
3083
                                                        else if ( j == GAMMA7 ) ncoef = -ncoef;
×
3084
                                                        if ( nnum & 1 ) ncoef = -ncoef;
44✔
3085
                                                }
3086
                                                else if ( gtype == GAMMA6 || gtype == GAMMA7 ) {
16,148✔
3087
                                                        if ( nnum & 1 ) {
×
3088
                                                                if ( gtype == GAMMA6 ) gtype = GAMMA7;
×
3089
                                                                else                                   gtype = GAMMA6;
×
3090
                                                        }
3091
                                                        if ( j == GAMMA1 ) j = gtype;
×
3092
                                                        else if ( j == GAMMA5 ) {
×
3093
                                                                j = gtype;
×
3094
                                                                if ( j == GAMMA7 ) ncoef = -ncoef;
×
3095
                                                        }
3096
                                                        else if ( j != gtype ) goto NormZero;
×
3097
                                                        else {
3098
                                                                shortnum = 2;
×
3099
                                                                ncoef = REDLENG(ncoef);
×
3100
                                                                if ( Mully(BHEAD (UWORD *)n_coef,&ncoef,(UWORD *)(&shortnum),1) ) goto FromNorm;
×
3101
                                                                ncoef = INCLENG(ncoef);
×
3102
                                                        }
3103
                                                }
3104
                                                else {
3105
                                                        *m++ = gtype; nnum++;
16,148✔
3106
                                                }
3107
                                                t++;
16,192✔
3108
                                        }
3109
                                        
3110
                                } while ( ( ++i < nnco ) && ( *(t = pnco[i]) >= GAMMA
20✔
3111
                                && *t <= GAMMASEVEN ) && ( t[FUNHEAD] == stype ) );
2,116✔
3112
                                i--;
2,084✔
3113
                                if ( j ) {
2,084✔
3114
                                        k = WORDDIF(m,to) - FUNHEAD-1;
36✔
3115
                                        r = m;
36✔
3116
                                        from = m++;
36✔
3117
                                        while ( --k >= 0 ) *from-- = *--r;
132✔
3118
                                        *from = j;
36✔
3119
                                }
3120
                                to[1] = WORDDIF(m,to);
2,084✔
3121
                        }
3122
                        else if ( *t < 0 ) {
6,735✔
3123
                                *m++ = -*t; *m++ = FUNHEAD; *m++ = 0;
×
3124
                                FILLFUN3(m)
3125
                        }
3126
                        else {
3127
                                if ( ( t[2] & DIRTYFLAG ) == DIRTYFLAG
6,735✔
3128
                                                && *t != REPLACEMENT && *t != DOLLAREXPRESSION
225✔
3129
                                                && TestFunFlag(BHEAD t) ) ReplaceVeto = 1;
204✔
3130
                                k = t[1];
6,735✔
3131
                                NCOPY(m,t,k);
127,198✔
3132
                        }
3133
                }
3134

3135
        }
3136
/*
3137
          #] NonCommuting Functions : 
3138
          #[ Commuting Functions :
3139
*/
3140
        if ( ncom ) {
32,386,550✔
3141
                for ( i = 0; i < ncom; i++ ) {
15,551,770✔
3142
                        t = pcom[i];
11,559,920✔
3143
                        if ( ( *t >= (FUNCTION+WILDOFFSET)
11,559,920✔
3144
                        && functions[*t-FUNCTION-WILDOFFSET].spec <= 0 )
350✔
3145
                        || ( *t >= FUNCTION && *t < (FUNCTION + WILDOFFSET)
11,559,570✔
3146
                        && functions[*t-FUNCTION].spec <= 0 ) ) {
11,559,570✔
3147
                                DoRevert(t,m);
11,559,370✔
3148
                                if ( didcontr ) {
11,559,370✔
3149
                                        r = t + FUNHEAD;
72✔
3150
                                        t += t[1];
72✔
3151
                                        while ( r < t ) {
216✔
3152
                                                if ( *r == -INDEX && r[1] >= 0 && r[1] < AM.OffsetIndex ) {
144✔
3153
                                                        *r = -SNUMBER;
×
3154
                                                        didcontr--;
×
3155
                                                        pcom[i][2] |= DIRTYSYMFLAG;
×
3156
                                                }
3157
                                                NEXTARG(r)
144✔
3158
                                        }
3159
                                }
3160
                        }
3161
                }
3162

3163
                /* Now we test for symmetric properties and the DIRTYSYMFLAG */
3164

3165
                for ( i = 0; i < ncom; i++ ) {
15,551,770✔
3166
                        t = pcom[i];
11,559,920✔
3167
                        if ( *t > 0 && ( t[2] & DIRTYSYMFLAG ) ) {
11,559,920✔
3168
                                l = 0; /* to make the compiler happy */
2,676,234✔
3169
                                if ( ( *t >= (FUNCTION+WILDOFFSET)
2,676,234✔
3170
                                && ( l = functions[*t-FUNCTION-WILDOFFSET].symmetric ) > 0 )
168✔
3171
                                || ( *t >= FUNCTION && *t < (FUNCTION + WILDOFFSET)
2,676,213✔
3172
                                && ( l = functions[*t-FUNCTION].symmetric ) > 0 ) ) {
2,676,066✔
3173
                                        if ( *t >= (FUNCTION+WILDOFFSET) ) {
3,805✔
3174
                                                *t -= WILDOFFSET;
21✔
3175
                                                j = FullSymmetrize(BHEAD t,l);
21✔
3176
                                                *t += WILDOFFSET;
21✔
3177
                                        }
3178
                                        else j = FullSymmetrize(BHEAD t,l);
3,784✔
3179
                                        if ( (l & ~REVERSEORDER) == ANTISYMMETRIC ) {
3,805✔
3180
                                                if ( ( j & 2 ) != 0 ) goto NormZero;
582✔
3181
                                                if ( ( j & 1 ) != 0 ) ncoef = -ncoef;
582✔
3182
                                        }
3183
                                }
3184
                                else t[2] &= ~DIRTYSYMFLAG;
2,672,429✔
3185
                        }
3186
                }
3187
/*
3188
                Sort the functions
3189
                From a purists point of view this can be improved.
3190
                There are slow and fast arguments and no conversions are
3191
                taken into account here.
3192
*/
3193
                for ( i = 1; i < ncom; i++ ) {
11,559,920✔
3194
                        for ( j = i; j > 0; j-- ) {
14,277,270✔
3195
                                WORD jj,kk;
14,236,930✔
3196
                                jj = j-1;
14,236,930✔
3197
                                t = pcom[jj];
14,236,930✔
3198
                                r = pcom[j];
14,236,930✔
3199
                                if ( *t < 0 ) {
14,236,930✔
3200
                                        if ( *r < 0 ) { if ( *t >= *r ) goto NextI; }
×
3201
                                        else { if ( -*t <= *r ) goto NextI; }
×
3202
                                        goto jexch;
×
3203
                                }
3204
                                else if ( *r < 0 ) {
14,236,930✔
3205
                                        if ( *t < -*r ) goto NextI;
×
3206
                                        goto jexch;
×
3207
                                }
3208
                                else if ( *t != *r ) {
14,236,930✔
3209
                                        if ( *t < *r ) goto NextI;
3,474,906✔
3210
jexch:                                t = pcom[j]; pcom[j] = pcom[jj]; pcom[jj] = t;
182,860✔
3211
                                        continue;
6,709,180✔
3212
                                }
3213
                                if ( AC.properorderflag ) {
10,762,030✔
3214
                                        if ( ( *t >= (FUNCTION+WILDOFFSET)
×
3215
                                        && functions[*t-FUNCTION-WILDOFFSET].spec >= TENSORFUNCTION )
×
3216
                                        || ( *t >= FUNCTION && *t < (FUNCTION + WILDOFFSET)
×
3217
                                        && functions[*t-FUNCTION].spec >= TENSORFUNCTION ) ) {}
×
3218
                                        else {
3219
                                                WORD *s1, *s2, *ss1, *ss2;
×
3220
                                                s1 = t+FUNHEAD; s2 = r+FUNHEAD;
×
3221
                                                ss1 = t + t[1]; ss2 = r + r[1];
×
3222
                                                while ( s1 < ss1 && s2 < ss2 ) {
×
3223
                                                        k = CompArg(s1,s2);
×
3224
                                                        if ( k > 0 ) goto jexch;
×
3225
                                                        if ( k < 0 ) goto NextI;
×
3226
                                                        NEXTARG(s1)
×
3227
                                                        NEXTARG(s2)
×
3228
                                                }
3229
                                                if ( s1 < ss1 ) goto jexch;
×
3230
                                                goto NextI;
×
3231
                                        }
3232
                                        k = t[1] - FUNHEAD;
×
3233
                                        kk = r[1] - FUNHEAD;
×
3234
                                        t += FUNHEAD;
×
3235
                                        r += FUNHEAD;
×
3236
                                        while ( k > 0 && kk > 0 ) {
×
3237
                                                if ( *t < *r ) goto NextI;
×
3238
                                                else if ( *t++ > *r++ ) goto jexch;
×
3239
                                                k--; kk--;
×
3240
                                        }
3241
                                        if ( k > 0 ) goto jexch;
×
3242
                                        goto NextI;
×
3243
                                }
3244
                                else
3245
                                {
3246
                                        k = t[1] - FUNHEAD;
10,762,030✔
3247
                                        kk = r[1] - FUNHEAD;
10,762,030✔
3248
                                        t += FUNHEAD;
10,762,030✔
3249
                                        r += FUNHEAD;
10,762,030✔
3250
                                        while ( k > 0 && kk > 0 ) {
150,893,200✔
3251
                                                if ( *t < *r ) goto NextI;
146,944,200✔
3252
                                                else if ( *t++ > *r++ ) goto jexch;
146,657,500✔
3253
                                                k--; kk--;
140,131,200✔
3254
                                        }
3255
                                        if ( k > 0 ) goto jexch;
3,949,008✔
3256
                                        goto NextI;
3,948,996✔
3257
                                }
3258
                        }
3259
NextI:;
7,568,080✔
3260
                }
3261
                for ( i = 0; i < ncom; i++ ) {
15,550,640✔
3262
                        t = pcom[i];
11,559,200✔
3263
                        if ( *t == THETA || *t == THETA2 ) {
11,559,200✔
3264
                                if ( ( k = DoTheta(BHEAD t) ) == 0 ) goto NormZero;
×
3265
                                else if ( k < 0 ) {
×
3266
                                        k = t[1];
×
3267
                                        NCOPY(m,t,k);
×
3268
                                }
3269
                        }
3270
                        else if ( *t == DELTA2 || *t == DELTAP ) {
11,559,200✔
3271
                                if ( ( k = DoDelta(t) ) == 0 ) goto NormZero;
×
3272
                                else if ( k < 0 ) {
×
3273
                                        k = t[1];
×
3274
                                        NCOPY(m,t,k);
×
3275
                                }
3276
                        }
3277
                        else if ( *t == AR.PolyFunInv && AR.PolyFunType == 2 ) {
11,559,200✔
3278
/*
3279
                                If there are two arguments, exchange them, change the
3280
                                name of the function and go to dealing with PolyRatFun.
3281
*/
3282
                                WORD *mm, *tt = t, numt = 0;
8✔
3283
                                tt += FUNHEAD;
8✔
3284
                                while ( tt < t+t[1] ) { numt++; NEXTARG(tt) }
24✔
3285
                                if ( numt == 2 ) {
8✔
3286
                                        tt = t; mm = m; k = t[1];
3287
                                        NCOPY(mm,tt,k)
160✔
3288
                                        mm = m+FUNHEAD;
8✔
3289
                                        NEXTARG(mm);
8✔
3290
                                        tt = t+FUNHEAD;
8✔
3291
                                        if ( *mm < 0 ) {
8✔
3292
                                                if ( *mm <= -FUNCTION ) { *tt++ = *mm++; }
8✔
3293
                                                else { *tt++ = *mm++;  *tt++ = *mm++; }
8✔
3294
                                        }
3295
                                        else {
3296
                                                k = *mm; NCOPY(tt,mm,k)
×
3297
                                        }
3298
                                        mm = m+FUNHEAD;
8✔
3299
                                        if ( *mm < 0 ) {
8✔
3300
                                                if ( *mm <= -FUNCTION ) { *tt++ = *mm++; }
×
3301
                                                else { *tt++ = *mm++;  *tt++ = *mm++; }
×
3302
                                        }
3303
                                        else {
3304
                                                k = *mm; NCOPY(tt,mm,k)
120✔
3305
                                        }
3306
                                        *t = AR.PolyFun;
8✔
3307
                                        t[2] |= MUSTCLEANPRF;
8✔
3308
                                        goto regularratfun;
8✔
3309
                                }
3310
                        }
3311
                        else if ( *t == AR.PolyFun ) {
11,559,200✔
3312
                          if ( AR.PolyFunType == 1 ) { /* Regular PolyFun with one argument */
137,047✔
3313
                                if ( t[FUNHEAD+1] == 0 && AR.Eside != LHSIDE && 
96✔
3314
                                t[1] == FUNHEAD + 2 && t[FUNHEAD] == -SNUMBER ) goto NormZero;
56✔
3315
                                if ( i > 0 && pcom[i-1][0] == AR.PolyFun ) {
96✔
3316
                                        if ( AN.PolyNormFlag == 0 ) {
×
3317
                                                AN.PolyNormFlag = 1;
×
3318
                                                AN.PolyFunTodo = 0;
×
3319
                                        }
3320
                                }
3321
                                k = t[1];
96✔
3322
                                NCOPY(m,t,k);
1,760✔
3323
                          }
3324
                          else if ( AR.PolyFunType == 2 ) {
136,951✔
3325
/*
3326
                                PolyRatFun.
3327
                                        Regular type: Two arguments
3328
                                        Power expanded: One argument. Here to be treated as
3329
                                                AR.PolyFunType == 1, but with power cutoff.
3330
*/
3331
regularratfun:;
136,951✔
3332
/*
3333
                                First check for zeroes.
3334
*/
3335
                                if ( t[FUNHEAD+1] == 0 && AR.Eside != LHSIDE && 
136,959✔
3336
                                t[1] > FUNHEAD + 2 && t[FUNHEAD] == -SNUMBER ) {
71,871✔
3337
                                        u = t + FUNHEAD + 2;
400✔
3338
                                        if ( *u < 0 ) {
400✔
3339
                                                if ( *u <= -FUNCTION ) {}
40✔
3340
                                                else if ( t[1] == FUNHEAD+4 && t[FUNHEAD+2] == -SNUMBER
40✔
3341
                                                        && t[FUNHEAD+3] == 0 ) goto NormPRF;
16✔
3342
                                                else if ( t[1] == FUNHEAD+4 ) goto NormZero;
40✔
3343
                                        }
3344
                                        else if ( t[1] == *u+FUNHEAD+2 ) goto NormZero;
360✔
3345
                                }
3346
                                else {
3347
                                        u = t+FUNHEAD; NEXTARG(u);
136,559✔
3348
                                        if ( *u == -SNUMBER && u[1] == 0 ) goto NormInf;
136,559✔
3349
                                }
3350
                                if ( i > 0 && pcom[i-1][0] == AR.PolyFun ) AN.PolyNormFlag = 1;
136,559✔
3351
                                else if ( i < ncom-1 && pcom[i+1][0] == AR.PolyFun ) AN.PolyNormFlag = 1;
85,871✔
3352
                                k = t[1];
136,559✔
3353
                                if ( AN.PolyNormFlag ) {
136,559✔
3354
                                        if ( AR.PolyFunExp == 0 ) {
85,392✔
3355
                                                AN.PolyFunTodo = 0;
83,852✔
3356
                                                NCOPY(m,t,k);
7,185,800✔
3357
                                        }
3358
                                        else if ( AR.PolyFunExp == 1 ) { /* get highest divergence */
1,540✔
3359
                                                if ( PolyFunMode == 0 ) {
×
3360
                                                        NCOPY(m,t,k);
×
3361
                                                        AN.PolyFunTodo = 1;
×
3362
                                                }
3363
                                                else {
3364
                                                        WORD *mmm = m;
×
3365
                                                        NCOPY(m,t,k);
×
3366
                                                        if ( TreatPolyRatFun(BHEAD mmm) != 0 )
×
3367
                                                                        goto FromNorm;
×
3368
                                                        m = mmm+mmm[1];
×
3369
                                                }
3370
                                        }
3371
                                        else {
3372
                                                if ( PolyFunMode == 0 ) {
1,540✔
3373
                                                        NCOPY(m,t,k);
30,280✔
3374
                                                                AN.PolyFunTodo = 1;
1,520✔
3375
                                                }
3376
                                                else {
3377
                                                        WORD *mmm = m;
328✔
3378
                                                        NCOPY(m,t,k);
328✔
3379
                                                        if ( ExpandRat(BHEAD mmm) != 0 )
20✔
3380
                                                                        goto FromNorm;
×
3381
                                                        m = mmm+mmm[1];
20✔
3382
                                                }
3383
                                        }
3384
                                }
3385
                                else {
3386
                                        if ( AR.PolyFunExp == 0 ) {
51,167✔
3387
                                                AN.PolyFunTodo = 0;
51,087✔
3388
                                                NCOPY(m,t,k);
8,731,420✔
3389
                                        }
3390
                                        else if ( AR.PolyFunExp == 1 ) { /* get highest divergence */
80✔
3391
                                                WORD *mmm = m;
×
3392
                                                NCOPY(m,t,k);
×
3393
                                                if ( TreatPolyRatFun(BHEAD mmm) != 0 )
×
3394
                                                                goto FromNorm;
×
3395
                                                m = mmm+mmm[1];
×
3396
                                        }
3397
                                        else {
3398
                                                WORD *mmm = m;
30,056✔
3399
                                                NCOPY(m,t,k);
30,056✔
3400
                                                if ( ExpandRat(BHEAD mmm) != 0 )
80✔
3401
                                                                goto FromNorm;
×
3402
                                                m = mmm+mmm[1];
80✔
3403
                                        }
3404
                                }
3405
                          }
3406
                        }
3407
                        else if ( *t > 0 ) {
11,422,160✔
3408
                                if ( ( t[2] & DIRTYFLAG ) == DIRTYFLAG
11,422,160✔
3409
                                        && *t != REPLACEMENT && TestFunFlag(BHEAD t) ) ReplaceVeto = 1;
4,534✔
3410
                                k = t[1];
11,422,160✔
3411
                                NCOPY(m,t,k);
127,814,800✔
3412
                        }
3413
                        else {
3414
                                *m++ = -*t; *m++ = FUNHEAD; *m++ = 0;
×
3415
                                FILLFUN3(m)
3416
                        }
3417
                }
3418
        }
3419
/*
3420
          #] Commuting Functions : 
3421
          #[ Track Replace_ :
3422
*/
3423
        if ( ReplaceVeto < 0 ) {
32,386,150✔
3424
/*
3425
                We found one (or more) replace_ functions and all other
3426
                functions are 'clean' (no dirty flag).
3427
                Now we check whether one of these functions can be used.
3428
                Thus far the functions go from fillsetexp to m.
3429
                Somewhere in there there are -ReplaceVeto occurrences of REPLACEMENT.
3430
                Hunt for the first one that fits the bill.
3431
                Note that replace_ is a commuting function.
3432
*/
3433
                WORD *ma = fillsetexp, *mb, *mc;
3434
                while ( ma < m ) {
4,587✔
3435
                        mb = ma + ma[1];
4,587✔
3436
                        if ( *ma != REPLACEMENT ) {
4,587✔
3437
                                ma = mb;
40✔
3438
                                continue;
40✔
3439
                        }
3440
                        if ( *ma == REPLACEMENT && ReplaceType == -1 ) {
4,547✔
3441
                                mc = ma;
4,547✔
3442
                                ReplaceType = 0;
4,547✔
3443
                                if ( AN.RSsize < 2*ma[1]+SUBEXPSIZE ) {
4,547✔
3444
                                        if ( AN.ReplaceScrat ) M_free(AN.ReplaceScrat,"AN.ReplaceScrat");
101✔
3445
                                        AN.RSsize = 2*ma[1]+SUBEXPSIZE+40;
101✔
3446
                                        AN.ReplaceScrat = (WORD *)Malloc1((AN.RSsize+1)*sizeof(WORD),"AN.ReplaceScrat");
101✔
3447
                                }
3448
                                ma += FUNHEAD;
4,547✔
3449
                                ReplaceSub = AN.ReplaceScrat;
4,547✔
3450
                                ReplaceSub += SUBEXPSIZE;
4,547✔
3451
                                while ( ma < mb ) {
9,182✔
3452
                                        if ( *ma > 0 ) goto NoRep;
4,635✔
3453
                                        if ( *ma <= -FUNCTION ) {
4,635✔
3454
                                                *ReplaceSub++ = FUNTOFUN;
×
3455
                                                *ReplaceSub++ = 4;
×
3456
                                                *ReplaceSub++ = -*ma++;
×
3457
                                                if ( *ma > -FUNCTION ) goto NoRep;
×
3458
                                                *ReplaceSub++ = -*ma++;
×
3459
                                        }
3460
                                        else if ( ma+4 > mb ) goto NoRep;
4,635✔
3461
                                        else {
3462
                                                if ( *ma == -SYMBOL ) {
4,635✔
3463
                                                        if ( ma[2] == -SYMBOL && ma+4 <= mb )
4,587✔
3464
                                                                *ReplaceSub++ = SYMTOSYM;
2,796✔
3465
                                                        else if ( ma[2] == -SNUMBER && ma+4 <= mb ) {
1,791✔
3466
                                                                *ReplaceSub++ = SYMTONUM;
124✔
3467
                                                                if ( ReplaceType == 0 ) {
124✔
3468
                                                                        oldtoprhs = C->numrhs;
92✔
3469
                                                                        oldcpointer = C->Pointer - C->Buffer;
92✔
3470
                                                                }
3471
                                                                ReplaceType = 1;
3472
                                                        }
3473
                                                        else if ( ma[2] == ARGHEAD && ma+2+ARGHEAD <= mb ) {
1,667✔
3474
                                                                *ReplaceSub++ = SYMTONUM;
×
3475
                                                                *ReplaceSub++ = 4;
×
3476
                                                                *ReplaceSub++ = ma[1];
×
3477
                                                                *ReplaceSub++ = 0;
×
3478
                                                                ma += 2+ARGHEAD;
×
3479
                                                                continue;
×
3480
                                                        }
3481
/*
3482
                                                        Next is the subexpression. We have to test that
3483
                                                        it isn't vector-like or index-like
3484
*/
3485
                                                        else if ( ma[2] > 0 ) {
1,667✔
3486
                                                                WORD *sstop, *ttstop, n;
1,667✔
3487
                                                                ss = ma+2;
1,667✔
3488
                                                                sstop = ss + *ss;
1,667✔
3489
                                                                ss += ARGHEAD;
1,667✔
3490
                                                                while ( ss < sstop ) {
3,797✔
3491
                                                                        tt = ss + *ss;
2,130✔
3492
                                                                        ttstop = tt - ABS(tt[-1]);
2,130✔
3493
                                                                        ss++;
2,130✔
3494
                                                                        while ( ss < ttstop ) {
3,053✔
3495
                                                                                if ( *ss == INDEX ) goto NoRep;
923✔
3496
                                                                                ss += ss[1];
923✔
3497
                                                                        }
3498
                                                                        ss = tt;
3499
                                                                }
3500
                                                                subtype = SYMTOSUB;
1,667✔
3501
                                                                if ( ReplaceType == 0 ) {
1,667✔
3502
                                                                        oldtoprhs = C->numrhs;
1,667✔
3503
                                                                        oldcpointer = C->Pointer - C->Buffer;
1,667✔
3504
                                                                }
3505
                                                                ReplaceType = 1;
1,667✔
3506
                                                                ss = AddRHS(AT.ebufnum,1);
1,667✔
3507
                                                                tt = ma+2;
1,667✔
3508
                                                                n = *tt - ARGHEAD;
1,667✔
3509
                                                                tt += ARGHEAD;
1,667✔
3510
                                                                while ( (ss + n + 10) > C->Top ) ss = DoubleCbuffer(AT.ebufnum,ss,14);
1,667✔
3511
                                                                while ( --n >= 0 ) *ss++ = *tt++;
13,879✔
3512
                                                                *ss++ = 0;
1,667✔
3513
                                                                C->rhs[C->numrhs+1] = ss;
1,667✔
3514
                                                                C->Pointer = ss;
1,667✔
3515
                                                                *ReplaceSub++ = subtype;
1,667✔
3516
                                                                *ReplaceSub++ = 4;
1,667✔
3517
                                                                *ReplaceSub++ = ma[1];
1,667✔
3518
                                                                *ReplaceSub++ = C->numrhs;
1,667✔
3519
                                                                ma += 2 + ma[2];
1,667✔
3520
                                                                continue;
1,667✔
3521
                                                        }
3522
                                                        else goto NoRep;
×
3523
                                                }
3524
                                                else if ( ( *ma == -VECTOR || *ma == -MINVECTOR ) && ma+4 <= mb ) {
48✔
3525
                                                        if ( ma[2] == -VECTOR ) {
48✔
3526
                                                                if ( *ma == -VECTOR ) *ReplaceSub++ = VECTOVEC;
44✔
3527
                                                                else *ReplaceSub++ = VECTOMIN;
×
3528
                                                        }
3529
                                                        else if ( ma[2] == -MINVECTOR ) {
4✔
3530
                                                                if ( *ma == -VECTOR ) *ReplaceSub++ = VECTOMIN;
×
3531
                                                                else *ReplaceSub++ = VECTOVEC;
×
3532
                                                        }
3533
/*
3534
                                                        Next is a vector-like subexpression
3535
                                                        Search for vector nature first
3536
*/
3537
                                                        else if ( ma[2] > 0 ) {
4✔
3538
                                                                WORD *sstop, *ttstop, *w, *mm, n, count;
4✔
3539
                                                                WORD *v1, *v2 = 0;
4✔
3540
                                                                if ( *ma == -MINVECTOR ) {
4✔
3541
                                                                        ss = ma+2;
×
3542
                                                                        sstop = ss + *ss;
×
3543
                                                                        ss += ARGHEAD;
×
3544
                                                                        while ( ss < sstop ) {
×
3545
                                                                                ss += *ss;
×
3546
                                                                                ss[-1] = -ss[-1];
×
3547
                                                                        }
3548
                                                                        *ma = -VECTOR;
×
3549
                                                                }
3550
                                                                ss = ma+2;
4✔
3551
                                                                sstop = ss + *ss;
4✔
3552
                                                                ss += ARGHEAD;
4✔
3553
                                                                while ( ss < sstop ) {
12✔
3554
                                                                        tt = ss + *ss;
8✔
3555
                                                                        ttstop = tt - ABS(tt[-1]);
8✔
3556
                                                                        ss++;
8✔
3557
                                                                        count = 0;
8✔
3558
                                                                        while ( ss < ttstop ) {
16✔
3559
                                                                                if ( *ss == INDEX ) {
8✔
3560
                                                                                        n = ss[1] - 2; ss += 2;
8✔
3561
                                                                                        while ( --n >= 0 ) {
16✔
3562
                                                                                                if ( *ss < MINSPEC ) count++;
8✔
3563
                                                                                                ss++;
8✔
3564
                                                                                        }
3565
                                                                                }
3566
                                                                                else ss += ss[1];
×
3567
                                                                        }
3568
                                                                        if ( count != 1 ) goto NoRep;
8✔
3569
                                                                        ss = tt;
3570
                                                                }
3571
                                                                subtype = VECTOSUB;
4✔
3572
                                                                if ( ReplaceType == 0 ) {
4✔
3573
                                                                        oldtoprhs = C->numrhs;
4✔
3574
                                                                        oldcpointer = C->Pointer - C->Buffer;
4✔
3575
                                                                }
3576
                                                                ReplaceType = 1;
4✔
3577
                                                                mm = AddRHS(AT.ebufnum,1);
4✔
3578
                                                                *ReplaceSub++ = subtype;
4✔
3579
                                                                *ReplaceSub++ = 4;
4✔
3580
                                                                *ReplaceSub++ = ma[1];
4✔
3581
                                                                *ReplaceSub++ = C->numrhs;
4✔
3582
                                                                w = ma+2;
4✔
3583
                                                                n = *w - ARGHEAD;
4✔
3584
                                                                w += ARGHEAD;
4✔
3585
                                                                while ( (mm + n + 10) > C->Top )
4✔
3586
                                                                        mm = DoubleCbuffer(AT.ebufnum,mm,15);
×
3587
                                                                while ( --n >= 0 ) *mm++ = *w++;
60✔
3588
                                                                *mm++ = 0;
4✔
3589
                                                                C->rhs[C->numrhs+1] = mm;
4✔
3590
                                                                C->Pointer = mm;
4✔
3591
                                                                mm = AddRHS(AT.ebufnum,1);
4✔
3592
                                                                w = ma+2;
4✔
3593
                                                                n = *w - ARGHEAD;
4✔
3594
                                                                w += ARGHEAD;
4✔
3595
                                                                while ( (mm + n + 13) > C->Top )
4✔
3596
                                                                        mm = DoubleCbuffer(AT.ebufnum,mm,16);
×
3597
                                                                sstop = w + n;
4✔
3598
                                                                while ( w < sstop ) {
12✔
3599
                                                                        tt = w + *w; ttstop = tt - ABS(tt[-1]);
8✔
3600
                                                                        ss = mm; mm++; w++;
8✔
3601
                                                                        while ( w < ttstop ) {                /* Subterms */
16✔
3602
                                                                                if ( *w != INDEX ) {
8✔
3603
                                                                                        n = w[1];
×
3604
                                                                                        NCOPY(mm,w,n);
×
3605
                                                                                }
3606
                                                                                else {
3607
                                                                                        v1 = mm;
8✔
3608
                                                                                        *mm++ = *w++;
8✔
3609
                                                                                        *mm++ = n = *w++;
8✔
3610
                                                                                        n -= 2;
8✔
3611
                                                                                        while ( --n >= 0 ) {
16✔
3612
                                                                                                if ( *w >= MINSPEC ) *mm++ = *w++;
8✔
3613
                                                                                                else v2 = w++;
8✔
3614
                                                                                        }
3615
                                                                                        n = WORDDIF(mm,v1);
8✔
3616
                                                                                        if ( n != v1[1] ) {
8✔
3617
                                                                                                if ( n <= 2 ) mm -= 2;
8✔
3618
                                                                                                else v1[1] = n;
×
3619
                                                                                                *mm++ = VECTOR;
8✔
3620
                                                                                                *mm++ = 4;
8✔
3621
                                                                                                *mm++ = *v2;
8✔
3622
                                                                                                *mm++ = FUNNYVEC;
8✔
3623
                                                                                        }
3624
                                                                                }
3625
                                                                        }
3626
                                                                        while ( w < tt ) *mm++ = *w++;
32✔
3627
                                                                        *ss = WORDDIF(mm,ss);
8✔
3628
                                                                }
3629
                                                                *mm++ = 0;
4✔
3630
                                                                C->rhs[C->numrhs+1] = mm;
4✔
3631
                                                                C->Pointer = mm;
4✔
3632
                                                                if ( mm > C->Top ) {
4✔
3633
                                                                        MLOCK(ErrorMessageLock);
×
3634
                                                                        MesPrint("Internal error in Normalize with extra compiler buffer");
×
3635
                                                                        MUNLOCK(ErrorMessageLock);
×
NEW
3636
                                                                        TERMINATE(-1);
×
3637
                                                                }
3638
                                                                ma += 2 + ma[2];
4✔
3639
                                                                continue;
4✔
3640
                                                        }
3641
                                                        else goto NoRep;
×
3642
                                                }
3643
                                                else if ( *ma == -INDEX ) {
×
3644
                                                        if ( ( ma[2] == -INDEX || ma[2] == -VECTOR )
×
3645
                                                        && ma+4 <= mb )
3646
                                                                *ReplaceSub++ = INDTOIND;
×
3647
                                                        else if ( ma[1] >= AM.OffsetIndex ) {
×
3648
                                                                if ( ma[2] == -SNUMBER && ma+4 <= mb
×
3649
                                                                && ma[3] >= 0 && ma[3] < AM.OffsetIndex )
×
3650
                                                                        *ReplaceSub++ = INDTOIND;
×
3651
                                                                else if ( ma[2] == ARGHEAD && ma+2+ARGHEAD <= mb ) {
×
3652
                                                                        *ReplaceSub++ = INDTOIND;
×
3653
                                                                        *ReplaceSub++ = 4;
×
3654
                                                                        *ReplaceSub++ = ma[1];
×
3655
                                                                        *ReplaceSub++ = 0;
×
3656
                                                                        ma += 2+ARGHEAD;
×
3657
                                                                        continue;
×
3658
                                                                }
3659
                                                                else goto NoRep;
×
3660
                                                        }
3661
                                                        else goto NoRep;
×
3662
                                                }
3663
                                                else goto NoRep;
×
3664
                                                *ReplaceSub++ = 4;
2,964✔
3665
                                                *ReplaceSub++ = ma[1];
2,964✔
3666
                                                *ReplaceSub++ = ma[3];
2,964✔
3667
                                                ma += 4;
2,964✔
3668
                                        }
3669
                                                
3670
                                }
3671
                                AN.ReplaceScrat[1] = ReplaceSub-AN.ReplaceScrat;
4,547✔
3672
/*
3673
                                Success. This means that we have to remove the replace_
3674
                                from the functions. It starts at mc and end at mb.
3675
*/
3676
                                while ( mb < m ) *mc++ = *mb++;
808,235✔
3677
                                m = mc;
3678
                                break;
3679
NoRep:
×
3680
                                if ( ReplaceType > 0 ) {
×
3681
                                        C->numrhs = oldtoprhs;
×
3682
                                        C->Pointer = C->Buffer + oldcpointer;
×
3683
                                }
3684
                                ReplaceType = -1;
×
3685
                                if ( ++ReplaceVeto >= 0 ) break;
×
3686
                        }
3687
                        ma = mb;
3688
                }
3689
        }
3690
/*
3691
          #] Track Replace_ : 
3692
          #[ LeviCivita tensors :
3693
*/
3694
        if ( neps ) {
32,386,150✔
3695
                to = m;
432,488✔
3696
                for ( i = 0; i < neps; i++ ) {        /* Put the indices in order */
432,488✔
3697
                        t = peps[i];
216,320✔
3698
                        if ( ( t[2] & DIRTYSYMFLAG ) != DIRTYSYMFLAG ) continue;
216,320✔
3699
                        t[2] &= ~DIRTYSYMFLAG;
6,424✔
3700
                        if ( AR.Eside == LHSIDE || AR.Eside == LHSIDEX ) {
6,424✔
3701
                                                /* Potential problems with FUNNYWILD */
3702
/*
3703
                                First make sure all FUNNIES are at the end.
3704
                                Then sort separately
3705
*/
3706
                                r = t + FUNHEAD;
×
3707
                                m = tt = t + t[1];
×
3708
                                while ( r < m ) {
×
3709
                                        if ( *r != FUNNYWILD ) { r++; continue; }
×
3710
                                        k = r[1]; u = r + 2;
×
3711
                                        while ( u < tt ) {
×
3712
                                                u[-2] = *u;
×
3713
                                                if ( *u != FUNNYWILD ) ncoef = -ncoef;
×
3714
                                                u++;
×
3715
                                        }
3716
                                        tt[-2] = FUNNYWILD; tt[-1] = k; m -= 2;
×
3717
                                }
3718
                                t += FUNHEAD;
3719
                                do {
×
3720
                                        for ( r = t + 1; r < m; r++ ) {
×
3721
                                                if ( *r < *t ) { k = *r; *r = *t; *t = k; ncoef = -ncoef; }
×
3722
                                                else if ( *r == *t ) goto NormZero;
×
3723
                                        }
3724
                                        t++;
×
3725
                                } while ( t < m );
×
3726
                                do {
×
3727
                                        for ( r = t + 2; r < tt; r += 2 ) {
×
3728
                                                if ( r[1] < t[1] ) {
×
3729
                                                        k = r[1]; r[1] = t[1]; t[1] = k; ncoef = -ncoef; }
×
3730
                                                else if ( r[1] == t[1] ) goto NormZero;
×
3731
                                        }
3732
                                        t += 2;
×
3733
                                } while ( t < tt );
×
3734
                        }
3735
                        else {
3736
                                m = t + t[1];
6,424✔
3737
                                t += FUNHEAD;
6,424✔
3738
                                do {
25,396✔
3739
                                        for ( r = t + 1; r < m; r++ ) {
63,220✔
3740
                                                if ( *r < *t ) { k = *r; *r = *t; *t = k; ncoef = -ncoef; }
37,884✔
3741
                                                else if ( *r == *t ) goto NormZero;
37,804✔
3742
                                        }
3743
                                        t++;
25,336✔
3744
                                } while ( t < m );
25,336✔
3745
                        }
3746
                }
3747

3748
                /* Sort the tensors */
3749

3750
                for ( i = 0; i < (neps-1); i++ ) {
216,260✔
3751
                        t = peps[i];
92✔
3752
                        for ( j = i+1; j < neps; j++ ) {
192✔
3753
                                r = peps[j];
100✔
3754
                                if ( t[1] > r[1] ) {
100✔
3755
                                        peps[i] = m = r; peps[j] = r = t; t = m;
×
3756
                                }
3757
                                else if ( t[1] == r[1] ) {
100✔
3758
                                        k = t[1] - FUNHEAD;
100✔
3759
                                        m = t + FUNHEAD;
100✔
3760
                                        r += FUNHEAD;
100✔
3761
                                        do {
268✔
3762
                                                if ( *r < *m ) {
268✔
3763
                                                        m = peps[j]; peps[j] = t; peps[i] = t = m;
×
3764
                                                        break;
×
3765
                                                }
3766
                                                else if ( *r++ > *m++ ) break;
268✔
3767
                                        } while ( --k > 0 );
240✔
3768
                                }
3769
                        }
3770
                }
3771
                m = to;
3772
                for ( i = 0; i < neps; i++ ) {
432,428✔
3773
                        t = peps[i];
216,260✔
3774
                        k = t[1];
216,260✔
3775
                        NCOPY(m,t,k);
1,729,928✔
3776
                }
3777
        }
3778
/*
3779
          #] LeviCivita tensors : 
3780
          #[ Delta :
3781
*/
3782
        if ( ndel ) {
32,386,070✔
3783
                r = t = pdel;
147,007,200✔
3784
                for ( i = 0; i < ndel; i += 2, r += 2 ) {
147,007,200✔
3785
                        if ( r[1] < r[0] ) { k = *r; *r = r[1]; r[1] = k; }
130,578,400✔
3786
                }
3787
                for ( i = 2; i < ndel; i += 2, t += 2 ) {
130,578,400✔
3788
                        r = t + 2;
114,150,000✔
3789
                        for ( j = i; j < ndel; j += 2 ) {
569,476,000✔
3790
                                if ( *r > *t ) { r += 2; }
455,328,000✔
3791
                                else if ( *r < *t ) {
10,040✔
3792
                                        k = *r; *r++ = *t; *t++ = k;
9,872✔
3793
                                        k = *r; *r++ = *t; *t-- = k;
9,872✔
3794
                                }
3795
                                else {
3796
                                        if ( *++r < t[1] ) {
168✔
3797
                                                k = *r; *r = t[1]; t[1] = k;
4✔
3798
                                        }
3799
                                        r++;
168✔
3800
                                }
3801
                        }
3802
                }
3803
                t = pdel;
16,428,560✔
3804
                *m++ = DELTA;
16,428,560✔
3805
                *m++ = ndel + 2;
16,428,560✔
3806
                i = ndel;
16,428,560✔
3807
                NCOPY(m,t,i);
277,585,600✔
3808
        }
3809
/*
3810
          #] Delta : 
3811
          #[ Loose Vectors/Indices :
3812
*/
3813
        if ( nind ) {
32,386,070✔
3814
                t = pind;
3815
                for ( i = 0; i < nind; i++ ) {
1,058✔
3816
                        r = t + 1;
529✔
3817
                        for ( j = i+1; j < nind; j++ ) {
529✔
3818
                                if ( *r < *t ) {
×
3819
                                        k = *r; *r = *t; *t = k;
×
3820
                                }
3821
                                r++;
×
3822
                        }
3823
                        t++;
3824
                }
3825
                t = pind;
529✔
3826
                *m++ = INDEX;
529✔
3827
                *m++ = nind + 2;
529✔
3828
                i = nind;
529✔
3829
                NCOPY(m,t,i);
1,058✔
3830
        }
3831
/*
3832
          #] Loose Vectors/Indices : 
3833
          #[ Vectors :
3834
*/
3835
        if ( nvec ) {
32,386,070✔
3836
                t = pvec;
3837
                for ( i = 2; i < nvec; i += 2 ) {
88✔
3838
                        r = t + 2;
×
3839
                        for ( j = i; j < nvec; j += 2 ) {
×
3840
                                if ( *r == *t ) {
×
3841
                                        if ( *++r < t[1] ) {
×
3842
                                                k = *r; *r = t[1]; t[1] = k;
×
3843
                                        }
3844
                                        r++;
×
3845
                                }
3846
                                else if ( *r < *t ) {
×
3847
                                        k = *r; *r++ = *t; *t++ = k;
×
3848
                                        k = *r; *r++ = *t; *t-- = k;
×
3849
                                }
3850
                                else { r += 2; }
×
3851
                        }
3852
                        t += 2;
×
3853
                }
3854
                t = pvec;
88✔
3855
                *m++ = VECTOR;
88✔
3856
                *m++ = nvec + 2;
88✔
3857
                i = nvec;
88✔
3858
                NCOPY(m,t,i);
264✔
3859
        }
3860
/*
3861
          #] Vectors : 
3862
          #[ Dotproducts :
3863
*/
3864
        if ( ndot ) {
32,386,070✔
3865
                to = m;
1,754✔
3866
                m = t = pdot;
1,754✔
3867
                i = ndot;
3868
                while ( --i >= 0 ) {
1,754✔
3869
                        if ( *t > t[1] ) { j = *t; *t = t[1]; t[1] = j; }
1,181✔
3870
                        t += 3;
1,181✔
3871
                }
3872
                t = m;
573✔
3873
                ndot *= 3;
573✔
3874
                m += ndot;
573✔
3875
                while ( t < (m-3) ) {
1,181✔
3876
                        r = t + 3;
608✔
3877
                        do {
1,024✔
3878
                                if ( *r == *t ) {
1,024✔
3879
                                        if ( *++r == *++t ) {
92✔
3880
                                                r++;
8✔
3881
                                                if ( ( *r < MAXPOWER && t[1] < MAXPOWER )
8✔
3882
                                                || ( *r > -MAXPOWER && t[1] > -MAXPOWER ) ) {
×
3883
                                                        t++;
8✔
3884
                                                        *t += *r;
8✔
3885
                                                        if ( *t > MAXPOWER || *t < -MAXPOWER ) {
8✔
3886
                                                                MLOCK(ErrorMessageLock);
×
3887
                                                                MesPrint("Exponent of dotproduct out of range: %d",*t);
×
3888
                                                                MUNLOCK(ErrorMessageLock);
×
3889
                                                                goto NormMin;
×
3890
                                                        }
3891
                                                        ndot -= 3;
8✔
3892
                                                        *r-- = *--m;
8✔
3893
                                                        *r-- = *--m;
8✔
3894
                                                        *r   = *--m;
8✔
3895
                                                        if ( !*t ) {
8✔
3896
                                                                ndot -= 3;
×
3897
                                                                *t-- = *--m;
×
3898
                                                                *t-- = *--m;
×
3899
                                                                *t   = *--m;
×
3900
                                                                t -= 3;
×
3901
                                                                break;
×
3902
                                                        }
3903
                                                }
3904
                                                else if ( *r < *++t ) {
×
3905
                                                        k = *r; *r++ = *t; *t = k;
×
3906
                                                }
3907
                                                else r++;
×
3908
                                                t -= 2;
8✔
3909
                                        }
3910
                                        else if ( *r < *t ) {
84✔
3911
                                                k = *r; *r++ = *t; *t++ = k;
×
3912
                                                k = *r; *r++ = *t; *t = k;
×
3913
                                                t -= 2;
×
3914
                                        }
3915
                                        else { r += 2; t--; }
84✔
3916
                                }
3917
                                else if ( *r < *t ) {
932✔
3918
                                        k = *r; *r++ = *t; *t++ = k;
28✔
3919
                                        k = *r; *r++ = *t; *t++ = k;
28✔
3920
                                        k = *r; *r++ = *t; *t   = k;
28✔
3921
                                        t -= 2;
28✔
3922
                                }
3923
                                else { r += 3; }
904✔
3924
                        } while ( r < m );
1,024✔
3925
                        t += 3;
608✔
3926
                }
3927
                m = to;
573✔
3928
                t = pdot;
573✔
3929
                if ( ( i = ndot ) > 0 ) {
573✔
3930
                        *m++ = DOTPRODUCT;
573✔
3931
                        *m++ = i + 2;
573✔
3932
                        NCOPY(m,t,i);
4,092✔
3933
                }
3934
        }
3935
/*
3936
          #] Dotproducts : 
3937
          #[ Symbols :
3938
*/
3939
        if ( nsym ) {
32,386,070✔
3940
                nsym <<= 1;
5,317,780✔
3941
                t = psym;
5,317,780✔
3942
                *m++ = SYMBOL;
5,317,780✔
3943
                r = m;
5,317,780✔
3944
                *m++ = ( i = nsym ) + 2;
5,317,780✔
3945
                if ( i ) { do {
5,317,780✔
3946
                        if ( !*t ) {
7,511,830✔
3947
                                if ( t[1] < (2*MAXPOWER) ) {                /* powers of i */
×
3948
                                        if ( t[1] & 1 ) { *m++ = 0; *m++ = 1; }
×
3949
                                        else *r -= 2;
×
3950
                                        if ( *++t & 2 ) ncoef = -ncoef;
×
3951
                                        t++;
×
3952
                                }
3953
                        }
3954
                        else if ( *t <= NumSymbols && *t > -2*MAXPOWER ) {        /* Put powers in range */
7,511,830✔
3955
                                if ( ( ( ( t[1] > symbols[*t].maxpower ) && ( symbols[*t].maxpower < MAXPOWER ) ) ||
7,505,710✔
3956
                                           ( ( t[1] < symbols[*t].minpower ) && ( symbols[*t].minpower > -MAXPOWER ) ) ) &&
7,505,710✔
3957
                                           ( t[1] < 2*MAXPOWER ) && ( t[1] > -2*MAXPOWER ) ) {
16✔
3958
                                        if ( i <= 2 || t[2] != *t ) goto NormZero;
16✔
3959
                                }
3960
                                if ( AN.ncmod == 1 && ( AC.modmode & ALSOPOWERS ) != 0 ) {
7,505,670✔
3961
                                        if ( AC.cmod[0] == 1 ) t[1] = 0;
×
3962
                                        else if ( t[1] >= 0 ) t[1] = 1 + (t[1]-1)%(AC.cmod[0]-1);
×
3963
                                        else {
3964
                                                t[1] = -1 - (-t[1]-1)%(AC.cmod[0]-1);
×
3965
                                                if ( t[1] < 0 ) t[1] += (AC.cmod[0]-1);
×
3966
                                        }
3967
                                }
3968
                                if ( ( t[1] < (2*MAXPOWER) && t[1] >= MAXPOWER )
7,505,670✔
3969
                                || ( t[1] > -(2*MAXPOWER) && t[1] <= -MAXPOWER ) ) {
7,505,670✔
3970
                                        MLOCK(ErrorMessageLock);
×
3971
                                        MesPrint("Exponent out of range: %d",t[1]);
×
3972
                                        MUNLOCK(ErrorMessageLock);
×
3973
                                        goto NormMin;
×
3974
                                }
3975
                                if ( AT.TrimPower && AR.PolyFunVar == *t && t[1] > AR.PolyFunPow ) {
7,505,670✔
3976
                                        goto NormZero;
4✔
3977
                                }
3978
                                else if ( t[1] ) {
7,505,670✔
3979
                                        *m++ = *t++;
7,505,670✔
3980
                                        *m++ = *t++;
7,505,670✔
3981
                                }
3982
                                else { *r -= 2; t += 2; }
×
3983
                        }
3984
                        else {
3985
                                *m++ = *t++; *m++ = *t++;
6,144✔
3986
                        }
3987
                } while ( (i-=2) > 0 ); }
7,511,830✔
3988
                if ( *r <= 2 ) m = r-1;
5,317,770✔
3989
        }
3990
/*
3991
          #] Symbols : 
3992
          #[ float_ :
3993

3994
        Here we treat float_ functions and combined them with the regular
3995
        coefficient.
3996
*/
3997

3998
#ifdef WITHFLOAT
3999
        if ( withfloat ) {
32,386,070✔
4000
                WORD floatsign = 3;
×
4001
/*
4002
                First check whether the coefficient is already 1/1
4003
*/
4004
                if ( ABS(ncoef) == 3 && n_coef[0] == 1 && n_coef[1] == 1 ) {
×
4005
                        if ( withfloat == 1 ) {
×
4006
                                t = firstfloat;
×
4007
/*
4008
                                We only interfere by making the sign positive.
4009
                                The float_ function has already been tested.
4010
*/
4011
                                if ( t[FUNHEAD+3] < 0 ) {
×
4012
                                        t[FUNHEAD+3] = -t[FUNHEAD+3];
×
4013
                                        floatsign = -floatsign;
×
4014
                                }
4015
                                if ( ncoef < 0 ) floatsign = -floatsign;
×
4016
/*
4017
                                Copy to output;
4018
*/
4019
                                AT.FloatPos = m-termout;
×
4020
                                i = t[1]; NCOPY(m,t,i)
×
4021
                        }
4022
                        else {
4023
                                PackFloat(m,aux4);
×
4024
                                if ( m[FUNHEAD+3] < 0 ) {
×
4025
                                        m[FUNHEAD+3] = -m[FUNHEAD+3];
×
4026
                                        floatsign = -floatsign;
×
4027
                                }
4028
                                if ( ncoef < 0 ) floatsign = -floatsign;
×
4029
                                AT.FloatPos = m-termout;
×
4030
                                m += m[1];
×
4031
                        }
4032
                }
4033
                else {
4034
                        if ( withfloat == 1 ) UnpackFloat(aux4,firstfloat);
×
4035
                        RatToFloat(aux5,(UWORD *)n_coef,ncoef);
×
4036
                        mpf_mul(aux4,aux4,aux5);
×
4037
                        PackFloat(m,aux4);
×
4038
                        AT.FloatPos = m-termout;
×
4039
                        if ( m[FUNHEAD+3] < 0 ) {
×
4040
                                m[FUNHEAD+3] = -m[FUNHEAD+3];
×
4041
                                floatsign = -floatsign;
×
4042
                        }
4043
                        m += m[1];
×
4044
                }
4045
                n_coef[0] = 1; n_coef[1] = 1; ncoef = floatsign;
×
4046
        }
4047
        else AT.FloatPos = 0;
32,386,070✔
4048
#endif
4049

4050
/*
4051
          #] float_ : 
4052
          #[ Do Replace_ :
4053
*/
4054
    stop = (WORD *)(((UBYTE *)(termout)) + AM.MaxTer);
32,386,070✔
4055
        i = ABS(ncoef);
32,386,070✔
4056
        if ( ( m + i ) > stop ) {
32,386,070✔
4057
                MLOCK(ErrorMessageLock);
3✔
4058
                MesPrint("Term too complex during normalization");
3✔
4059
                MUNLOCK(ErrorMessageLock);
3✔
4060
                goto NormMin;
3✔
4061
        }
4062
        if ( ReplaceType >= 0 ) {
32,386,050✔
4063
                t = n_coef;
4,547✔
4064
                i--;
4,547✔
4065
                NCOPY(m,t,i);
13,657✔
4066
                *m++ = ncoef;
4,547✔
4067
                t = termout;
4,547✔
4068
                *t = WORDDIF(m,t);
4,547✔
4069
                if ( ReplaceType == 0 ) {
4,547✔
4070
                        AT.WorkPointer = termout+*termout;
2,784✔
4071
                        WildFill(BHEAD term,termout,AN.ReplaceScrat);
2,784✔
4072
                        termout = term + *term;
2,784✔
4073
                }
4074
                else {
4075
                        AT.WorkPointer = r = termout + *termout;
1,763✔
4076
                        WildFill(BHEAD r,termout,AN.ReplaceScrat);
1,763✔
4077
                        i = *r; m = term;
1,763✔
4078
                        NCOPY(m,r,i);
824,146✔
4079
                        termout = m;
1,763✔
4080

4081

4082
                        r = m = term;
1,763✔
4083
                        r += *term; r -= ABS(r[-1]);
1,763✔
4084
                        m++;
1,763✔
4085
                        while ( m < r ) {
4,114✔
4086
                                if ( *m >= FUNCTION && m[1] > FUNHEAD &&
2,351✔
4087
                                functions[*m-FUNCTION].spec != TENSORFUNCTION )
2,320✔
4088
                                        m[2] |= DIRTYFLAG;
2,320✔
4089
                                m += m[1];
2,351✔
4090
                        }
4091
                }
4092
/*
4093
                The next 'reset' cannot be done. We still need the expression
4094
                in the buffer. Note though that this may cause a runaway pointer
4095
                if we are not very careful.
4096

4097
                C->numrhs = oldtoprhs;
4098
                C->Pointer = C->Buffer + oldcpointer;
4099
*/
4100
                TermFree(n_llnum,"n_llnum");
4,547✔
4101
                TermFree(n_coef,"NormCoef");
4,547✔
4102
                return(1);
4,547✔
4103
        }
4104
        else {
4105
                t = termout;
32,381,510✔
4106
                k = WORDDIF(m,t);
32,381,510✔
4107
                *t = k + i;
32,381,510✔
4108
                m = term;
32,381,510✔
4109
                NCOPY(m,t,k);
517,400,000✔
4110
                i--;
32,381,510✔
4111
                t = n_coef;
32,381,510✔
4112
                NCOPY(m,t,i);
99,225,400✔
4113
                *m++ = ncoef;
32,381,510✔
4114
        }
4115
/*
4116
          #] Do Replace_ : 
4117
          #[ Errors and Finish :
4118
*/
4119
RegEnd:
32,381,510✔
4120
        if ( termout < term + *term && termout >= term ) AT.WorkPointer = term + *term;
32,381,510✔
4121
        else AT.WorkPointer = termout;
32,381,270✔
4122
/*
4123
        if ( termflag ) {        We have to assign the term to $variable(s)
4124
                TermAssign(term);
4125
        }
4126
*/
4127
        TermFree(n_llnum,"n_llnum");
32,381,510✔
4128
        TermFree(n_coef,"NormCoef");
32,381,510✔
4129
        return(regval);
32,381,510✔
4130

4131
NormInf:
×
4132
        MLOCK(ErrorMessageLock);
×
4133
        MesPrint("Division by zero during normalization");
×
4134
        MUNLOCK(ErrorMessageLock);
×
NEW
4135
        TERMINATE(-1);
×
4136

4137
NormZZ:
×
4138
        MLOCK(ErrorMessageLock);
×
4139
        MesPrint("0^0 during normalization of term");
×
4140
        MUNLOCK(ErrorMessageLock);
×
NEW
4141
        TERMINATE(-1);
×
4142

4143
NormPRF:
×
4144
        MLOCK(ErrorMessageLock);
×
4145
        MesPrint("0/0 in polyratfun during normalization of term");
×
4146
        MUNLOCK(ErrorMessageLock);
×
NEW
4147
        TERMINATE(-1);
×
4148

4149
NormZero:
5,546✔
4150
        *term = 0;
5,546✔
4151
        AT.WorkPointer = termout;
5,546✔
4152
        TermFree(n_llnum,"n_llnum");
5,546✔
4153
        TermFree(n_coef,"NormCoef");
5,546✔
4154
        return(regval);
5,546✔
4155

4156
NormMin:
6✔
4157
        TermFree(n_llnum,"n_llnum");
6✔
4158
        TermFree(n_coef,"NormCoef");
6✔
4159
        return(-1);
6✔
4160

4161
FromNorm:
×
4162
        MLOCK(ErrorMessageLock);
×
4163
        MesCall("Norm");
×
4164
        MUNLOCK(ErrorMessageLock);
×
4165
        TermFree(n_llnum,"n_llnum");
×
4166
        TermFree(n_coef,"NormCoef");
×
4167
        return(-1);
×
4168

4169
/*
4170
          #] Errors and Finish : 
4171
*/
4172
}
4173

4174
/*
4175
                 #] Normalize : 
4176
                 #[ ExtraSymbol :
4177
*/
4178

4179
WORD ExtraSymbol(WORD sym, WORD pow, WORD nsym, WORD *ppsym, WORD *ncoef)
57✔
4180
{
4181
        WORD *m, i;
57✔
4182
        i = nsym;
57✔
4183
        m = ppsym - 2;
57✔
4184
        while        ( i > 0 ) {
57✔
4185
                if ( sym == *m ) {
35✔
4186
                        m++;
28✔
4187
                        if        ( pow > 2*MAXPOWER || pow < -2*MAXPOWER
28✔
4188
                        ||        *m > 2*MAXPOWER || *m < -2*MAXPOWER ) {
28✔
4189
                                MLOCK(ErrorMessageLock);
×
4190
                                MesPrint("Illegal wildcard power combination.");
×
4191
                                MUNLOCK(ErrorMessageLock);
×
NEW
4192
                                TERMINATE(-1);
×
4193
                        }
4194
                        *m += pow;
28✔
4195

4196
                        if ( ( sym <= NumSymbols && sym > -MAXPOWER )
28✔
4197
                         && ( symbols[sym].complex & VARTYPEROOTOFUNITY ) == VARTYPEROOTOFUNITY ) {
28✔
4198
                                *m %= symbols[sym].maxpower;
×
4199
                                if ( *m < 0 ) *m += symbols[sym].maxpower;
×
4200
                                if ( ( symbols[sym].complex & VARTYPEMINUS ) == VARTYPEMINUS ) {
×
4201
                                        if ( ( ( symbols[sym].maxpower & 1 ) == 0 ) &&
×
4202
                                                ( *m >= symbols[sym].maxpower/2 ) ) {
×
4203
                                                *m -= symbols[sym].maxpower/2; *ncoef = -*ncoef;
×
4204
                                        }
4205
                                }
4206
                        }
4207

4208
                        if        ( *m >= 2*MAXPOWER || *m <= -2*MAXPOWER ) {
28✔
4209
                                MLOCK(ErrorMessageLock);
×
4210
                                MesPrint("Power overflow during normalization");
×
4211
                                MUNLOCK(ErrorMessageLock);
×
4212
                                return(-1);
×
4213
                        }
4214
                        if ( !*m ) {
28✔
4215
                                m--;
4216
                                while ( i < nsym )
21✔
4217
                                        { *m = m[2]; m++; *m = m[2]; m++; i++; }
×
4218
                                return(-1);
4219
                        }
4220
                        return(0);
4221
                }
4222
                else if ( sym < *m ) {
7✔
4223
                        m -= 2;
×
4224
                        i--;
×
4225
                }
4226
                else break;
4227
        }
4228
        m = ppsym;
4229
        while ( i < nsym )
29✔
4230
                { m--; m[2] = *m; m--; m[2] = *m; i++; }
×
4231
        *m++ = sym;
29✔
4232
        *m = pow;
29✔
4233
        return(1);
29✔
4234
}
4235

4236
/*
4237
                 #] ExtraSymbol : 
4238
                 #[ DoTheta :
4239
*/
4240

4241
WORD DoTheta(PHEAD WORD *t)
552✔
4242
{
4243
        GETBIDENTITY
4244
        WORD k, *r1, *r2, *tstop, type;
552✔
4245
        WORD ia, *ta, *tb, *stopa, *stopb;
552✔
4246
        if ( AC.BracketNormalize ) return(-1);
552✔
4247
        type = *t;
552✔
4248
        k = t[1];
552✔
4249
        tstop = t + k;
552✔
4250
        t += FUNHEAD;
552✔
4251
        if ( k <= FUNHEAD ) return(1);
552✔
4252
        r1 = t;
552✔
4253
        NEXTARG(r1)
552✔
4254
        if ( r1 == tstop ) {
552✔
4255
/*
4256
                One argument
4257
*/
4258
                if ( *t == ARGHEAD ) {
552✔
4259
                        if ( type == THETA ) return(1);
×
4260
                        else return(0);  /* THETA2 */
×
4261
                }
4262
                if ( *t < 0 ) {
552✔
4263
                        if ( *t == -SNUMBER ) {
552✔
4264
                                if ( t[1] < 0 ) return(0);
552✔
4265
                                else {
4266
                                        if ( type == THETA2 && t[1] == 0 ) return(0);
372✔
4267
                                        else return(1);
260✔
4268
                                }
4269
                        }
4270
                        return(-1);
4271
                }
4272
                k = t[*t-1];
×
4273
                if ( *t == ABS(k)+1+ARGHEAD ) {
×
4274
                        if ( k > 0 ) return(1);
×
4275
                        else return(0);
×
4276
                }
4277
                return(-1);
4278
        }
4279
/*
4280
        At least two arguments
4281
*/
4282
        r2 = r1;
×
4283
        NEXTARG(r2)
×
4284
        if ( r2 < tstop ) return(-1);        /* More than 2 arguments */
×
4285
/*
4286
        Note now that zero has to be treated specially
4287
        We take the criteria from the symmetrize routine
4288
*/
4289
        if ( *t == -SNUMBER && *r1 == -SNUMBER ) {
×
4290
                if ( t[1] > r1[1] ) return(0);
×
4291
                else if ( t[1] < r1[1] ) {
×
4292
                        return(1);
4293
                }
4294
                else if ( type == THETA ) return(1);
×
4295
                else return(0);   /* THETA2 */
×
4296
        }
4297
        else if ( t[1] == 0 && *t == -SNUMBER ) {
×
4298
                if ( *r1 > 0 ) { }
×
4299
                else if ( *t < *r1 ) return(1);
×
4300
                else if ( *t > *r1 ) return(0);
×
4301
        }
4302
        else if ( r1[1] == 0 && *r1 == -SNUMBER ) {
×
4303
                if ( *t > 0 ) { }
×
4304
                else if ( *t < *r1 ) return(1);
×
4305
                else if ( *t > *r1 ) return(0);
×
4306
        }
4307
        r2 = AT.WorkPointer;
×
4308
        if ( *t < 0 ) {
×
4309
                ta = r2;
×
4310
                ToGeneral(t,ta,0);
×
4311
                r2 += *r2;
×
4312
        }
4313
        else ta = t;
4314
        if ( *r1 < 0 ) {
×
4315
                tb = r2;
×
4316
                ToGeneral(r1,tb,0);
×
4317
        }
4318
        else tb = r1;
4319
        stopa = ta + *ta;
×
4320
        stopb = tb + *tb;
×
4321
        ta += ARGHEAD; tb += ARGHEAD;
×
4322
        while ( ta < stopa ) {
×
4323
                if ( tb >= stopb ) return(0);
×
4324
                if ( ( ia = CompareTerms(BHEAD ta,tb,(WORD)1) ) < 0 ) return(0);
×
4325
                if ( ia > 0 ) return(1);
×
4326
                ta += *ta;
×
4327
                tb += *tb;
×
4328
        }
4329
        if ( type == THETA ) return(1);
×
4330
        else return(0); /* THETA2 */
×
4331
}
4332

4333
/*
4334
                 #] DoTheta : 
4335
                 #[ DoDelta :
4336
*/
4337

4338
WORD DoDelta(WORD *t)
232✔
4339
{
4340
        WORD k, *r1, *r2, *tstop, isnum, isnum2, type = *t;
232✔
4341
        if ( AC.BracketNormalize ) return(-1);
232✔
4342
        k = t[1];
232✔
4343
        if ( k <= FUNHEAD ) goto argzero;
232✔
4344
        if ( k == FUNHEAD+ARGHEAD && t[FUNHEAD] == ARGHEAD ) goto argzero;
232✔
4345
        tstop = t + k;
232✔
4346
        t += FUNHEAD;
232✔
4347
        r1 = t;
232✔
4348
        NEXTARG(r1)
232✔
4349
        if ( *t < 0 ) {
232✔
4350
                k = 1;
232✔
4351
                if ( *t == -SNUMBER ) { isnum = 1; k = t[1]; }
232✔
4352
                else isnum = 0;
4353
        }
4354
        else {
4355
                k = t[*t-1];
×
4356
                k = ABS(k);
×
4357
                if ( k == *t-ARGHEAD-1 ) isnum = 1;
×
4358
                else isnum = 0;
×
4359
                k = 1;
4360
        }
4361
        if ( r1 >= tstop ) {                /* Single argument */
232✔
4362
                if ( !isnum ) return(-1);
232✔
4363
                if ( k == 0 ) goto argzero;
232✔
4364
                goto argnonzero;
164✔
4365
        }
4366
        r2 = r1;
×
4367
        NEXTARG(r2)
×
4368
        if ( r2 < tstop ) return(-1);
×
4369
        if ( *r1 < 0 ) {
×
4370
                if ( *r1 == -SNUMBER ) { isnum2 = 1; }
×
4371
                else isnum2 = 0;
×
4372
        }
4373
        else {
4374
                k = r1[*r1-1];
×
4375
                k = ABS(k);
×
4376
                if ( k == *r1-ARGHEAD-1 ) isnum2 = 1;
×
4377
                else isnum2 = 0;
×
4378
        }
4379
        if ( isnum != isnum2 ) return(-1);
×
4380
        tstop = r1;
×
4381
        while ( t < tstop && r1 < r2 ) {
×
4382
                if ( *t != *r1 ) {
×
4383
                        if ( !isnum ) return(-1);
×
4384
                        goto argnonzero;
×
4385
                }
4386
                t++; r1++;
×
4387
        }
4388
        if ( t != tstop || r1 != r2 ) {
×
4389
                if ( !isnum ) return(-1);
×
4390
                goto argnonzero;
×
4391
        }
4392
argzero:
×
4393
        if ( type == DELTA2 ) return(1);
68✔
4394
        else return(0);
×
4395
argnonzero:
164✔
4396
        if ( type == DELTA2 ) return(0);
164✔
4397
        else return(1);
×
4398
}
4399

4400
/*
4401
                 #] DoDelta : 
4402
                 #[ DoRevert :
4403
*/
4404

4405
void DoRevert(WORD *fun, WORD *tmp)
11,566,070✔
4406
{
4407
        WORD *t, *r, *m, *to, *tt, *mm, i, j;
11,566,070✔
4408
        to = fun + fun[1];
11,566,070✔
4409
        r = fun + FUNHEAD;
11,566,070✔
4410
        while ( r < to ) {
24,782,910✔
4411
                if ( *r <= 0 ) {
13,216,840✔
4412
                        if ( *r == -REVERSEFUNCTION ) {
8,847,330✔
4413
                                m = r; mm = m+1;
×
4414
                                while ( mm < to ) *m++ = *mm++;
×
4415
                                to--;
×
4416
                                (fun[1])--;
×
4417
                                fun[2] |= DIRTYSYMFLAG;
×
4418
                        }
4419
                        else if ( *r <= -FUNCTION ) r++;
8,847,330✔
4420
                        else {
4421
                                if ( *r == -INDEX && r[1] < MINSPEC ) *r = -VECTOR;
8,846,968✔
4422
                                r += 2;
8,846,968✔
4423
                        }
4424
                }
4425
                else {
4426
                        if ( ( *r > ARGHEAD )
4,369,510✔
4427
                        && ( r[ARGHEAD+1] == REVERSEFUNCTION )
4,369,510✔
4428
                        && ( *r == (r[ARGHEAD]+ARGHEAD) )
×
4429
                        && ( r[ARGHEAD] == (r[ARGHEAD+2]+4) )
×
4430
                        && ( *(r+*r-3) == 1 )
×
4431
                        && ( *(r+*r-2) == 1 )
×
4432
                        && ( *(r+*r-1) == 3 ) ) {
×
4433
                                mm = r;
×
4434
                                r += ARGHEAD + 1;
×
4435
                                tt = r + r[1];
×
4436
                                r += FUNHEAD;
×
4437
                                m = tmp;
×
4438
                                t = r;
×
4439
                                j = 0;
×
4440
                                while ( t < tt ) {
×
4441
                                        NEXTARG(t)
×
4442
                                        j++;
×
4443
                                }
4444
                                while ( --j >= 0 ) {
×
4445
                                        i = j;
4446
                                        t = r;
4447
                                        while ( --i >= 0 ) {
×
4448
                                                NEXTARG(t)
×
4449
                                        }
4450
                                        if ( *t > 0 ) {
×
4451
                                                i = *t;
4452
                                                NCOPY(m,t,i);
×
4453
                                        }
4454
                                        else if ( *t <= -FUNCTION ) *m++ = *t++;
×
4455
                                        else { *m++ = *t++; *m++ = *t++; }
×
4456
                                }
4457
                                i = WORDDIF(m,tmp);
×
4458
                                m = tmp;
×
4459
                                t = mm;
×
4460
                                r = t + *t;
×
4461
                                NCOPY(t,m,i);
×
4462
                                m = r;
×
4463
                                r = t;
×
4464
                                i = WORDDIF(to,m);
×
4465
                                NCOPY(t,m,i);
×
4466
                                fun[1] = WORDDIF(t,fun);
×
4467
                                to = t;
×
4468
                                fun[2] |= DIRTYSYMFLAG;
×
4469
                        }
4470
                        else r += *r;
4,369,510✔
4471
                }
4472
        }
4473
}
11,566,070✔
4474

4475
/*
4476
                 #] DoRevert : 
4477
         #] Normalize :
4478
          #[ DetCommu :
4479

4480
        Determines the number of terms in an expression that contain
4481
        noncommuting objects. This can be used to see whether products of
4482
        this expression can be evaluated with binomial coefficients.
4483

4484
        We don't try to be fancy. If a term contains noncommuting objects
4485
        we are not looking whether they can commute with complete other
4486
        terms.
4487

4488
        If the number gets too large we cut it off.
4489
*/
4490

4491
#define MAXNUMBEROFNONCOMTERMS 2
4492

4493
WORD DetCommu(WORD *terms)
11,606✔
4494
{
4495
        WORD *t, *tnext, *tstop;
11,606✔
4496
        WORD num = 0;
11,606✔
4497
        if ( *terms == 0 ) return(0);
11,606✔
4498
        if ( terms[*terms] == 0 ) return(0);
11,588✔
4499
        t = terms;
4500
        while ( *t ) {
48,129✔
4501
                tnext = t + *t;
47,704✔
4502
                tstop = tnext - ABS(tnext[-1]);
47,704✔
4503
                t++;
47,704✔
4504
                while ( t < tstop ) {
95,315✔
4505
                        if ( *t >= FUNCTION ) {
47,611✔
4506
                                if ( functions[*t-FUNCTION].commute ) {
×
4507
                                        num++;
×
4508
                                        if ( num >= MAXNUMBEROFNONCOMTERMS ) return(num);
×
4509
                                        break;
4510
                                }
4511
                        }
4512
                        else if ( *t == SUBEXPRESSION ) {
47,611✔
4513
                                if ( cbuf[t[4]].CanCommu[t[2]] ) {
×
4514
                                        num++;
×
4515
                                        if ( num >= MAXNUMBEROFNONCOMTERMS ) return(num);
×
4516
                                        break;
4517
                                }
4518
                        }
4519
                        else if ( *t == EXPRESSION ) {
47,611✔
4520
                                num++;
×
4521
                                if ( num >= MAXNUMBEROFNONCOMTERMS ) return(num);
×
4522
                                break;
4523
                        }
4524
                        else if ( *t == DOLLAREXPRESSION ) {
47,611✔
4525
/*
4526
                                Technically this is not correct. We have to test first
4527
                                whether this is MODLOCAL (in TFORM) and if so, use the
4528
                                local version. Anyway, this should be rare to never
4529
                                occurring because dollars should be replaced.
4530
*/
4531
                                if ( cbuf[AM.dbufnum].CanCommu[t[2]] ) {
×
4532
                                        num++;
×
4533
                                        if ( num >= MAXNUMBEROFNONCOMTERMS ) return(num);
×
4534
                                        break;
4535
                                }
4536
                        }
4537
                        t += t[1];
47,611✔
4538
                }
4539
                t = tnext;
4540
        }
4541
        return(num);
4542
}
4543

4544
/*
4545
          #] DetCommu : 
4546
          #[ DoesCommu :
4547

4548
        Determines the number of noncommuting objects in a term.
4549
        If the number gets too large we cut it off.
4550
*/
4551

4552
WORD DoesCommu(WORD *term)
1,723✔
4553
{
4554
        WORD *tstop;
1,723✔
4555
        WORD num = 0;
1,723✔
4556
        if ( *term == 0 ) return(0);
1,723✔
4557
        tstop = term + *term;
1,723✔
4558
        tstop = tstop - ABS(tstop[-1]);
1,723✔
4559
        term++;
1,723✔
4560
        while ( term < tstop ) {
3,678✔
4561
                if ( ( *term >= FUNCTION ) && ( functions[*term-FUNCTION].commute ) ) {
1,955✔
4562
                        num++;
×
4563
                        if ( num >= MAXNUMBEROFNONCOMTERMS ) return(num);
×
4564
                }
4565
                term += term[1];
1,955✔
4566
        }
4567
        return(num);
4568
}
4569

4570
/*
4571
          #] DoesCommu : 
4572
          #[ PolyNormPoly :
4573

4574
                Normalizes a polynomial
4575
*/
4576

4577
#ifdef EVALUATEGCD
4578
WORD *PolyNormPoly (PHEAD WORD *Poly) {
4579
        
4580
        GETBIDENTITY;
4581
        WORD *buffer = AT.WorkPointer;
4582
        WORD *p;
4583
        if ( NewSort(BHEAD0) ) { TERMINATE(-1); }
4584
        AR.CompareRoutine = (COMPAREDUMMY)(&CompareSymbols);
4585
        while ( *Poly ) {
4586
                p = Poly + *Poly;
4587
                if ( SymbolNormalize(Poly) < 0 ) return(0);
4588
                if ( StoreTerm(BHEAD Poly) ) {
4589
                        AR.CompareRoutine = (COMPAREDUMMY)(&Compare1);
4590
                        LowerSortLevel();
4591
                        TERMINATE(-1);
4592
                }
4593
                Poly = p;
4594
        }
4595
        if ( EndSort(BHEAD buffer,1) < 0 ) {
4596
                AR.CompareRoutine = (COMPAREDUMMY)(&Compare1);
4597
                TERMINATE(-1);
4598
        }
4599
        p = buffer;
4600
        while ( *p ) p += *p;
4601
        AR.CompareRoutine = (COMPAREDUMMY)(&Compare1);
4602
        AT.WorkPointer = p + 1;
4603
        return(buffer);
4604
}
4605
#endif
4606

4607
/*
4608
          #] PolyNormPoly : 
4609
          #[ EvaluateGcd :
4610

4611
        Try to evaluate the GCDFUNCTION gcd_.
4612
        This function can have a number of arguments which can be numbers
4613
        and/or polynomials. If there are objects that aren't SYMBOLS or numbers
4614
        it cannot work currently.
4615

4616
        To make this work properly we have to intervene in proces.c
4617
     proces.c:                                                if ( Normalize(BHEAD m) ) {
4618
1060 proces.c:                                                        if ( Normalize(BHEAD r) ) {
4619
1126?proces.c:                                                        if ( Normalize(BHEAD term) ) {
4620
     proces.c:                                if ( Normalize(BHEAD AT.WorkPointer) ) goto PasErr;
4621
2308!proces.c:                if ( ( retnorm = Normalize(BHEAD term) ) != 0 ) {
4622
     proces.c:                                        ReNumber(BHEAD term); Normalize(BHEAD term);
4623
     proces.c:                                if ( Normalize(BHEAD v) ) TERMINATE(-1);
4624
     proces.c:                if ( Normalize(BHEAD w) ) { LowerSortLevel(); goto PolyCall; }
4625
     proces.c:                if ( Normalize(BHEAD term) ) goto PolyCall;
4626
*/
4627
#ifdef EVALUATEGCD
4628

4629
WORD *EvaluateGcd(PHEAD WORD *subterm)
4630
{
4631
        GETBIDENTITY
4632
        WORD *oldworkpointer = AT.WorkPointer, *work1, *work2, *work3;
4633
        WORD *t, *tt, *ttt, *t1, *t2, *t3, *t4, *tstop;
4634
        WORD ct, nnum;
4635
        UWORD gcdnum, stor;
4636
        WORD *lnum=n_llnum+1;
4637
        WORD *num1, *num2, *num3, *den1, *den2, *den3;
4638
        WORD sizenum1, sizenum2, sizenum3, sizeden1, sizeden2, sizeden3;
4639
        int i, isnumeric = 0, numarg = 0 /*, sizearg */;
4640
        LONG size;
4641
/*
4642
        Step 1: Look for -SNUMBER or -SYMBOL arguments.
4643
                If encountered, treat everybody with it.
4644
*/
4645
        tt = subterm + subterm[1]; t = subterm + FUNHEAD;
4646

4647
        while ( t < tt ) {
4648
                numarg++;
4649
                if ( *t == -SNUMBER ) {
4650
                        if ( t[1] == 0 ) {
4651
gcdzero:;
4652
                                MLOCK(ErrorMessageLock);
4653
                                MesPrint("Trying to take the GCD involving a zero term.");
4654
                                MUNLOCK(ErrorMessageLock);
4655
                                return(0);
4656
                        }
4657
                        gcdnum = ABS(t[1]);
4658
                        t1 = subterm + FUNHEAD;
4659
                        while ( gcdnum > 1 && t1 < tt ) {
4660
                                if ( *t1 == -SNUMBER ) {
4661
                                        stor = ABS(t1[1]);
4662
                                        if ( stor == 0 ) goto gcdzero;
4663
                                        if ( GcdLong(BHEAD (UWORD *)&stor,1,(UWORD *)&gcdnum,1,
4664
                                                                        (UWORD *)lnum,&nnum) ) goto FromGCD;
4665
                                        gcdnum = lnum[0];
4666
                                        t1 += 2;
4667
                                        continue;
4668
                                }
4669
                                else if ( *t1 == -SYMBOL ) goto gcdisone;
4670
                                else if ( *t1 < 0 ) goto gcdillegal;
4671
/*
4672
                                Now we have to go through all the terms in the argument.
4673
                                This includes long numbers.
4674
*/
4675
                                ttt = t1 + *t1;
4676
                                ct = *ttt; *ttt = 0;
4677
                                if ( t1[1] != 0 ) {        /* First normalize the argument */
4678
                                        t1 = PolyNormPoly(BHEAD t1+ARGHEAD);
4679
                                }
4680
                                else t1 += ARGHEAD;
4681
                                while ( *t1 ) {
4682
                                        t1 += *t1;
4683
                                        i = ABS(t1[-1]);
4684
                                        t2 = t1 - i;
4685
                                        i = (i-1)/2;
4686
                                        t3 = t2+i-1;
4687
                                        while ( t3 > t2 && *t3 == 0 ) { t3--; i--; }
4688
                                        if ( GcdLong(BHEAD (UWORD *)t2,(WORD)i,(UWORD *)&gcdnum,1,
4689
                                                                        (UWORD *)lnum,&nnum) ) {
4690
                                                *ttt = ct;
4691
                                                goto FromGCD;
4692
                                        }
4693
                                        gcdnum = lnum[0];
4694
                                        if ( gcdnum == 1 ) {
4695
                                                *ttt = ct;
4696
                                                goto gcdisone;
4697
                                        }
4698
                                }
4699
                                *ttt = ct;
4700
                                t1 = ttt;
4701
                                AT.WorkPointer = oldworkpointer;
4702
                        }
4703
                        if ( gcdnum == 1 ) goto gcdisone;
4704
                        oldworkpointer[0] = 4;
4705
                        oldworkpointer[1] = gcdnum;
4706
                        oldworkpointer[2] = 1;
4707
                        oldworkpointer[3] = 3;
4708
                        oldworkpointer[4] = 0;
4709
                        AT.WorkPointer = oldworkpointer + 5;
4710
                        return(oldworkpointer);
4711
                }
4712
                else if ( *t == -SYMBOL ) {
4713
                        t1 = subterm + FUNHEAD;
4714
                        i = t[1];
4715
                        while ( t1 < tt ) {
4716
                                if ( *t1 == -SNUMBER ) goto gcdisone;
4717
                                if ( *t1 == -SYMBOL ) {
4718
                                        if ( t1[1] != i ) goto gcdisone;
4719
                                        t1 += 2; continue;
4720
                                }
4721
                                if ( *t1 < 0 ) goto gcdillegal;
4722
                                ttt = t1 + *t1;
4723
                                ct = *ttt; *ttt = 0;
4724
                                if ( t1[1] != 0 ) {        /* First normalize the argument */
4725
                                        t2 = PolyNormPoly(BHEAD t1+ARGHEAD);
4726
                                }
4727
                                else t2 = t1 + ARGHEAD;
4728
                                while ( *t2 ) {
4729
                                        t3 = t2+1;
4730
                                        t2 = t2 + *t2;
4731
                                        tstop = t2 - ABS(t2[-1]);
4732
                                        while ( t3 < tstop ) {
4733
                                                if ( *t3 != SYMBOL ) {
4734
                                                        *ttt = ct;
4735
                                                        goto gcdillegal;
4736
                                                }
4737
                                                t4 = t3 + 2;
4738
                                                t3 += t3[1];
4739
                                                while ( t4 < t3 ) {
4740
                                                        if ( *t4 == i && t4[1] > 0 ) goto nextterminarg;
4741
                                                        t4 += 2;
4742
                                                }
4743
                                        }
4744
                                        *ttt = ct;
4745
                                        goto gcdisone;
4746
nextterminarg:;
4747
                                }
4748
                                *ttt = ct;
4749
                                t1 = ttt;
4750
                                AT.WorkPointer = oldworkpointer;
4751
                        }
4752
                        oldworkpointer[0] = 8;
4753
                        oldworkpointer[1] = SYMBOL;
4754
                        oldworkpointer[2] = 4;
4755
                        oldworkpointer[3] = t[1];
4756
                        oldworkpointer[4] = 1;
4757
                        oldworkpointer[5] = 1;
4758
                        oldworkpointer[6] = 1;
4759
                        oldworkpointer[7] = 3;
4760
                        oldworkpointer[8] = 0;
4761
                        AT.WorkPointer = oldworkpointer+9;
4762
                        return(oldworkpointer);
4763
                }
4764
                else if ( *t < 0 ) {
4765
gcdillegal:;
4766
                        MLOCK(ErrorMessageLock);
4767
                        MesPrint("Illegal object in gcd_ function. Object not a number or a symbol.");
4768
                        MUNLOCK(ErrorMessageLock);
4769
                        goto FromGCD;
4770
                }
4771
                else if ( ABS(t[*t-1]) == *t-ARGHEAD-1 ) isnumeric = numarg;
4772
                else if ( t[1] != 0 ) {
4773
                        ttt = t + *t; ct = *ttt; *ttt = 0;
4774
                        t = PolyNormPoly(BHEAD t+ARGHEAD);
4775
                        *ttt = ct;
4776
                        if ( t[*t] == 0 && ABS(t[*t-1]) == *t-ARGHEAD-1 ) isnumeric = numarg;
4777
                        AT.WorkPointer = oldworkpointer;
4778
                        t = ttt;
4779
                }
4780
                t += *t;
4781
        }
4782
/*
4783
        At this point there are only generic arguments.
4784
        There are however still two cases:
4785
        1: There is an argument that is purely numerical
4786
           In that case we have to take the gcd of all coefficients
4787
        2: All arguments are nontrivial polynomials.
4788
           Here we don't worry so much about the factor. (???)
4789
        We know whether case 1 occurs when isnumeric > 0.
4790
        We can look up numarg to get a good starting value.
4791
*/
4792
        AT.WorkPointer = oldworkpointer;
4793
        if ( isnumeric ) {
4794
                t = subterm + FUNHEAD;
4795
                for ( i = 1; i < isnumeric; i++ ) {
4796
                        NEXTARG(t);
4797
                }
4798
                if ( t[1] != 0 ) {        /* First normalize the argument */
4799
                        ttt = t + *t; ct = *ttt; *ttt = 0;
4800
                        t = PolyNormPoly(BHEAD t+ARGHEAD);
4801
                        *ttt = ct;
4802
                }
4803
                t += *t;
4804
                i = (ABS(t[-1])-1)/2;
4805
                den1 = t - 1 - i;
4806
                num1 = den1 - i;
4807
                sizenum1 = sizeden1 = i;
4808
                while ( sizenum1 > 1 && num1[sizenum1-1] == 0 ) sizenum1--;
4809
                while ( sizeden1 > 1 && den1[sizeden1-1] == 0 ) sizeden1--;
4810
                work1 = AT.WorkPointer+1; work2 = work1+sizenum1;
4811
                for ( i = 0; i < sizenum1; i++ ) work1[i] = num1[i];
4812
                for ( i = 0; i < sizeden1; i++ ) work2[i] = den1[i];
4813
                num1 = work1; den1 = work2;
4814
                AT.WorkPointer = work2 = work2 + sizeden1;
4815
                t = subterm + FUNHEAD;
4816
                while ( t < tt ) {
4817
                        ttt = t + *t; ct = *ttt; *ttt = 0;
4818
                        if ( t[1] != 0 ) {
4819
                                t = PolyNormPoly(BHEAD t+ARGHEAD);
4820
                        }
4821
                        else t += ARGHEAD;
4822
                        while ( *t ) {
4823
                                t += *t;
4824
                                i = (ABS(t[-1])-1)/2;
4825
                                den2 = t - 1 - i;
4826
                                num2 = den2 - i;
4827
                                sizenum2 = sizeden2 = i;
4828
                                while ( sizenum2 > 1 && num2[sizenum2-1] == 0 ) sizenum2--;
4829
                                while ( sizeden2 > 1 && den2[sizeden2-1] == 0 ) sizeden2--;
4830
                                num3 = AT.WorkPointer;
4831
                                if ( GcdLong(BHEAD (UWORD *)num2,sizenum2,(UWORD *)num1,sizenum1,
4832
                                                                        (UWORD *)num3,&sizenum3) ) goto FromGCD;
4833
                                sizenum1 = sizenum3;
4834
                                for ( i = 0; i < sizenum1; i++ ) num1[i] = num3[i];
4835
                                den3 = AT.WorkPointer;
4836
                                if ( GcdLong(BHEAD (UWORD *)den2,sizeden2,(UWORD *)den1,sizeden1,
4837
                                                                        (UWORD *)den3,&sizeden3) ) goto FromGCD;
4838
                                sizeden1 = sizeden3;
4839
                                for ( i = 0; i < sizeden1; i++ ) den1[i] = den3[i];
4840
                                if ( sizenum1 == 1 && num1[0] == 1 && sizeden1 == 1 && den1[1] == 1 )
4841
                                        goto gcdisone;
4842
                        }
4843
                        *ttt = ct;
4844
                        t = ttt;
4845
                        AT.WorkPointer = work2;
4846
                }
4847
                AT.WorkPointer = oldworkpointer;
4848
/*
4849
                Now copy the GCD to the 'output'
4850
*/
4851
                if ( sizenum1 > sizeden1 ) {
4852
                        while ( sizenum1 > sizeden1 ) den1[sizeden1++] = 0;
4853
                }
4854
                else if ( sizenum1 < sizeden1 ) {
4855
                        while ( sizenum1 < sizeden1 ) num1[sizenum1++] = 0;
4856
                }
4857
                t = oldworkpointer;
4858
                i = 2*sizenum1+1;
4859
                *t++ = i+1;
4860
                if ( num1 != t ) { NCOPY(t,num1,sizenum1); }
4861
                else t += sizenum1;
4862
                if ( den1 != t ) { NCOPY(t,den1,sizeden1); }
4863
                else t += sizeden1;
4864
                *t++ = i;
4865
                *t++ = 0;
4866
                AT.WorkPointer = t;
4867
                return(oldworkpointer);
4868
        }
4869
/*
4870
        Now the real stuff with only polynomials.
4871
        Pick up the shortest term to start.
4872
        We are a bit brutish about this.
4873
*/
4874
        t = subterm + FUNHEAD;
4875
        AT.WorkPointer += AM.MaxTer/sizeof(WORD);
4876
        work2 = AT.WorkPointer;
4877
/*
4878
        sizearg = subterm[1];
4879
*/
4880
        i = 0; work3 = 0;
4881
        while ( t < tt ) {
4882
                i++;
4883
                work1 = AT.WorkPointer;
4884
                ttt = t + *t; ct = *ttt; *ttt = 0;
4885
                t = PolyNormPoly(BHEAD t+ARGHEAD);
4886
                if ( *work1 < AT.WorkPointer-work1 ) {
4887
/*
4888
                        sizearg = AT.WorkPointer-work1;
4889
*/
4890
                        numarg = i;
4891
                        work3 = work1;
4892
                }
4893
                *ttt = ct; t = ttt;                
4894
        }
4895
        *AT.WorkPointer++ = 0;
4896
/*
4897
        We have properly normalized arguments and the shortest is indicated in work3
4898
*/
4899
        work1 = work3;
4900
        while ( *work2 ) {
4901
                if ( work2 != work3 ) {
4902
                        work1 = PolyGCD2(BHEAD work1,work2);
4903
                }
4904
                while ( *work2 ) work2 += *work2;
4905
                work2++;
4906
        }
4907
        work2 = work1;
4908
        while ( *work2 ) work2 += *work2;
4909
        size = work2 - work1 + 1;
4910
        t = oldworkpointer;
4911
        NCOPY(t,work1,size);
4912
        AT.WorkPointer = t;
4913
        return(oldworkpointer);
4914

4915
gcdisone:;
4916
        oldworkpointer[0] = 4;
4917
        oldworkpointer[1] = 1;
4918
        oldworkpointer[2] = 1;
4919
        oldworkpointer[3] = 3;
4920
        oldworkpointer[4] = 0;
4921
        AT.WorkPointer = oldworkpointer+5;
4922
        return(oldworkpointer);
4923
FromGCD:
4924
        MLOCK(ErrorMessageLock);
4925
        MesCall("EvaluateGcd");
4926
        MUNLOCK(ErrorMessageLock);
4927
        return(0);
4928
}
4929

4930
#endif
4931

4932
/*
4933
          #] EvaluateGcd : 
4934
          #[ TreatPolyRatFun :
4935

4936
        if ( AR.PolyFunExp == 1 ) we have to trim the contents of the polyratfun
4937
        down to its most divergent term and give it coefficient +1. This is done
4938
        by taking the terms with the least power in the variable in the numerator
4939
        and in the denominator and then combine them.
4940
        Answer is either PolyRatFun(ep^n,1) or PolyRatFun(1,1) or PolyRatFun(1,ep^n)
4941
*/
4942

4943
int TreatPolyRatFun(PHEAD WORD *prf)
×
4944
{
4945
        WORD *t, *tstop, *r, *rstop, *m, *mstop;
×
4946
        WORD exp1 = MAXPOWER, exp2 = MAXPOWER;
×
4947
        t = prf+FUNHEAD;
×
4948
        if ( *t < 0 ) {
×
4949
                if ( *t == -SYMBOL && t[1] == AR.PolyFunVar ) {
×
4950
                        if ( exp1 > 1 ) exp1 = 1;
×
4951
                        t += 2;
×
4952
                }
4953
                else {
4954
                        if ( exp1 > 0 ) exp1 = 0;
×
4955
                        NEXTARG(t)
×
4956
                }
4957
        }
4958
        else {
4959
                tstop = t + *t;
×
4960
                t += ARGHEAD;
×
4961
                while ( t < tstop ) {
×
4962
/*
4963
                        Now look for the minimum power of AR.PolyFunVar
4964
*/
4965
                        r = t+1;
×
4966
                        t += *t;
×
4967
                        rstop = t - ABS(t[-1]);
×
4968
                        while ( r < rstop ) {
×
4969
                                if ( *r != SYMBOL ) { r += r[1]; continue; }
×
4970
                                m = r;
×
4971
                                mstop = m + m[1];
×
4972
                                m += 2;
×
4973
                                while ( m < mstop ) {
×
4974
                                        if ( *m == AR.PolyFunVar ) {
×
4975
                                                if ( m[1] < exp1 ) exp1 = m[1];
×
4976
                                                break;
4977
                                        }
4978
                                        m += 2;
×
4979
                                }
4980
                                if ( m == mstop ) {
×
4981
                                        if ( exp1 > 0 ) exp1 = 0;
×
4982
                                }
4983
                                break;
4984
                        }
4985
                        if ( r == rstop ) {
×
4986
                                if ( exp1 > 0 ) exp1 = 0;
×
4987
                        }
4988
                }
4989
                t = tstop;
4990
        }
4991
        if ( *t < 0 ) {
×
4992
                if ( *t == -SYMBOL && t[1] == AR.PolyFunVar ) {
×
4993
                        if ( exp2 > 1 ) exp2 = 1;
4994
                }
4995
                else {
4996
                        if ( exp2 > 0 ) exp2 = 0;
×
4997
                }
4998
        }
4999
        else {
5000
                tstop = t + *t;
×
5001
                t += ARGHEAD;
×
5002
                while ( t < tstop ) {
×
5003
/*
5004
                        Now look for the minimum power of AR.PolyFunVar
5005
*/
5006
                        r = t+1;
×
5007
                        t += *t;
×
5008
                        rstop = t - ABS(t[-1]);
×
5009
                        while ( r < rstop ) {
×
5010
                                if ( *r != SYMBOL ) { r += r[1]; continue; }
×
5011
                                m = r;
×
5012
                                mstop = m + m[1];
×
5013
                                m += 2;
×
5014
                                while ( m < mstop ) {
×
5015
                                        if ( *m == AR.PolyFunVar ) {
×
5016
                                                if ( m[1] < exp2 ) exp2 = m[1];
×
5017
                                                break;
5018
                                        }
5019
                                        m += 2;
×
5020
                                }
5021
                                if ( m == mstop ) {
×
5022
                                        if ( exp2 > 0 ) exp2 = 0;
×
5023
                                }
5024
                                break;
5025
                        }
5026
                        if ( r == rstop ) {
×
5027
                                if ( exp2 > 0 ) exp2 = 0;
×
5028
                        }
5029
                }
5030
        }
5031
/*
5032
        Now we can compose the output.
5033
        Notice that the output can never be longer than the input provided
5034
        we never can have arguments that consist of just a function.
5035
*/
5036
        exp1 = exp1-exp2;
×
5037
/*        if ( exp1 > 0 ) exp1 = 0; */
5038
        t = prf+FUNHEAD;
×
5039
        if ( exp1 == 0 ) {
×
5040
                *t++ = -SNUMBER; *t++ = 1;
×
5041
                *t++ = -SNUMBER; *t++ = 1;
×
5042
        }
5043
        else if ( exp1 > 0 ) {
×
5044
                if ( exp1 == 1 ) {
×
5045
                        *t++ = -SYMBOL; *t++ = AR.PolyFunVar;
×
5046
                }
5047
                else {
5048
                        *t++ = 8+ARGHEAD;
×
5049
                        *t++ = 0;
×
5050
                        FILLARG(t);
×
5051
                        *t++ = 8; *t++ = SYMBOL; *t++ = 4; *t++ = AR.PolyFunVar;
×
5052
                        *t++ = exp1; *t++ = 1; *t++ = 1; *t++ = 3;
×
5053
                }
5054
                *t++ = -SNUMBER; *t++ = 1;
×
5055
        }
5056
        else {
5057
                *t++ = -SNUMBER; *t++ = 1;
×
5058
                if ( exp1 == -1 ) {
×
5059
                        *t++ = -SYMBOL; *t++ = AR.PolyFunVar;
×
5060
                }
5061
                else {
5062
                        *t++ = 8+ARGHEAD;
×
5063
                        *t++ = 0;
×
5064
                        FILLARG(t);
×
5065
                        *t++ = 8; *t++ = SYMBOL; *t++ = 4; *t++ = AR.PolyFunVar;
×
5066
                        *t++ = -exp1; *t++ = 1; *t++ = 1; *t++ = 3;
×
5067
                }
5068
        }
5069
        prf[2] = 0;  /* Clean */
×
5070
        prf[1] = t - prf;
×
5071
        return(0);
×
5072
}
5073

5074
/*
5075
          #] TreatPolyRatFun : 
5076
          #[ DropCoefficient :
5077
*/
5078

5079
void DropCoefficient(PHEAD WORD *term)
4,608✔
5080
{
5081
        GETBIDENTITY
5082
        WORD *t = term + *term;
4,608✔
5083
        WORD n, na;
4,608✔
5084
        n = t[-1]; na = ABS(n);
4,608✔
5085
        t -= na;
4,608✔
5086
        if ( n == 3 && t[0] == 1 && t[1] == 1 ) return;
4,608✔
5087
        *AN.RepPoint = 1;
4,416✔
5088
        t[0] = 1; t[1] = 1; t[2] = 3;
4,416✔
5089
        *term -= (na-3);
4,416✔
5090
}
5091

5092
/*
5093
          #] DropCoefficient : 
5094
          #[ DropSymbols :
5095
*/
5096

5097
void DropSymbols(PHEAD WORD *term)
×
5098
{
5099
        GETBIDENTITY
5100
        WORD *tend = term + *term, *t1, *t2, *tstop;
×
5101
        tstop = tend - ABS(tend[-1]);
×
5102
        t1 = term+1;
×
5103
        while ( t1 < tstop ) {
×
5104
                if ( *t1 == SYMBOL ) {
×
5105
                        *AN.RepPoint = 1;
×
5106
                        t2 = t1+t1[1];
×
5107
                        while ( t2 < tend ) *t1++ = *t2++;
×
5108
                        *term = t1 - term;
×
5109
                        break;
×
5110
                }
5111
                t1 += t1[1];
×
5112
        }
5113
}
×
5114

5115
/*
5116
          #] DropSymbols : 
5117
          #[ SymbolNormalize :
5118
*/
5119
/**
5120
 *        Routine normalizes terms that contain only symbols.
5121
 *        Regular minimum and maximum properties are ignored.
5122
 *
5123
 *        We check whether there are negative powers in the output.
5124
 *        This is not allowed.
5125
 */
5126

5127
int SymbolNormalize(WORD *term)
368,276✔
5128
{
5129
        GETIDENTITY
184,528✔
5130
        WORD buffer[7*NORMSIZE], *t, *b, *bb, *tt, *m, *tstop;
368,276✔
5131
        int i;
368,276✔
5132
        b = buffer;
368,276✔
5133
        *b++ = SYMBOL; *b++ = 2;
368,276✔
5134
        t = term + *term;
368,276✔
5135
        tstop = t - ABS(t[-1]);
368,276✔
5136
        t = term + 1;
368,276✔
5137
        while ( t < tstop ) {        /* Step 1: collect symbols */
736,844✔
5138
          if ( *t == SYMBOL && t < tstop ) {
368,568✔
5139
                for ( i = 2; i < t[1]; i += 2 ) {
1,524,431✔
5140
                        bb = buffer+2;
5141
                        while ( bb < b ) {
2,138,693✔
5142
                                if ( bb[0] == t[i] ) {        /* add powers */
1,264,819✔
5143
                                        bb[1] += t[i+1];
10,790✔
5144
                                        if ( bb[1] > MAXPOWER || bb[1] < -MAXPOWER ) {
10,790✔
5145
                                                MLOCK(ErrorMessageLock);
×
5146
                                                MesPrint("Power in SymbolNormalize out of range");
×
5147
                                                MUNLOCK(ErrorMessageLock);
×
5148
                                                return(-1);
×
5149
                                        }
5150
                                        if ( bb[1] == 0 ) {
10,790✔
5151
                                                b -= 2;
7,398✔
5152
                                                while ( bb < b ) {
31,326✔
5153
                                                        bb[0] = bb[2]; bb[1] = bb[3]; bb += 2;
23,928✔
5154
                                                }
5155
                                        }
5156
                                        goto Nexti;
10,790✔
5157
                                }
5158
                                else if ( bb[0] > t[i] ) { /* insert it */
1,254,029✔
5159
                                        m = b;
5160
                                        while ( m > bb ) { m[1] = m[-1]; m[0] = m[-2]; m -= 2; }
738,599✔
5161
                                        b += 2;
271,199✔
5162
                                        bb[0] = t[i];
271,199✔
5163
                                        bb[1] = t[i+1];
271,199✔
5164
                                        goto Nexti;
271,199✔
5165
                                }
5166
                                bb += 2;
982,830✔
5167
                        }
5168
                        if ( bb >= b ) { /* add it to the end */
873,874✔
5169
                                *b++ = t[i]; *b++ = t[i+1];
873,874✔
5170
                        }
5171
Nexti:;
1,155,863✔
5172
                }
5173
          }
5174
          else {
5175
                MLOCK(ErrorMessageLock);
×
5176
                MesPrint("Illegal term in SymbolNormalize");
×
5177
                MUNLOCK(ErrorMessageLock);
×
5178
                return(-1);
×
5179
          }
5180
          t += t[1];
368,568✔
5181
        }
5182
        buffer[1] = b - buffer;
368,276✔
5183
/*
5184
        Veto negative powers
5185
*/
5186
        if ( AT.LeaveNegative == 0 ) {
368,276✔
5187
                b = buffer; bb = b + b[1]; b += 3;
368,256✔
5188
                while ( b < bb ) {
1,505,927✔
5189
                        if ( *b < 0 ) {
1,137,671✔
5190
                                MLOCK(ErrorMessageLock);
×
5191
                                MesPrint("Negative power in SymbolNormalize");
×
5192
                                MUNLOCK(ErrorMessageLock);
×
5193
                                return(-1);
×
5194
                        }
5195
                        b += 2;
1,137,671✔
5196
                }
5197
        }
5198
/*
5199
        Now we use the fact that the new term will not be longer than the old one
5200
        Actually it should be shorter when there is more than one subterm!
5201
        Copy back.
5202
*/
5203
        i = buffer[1];
368,276✔
5204
        b = buffer; tt = term + 1;
368,276✔
5205
        if ( i > 2 ) { NCOPY(tt,b,i) }
3,377,610✔
5206
        if ( tt < tstop ) {
368,276✔
5207
                i = term[*term-1];
1,562✔
5208
                if ( i < 0 ) i = -i;
1,562✔
5209
                *term -= (tstop-tt);
1,562✔
5210
                NCOPY(tt,tstop,i)
6,248✔
5211
        }
5212
        return(0);
5213
}
5214

5215
/*
5216
          #] SymbolNormalize : 
5217
          #[ TestFunFlag :
5218

5219
        Tests whether a function still has unsubstituted subexpressions
5220
        This function has its dirtyflag on!
5221
*/
5222

5223
int TestFunFlag(PHEAD WORD *tfun)
204✔
5224
{
5225
        WORD *t, *tstop, *r, *rstop, *m, *mstop;
204✔
5226
        if ( functions[*tfun-FUNCTION].spec <= 0 ) return(0);
204✔
5227
        tstop = tfun + tfun[1];
×
5228
        t = tfun + FUNHEAD;
×
5229
        while ( t < tstop ) {
×
5230
                if ( *t < 0 ) { NEXTARG(t); continue; }
×
5231
                rstop = t + *t;
×
5232
                if ( t[1] == 0 ) { t = rstop; continue; }
×
5233
                r = t + ARGHEAD;
×
5234
                while ( r < rstop ) { /* Here we loop over terms */
×
5235
                        m = r+1; mstop = r+*r; mstop -= ABS(mstop[-1]);
×
5236
                        while ( m < mstop ) {        /* Loop over the subterms */
×
5237
                                if ( *m == SUBEXPRESSION || *m == EXPRESSION || *m == DOLLAREXPRESSION ) return(1);
×
5238
                                if ( ( *m >= FUNCTION ) && ( ( m[2] & DIRTYFLAG ) == DIRTYFLAG )
×
5239
                                        && ( *m != REPLACEMENT ) && TestFunFlag(BHEAD m) ) return(1);
×
5240
                                m += m[1];
×
5241
                        }
5242
                        r += *r;
×
5243
                }
5244
                t += *t;
×
5245
        }
5246
        return(0);
5247
}
5248

5249
/*
5250
          #] TestFunFlag : 
5251
          #[ BracketNormalize :
5252
*/
5253

5254
WORD BracketNormalize(PHEAD WORD *term)
157✔
5255
{
5256
        WORD *stop = term+*term-3, *t, *tt, *tstart, *r;
157✔
5257
        WORD *oldwork = AT.WorkPointer;
157✔
5258
        WORD *termout;
157✔
5259
        WORD i, ii, j;
157✔
5260
        termout = AT.WorkPointer = term+*term;
157✔
5261
/*
5262
        First collect all functions and sort them
5263
*/
5264
        tt = termout+1; t = term+1;
157✔
5265
        while ( t < stop ) {
398✔
5266
                if ( *t >= FUNCTION ) { i = t[1]; NCOPY(tt,t,i); }
544✔
5267
                else t += t[1];
140✔
5268
        }
5269
        if ( tt > termout+1 && tt-termout-1 > termout[2] ) { /* sorting */
157✔
5270
                r = termout+1; ii = tt-r;
42✔
5271
                for ( i = 0; i < ii-FUNHEAD; i += FUNHEAD ) {        /* Bubble sort */
84✔
5272
                        for ( j = i+FUNHEAD; j > 0; j -= FUNHEAD ) {
70✔
5273
                                if ( functions[r[j-FUNHEAD]-FUNCTION].commute
42✔
5274
                                  && functions[r[j]-FUNCTION].commute == 0 ) break;
×
5275
                                if ( r[j-FUNHEAD] > r[j] ) EXCH(r[j-FUNHEAD],r[j])
42✔
5276
                                else break;
5277
                        }
5278
                }
5279
        }
5280

5281
        tstart = tt; t = term + 1; *tt++ = DELTA; *tt++ = 2;
157✔
5282
        while ( t < stop ) {
398✔
5283
                if ( *t == DELTA ) { i = t[1]-2; t += 2; tstart[1] += i; NCOPY(tt,t,i); }
241✔
5284
                else t += t[1];
241✔
5285
        }
5286
        if ( tstart[1] > 2 ) {
157✔
5287
                for ( r = tstart+2; r < tstart+tstart[1]; r += 2 ) {
×
5288
                        if ( r[0] > r[1] ) EXCH(r[0],r[1])
×
5289
                }
5290
        }
5291
        if ( tstart[1] > 4 ) { /* sorting */
157✔
5292
                r = tstart+2; ii = tstart[1]-2;
×
5293
                for ( i = 0; i < ii-2; i += 2 ) {        /* Bubble sort */
×
5294
                        for ( j = i+2; j > 0; j -= 2 ) {
×
5295
                                if ( r[j-2] > r[j] ) {
×
5296
                                        EXCH(r[j-2],r[j])
×
5297
                                        EXCH(r[j-1],r[j+1])
×
5298
                                }
5299
                                else if ( r[j-2] < r[j] ) break;
×
5300
                                else {
5301
                                        if ( r[j-1] > r[j+1] ) EXCH(r[j-1],r[j+1])
×
5302
                                        else break;
5303
                                }
5304
                        }
5305
                }
5306
                tt = tstart+tstart[1];
×
5307
        }
5308
        else if ( tstart[1] == 2 ) { tt = tstart; }
157✔
5309
        else tt = tstart+4;
×
5310

5311
        tstart = tt; t = term + 1; *tt++ = INDEX; *tt++ = 2;
157✔
5312
        while ( t < stop ) {
398✔
5313
                if ( *t == INDEX ) { i = t[1]-2; t += 2; tstart[1] += i; NCOPY(tt,t,i); }
241✔
5314
                else t += t[1];
241✔
5315
        }
5316
        if ( tstart[1] >= 4 ) { /* sorting */
157✔
5317
                r = tstart+2; ii = tstart[1]-2;
×
5318
                for ( i = 0; i < ii-1; i += 1 ) {        /* Bubble sort */
×
5319
                        for ( j = i+1; j > 0; j -= 1 ) {
×
5320
                                if ( r[j-1] > r[j] ) EXCH(r[j-1],r[j])
×
5321
                                else break;
5322
                        }
5323
                }
5324
                tt = tstart+tstart[1];
×
5325
        }
5326
        else if ( tstart[1] == 2 ) { tt = tstart; }
157✔
5327
        else tt = tstart+3;
×
5328

5329
        tstart = tt; t = term + 1; *tt++ = DOTPRODUCT; *tt++ = 2;
157✔
5330
        while ( t < stop ) {
398✔
5331
                if ( *t == DOTPRODUCT ) { i = t[1]-2; t += 2; tstart[1] += i; NCOPY(tt,t,i); }
241✔
5332
                else t += t[1];
241✔
5333
        }
5334
        if ( tstart[1] > 5 ) { /* sorting */
157✔
5335
                r = tstart+2; ii = tstart[1]-2;
×
5336
                for ( i = 0; i < ii; i += 3 ) {
×
5337
                        if ( r[i] > r[i+1] ) EXCH(r[i],r[i+1])
×
5338
                }
5339
                for ( i = 0; i < ii-3; i += 3 ) {        /* Bubble sort */
×
5340
                        for ( j = i+3; j > 0; j -= 3 ) {
×
5341
                                if ( r[j-3] < r[j] ) break;
×
5342
                                if ( r[j-3] > r[j] ) {
×
5343
                                        EXCH(r[j-3],r[j])
×
5344
                                        EXCH(r[j-2],r[j+1])
×
5345
                                }
5346
                                else {
5347
                                        if ( r[j-2] > r[j+1] ) EXCH(r[j-2],r[j+1])
×
5348
                                        else break;
5349
                                }
5350
                        }
5351
                }
5352
                tt = tstart+tstart[1];
×
5353
        }
5354
        else if ( tstart[1] == 2 ) { tt = tstart; }
157✔
5355
        else {
5356
                if ( tstart[2] > tstart[3] ) EXCH(tstart[2],tstart[3])
×
5357
                tt = tstart+5;
×
5358
        }
5359

5360
        tstart = tt; t = term + 1; *tt++ = SYMBOL; *tt++ = 2;
157✔
5361
        while ( t < stop ) {
398✔
5362
                if ( *t == SYMBOL ) { i = t[1]-2; t += 2; tstart[1] += i; NCOPY(tt,t,i); }
507✔
5363
                else t += t[1];
108✔
5364
        }
5365
        if ( tstart[1] > 4 ) { /* sorting */
157✔
5366
                r = tstart+2; ii = tstart[1]-2;
7✔
5367
                for ( i = 0; i < ii-2; i += 2 ) {        /* Bubble sort */
21✔
5368
                        for ( j = i+2; j > 0; j -= 2 ) {
14✔
5369
                                if ( r[j-2] > r[j] ) EXCH(r[j-2],r[j])
14✔
5370
                                else break;
5371
                        }
5372
                }
5373
                tt = tstart+tstart[1];
7✔
5374
        }
5375
        else if ( tstart[1] == 2 ) { tt = tstart; }
150✔
5376
        else tt = tstart+4;
112✔
5377

5378
        tstart = tt; t = term + 1; *tt++ = SETSET; *tt++ = 2;
157✔
5379
        while ( t < stop ) {
398✔
5380
                if ( *t == SETSET ) { i = t[1]-2; t += 2; tstart[1] += i; NCOPY(tt,t,i); }
255✔
5381
                else t += t[1];
234✔
5382
        }
5383
        if ( tstart[1] > 4 ) { /* sorting */
157✔
5384
                r = tstart+2; ii = tstart[1]-2;
×
5385
                for ( i = 0; i < ii-2; i += 2 ) {        /* Bubble sort */
×
5386
                        for ( j = i+2; j > 0; j -= 2 ) {
×
5387
                                if ( r[j-2] > r[j] ) {
×
5388
                                        EXCH(r[j-2],r[j])
×
5389
                                        EXCH(r[j-1],r[j+1])
×
5390
                                }
5391
                                else break;
5392
                        }
5393
                }
5394
                tt = tstart+tstart[1];
×
5395
        }
5396
        else if ( tstart[1] == 2 ) { tt = tstart; }
157✔
5397
        else tt = tstart+4;
7✔
5398
        *tt++ = 1; *tt++ = 1; *tt++ = 3;
157✔
5399
        t = term; i = *termout = tt - termout; tt = termout;
157✔
5400
        NCOPY(t,tt,i);
1,620✔
5401
        AT.WorkPointer = oldwork;
157✔
5402
        return(0);
157✔
5403
}
5404

5405
/*
5406
          #] BracketNormalize : 
5407
*/
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

© 2025 Coveralls, Inc