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

vermaseren / form / 11295040260

11 Oct 2024 03:25PM UTC coverage: 50.096% (+0.1%) from 49.968%
11295040260

Pull #565

github

web-flow
Merge fbdb87bb1 into 4fc8e4047
Pull Request #565: Use par=1 EndSorts in ArgFactorize

34 of 46 new or added lines in 1 file covered. (73.91%)

2 existing lines in 1 file now uncovered.

41483 of 82807 relevant lines covered (50.1%)

888291.87 hits per line

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

55.97
/sources/argument.c
1
/** @file argument.c
2
 * 
3
 *  Contains the routines that deal with the execution phase of the argument
4
 *        and related statements (like term)
5
 */
6

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

34
/*
35
          #[ include : argument.c
36
*/
37

38
#include "form3.h"
39

40
/*
41
          #] include : 
42
          #[ execarg :
43

44
        Executes the subset of statements in an argument environment.
45
        The calling routine should be of the type
46
        if ( C->lhs[level][0] == TYPEARG ) {
47
                if ( execarg(term,level) ) goto GenCall;
48
                level = C->lhs[level][2];
49
                goto SkipCount;
50
        }
51
        Note that there will be cases in which extra space is needed.
52
        In addition the compare with C->numlhs isn't very fine, because we
53
        need to insert a different value (C->lhs[level][2]).
54
*/
55

56
WORD execarg(PHEAD WORD *term, WORD level)
302,453✔
57
{
58
        GETBIDENTITY
59
        WORD *t, *r, *m, *v;
302,453✔
60
        WORD *start, *stop, *rstop, *r1, *r2 = 0, *r3 = 0, *r4, *r5, *r6, *r7, *r8, *r9;
302,453✔
61
        WORD *mm, *mstop, *rnext, *rr, *factor, type, ngcd, nq;
302,453✔
62
        CBUF *C = cbuf+AM.rbufnum, *CC = cbuf+AT.ebufnum;
302,453✔
63
        WORD i, j, k, oldnumlhs = AR.Cnumlhs, count, action = 0, olddefer = AR.DeferFlag;
302,453✔
64
        WORD oldnumrhs = CC->numrhs, size, pow, jj;
302,453✔
65
        LONG oldcpointer = CC->Pointer - CC->Buffer, oldppointer = AT.pWorkPointer, lp;
302,453✔
66
        WORD *oldwork = AT.WorkPointer, *oldwork2, scale, renorm;
302,453✔
67
        WORD kLCM = 0, kGCD = 0, kGCD2, kkLCM = 0, jLCM = 0, jGCD, sign = 1;
302,453✔
68
        int ii, didpolyratfun;
302,453✔
69
        UWORD *EAscrat, *GCDbuffer = 0, *GCDbuffer2 = 0, *LCMbuffer = 0, *LCMb = 0, *LCMc = 0;
302,453✔
70
        AT.WorkPointer += *term;
302,453✔
71
        start = C->lhs[level];
302,453✔
72
        AR.Cnumlhs = start[2];
302,453✔
73
        stop = start + start[1];
302,453✔
74
        type = *start;
302,453✔
75
        scale = start[4];
302,453✔
76
        renorm = start[5];
302,453✔
77
        start += TYPEARGHEADSIZE;
302,453✔
78
/*
79
          #[ Dollars :
80
*/
81
        if ( renorm && start[1] != 0 ) {/* We have to evaluate $ symbols inside () */
302,453✔
82
                t = start+1; factor = oldwork2 = v = AT.WorkPointer;
×
83
                i = *t; t++;
×
84
                *v++ = i+3; i--; NCOPY(v,t,i);
×
85
                *v++ = 1; *v++ = 1; *v++ = 3;
×
86
                AT.WorkPointer = v;
×
87
                start = t; AR.Eside = LHSIDEX;
×
88
                NewSort(BHEAD0);
×
89
                if ( Generator(BHEAD factor,AR.Cnumlhs) ) {
×
90
                        LowerSortLevel();
×
91
                        AT.WorkPointer = oldwork;
×
92
                        return(-1);
×
93
                }
94
                AT.WorkPointer = v;
×
95
                if ( EndSort(BHEAD factor,0) < 0 ) {}
×
96
                if ( *factor && *(factor+*factor) != 0 ) {
×
97
                        MLOCK(ErrorMessageLock);
×
98
                        MesPrint("&$ in () does not evaluate into a single term");
×
99
                        MUNLOCK(ErrorMessageLock);
×
100
                        return(-1);
×
101
                }
102
                AR.Eside = RHSIDE;
×
103
                if ( *factor > 0 ) {
×
104
                        v = factor+*factor;
×
105
                        v -= ABS(v[-1]);
×
106
                        *factor = v-factor;
×
107
                }
108
                AT.WorkPointer = v;
×
109
        }
110
        else {
111
                if ( *start < 0 ) {
302,453✔
112
                        factor = start + 1;
9,360✔
113
                        start += -*start;
9,360✔
114
                }
115
                else factor = 0;
116
        }
117
/*
118
          #] Dollars : 
119
*/
120
        t = term;
302,453✔
121
        r = t + *t;
302,453✔
122
        rstop = r - ABS(r[-1]);
302,453✔
123
        t++;
302,453✔
124
/*
125
          #[ Argument detection : + argument statement
126
*/
127
/*
128
        Allocate Numbers for MakeInteger here, for re-use in case multiple
129
        functions are treated in the same term.
130
*/
131
        if ( type == TYPENORM4 ) {
302,453✔
132
                GCDbuffer = NumberMalloc("execarg");
20,004✔
133
                GCDbuffer2 = NumberMalloc("execarg");
20,004✔
134
                LCMbuffer = NumberMalloc("execarg");
20,004✔
135
                LCMb = NumberMalloc("execarg"); LCMc = NumberMalloc("execarg");
20,004✔
136
        }
137
        didpolyratfun = 0;
302,453✔
138
        while ( t < rstop ) {
1,672,255✔
139
                if ( *t >= FUNCTION && functions[*t-FUNCTION].spec <= 0 ) {
1,369,805✔
140
/*
141
                        We have a function. First count the number of arguments.
142
                        Tensors are excluded.
143
*/
144
                        count = 0;
1,338,928✔
145
                        v = t;
1,338,928✔
146
                        m = t + FUNHEAD;
1,338,928✔
147
                        r = t + t[1];
1,338,928✔
148
                        while ( m < r ) {
2,703,712✔
149
                                count++;
1,364,784✔
150
                                NEXTARG(m)
1,364,784✔
151
                        }
152
                        if ( count <= 0 ) { t += t[1]; continue; }
1,338,928✔
153
/*
154
                        Now we take the arguments one by one and test for a match
155
*/
156
                        for ( i = 1; i <= count; i++ ) {
2,703,709✔
157
                                m = start;
158
                                while ( m < stop ) {
1,686,310✔
159
                                        r = m + m[1];
1,364,784✔
160
                                        j = *r++;
1,364,784✔
161
                                        if ( j > 1 ) {
1,364,784✔
162
                                                while ( --j > 0 ) {
×
163
                                                        if ( *r == i ) goto RightNum;
×
164
                                                        r++;
×
165
                                                }
166
                                                m = r;
×
167
                                                continue;
×
168
                                        }
169
RightNum:
1,364,784✔
170
                                        if ( m[1] == 2 ) {
1,364,784✔
171
#ifdef WITHFLOAT
172
                                                if ( *t != FLOATFUN || AT.aux_ == 0 || TestFloat(t) == 0 )
12,076✔
173
#endif
174
                                                {
175
                                                        m += 2;
12,076✔
176
                                                        m += *m;
12,076✔
177
                                                        goto HaveTodo;
12,076✔
178
                                                }
179
                                        }
180
                                        else {
181
                                                r = m + m[1];
1,352,708✔
182
                                                m += 2;
1,352,708✔
183
                                                while ( m < r ) {
1,674,238✔
184
                                                        if ( *m == CSET ) {
1,352,712✔
185
                                                                r1 = SetElements + Sets[m[1]].first;
12✔
186
                                                                r2 = SetElements + Sets[m[1]].last;
12✔
187
                                                                while ( r1 < r2 ) {
20✔
188
                                                                        if ( *r1++ == *t ) goto HaveTodo;
12✔
189
                                                                }
190
                                                        }
191
                                                        else if ( m[1] == *t ) goto HaveTodo;
1,352,700✔
192
                                                        m += 2;
321,530✔
193
                                                }
194
                                        }
195
                                        m += *m;
321,526✔
196
                                }
197
                                continue;
321,526✔
198
HaveTodo:
1,043,258✔
199
/*
200
                                If we come here we have to do the argument i (first is 1).
201
*/
202
                                sign = 1;
1,043,258✔
203
                                action = 1;
1,043,258✔
204
                                if ( *t == AR.PolyFun ) didpolyratfun = 1;
1,043,258✔
205
                                v[2] |= DIRTYFLAG;
1,043,258✔
206
                                r = t + FUNHEAD;
1,043,258✔
207
                                j = i;
1,043,258✔
208
                                while ( --j > 0 ) { NEXTARG(r) }
1,048,662✔
209
                                if ( ( type == TYPESPLITARG ) || ( type == TYPESPLITFIRSTARG )
1,043,258✔
210
                                 || ( type == TYPESPLITLASTARG ) ) {
1,043,258✔
211
                                        if ( *t > FUNCTION && *r > 0 ) {
×
212
                                                WantAddPointers(2);
×
213
                                                AT.pWorkSpace[AT.pWorkPointer++] = t;
×
214
                                                AT.pWorkSpace[AT.pWorkPointer++] = r;
×
215
                                        }
216
                                        continue;
×
217
                                }
218
                                else if ( type == TYPESPLITARG2 ) {
1,043,258✔
219
                                        if ( *t > FUNCTION && *r > 0 ) {
7,452✔
220
                                                WantAddPointers(2);
3,676✔
221
                                                AT.pWorkSpace[AT.pWorkPointer++] = t;
3,676✔
222
                                                AT.pWorkSpace[AT.pWorkPointer++] = r;
3,676✔
223
                                        }
224
                                        continue;
7,452✔
225
                                }
226
                                else if ( type == TYPEFACTARG || type == TYPEFACTARG2 ) {
1,035,806✔
227
                                        if ( *t > FUNCTION || *t == DENOMINATOR ) {
9,539✔
228
                                                if ( *r > 0 ) {
9,539✔
229
                                                mm = r + ARGHEAD; mstop = r + *r;
5,155✔
230
                                                if ( mm + *mm < mstop ) {
5,155✔
231
                                                        WantAddPointers(2);
5,108✔
232
                                                        AT.pWorkSpace[AT.pWorkPointer++] = t;
5,067✔
233
                                                        AT.pWorkSpace[AT.pWorkPointer++] = r;
5,067✔
234
                                                        continue;
5,067✔
235
                                                }
236
                                                if ( *mm == 1+ABS(mstop[-1]) ) continue;
88✔
237
                                                if ( mstop[-3] != 1 || mstop[-2] != 1
88✔
238
                                                        || mstop[-1] != 3 ) {
56✔
239
                                                        WantAddPointers(2);
36✔
240
                                                        AT.pWorkSpace[AT.pWorkPointer++] = t;
32✔
241
                                                        AT.pWorkSpace[AT.pWorkPointer++] = r;
32✔
242
                                                        continue;
32✔
243
                                                }
244
                                                GETSTOP(mm,mstop); mm++;
56✔
245
                                                if ( mm + mm[1] < mstop ) {
56✔
246
                                                        WantAddPointers(2);
22✔
247
                                                        AT.pWorkSpace[AT.pWorkPointer++] = t;
16✔
248
                                                        AT.pWorkSpace[AT.pWorkPointer++] = r;
16✔
249
                                                        continue;
16✔
250
                                                }
251
                                                if ( *mm == SYMBOL && ( mm[1] > 4 ||
40✔
252
                                                        ( mm[3] != 1 && mm[3] != -1 ) ) ) {
32✔
253
                                                        WantAddPointers(2);
37✔
254
                                                        AT.pWorkSpace[AT.pWorkPointer++] = t;
36✔
255
                                                        AT.pWorkSpace[AT.pWorkPointer++] = r;
36✔
256
                                                        continue;
36✔
257
                                                }
258
                                                else if ( *mm == DOTPRODUCT && ( mm[1] > 5 ||
4✔
259
                                                        ( mm[4] != 1 && mm[4] != -1 ) ) ) {
×
260
                                                        WantAddPointers(2);
8✔
261
                                                        AT.pWorkSpace[AT.pWorkPointer++] = t;
4✔
262
                                                        AT.pWorkSpace[AT.pWorkPointer++] = r;
4✔
263
                                                        continue;
4✔
264
                                                }
265
                                                else if ( ( *mm == DELTA || *mm == VECTOR )
×
266
                                                         && mm[1] > 4 ) {
×
267
                                                        WantAddPointers(2);
×
268
                                                        AT.pWorkSpace[AT.pWorkPointer++] = t;
×
269
                                                        AT.pWorkSpace[AT.pWorkPointer++] = r;
×
270
                                                        continue;
×
271
                                                }
272
                                                }
273
                                                else if ( factor && *factor == 4 && factor[2] == 1 ) {
4,384✔
274
                                                        WantAddPointers(2);
×
275
                                                        AT.pWorkSpace[AT.pWorkPointer++] = t;
×
276
                                                        AT.pWorkSpace[AT.pWorkPointer++] = r;
×
277
                                                        continue;
×
278
                                                }
279
                                                else if ( factor && *factor == 0
4,384✔
280
                                                && ( *r == -SNUMBER && r[1] != 1 ) ) {
×
281
                                                        WantAddPointers(2);
×
282
                                                        AT.pWorkSpace[AT.pWorkPointer++] = t;
×
283
                                                        AT.pWorkSpace[AT.pWorkPointer++] = r;
×
284
                                                        continue;
×
285
                                                }
286
                                                else if ( *r == -MINVECTOR ) {
4,384✔
287
                                                        WantAddPointers(2);
×
288
                                                        AT.pWorkSpace[AT.pWorkPointer++] = t;
×
289
                                                        AT.pWorkSpace[AT.pWorkPointer++] = r;
×
290
                                                        continue;
×
291
                                                }
292
                                        }
293
                                        continue;
4,384✔
294
                                }
295
                                else if ( type == TYPENORM || type == TYPENORM2 || type == TYPENORM3 || type == TYPENORM4 ) {
1,026,267✔
296
                                        if ( *r < 0 ) {
1,000,668✔
297
                                                WORD rone;
152✔
298
                                                if ( *r == -MINVECTOR ) { rone = -1; *r = -INDEX; }
152✔
299
                                                else if ( *r != -SNUMBER || r[1] == 1 || r[1] == 0 ) continue;
152✔
300
                                                else { rone = r[1]; r[1] = 1; }
×
301
/*
302
                                                Now we must multiply the general coefficient by r[1]
303
*/
304
                                                if ( scale && ( factor == 0 || *factor ) ) {
8✔
305
                                                        action = 1;
4✔
306
                                                        v[2] |= DIRTYFLAG;
4✔
307
                                                        if ( rone < 0 ) {
4✔
308
                                                                if ( type == TYPENORM3 ) k = 1;
4✔
309
                                                                else k = -1;
4✔
310
                                                                rone = -rone;
4✔
311
                                                        }
312
                                                        else k = 1;
313
                                                        r1 = term + *term;
4✔
314
                                                        size = r1[-1];
4✔
315
                                                        size = REDLENG(size);
4✔
316
                                                        if ( scale > 0 ) {
4✔
317
                                                                for ( jj = 0; jj < scale; jj++ ) {
8✔
318
                                                                        if ( Mully(BHEAD (UWORD *)rstop,&size,(UWORD *)(&rone),k) )
4✔
319
                                                                                goto execargerr;
×
320
                                                                }
321
                                                        }
322
                                                        else {
323
                                                                for ( jj = 0; jj > scale; jj-- ) {
×
324
                                                                        if ( Divvy(BHEAD (UWORD *)rstop,&size,(UWORD *)(&rone),k) )
×
325
                                                                                goto execargerr;
×
326
                                                                }
327
                                                        }
328
                                                        size = INCLENG(size);
4✔
329
                                                        k = size < 0 ? -size: size;
4✔
330
                                                        rstop[k-1] = size;
4✔
331
                                                        *term = (WORD)(rstop - term) + k;
4✔
332
                                                }
333
                                                continue;
8✔
334
                                        }
335
/*
336
                                        Now we have to find a reference term.
337
                                        If factor is defined and *factor != 0 we have to
338
                                        look for the first term that matches the pattern exactly
339
                                        Otherwise the first term plays this role
340
                                        If its coefficient is not one,
341
                                        we must set up a division of the whole argument by
342
                                        this coefficient, and a multiplication of the term
343
                                        when the type is not equal to TYPENORM2.
344
                                        We first multiply the coefficient of the term.
345
                                        Then we set up the division.
346

347
                                        First find the magic term
348
*/
349
                                        if ( type == TYPENORM4 ) {
1,000,516✔
350
/*
351
                                                For normalizing everything to integers we have to
352
                                                determine for all elements of this argument the LCM of
353
                                                the denominators and the GCD of the numerators.
354
                                                The buffers have been allocated already.
355
*/
356
                                                r4 = r + *r;
1,000,004✔
357
                                                r1 = r + ARGHEAD;
1,000,004✔
358
/*
359
                                                First take the first term to load up the LCM and the GCD
360
*/
361
                                                r2 = r1 + *r1;
1,000,004✔
362
                                                j = r2[-1];
1,000,004✔
363
                                                if ( j < 0 ) sign = -1;
1,000,004✔
364
                                                r3 = r2 - ABS(j);
1,000,004✔
365
                                                k = REDLENG(j);
1,000,004✔
366
                                                if ( k < 0 ) k = -k;
1,000,004✔
367
                                                while ( ( k > 1 ) && ( r3[k-1] == 0 ) ) k--;
1,000,004✔
368
                                                for ( kGCD = 0; kGCD < k; kGCD++ ) GCDbuffer[kGCD] = r3[kGCD];
2,000,008✔
369
                                                k = REDLENG(j);
1,000,004✔
370
                                                if ( k < 0 ) k = -k;
1,000,004✔
371
                                                r3 += k;
1,000,004✔
372
                                                while ( ( k > 1 ) && ( r3[k-1] == 0 ) ) k--;
1,000,004✔
373
                                                for ( kLCM = 0; kLCM < k; kLCM++ ) LCMbuffer[kLCM] = r3[kLCM];
2,000,008✔
374
                                                r1 = r2;
375
/*
376
                                                Now go through the rest of the terms in this argument.
377
*/
378
                                                while ( r1 < r4 ) {
2,000,012✔
379
                                                        r2 = r1 + *r1;
1,000,008✔
380
                                                        j = r2[-1];
1,000,008✔
381
                                                        r3 = r2 - ABS(j);
1,000,008✔
382
                                                        k = REDLENG(j);
1,000,008✔
383
                                                        if ( k < 0 ) k = -k;
1,000,008✔
384
                                                        while ( ( k > 1 ) && ( r3[k-1] == 0 ) ) k--;
1,000,008✔
385
                                                        if ( ( ( GCDbuffer[0] == 1 ) && ( kGCD == 1 ) ) ) {
1,000,008✔
386
/*
387
                                                                GCD is already 1
388
*/
389
                                                        }
390
                                                        else if ( ( ( k != 1 ) || ( r3[0] != 1 ) ) ) {
8✔
391
                                                                if ( GcdLong(BHEAD GCDbuffer,kGCD,(UWORD *)r3,k,GCDbuffer2,&kGCD2) ) {
8✔
392
                                                                        NumberFree(GCDbuffer,"execarg");
×
393
                                                                        NumberFree(GCDbuffer2,"execarg");
×
394
                                                                        NumberFree(LCMbuffer,"execarg");
×
395
                                                                        NumberFree(LCMb,"execarg"); NumberFree(LCMc,"execarg");
×
396
                                                                        goto execargerr;
×
397
                                                                }
398
                                                                kGCD = kGCD2;
8✔
399
                                                                for ( ii = 0; ii < kGCD; ii++ ) GCDbuffer[ii] = GCDbuffer2[ii];
16✔
400
                                                        }
401
                                                        else {
402
                                                                kGCD = 1; GCDbuffer[0] = 1;
×
403
                                                        }
404
                                                        k = REDLENG(j);
1,000,008✔
405
                                                        if ( k < 0 ) k = -k;
1,000,008✔
406
                                                        r3 += k;
1,000,008✔
407
                                                        while ( ( k > 1 ) && ( r3[k-1] == 0 ) ) k--;
1,000,008✔
408
                                                        if ( ( ( LCMbuffer[0] == 1 ) && ( kLCM == 1 ) ) ) {
1,000,008✔
409
                                                                for ( kLCM = 0; kLCM < k; kLCM++ )
400✔
410
                                                                        LCMbuffer[kLCM] = r3[kLCM];
200✔
411
                                                        }
412
                                                        else if ( ( k != 1 ) || ( r3[0] != 1 ) ) {
999,808✔
413
                                                                if ( GcdLong(BHEAD LCMbuffer,kLCM,(UWORD *)r3,k,LCMb,&kkLCM) ) {
8✔
414
                                                                        NumberFree(GCDbuffer,"execarg"); NumberFree(GCDbuffer2,"execarg");
×
415
                                                                        NumberFree(LCMbuffer,"execarg"); NumberFree(LCMb,"execarg"); NumberFree(LCMc,"execarg");
×
416
                                                                        goto execargerr;
×
417
                                                                }
418
                                                                DivLong((UWORD *)r3,k,LCMb,kkLCM,LCMb,&kkLCM,LCMc,&jLCM);
8✔
419
                                                                MulLong(LCMbuffer,kLCM,LCMb,kkLCM,LCMc,&jLCM);
8✔
420
                                                                for ( kLCM = 0; kLCM < jLCM; kLCM++ )
24✔
421
                                                                        LCMbuffer[kLCM] = LCMc[kLCM];
8✔
422
                                                        }
423
                                                        else {} /* LCM doesn't change */
424
                                                        r1 = r2;
425
                                                }
426
/*
427
                                                Now put the factor together: GCD/LCM
428
*/
429
                                                r3 = (WORD *)(GCDbuffer);
1,000,004✔
430
                                                if ( kGCD == kLCM ) {
1,000,004✔
431
                                                        for ( jGCD = 0; jGCD < kGCD; jGCD++ )
2,000,008✔
432
                                                                r3[jGCD+kGCD] = LCMbuffer[jGCD];
1,000,004✔
433
                                                        k = kGCD;
434
                                                }
435
                                                else if ( kGCD > kLCM ) {
×
436
                                                        for ( jGCD = 0; jGCD < kLCM; jGCD++ )
×
437
                                                                r3[jGCD+kGCD] = LCMbuffer[jGCD];
×
438
                                                        for ( jGCD = kLCM; jGCD < kGCD; jGCD++ )
×
439
                                                                r3[jGCD+kGCD] = 0;
×
440
                                                        k = kGCD;
441
                                                }
442
                                                else {
443
                                                        for ( jGCD = kGCD; jGCD < kLCM; jGCD++ )
×
444
                                                                r3[jGCD] = 0;
×
445
                                                        for ( jGCD = 0; jGCD < kLCM; jGCD++ )
×
446
                                                                r3[jGCD+kLCM] = LCMbuffer[jGCD];
×
447
                                                        k = kLCM;
448
                                                }
449

450
                                                j = 2*k+1;
1,000,004✔
451
/*
452
                                                Now we have to correct the overall factor
453
*/
454
                                                if ( scale && ( factor == 0 || *factor > 0 ) )
1,000,004✔
455
                                                        goto ScaledVariety;
1,000,004✔
456
/*
457
                                                The if was added 28-nov-2012 to give MakeInteger also
458
                                                the (0) option.
459
*/
460
                                                if ( scale && ( factor == 0 || *factor ) ) {
×
461
                                                        size = term[*term-1];
×
462
                                                        size = REDLENG(size);
×
463
                                                        if ( MulRat(BHEAD (UWORD *)rstop,size,(UWORD *)r3,k,
×
464
                                                                        (UWORD *)rstop,&size) ) goto execargerr;
×
465
                                                        size = INCLENG(size);
×
466
                                                        k = size < 0 ? -size: size;
×
467
                                                        rstop[k-1] = size*sign;
×
468
                                                        *term = (WORD)(rstop - term) + k;
×
469
                                                }
470
                                        }
471
                                        else {
472
                                                if ( factor && *factor >= 1 ) {
512✔
473
                                                        r4 = r + *r;
×
474
                                                        r1 = r + ARGHEAD;
×
475
                                                        while ( r1 < r4 ) {
×
476
                                                                r2 = r1 + *r1;
×
477
                                                                r3 = r2 - ABS(r2[-1]);
×
478
                                                                j = r3 - r1;
×
479
                                                                r5 = factor;
×
480
                                                                if ( j != *r5 ) { r1 = r2; continue; }
×
481
                                                                r5++; r6 = r1+1;
×
482
                                                                while ( --j > 0 ) {
×
483
                                                                        if ( *r5 != *r6 ) break;
×
484
                                                                        r5++; r6++;
×
485
                                                                }
486
                                                                if ( j > 0 ) { r1 = r2; continue; }
×
487
                                                                break;
488
                                                        }
489
                                                        if ( r1 >= r4 ) continue;
×
490
                                                }
491
                                                else {
492
                                                        r1 = r + ARGHEAD;
512✔
493
                                                        r2 = r1 + *r1;
512✔
494
                                                        r3 = r2 - ABS(r2[-1]);
512✔
495
                                                }
496
                                                if ( *r3 == 1 && r3[1] == 1 ) {
512✔
497
                                                        if ( r2[-1] == 3 ) continue;
488✔
498
                                                        if ( r2[-1] == -3 && type == TYPENORM3 ) continue;
×
499
                                                }
500
                                                action = 1;
24✔
501
                                                v[2] |= DIRTYFLAG;
24✔
502
                                                j = r2[-1];
24✔
503
                                                k = REDLENG(j);
24✔
504
                                                if ( j < 0 ) j = -j;
24✔
505
                                                if ( type == TYPENORM && scale && ( factor == 0 || *factor ) ) {
24✔
506
/*
507
                                                        Now we correct the overall factor
508
*/
509
ScaledVariety:;
24✔
510
                                                        size = term[*term-1];
1,000,028✔
511
                                                        size = REDLENG(size);
1,000,028✔
512
                                                        if ( scale > 0 ) {
1,000,028✔
513
                                                                for ( jj = 0; jj < scale; jj++ ) {
2,000,024✔
514
                                                                        if ( MulRat(BHEAD (UWORD *)rstop,size,(UWORD *)r3,k,
1,000,012✔
515
                                                                                (UWORD *)rstop,&size) ) goto execargerr;
×
516
                                                                }
517
                                                        }
518
                                                        else {
519
                                                                for ( jj = 0; jj > scale; jj-- ) {
32✔
520
                                                                        if ( DivRat(BHEAD (UWORD *)rstop,size,(UWORD *)r3,k,
16✔
521
                                                                                (UWORD *)rstop,&size) ) goto execargerr;
×
522
                                                                }
523
                                                        }
524
                                                        size = INCLENG(size);
1,000,028✔
525
                                                        k = size < 0 ? -size: size;
1,000,028✔
526
                                                        rstop[k-1] = size*sign;
1,000,028✔
527
                                                        *term = (WORD)(rstop - term) + k;
1,000,028✔
528
                                                }
529
                                        }
530
/*
531
                          We generate a statement for adapting all terms in the
532
                                        argument successively
533
*/
534
                                        r4 = AddRHS(AT.ebufnum,1);
1,000,028✔
535
                                        while ( (r4+j+12) > CC->Top ) r4 = DoubleCbuffer(AT.ebufnum,r4,3);
1,000,028✔
536
                                        *r4++ = j+1;
1,000,028✔
537
                                        i = (j-1)/2;  /* was (j-1)*2  ????? 17-oct-2017 */
1,000,028✔
538
                                        for ( k = 0; k < i; k++ ) *r4++ = r3[i+k];
2,000,056✔
539
                                        for ( k = 0; k < i; k++ ) *r4++ = r3[k];
2,000,056✔
540
                                        if ( ( type == TYPENORM3 ) || ( type == TYPENORM4 ) ) *r4++ = j*sign;
1,000,028✔
541
                                        else *r4++ = r3[j-1];
24✔
542
                                        *r4++ = 0;
1,000,028✔
543
                                        CC->rhs[CC->numrhs+1] = r4;
1,000,028✔
544
                                        CC->Pointer = r4;
1,000,028✔
545
                                        AT.mulpat[5] = CC->numrhs;
1,000,028✔
546
                                        AT.mulpat[7] = AT.ebufnum;
1,000,028✔
547
                                }
548
                                else if ( type == TYPEARGTOEXTRASYMBOL ) {
25,599✔
549
                                        WORD n;
6,076✔
550
                                        if ( r[0] < 0 ) {
6,076✔
551
                                                /* The argument is in the fast notation. */
552
                                                WORD tmp[MaX(9,FUNHEAD+5)];
56✔
553
                                                switch ( r[0] ) {
56✔
554
                                                        case -SNUMBER:
20✔
555
                                                                if ( r[1] == 0 ) {
20✔
556
                                                                        tmp[0] = 0;
4✔
557
                                                                }
558
                                                                else {
559
                                                                        tmp[0] = 4;
16✔
560
                                                                        tmp[1] = ABS(r[1]);
16✔
561
                                                                        tmp[2] = 1;
16✔
562
                                                                        tmp[3] = r[1] > 0 ? 3 : -3;
16✔
563
                                                                        tmp[4] = 0;
16✔
564
                                                                }
565
                                                                break;
566
                                                        case -SYMBOL:
20✔
567
                                                                tmp[0] = 8;
20✔
568
                                                                tmp[1] = SYMBOL;
20✔
569
                                                                tmp[2] = 4;
20✔
570
                                                                tmp[3] = r[1];
20✔
571
                                                                tmp[4] = 1;
20✔
572
                                                                tmp[5] = 1;
20✔
573
                                                                tmp[6] = 1;
20✔
574
                                                                tmp[7] = 3;
20✔
575
                                                                tmp[8] = 0;
20✔
576
                                                                break;
20✔
577
                                                        case -INDEX:
12✔
578
                                                        case -VECTOR:
579
                                                        case -MINVECTOR:
580
                                                                tmp[0] = 7;
12✔
581
                                                                tmp[1] = INDEX;
12✔
582
                                                                tmp[2] = 3;
12✔
583
                                                                tmp[3] = r[1];
12✔
584
                                                                tmp[4] = 1;
12✔
585
                                                                tmp[5] = 1;
12✔
586
                                                                tmp[6] = r[0] != -MINVECTOR ? 3 : -3;
12✔
587
                                                                tmp[7] = 0;
12✔
588
                                                                break;
12✔
589
                                                        default:
4✔
590
                                                                if ( r[0] <= -FUNCTION ) {
4✔
591
                                                                        tmp[0] = FUNHEAD+4;
4✔
592
                                                                        tmp[1] = -r[0];
4✔
593
                                                                        tmp[2] = FUNHEAD;
4✔
594
                                                                        ZeroFillRange(tmp,3,1+FUNHEAD);
8✔
595
                                                                        tmp[FUNHEAD+1] = 1;
4✔
596
                                                                        tmp[FUNHEAD+2] = 1;
4✔
597
                                                                        tmp[FUNHEAD+3] = 3;
4✔
598
                                                                        tmp[FUNHEAD+4] = 0;
4✔
599
                                                                        break;
4✔
600
                                                                }
601
                                                                else {
602
                                                                        MLOCK(ErrorMessageLock);
×
603
                                                                        MesPrint("Unknown fast notation found (TYPEARGTOEXTRASYMBOL)");
×
604
                                                                        MUNLOCK(ErrorMessageLock);
×
605
                                                                        return(-1);
×
606
                                                                }
607
                                                }
608
                                                n = FindSubexpression(tmp);
56✔
609
                                        }
610
                                        else {
611
                                                /*
612
                                                 * NOTE: writing to r[r[0]] is legal. As long as we work
613
                                                 * in a part of the term, at least the coefficient of
614
                                                 * the term must follow.
615
                                                 */
616
                                                WORD old_rr0 = r[r[0]];
6,020✔
617
                                                r[r[0]] = 0;  /* zero-terminated */
6,020✔
618
                                                n = FindSubexpression(r+ARGHEAD);
6,020✔
619
                                                r[r[0]] = old_rr0;
6,020✔
620
                                        }
621
                                        /* Put the new argument in the work space. */
622
                                        if ( AT.WorkPointer+2 > AT.WorkTop ) {
6,076✔
623
                                                MLOCK(ErrorMessageLock);
×
624
                                                MesWork();
×
625
                                                MUNLOCK(ErrorMessageLock);
×
626
                                                return(-1);
×
627
                                        }
628
                                        r1 = AT.WorkPointer;
6,076✔
629
                                        if ( scale ) {  /* means "tonumber" */
6,076✔
630
                                                r1[0] = -SNUMBER;
16✔
631
                                                r1[1] = n;
16✔
632
                                        }
633
                                        else {
634
                                                r1[0] = -SYMBOL;
6,060✔
635
                                                r1[1] = MAXVARIABLES-n;
6,060✔
636
                                        }
637
                                        /* We need r2, r3, m and k to shift the data. */
638
                                        r2 = r + (r[0] > 0 ? r[0] : r[0] <= -FUNCTION ? 1 : 2);
6,076✔
639
                                        r3 = r;
6,076✔
640
                                        m = r1+ARGHEAD+2;
6,076✔
641
                                        k = 2;
6,076✔
642
                                        goto do_shift;
6,076✔
643
                                }
644
                                r3 = r;
1,019,551✔
645
                                AR.DeferFlag = 0;
1,019,551✔
646
                                if ( *r > 0 ) {
1,019,551✔
647
                                        NewSort(BHEAD0);
1,005,567✔
648
                                        action = 1;
1,005,567✔
649
                                        r2 = r + *r;
1,005,567✔
650
                                        r += ARGHEAD;
1,005,567✔
651
                                        while ( r < r2 ) {        /* Sum over the terms */
3,023,947✔
652
                                                m = AT.WorkPointer;
2,018,383✔
653
                                                j = *r;
2,018,383✔
654
                                                while ( --j >= 0 ) *m++ = *r++;
14,189,830✔
655
                                                r1 = AT.WorkPointer;
2,018,383✔
656
                                                AT.WorkPointer = m;
2,018,383✔
657
/*
658
                                                What to do with dummy indices?
659
*/
660
                                                if ( type == TYPENORM || type == TYPENORM2 || type == TYPENORM3 || type == TYPENORM4 ) {
2,018,383✔
661
                                                        if ( MultDo(BHEAD r1,AT.mulpat) ) goto execargerr;
2,000,060✔
662
                                                        AT.WorkPointer = r1 + *r1;
2,000,060✔
663
                                                }
664
                                                if ( Generator(BHEAD r1,level) ) goto execargerr;
2,018,383✔
665
                                                AT.WorkPointer = r1;
2,018,380✔
666
                                        }
667
                                }
668
                                else {
669
                                        r2 = r + (( *r <= -FUNCTION ) ? 1:2);
13,984✔
670
                                        r1 = AT.WorkPointer;
13,984✔
671
                                        ToGeneral(r,r1,0);
13,984✔
672
                                        m = r1 + ARGHEAD;
13,984✔
673
                                        AT.WorkPointer = r1 + *r1;
13,984✔
674
                                        NewSort(BHEAD0);
13,984✔
675
                                        action = 1;
13,984✔
676
/*
677
                                        What to do with dummy indices?
678
*/
679
                                        if ( type == TYPENORM || type == TYPENORM2 || type == TYPENORM3 || type == TYPENORM4 ) {
13,984✔
680
                                                if ( MultDo(BHEAD m,AT.mulpat) ) goto execargerr;
×
681
                                                AT.WorkPointer = m + *m;
×
682
                                        }
683
                                        if ( (*m != 0 ) && Generator(BHEAD m,level) ) goto execargerr;
13,984✔
684
                                        AT.WorkPointer = r1;
13,984✔
685
                                }
686
                                if ( EndSort(BHEAD AT.WorkPointer+ARGHEAD,1) < 0 ) goto execargerr;
1,019,548✔
687
                                AR.DeferFlag = olddefer;
1,019,548✔
688
/*
689
                                Now shift the sorted entity over the old argument.
690
*/
691
                                m = AT.WorkPointer+ARGHEAD;
1,019,548✔
692
                                while ( *m ) m += *m;
3,055,256✔
693
                                k = WORDDIF(m,AT.WorkPointer);
1,019,548✔
694
                                *AT.WorkPointer = k;
1,019,548✔
695
                                AT.WorkPointer[1] = 0;
1,019,548✔
696
                                if ( ToFast(AT.WorkPointer,AT.WorkPointer) ) {
1,019,548✔
697
                                        if ( *AT.WorkPointer <= -FUNCTION ) k = 1;
8,460✔
698
                                        else k = 2;
8,460✔
699
                                }
700
do_shift:
1,011,088✔
701
                                if ( *r3 > 0 ) j = k - *r3;
1,025,624✔
702
                                else if ( *r3 <= -FUNCTION ) j = k - 1;
14,040✔
703
                                else j = k - 2;
14,036✔
704

705
                                t[1] += j;
1,025,624✔
706
                                action = 1;
1,025,624✔
707
                                v[2] |= DIRTYFLAG;
1,025,624✔
708
                                if ( j > 0 ) {
1,025,624✔
709
                                        r = m + j;
6,012✔
710
                                        while ( m > AT.WorkPointer ) *--r = *--m;
139,500✔
711
                                        AT.WorkPointer = r;
6,012✔
712
                                        m = term + *term;
6,012✔
713
                                        r = m + j;
6,012✔
714
                                        while ( m > r2 ) *--r = *--m;
54,064✔
715
                                }
716
                                else if ( j < 0 ) {
1,019,612✔
717
                                        r = r2 + j;
7,172✔
718
                                        r1 = term + *term;
7,172✔
719
                                        while ( r2 < r1 ) *r++ = *r2++;
136,840✔
720
                                }
721
                                r = r3;
1,025,624✔
722
                                m = AT.WorkPointer;
1,025,624✔
723
                                NCOPY(r,m,k);
15,306,560✔
724
                                *term += j;
1,025,624✔
725
                                rstop += j;
1,025,624✔
726
                                CC->numrhs = oldnumrhs;
1,025,624✔
727
                                CC->Pointer = CC->Buffer + oldcpointer;
1,025,624✔
728
                        }
729
                }
730
                t += t[1];
1,369,802✔
731
        }
732
/*
733
                If TYPENORM4, we allocated Number buffers before the above while loop. Free them.
734
*/
735
        if ( type == TYPENORM4 ) {
302,450✔
736
                NumberFree(GCDbuffer,"execarg");
20,004✔
737
                NumberFree(GCDbuffer2,"execarg");
20,004✔
738
                NumberFree(LCMbuffer,"execarg");
20,004✔
739
                NumberFree(LCMb,"execarg"); NumberFree(LCMc,"execarg");
20,004✔
740
        }
741
        if ( didpolyratfun ) {
302,450✔
742
                PolyFunDirty(BHEAD term);
4✔
743
                didpolyratfun = 0;
4✔
744
        }
745
/*
746
          #] Argument detection : 
747
          #[ SplitArg : + varieties
748
*/
749
        if ( ( type == TYPESPLITARG || type == TYPESPLITARG2
302,450✔
750
         || type == TYPESPLITFIRSTARG || type == TYPESPLITLASTARG ) && 
302,450✔
751
        AT.pWorkPointer > oldppointer ) {
9,240✔
752
                t = term+1;
3,660✔
753
                r1 = AT.WorkPointer + 1;
3,660✔
754
                lp = oldppointer;
3,660✔
755
                while ( t < rstop ) {
16,420✔
756
                        if ( lp < AT.pWorkPointer && t == AT.pWorkSpace[lp] ) {
12,760✔
757
                                v = t;
3,676✔
758
                                m = t + FUNHEAD;
3,676✔
759
                                r = t + t[1];
3,676✔
760
                                r2 = r1; while ( t < m ) *r1++ = *t++;
14,704✔
761
                                while ( m < r ) {
7,352✔
762
                                        t = m;
3,676✔
763
                                        NEXTARG(m)
3,676✔
764
                                        if ( lp >= AT.pWorkPointer || t != AT.pWorkSpace[lp+1] ) {
3,676✔
765
                                                if ( *t > 0 ) t[1] = 0;
×
766
                                                while ( t < m ) *r1++ = *t++;
×
767
                                                continue;
×
768
                                        }
769
/*
770
                                        Now we have a nontrivial argument that should be done.
771
*/
772
                                        lp += 2;
3,676✔
773
                                        action = 1;
3,676✔
774
                                        v[2] |= DIRTYFLAG;
3,676✔
775
                                        r3 = t + *t;
3,676✔
776
                                        t += ARGHEAD;
3,676✔
777
                                        if ( type == TYPESPLITFIRSTARG ) {
3,676✔
778
                                                r4 = r1; r5 = t; r7 = oldwork;
×
779
                                                *r1++ = *t + ARGHEAD;
×
780
                                                for ( i = 1; i < ARGHEAD; i++ ) *r1++ = 0;
×
781
                                                j = 0;
782
                                                while ( t < r3 ) {
×
783
                                                        i = *t;
×
784
                                                        if ( j == 0 ) {
×
785
                                                                NCOPY(r7,t,i)
×
786
                                                                j++;
×
787
                                                        }
788
                                                        else {
789
                                                                NCOPY(r1,t,i)
×
790
                                                        }
791
                                                }
792
                                                *r4 = r1 - r4;
×
793
                                                if ( j ) {
×
794
                                                        if ( ToFast(r4,r4) ) {
×
795
                                                                r1 = r4;
×
796
                                                                if ( *r1 > -FUNCTION ) r1++;
×
797
                                                                r1++;
×
798
                                                        }
799
                                                        r7 = oldwork;
800
                                                        while ( --j >= 0 ) {
×
801
                                                                r4 = r1; i = *r7;
×
802
                                                                *r1++ = i+ARGHEAD; *r1++ = 0;
×
803
                                                                FILLARG(r1);
×
804
                                                                NCOPY(r1,r7,i)
×
805
                                                                if ( ToFast(r4,r4) ) {
×
806
                                                                        r1 = r4;
×
807
                                                                        if ( *r1 > -FUNCTION ) r1++;
×
808
                                                                        r1++;
×
809
                                                                }
810
                                                        }
811
                                                }
812
                                                t = r3;
813
                                        }
814
                                        else if ( type == TYPESPLITLASTARG ) {
3,676✔
815
                                                r4 = r1; r5 = t; r7 = oldwork;
×
816
                                                *r1++ = *t + ARGHEAD;
×
817
                                                for ( i = 1; i < ARGHEAD; i++ ) *r1++ = 0;
×
818
                                                j = 0;
819
                                                while ( t < r3 ) {
×
820
                                                        i = *t;
×
821
                                                        if ( t+i >= r3 ) {
×
822
                                                                NCOPY(r7,t,i)
×
823
                                                                j++;
×
824
                                                        }
825
                                                        else {
826
                                                                NCOPY(r1,t,i)
×
827
                                                        }
828
                                                }
829
                                                *r4 = r1 - r4;
×
830
                                                if ( j ) {
×
831
                                                        if ( ToFast(r4,r4) ) {
×
832
                                                                r1 = r4;
×
833
                                                                if ( *r1 > -FUNCTION ) r1++;
×
834
                                                                r1++;
×
835
                                                        }
836
                                                        r7 = oldwork;
837
                                                        while ( --j >= 0 ) {
×
838
                                                                r4 = r1; i = *r7;
×
839
                                                                *r1++ = i+ARGHEAD; *r1++ = 0;
×
840
                                                                FILLARG(r1);
×
841
                                                                NCOPY(r1,r7,i)
×
842
                                                                if ( ToFast(r4,r4) ) {
×
843
                                                                        r1 = r4;
×
844
                                                                        if ( *r1 > -FUNCTION ) r1++;
×
845
                                                                        r1++;
×
846
                                                                }
847
                                                        }
848
                                                }
849
                                                t = r3;
850
                                        }
851
                                        else if ( factor == 0 || ( type == TYPESPLITARG2 && *factor == 0 ) ) {
3,676✔
852
                                                while ( t < r3 ) {
×
853
                                                        r4 = r1;
×
854
                                                        *r1++ = *t + ARGHEAD;                                        
×
855
                                                        for ( i = 1; i < ARGHEAD; i++ ) *r1++ = 0;
×
856
                                                        i = *t;
×
857
                                                        while ( --i >= 0 ) *r1++ = *t++;
×
858
                                                        if ( ToFast(r4,r4) ) {
×
859
                                                                r1 = r4;
×
860
                                                                if ( *r1 > -FUNCTION ) r1++;
×
861
                                                                r1++;
×
862
                                                        }
863
                                                }
864
                                        }
865
                                        else if ( type == TYPESPLITARG2 ) {
3,676✔
866
/*
867
                                                Here we better put the pattern matcher at work?
868
                                                Remember: there are no wildcards.
869
*/
870
                                                WORD *oRepFunList = AN.RepFunList;
3,676✔
871
                                                WORD *oWildMask = AT.WildMask, *oWildValue = AN.WildValue;
3,676✔
872
                                                AN.WildValue = AT.locwildvalue; AT.WildMask = AT.locwildvalue+2;
3,676✔
873
                                                AN.NumWild = 0;
3,676✔
874
                                                r4 = r1; r5 = t; r7 = oldwork;
3,676✔
875
                                                *r1++ = *t + ARGHEAD;
3,676✔
876
                                                for ( i = 1; i < ARGHEAD; i++ ) *r1++ = 0;
7,352✔
877
                                                j = 0;
878
                                                while ( t < r3 ) {
18,360✔
879
                                                        AN.UseFindOnly = 0; oldwork2 = AT.WorkPointer;
14,684✔
880
                                                        AN.RepFunList = r1;
14,684✔
881
                                                        AT.WorkPointer = r1+AN.RepFunNum+2;
14,684✔
882
                                                        i = *t;
14,684✔
883
                                                        if ( FindRest(BHEAD t,factor) &&
14,684✔
884
                                                         ( AN.UsedOtherFind || FindOnce(BHEAD t,factor) ) ) {
14,684✔
885
                                                                NCOPY(r7,t,i)
116,024✔
886
                                                                j++;
10,576✔
887
                                                        }
888
                                                        else if ( factor[0] == FUNHEAD+1 && factor[1] >= FUNCTION ) {
4,108✔
889
                                                                WORD *rr1 = t+1, *rr2 = t+i;
×
890
                                                                rr2 -= ABS(rr2[-1]);
×
891
                                                                while ( rr1 < rr2 ) {
×
892
                                                                        if ( *rr1 == factor[1] ) break;
×
893
                                                                        rr1 += rr1[1];
×
894
                                                                }
895
                                                                if ( rr1 < rr2 ) {
×
896
                                                                        NCOPY(r7,t,i)
×
897
                                                                        j++;
×
898
                                                                }
899
                                                                else {
900
                                                                        NCOPY(r1,t,i)
×
901
                                                                }
902
                                                        }
903
                                                        else {
904
                                                                NCOPY(r1,t,i)
36,348✔
905
                                                        }
906
                                                        AT.WorkPointer = oldwork2;
14,684✔
907
                                                }
908
                                                AN.RepFunList = oRepFunList;
3,676✔
909
                                                *r4 = r1 - r4;
3,676✔
910
                                                if ( j ) {
3,676✔
911
                                                        if ( ToFast(r4,r4) ) {
3,616✔
912
                                                                r1 = r4;
3,228✔
913
                                                                if ( *r1 > -FUNCTION ) r1++;
3,228✔
914
                                                                r1++;
3,228✔
915
                                                        }
916
                                                        r7 = oldwork;
917
                                                        while ( --j >= 0 ) {
14,192✔
918
                                                                r4 = r1; i = *r7;
10,576✔
919
                                                                *r1++ = i+ARGHEAD; *r1++ = 0;
10,576✔
920
                                                                FILLARG(r1);
10,576✔
921
                                                                NCOPY(r1,r7,i)
116,024✔
922
                                                                if ( ToFast(r4,r4) ) {
10,576✔
923
                                                                        r1 = r4;
140✔
924
                                                                        if ( *r1 > -FUNCTION ) r1++;
140✔
925
                                                                        r1++;
140✔
926
                                                                }
927
                                                        }
928
                                                }
929
                                                t = r3;
3,676✔
930
                                                AT.WildMask = oWildMask; AN.WildValue = oWildValue;
3,676✔
931
                                        }
932
                                        else {
933
/*
934
                                                This code deals with splitting off a single term
935
*/
936
                                                r4 = r1; r5 = t;
×
937
                                                *r1++ = *t + ARGHEAD;
×
938
                                                for ( i = 1; i < ARGHEAD; i++ ) *r1++ = 0;
×
939
                                                j = 0;
940
                                                while ( t < r3 ) {
×
941
                                                        r6 = t + *t; r6 -= ABS(r6[-1]);
×
942
                                                        if ( (r6 - t) == *factor ) {
×
943
                                                                k = *factor - 1;
×
944
                                                                for ( ; k > 0; k-- ) {
×
945
                                                                        if ( t[k] != factor[k] ) break;
×
946
                                                                }
947
                                                                if ( k <= 0 ) {
×
948
                                                                        j = r3 - t; t += *t; continue;
×
949
                                                                }
950
                                                        }
951
                                                        else if ( (r6 - t) == 1 && *factor == 0 ) {
×
952
                                                                j = r3 - t; t += *t; continue;
×
953
                                                        }
954
                                                        i = *t;
955
                                                        NCOPY(r1,t,i)
×
956
                                                }
957
                                                *r4 = r1 - r4;
×
958
                                                if ( j ) {
×
959
                                                        if ( ToFast(r4,r4) ) {
×
960
                                                                r1 = r4;
×
961
                                                                if ( *r1 > -FUNCTION ) r1++;
×
962
                                                                r1++;
×
963
                                                        }
964
                                                        t = r3 - j;
×
965
                                                        r4 = r1;
×
966
                                                        *r1++ = *t + ARGHEAD;
×
967
                                                        for ( i = 1; i < ARGHEAD; i++ ) *r1++ = 0;
×
968
                                                        i = *t;
×
969
                                                        while ( --i >= 0 ) *r1++ = *t++;
×
970
                                                        if ( ToFast(r4,r4) ) {
×
971
                                                                r1 = r4;
×
972
                                                                if ( *r1 > -FUNCTION ) r1++;
×
973
                                                                r1++;
×
974
                                                        }
975
                                                }
976
                                                t = r3;
977
                                        }
978
                                }
979
                                r2[1] = r1 - r2;
3,676✔
980
                        }
981
                        else {
982
                                r = t + t[1];
9,084✔
983
                                while ( t < r ) *r1++ = *t++;
155,044✔
984
                        }
985
                }
986
                r = term + *term;
3,660✔
987
                while ( t < r ) *r1++ = *t++;
14,640✔
988
                m = AT.WorkPointer;
3,660✔
989
                i = m[0] = r1 - m;
3,660✔
990
                t = term;
3,660✔
991
                while ( --i >= 0 ) *t++ = *m++;
315,096✔
992
                if ( AT.WorkPointer < m ) AT.WorkPointer = m;
3,660✔
993
        }
994
/*
995
          #] SplitArg : 
996
          #[ FACTARG :
997
*/
998
        if ( ( type == TYPEFACTARG || type == TYPEFACTARG2 ) && 
302,450✔
999
        AT.pWorkPointer > oldppointer ) {
9,720✔
1000
                t = term+1;
5,139✔
1001
                r1 = AT.WorkPointer + 1;
5,139✔
1002
                lp = oldppointer;
5,139✔
1003
                while ( t < rstop ) {
20,742✔
1004
                        if ( lp < AT.pWorkPointer && AT.pWorkSpace[lp] == t ) {
15,603✔
1005
                                v = t;
5,155✔
1006
                                m = t + FUNHEAD;
5,155✔
1007
                                r = t + t[1];
5,155✔
1008
                                r2 = r1; while ( t < m ) *r1++ = *t++;
20,620✔
1009
                                while ( m < r ) {
10,310✔
1010
                                        rr = t = m;
5,155✔
1011
                                        NEXTARG(m)
5,155✔
1012
                                        if ( lp >= AT.pWorkPointer || AT.pWorkSpace[lp+1] != t ) {
5,155✔
1013
                                                if ( *t > 0 ) t[1] = 0;
×
1014
                                                while ( t < m ) *r1++ = *t++;
×
1015
                                                continue;
×
1016
                                        }
1017
/*
1018
                                        Now we have a nontrivial argument that should be studied.
1019
                                        Try to find common factors.
1020
*/
1021
                                        lp += 2;
5,155✔
1022
                                        if ( *t < 0 ) {
5,155✔
1023
                                                if ( factor && ( *factor == 0 && *t == -SNUMBER ) ) {
×
1024
                                                        *r1++ = *t++;
×
1025
                                                        if ( *t == 0 ) *r1++ = *t++;
×
1026
                                                        else { *r1++ = 1; t++; }
×
1027
                                                        continue;
×
1028
                                                }
1029
                                                else if ( factor && *factor == 4 && factor[2] == 1 ) {
×
1030
                                                        if ( *t == -SNUMBER ) {
×
1031
                                                                if ( factor[3] < 0 || t[1] >= 0 ) {
×
1032
                                                                        while ( t < m ) *r1++ = *t++;
×
1033
                                                                }
1034
                                                                else {
1035
                                                                        *r1++ = -SNUMBER; *r1++ = -1;
×
1036
                                                                        *r1++ = *t++; *r1++ = -*t++;
×
1037
                                                                }
1038
                                                        }
1039
                                                        else {
1040
                                                                while ( t < m ) *r1++ = *t++;
×
1041
                                                                *r1++ = -SNUMBER; *r1++ = 1;
×
1042
                                                        }
1043
                                                        continue;
×
1044
                                                }
1045
                                                else if ( *t == -MINVECTOR ) {
×
1046
                                                        *r1++ = -VECTOR; t++; *r1++ = *t++;
×
1047
                                                        *r1++ = -SNUMBER; *r1++ = -1;
×
1048
                                                        *r1++ = -SNUMBER; *r1++ = 1;
×
1049
                                                        continue;
×
1050
                                                }
1051
                                        }
1052
/*
1053
                                        Now we have a nontrivial argument
1054
*/
1055
                                        r3 = t + *t;
5,155✔
1056
                                        t += ARGHEAD;  r5 = t; /* Store starting point */
5,155✔
1057
                                        /* We have terms from r5 to r3 */
1058
                                        if ( r5+*r5 == r3 && factor ) { /* One term only */
5,155✔
1059
                                                if ( *factor == 0 ) {
24✔
1060
                                                        GETSTOP(t,r6);
8✔
1061
                                                        r9 = r1; *r1++ = 0; *r1++ = 1;
8✔
1062
                                                        FILLARG(r1);
8✔
1063
                                                        *r1++ = (r6-t)+3; t++;
8✔
1064
                                                        while ( t < r6 ) *r1++ = *t++;
56✔
1065
                                                        *r1++ = 1; *r1++ = 1; *r1++ = 3;
8✔
1066
                                                        *r9 = r1-r9;
8✔
1067
                                                        if ( ToFast(r9,r9) ) {
8✔
1068
                                                                if ( *r9 <= -FUNCTION ) r1 = r9+1;
×
1069
                                                                else r1 = r9+2;
×
1070
                                                        }
1071
                                                        t = r3; continue;
8✔
1072
                                                }
1073
                                                if ( factor[0] == 4 && factor[2] == 1 ) {
16✔
1074
                                                        GETSTOP(t,r6);
16✔
1075
                                                        r7 = r1; *r1++ = (r6-t)+3+ARGHEAD; *r1++ = 0;
16✔
1076
                                                        FILLARG(r1);
16✔
1077
                                                        *r1++ = (r6-t)+3; t++;
16✔
1078
                                                        while ( t < r6 ) *r1++ = *t++;
112✔
1079
                                                        *r1++ = 1; *r1++ = 1; *r1++ = 3;
16✔
1080
                                                        if ( ToFast(r7,r7) ) {
16✔
1081
                                                                if ( *r7 <= -FUNCTION ) r1 = r7+1;
×
1082
                                                                else r1 = r7+2;
×
1083
                                                        }
1084
                                                        if ( r3[-1] < 0 && factor[3] > 0 ) {
16✔
1085
                                                                *r1++ = -SNUMBER; *r1++ = -1;
4✔
1086
                                                                if ( r3[-1] == -3 && r3[-2] == 1
4✔
1087
                                                                && ( r3[-3] & MAXPOSITIVE ) == r3[-3] ) {
4✔
1088
                                                                        *r1++ = -SNUMBER; *r1++ = r3[-3];
4✔
1089
                                                                }
1090
                                                                else {
1091
                                                                        *r1++ = (r3-r6)+1+ARGHEAD;
×
1092
                                                                        *r1++ = 0;
×
1093
                                                                        FILLARG(r1);
×
1094
                                                                        *r1++ = (r3-r6+1);
×
1095
                                                                        while ( t < r3 ) *r1++ = *t++;
×
1096
                                                                        r1[-1] = -r1[-1];
×
1097
                                                                }
1098
                                                        }
1099
                                                        else {
1100
                                                                if ( ( r3[-1] == -3 || r3[-1] == 3 )
12✔
1101
                                                                && r3[-2] == 1
12✔
1102
                                                                && ( r3[-3] & MAXPOSITIVE ) == r3[-3] ) {
12✔
1103
                                                                        *r1++ = -SNUMBER; *r1++ = r3[-3];
12✔
1104
                                                                        if ( r3[-1] < 0 ) r1[-1] = - r1[-1];
12✔
1105
                                                                }
1106
                                                                else {
1107
                                                                        *r1++ = (r3-r6)+1+ARGHEAD;
×
1108
                                                                        *r1++ = 0;
×
1109
                                                                        FILLARG(r1);
×
1110
                                                                        *r1++ = (r3-r6+1);
×
1111
                                                                        while ( t < r3 ) *r1++ = *t++;
×
1112
                                                                }
1113
                                                        }
1114
                                                        t = r3; continue;
16✔
1115
                                                }
1116
                                        }
1117
/*
1118
                                        Now we take the first term and look for its pieces
1119
                                        inside the other terms.
1120

1121
                                        It is at this point that a more general factorization
1122
                                        routine could take over (allowing for writing the output
1123
                                        properly of course).
1124
*/
1125
                                        if ( AC.OldFactArgFlag == NEWFACTARG ) {
5,131✔
1126
                                        if ( factor == 0 ) {
5,099✔
1127
                                                WORD *oldworkpointer2 = AT.WorkPointer;
5,083✔
1128
                                                AT.WorkPointer = r1 + AM.MaxTer+FUNHEAD;
5,083✔
1129
                                                if ( ArgFactorize(BHEAD t-ARGHEAD,r1) < 0 ) {
5,083✔
1130
                                                        MesCall("ExecArg");
×
1131
                                                        return(-1);
×
1132
                                                }
1133
                                                AT.WorkPointer = oldworkpointer2;
5,083✔
1134
                                                t = r3;
5,083✔
1135
                                                while ( *r1 ) { NEXTARG(r1) }
11,049✔
1136
                                        }
1137
                                        else {
1138
                                                rnext = t + *t;
16✔
1139
                                                GETSTOP(t,r6);
16✔
1140
                                                t++;
24✔
1141
                                                t = r5; pow = 1;
24✔
1142
                                                while ( t < r3 ) {
24✔
1143
                                                        t += *t; if ( t[-1] > 0 ) { pow = 0; break; }
20✔
1144
                                                }
1145
/*
1146
                                                We have to add here the code for computing the GCD
1147
                                                and to divide it out.
1148

1149
                        #[ Numerical factor :
1150
*/
1151
                                                t = r5;
16✔
1152
                                                EAscrat = (UWORD *)(TermMalloc("execarg"));
16✔
1153
                                                if ( t + *t == r3 ) {
16✔
1154
                                                        if ( factor == 0 || *factor > 2 ) {
×
1155
                                                          if ( pow > 0 ) {
×
1156
                                                                *r1++ = -SNUMBER; *r1++ = -1;
×
1157
                                                                t = r5;
×
1158
                                                                while ( t < r3 ) {
×
1159
                                                                        t += *t; t[-1] = -t[-1];
×
1160
                                                                }
1161
                                                          }
1162
                                                          t = rr; *r1++ = *t++; *r1++ = 1; t++;
×
1163
                                                          COPYARG(r1,t);
×
1164
                                                          while ( t < m ) *r1++ = *t++;
×
1165
                                                        }
1166
                                                }
1167
                                                else {
1168
                                                GETSTOP(t,r6);
16✔
1169
                                                ngcd = t[t[0]-1];
16✔
1170
                                                i = abs(ngcd)-1;
16✔
1171
                                                while ( --i >= 0 ) EAscrat[i] = r6[i];
48✔
1172
                                                t += *t;
16✔
1173
                                                while ( t < r3 ) {
16✔
1174
                                                        GETSTOP(t,r6);
16✔
1175
                                                        i = t[t[0]-1];
16✔
1176
                                                        if ( AccumGCD(BHEAD EAscrat,&ngcd,(UWORD *)r6,i) ) goto execargerr;
16✔
1177
                                                        if ( ngcd == 3 && EAscrat[0] == 1 && EAscrat[1] == 1 ) break;
16✔
1178
                                                        t += *t;
×
1179
                                                }
1180
/*
1181
                                                 if ( ngcd != 3 || EAscrat[0] != 1 || EAscrat[1] != 1 )
1182
*/
1183
                                                {
1184
                                                        if ( pow ) ngcd = -ngcd;
16✔
1185
                                                        t = r5; r9 = r1; *r1++ = t[-ARGHEAD]; *r1++ = 1;
16✔
1186
                                                        FILLARG(r1); ngcd = REDLENG(ngcd);
16✔
1187
                                                        while ( t < r3 ) {
52✔
1188
                                                                GETSTOP(t,r6);
36✔
1189
                                                                r7 = t; r8 = r1;
36✔
1190
                                                                while ( r7 < r6) *r1++ = *r7++;
192✔
1191
                                                                t += *t;
36✔
1192
                                                                i = REDLENG(t[-1]);
36✔
1193
                                                                if ( DivRat(BHEAD (UWORD *)r6,i,EAscrat,ngcd,(UWORD *)r1,&nq) ) goto execargerr;
36✔
1194
                                                                nq = INCLENG(nq);
36✔
1195
                                                                i = ABS(nq)-1;
36✔
1196
                                                                r1 += i; *r1++ = nq; *r8 = r1-r8;
36✔
1197
                                                        }
1198
                                                        *r9 = r1-r9;
16✔
1199
                                                        ngcd = INCLENG(ngcd);
16✔
1200
                                                        i = ABS(ngcd)-1;
16✔
1201
                                                        if ( factor && *factor == 0 ) {}
16✔
1202
                                                        else if ( ( factor && factor[0] == 4 && factor[2] == 1
×
1203
                                                        && factor[3] == -3 ) || pow == 0 ) {
×
1204
                                                                r9 = r1; *r1++ = ARGHEAD+2+i; *r1++ = 0;
×
1205
                                                                FILLARG(r1); *r1++ = i+2;
×
1206
                                                                for ( j = 0; j < i; j++ ) *r1++ = EAscrat[j];
×
1207
                                                                *r1++ = ngcd;
×
1208
                                                                if ( ToFast(r9,r9) ) r1 = r9+2;
×
1209
                                                        }
1210
                                                        else if ( factor && factor[0] == 4 && factor[2] == 1
×
1211
                                                        && factor[3] > 0 && pow ) {
×
1212
                                                                if ( ngcd < 0 ) ngcd = -ngcd;
×
1213
                                                                *r1++ = -SNUMBER; *r1++ = -1;
×
1214
                                                                r9 = r1; *r1++ = ARGHEAD+2+i; *r1++ = 0;
×
1215
                                                                FILLARG(r1); *r1++ = i+2;
×
1216
                                                                for ( j = 0; j < i; j++ ) *r1++ = EAscrat[j];
×
1217
                                                                *r1++ = ngcd;
×
1218
                                                                if ( ToFast(r9,r9) ) r1 = r9+2;
×
1219
                                                        }
1220
                                                        else {
1221
                                                                if ( ngcd < 0 ) ngcd = -ngcd;
×
1222
                                                                if ( pow ) { *r1++ = -SNUMBER; *r1++ = -1; }
×
1223
                                                                if ( ngcd != 3 || EAscrat[0] != 1 || EAscrat[1] != 1 ) {
×
1224
                                                                        r9 = r1; *r1++ = ARGHEAD+2+i; *r1++ = 0;
×
1225
                                                                        FILLARG(r1); *r1++ = i+2;
×
1226
                                                                        for ( j = 0; j < i; j++ ) *r1++ = EAscrat[j];
×
1227
                                                                        *r1++ = ngcd;
×
1228
                                                                        if ( ToFast(r9,r9) ) r1 = r9+2;
×
1229
                                                                }
1230
                                                        }
1231
                                                 }
1232
/*
1233
                        #] Numerical factor : 
1234
                                                else {
1235
onetermnew:;
1236

1237
                                                        if ( factor == 0 || *factor > 2 ) {
1238
                                                          if ( pow > 0 ) {
1239
                                                                *r1++ = -SNUMBER; *r1++ = -1;
1240
                                                                t = r5;
1241
                                                                while ( t < r3 ) {
1242
                                                                        t += *t; t[-1] = -t[-1];
1243
                                                                }
1244
                                                          }
1245
                                                          t = rr; *r1++ = *t++; *r1++ = 1; t++;
1246
                                                          COPYARG(r1,t);
1247
                                                          while ( t < m ) *r1++ = *t++;
1248
                                                        }
1249
                                                }
1250
onetermnew:;
1251
*/
1252
                                                }
1253
                                                TermFree(EAscrat,"execarg");
16✔
1254
                                        }
1255
                                        }
1256
                                        else {        /* AC.OldFactArgFlag is ON */
1257
                                        {
1258
                                        WORD *mnext, ncom;
32✔
1259
                                        rnext = t + *t;
32✔
1260
                                        GETSTOP(t,r6);
32✔
1261
                                        t++;
32✔
1262
                                        if ( factor == 0 ) {
32✔
1263
                                          while ( t < r6 ) {
80✔
1264
/*
1265
                        #[ SYMBOL :
1266
*/
1267
                                                if ( *t == SYMBOL ) {
48✔
1268
                                                        r7 = t; r8 = t + t[1]; t += 2;
28✔
1269
                                                        while ( t < r8 ) {
68✔
1270
                                                                pow = t[1];
40✔
1271
                                                                mm = rnext;
40✔
1272
                                                                while ( mm < r3 ) {
40✔
1273
                                                                        mnext = mm + *mm;
×
1274
                                                                        GETSTOP(mm,mstop); mm++;
×
1275
                                                                        while ( mm < mstop ) {
×
1276
                                                                                if ( *mm != SYMBOL ) mm += mm[1];
×
1277
                                                                                else break;
1278
                                                                        }
1279
                                                                        if ( *mm == SYMBOL ) {
×
1280
                                                                                mstop = mm + mm[1]; mm += 2;
×
1281
                                                                                while ( *mm != *t && mm < mstop ) mm += 2;
×
1282
                                                                                if ( mm >= mstop ) pow = 0;
×
1283
                                                                                else if ( pow > 0 && mm[1] > 0 ) {
×
1284
                                                                                        if ( mm[1] < pow ) pow = mm[1];
×
1285
                                                                                }
1286
                                                                                else if ( pow < 0 && mm[1] < 0 ) {
×
1287
                                                                                        if ( mm[1] > pow ) pow = mm[1];
×
1288
                                                                                }
1289
                                                                                else pow = 0;
1290
                                                                        }
1291
                                                                        else pow = 0;
1292
                                                                        if ( pow == 0 ) break;
×
1293
                                                                        mm = mnext;
1294
                                                                }
1295
                                                                if ( pow == 0 ) { t += 2; continue; }
40✔
1296
/*
1297
                                                                We have a factor
1298
*/
1299
                                                                action = 1; i = pow;
40✔
1300
                                                                if ( i > 0 ) {
40✔
1301
                                                                        while ( --i >= 0 ) {
80✔
1302
                                                                                *r1++ = -SYMBOL;
40✔
1303
                                                                                *r1++ = *t;
40✔
1304
                                                                        }
1305
                                                                }
1306
                                                                else {
1307
                                                                        while ( i++ < 0 ) {
×
1308
                                                                                *r1++ = 8 + ARGHEAD;
×
1309
                                                                                for ( j = 1; j < ARGHEAD; j++ ) *r1++ = 0;
×
1310
                                                                                *r1++ = 8; *r1++ = SYMBOL;
×
1311
                                                                                *r1++ = 4; *r1++ = *t; *r1++ = -1;
×
1312
                                                                                *r1++ = 1; *r1++ = 1; *r1++ = 3;
×
1313
                                                                        }
1314
                                                                }
1315
/*
1316
                                                                Now we have to remove the symbols
1317
*/
1318
                                                                t[1] -= pow;
40✔
1319
                                                                mm = rnext;
40✔
1320
                                                                while ( mm < r3 ) {
40✔
1321
                                                                        mnext = mm + *mm;
×
1322
                                                                        GETSTOP(mm,mstop); mm++;
×
1323
                                                                        while ( mm < mstop ) {
×
1324
                                                                                if ( *mm != SYMBOL ) mm += mm[1];
×
1325
                                                                                else break;
1326
                                                                        }
1327
                                                                        mstop = mm + mm[1]; mm += 2;
×
1328
                                                                        while ( mm < mstop && *mm != *t ) mm += 2;
×
1329
                                                                        mm[1] -= pow;
×
1330
                                                                        mm = mnext;
×
1331
                                                                }
1332
                                                                t += 2;
40✔
1333
                                                        }
1334
                                                }
1335
/*
1336
                        #] SYMBOL : 
1337
                        #[ DOTPRODUCT :
1338
*/
1339
                                                else if ( *t == DOTPRODUCT ) {
20✔
1340
                                                        r7 = t; r8 = t + t[1]; t += 2;
4✔
1341
                                                        while ( t < r8 ) {
12✔
1342
                                                                pow = t[2];
8✔
1343
                                                                mm = rnext;
8✔
1344
                                                                while ( mm < r3 ) {
8✔
1345
                                                                        mnext = mm + *mm;
×
1346
                                                                        GETSTOP(mm,mstop); mm++;
×
1347
                                                                        while ( mm < mstop ) {
×
1348
                                                                                if ( *mm != DOTPRODUCT ) mm += mm[1];
×
1349
                                                                                else break;
1350
                                                                        }
1351
                                                                        if ( *mm == DOTPRODUCT ) {
×
1352
                                                                                mstop = mm + mm[1]; mm += 2;
×
1353
                                                                                while ( ( *mm != *t || mm[1] != t[1] )
×
1354
                                                                                         && mm < mstop ) mm += 3;
×
1355
                                                                                if ( mm >= mstop ) pow = 0;
×
1356
                                                                                else if ( pow > 0 && mm[2] > 0 ) {
×
1357
                                                                                        if ( mm[2] < pow ) pow = mm[2];
×
1358
                                                                                }
1359
                                                                                else if ( pow < 0 && mm[2] < 0 ) {
×
1360
                                                                                        if ( mm[2] > pow ) pow = mm[2];
×
1361
                                                                                }
1362
                                                                                else pow = 0;
1363
                                                                        }
1364
                                                                        else pow = 0;
1365
                                                                        if ( pow == 0 ) break;
×
1366
                                                                        mm = mnext;
1367
                                                                }
1368
                                                                if ( pow == 0 ) { t += 3; continue; }
8✔
1369
/*
1370
                                                                We have a factor
1371
*/
1372
                                                                action = 1; i = pow;
8✔
1373
                                                                if ( i > 0 ) {
8✔
1374
                                                                        while ( --i >= 0 ) {
16✔
1375
                                                                                *r1++ = 9 + ARGHEAD;
8✔
1376
                                                                                for ( j = 1; j < ARGHEAD; j++ ) *r1++ = 0;
16✔
1377
                                                                                *r1++ = 9; *r1++ = DOTPRODUCT;
8✔
1378
                                                                                *r1++ = 5; *r1++ = *t; *r1++ = t[1]; *r1++ = 1;
8✔
1379
                                                                                *r1++ = 1; *r1++ = 1; *r1++ = 3;
8✔
1380
                                                                        }
1381
                                                                }
1382
                                                                else {
1383
                                                                        while ( i++ < 0 ) {
×
1384
                                                                                *r1++ = 9 + ARGHEAD;
×
1385
                                                                                for ( j = 1; j < ARGHEAD; j++ ) *r1++ = 0;
×
1386
                                                                                *r1++ = 9; *r1++ = DOTPRODUCT;
×
1387
                                                                                *r1++ = 5; *r1++ = *t; *r1++ = t[1]; *r1++ = -1;
×
1388
                                                                                *r1++ = 1; *r1++ = 1; *r1++ = 3;
×
1389
                                                                        }
1390
                                                                }
1391
/*
1392
                                                                Now we have to remove the dotproducts
1393
*/
1394
                                                                t[2] -= pow;
8✔
1395
                                                                mm = rnext;
8✔
1396
                                                                while ( mm < r3 ) {
8✔
1397
                                                                        mnext = mm + *mm;
×
1398
                                                                        GETSTOP(mm,mstop); mm++;
×
1399
                                                                        while ( mm < mstop ) {
×
1400
                                                                                if ( *mm != DOTPRODUCT ) mm += mm[1];
×
1401
                                                                                else break;
1402
                                                                        }
1403
                                                                        mstop = mm + mm[1]; mm += 2;
×
1404
                                                                        while ( mm < mstop && ( *mm != *t
×
1405
                                                                                || mm[1] != t[1] ) ) mm += 3;
×
1406
                                                                        mm[2] -= pow;
×
1407
                                                                        mm = mnext;
×
1408
                                                                }
1409
                                                                t += 3;
8✔
1410
                                                        }
1411
                                                }
1412
/*
1413
                        #] DOTPRODUCT : 
1414
                        #[ DELTA/VECTOR :
1415
*/
1416
                                                else if ( *t == DELTA || *t == VECTOR ) {
16✔
1417
                                                        r7 = t; r8 = t + t[1]; t += 2;
×
1418
                                                        while ( t < r8 ) {
×
1419
                                                                mm = rnext;
1420
                                                                pow = 1;
1421
                                                                while ( mm < r3 ) {
×
1422
                                                                        mnext = mm + *mm;
×
1423
                                                                        GETSTOP(mm,mstop); mm++;
×
1424
                                                                        while ( mm < mstop ) {
×
1425
                                                                                if ( *mm != *r7 ) mm += mm[1];
×
1426
                                                                                else break;
1427
                                                                        }
1428
                                                                        if ( *mm == *r7 ) {
×
1429
                                                                                mstop = mm + mm[1]; mm += 2;
×
1430
                                                                                while ( ( *mm != *t || mm[1] != t[1] )
×
1431
                                                                                        && mm < mstop ) mm += 2;
×
1432
                                                                                if ( mm >= mstop ) pow = 0;
×
1433
                                                                        }
1434
                                                                        else pow = 0;
1435
                                                                        if ( pow == 0 ) break;
×
1436
                                                                        mm = mnext;
1437
                                                                }
1438
                                                                if ( pow == 0 ) { t += 2; continue; }
×
1439
/*
1440
                                                                We have a factor
1441
*/
1442
                                                                action = 1;
×
1443
                                                                *r1++ = 8 + ARGHEAD;
×
1444
                                                                for ( j = 1; j < ARGHEAD; j++ ) *r1++ = 0;
×
1445
                                                                *r1++ = 8; *r1++ = *r7;
×
1446
                                                                *r1++ = 4; *r1++ = *t; *r1++ = t[1];
×
1447
                                                                *r1++ = 1; *r1++ = 1; *r1++ = 3;
×
1448
/*
1449
                                                                Now we have to remove the delta's/vectors
1450
*/
1451
                                                                mm = rnext;
×
1452
                                                                while ( mm < r3 ) {
×
1453
                                                                        mnext = mm + *mm;
×
1454
                                                                        GETSTOP(mm,mstop); mm++;
×
1455
                                                                        while ( mm < mstop ) {
×
1456
                                                                                if ( *mm != *r7 ) mm += mm[1];
×
1457
                                                                                else break;
1458
                                                                        }
1459
                                                                        mstop = mm + mm[1]; mm += 2;
×
1460
                                                                        while ( mm < mstop && (
×
1461
                                                                         *mm != *t || mm[1] != t[1] ) ) mm += 2;
×
1462
                                                                        *mm = mm[1] = NOINDEX;
×
1463
                                                                        mm = mnext;
×
1464
                                                                }
1465
                                                                *t = t[1] = NOINDEX;
×
1466
                                                                t += 2;
×
1467
                                                        }
1468
                                                }
1469
/*
1470
                        #] DELTA/VECTOR : 
1471
                        #[ INDEX :
1472
*/
1473
                                                else if ( *t == INDEX ) {
16✔
1474
                                                        r7 = t; r8 = t + t[1]; t += 2;
×
1475
                                                        while ( t < r8 ) {
×
1476
                                                                mm = rnext;
1477
                                                                pow = 1;
1478
                                                                while ( mm < r3 ) {
×
1479
                                                                        mnext = mm + *mm;
×
1480
                                                                        GETSTOP(mm,mstop); mm++;
×
1481
                                                                        while ( mm < mstop ) {
×
1482
                                                                                if ( *mm != *r7 ) mm += mm[1];
×
1483
                                                                                else break;
1484
                                                                        }
1485
                                                                        if ( *mm == *r7 ) {
×
1486
                                                                                mstop = mm + mm[1]; mm += 2;
×
1487
                                                                                while ( *mm != *t 
×
1488
                                                                                        && mm < mstop ) mm++;
×
1489
                                                                                if ( mm >= mstop ) pow = 0;
×
1490
                                                                        }
1491
                                                                        else pow = 0;
1492
                                                                        if ( pow == 0 ) break;
×
1493
                                                                        mm = mnext;
1494
                                                                }
1495
                                                                if ( pow == 0 ) { t++; continue; }
×
1496
/*
1497
                                                                We have a factor
1498
*/
1499
                                                                action = 1;
×
1500
/*
1501
                                                                The next looks like an error.
1502
                                                                We should have here a VECTOR or INDEX like object
1503

1504
                                                                *r1++ = 7 + ARGHEAD;
1505
                                                                for ( j = 1; j < ARGHEAD; j++ ) *r1++ = 0;
1506
                                                                *r1++ = 7; *r1++ = *r7;
1507
                                                                *r1++ = 3; *r1++ = *t;
1508
                                                                *r1++ = 1; *r1++ = 1; *r1++ = 3;
1509

1510
                                                                Replace this by:  (11-apr-2007)
1511
*/
1512
                                                                if ( *t < 0 ) { *r1++ = -VECTOR; }
×
1513
                                                                else { *r1++ = -INDEX; }
×
1514
                                                                *r1++ = *t;
×
1515
/*
1516
                                                                Now we have to remove the index
1517
*/
1518
                                                                *t = NOINDEX;
×
1519
                                                                mm = rnext;
×
1520
                                                                while ( mm < r3 ) {
×
1521
                                                                        mnext = mm + *mm;
×
1522
                                                                        GETSTOP(mm,mstop); mm++;
×
1523
                                                                        while ( mm < mstop ) {
×
1524
                                                                                if ( *mm != *r7 ) mm += mm[1];
×
1525
                                                                                else break;
1526
                                                                        }
1527
                                                                        mstop = mm + mm[1]; mm += 2;
×
1528
                                                                        while ( mm < mstop && 
×
1529
                                                                         *mm != *t ) mm += 1;
×
1530
                                                                        *mm = NOINDEX;
×
1531
                                                                        mm = mnext;
×
1532
                                                                }
1533
                                                                t += 1;
×
1534
                                                        }
1535
                                                }
1536
/*
1537
                        #] INDEX : 
1538
                        #[ FUNCTION :
1539
*/
1540
                                                else if ( *t >= FUNCTION ) {
16✔
1541
/*
1542
                                                        In the next code we should actually look inside
1543
                                                        the DENOMINATOR or EXPONENT for noncommuting objects
1544
*/
1545
                                                        if ( *t >= FUNCTION &&
16✔
1546
                                                                functions[*t-FUNCTION].commute == 0 ) ncom = 0;
16✔
1547
                                                        else ncom = 1;
1548
                                                        if ( ncom ) {
1549
                                                                mm = r5 + 1;
1550
                                                                while ( mm < t && ( *mm == DUMMYFUN
×
1551
                                                                || *mm == DUMMYTEN ) ) mm += mm[1];
×
1552
                                                                if ( mm < t ) { t += t[1]; continue; }
×
1553
                                                        }
1554
                                                        mm = rnext; pow = 1;
1555
                                                        while ( mm < r3 ) {
16✔
1556
                                                                mnext = mm + *mm;
×
1557
                                                                GETSTOP(mm,mstop); mm++;
×
1558
                                                                while ( mm < mstop ) {
×
1559
                                                                        if ( *mm == *t && mm[1] == t[1] ) {
×
1560
                                                                                for ( i = 2; i < t[1]; i++ ) {
×
1561
                                                                                        if ( mm[i] != t[i] ) break;
×
1562
                                                                                }
1563
                                                                                if ( i >= t[1] )
×
1564
                                                                                        { mm += mm[1]; goto nextmterm; }
×
1565
                                                                        }
1566
                                                                        if ( ncom && *mm != DUMMYFUN && *mm != DUMMYTEN )
×
1567
                                                                                { pow = 0; break; }
1568
                                                                        mm += mm[1];
×
1569
                                                                }
1570
                                                                if ( mm >= mstop ) pow = 0;
×
1571
                                                                if ( pow == 0 ) break;
×
1572
nextmterm:                                                mm = mnext;
×
1573
                                                        }
1574
                                                        if ( pow == 0 ) { t += t[1]; continue; }
16✔
1575
/*
1576
                                                        Copy the function
1577
*/
1578
                                                        action = 1;
16✔
1579
                                                        *r1++ = t[1] + 4 + ARGHEAD;
16✔
1580
                                                        for ( i = 1; i < ARGHEAD; i++ ) *r1++ = 0;
32✔
1581
                                                        *r1++ = t[1] + 4;
16✔
1582
                                                        for ( i = 0; i < t[1]; i++ ) *r1++ = t[i];
104✔
1583
                                                        *r1++ = 1; *r1++ = 1; *r1++ = 3;
16✔
1584
/*
1585
                                                        Now we have to take out the functions
1586
*/
1587
                                                        mm = rnext;
16✔
1588
                                                        while ( mm < r3 ) {
16✔
1589
                                                                mnext = mm + *mm;
×
1590
                                                                GETSTOP(mm,mstop); mm++;
×
1591
                                                                while ( mm < mstop ) {
×
1592
                                                                        if ( *mm == *t && mm[1] == t[1] ) {
×
1593
                                                                                for ( i = 2; i < t[1]; i++ ) {
×
1594
                                                                                        if ( mm[i] != t[i] ) break;
×
1595
                                                                                }
1596
                                                                                if ( i >= t[1] ) {
×
1597
                                                                                        if ( functions[*t-FUNCTION].spec > 0 )
×
1598
                                                                                                *mm = DUMMYTEN;
×
1599
                                                                                        else
1600
                                                                                                *mm = DUMMYFUN;
×
1601
                                                                                        mm += mm[1];
×
1602
                                                                                        goto nextterm;
×
1603
                                                                                }
1604
                                                                        }
1605
                                                                        mm += mm[1];
×
1606
                                                                }
1607
nextterm:                                                mm = mnext;
×
1608
                                                        }
1609
                                                        if ( functions[*t-FUNCTION].spec > 0 )
16✔
1610
                                                                        *t = DUMMYTEN;
16✔
1611
                                                        else
1612
                                                                        *t = DUMMYFUN;
×
1613
                                                        action = 1;
16✔
1614
                                                        v[2] = DIRTYFLAG;
16✔
1615
                                                        t += t[1];
16✔
1616
                                                }
1617
/*
1618
                        #] FUNCTION : 
1619
*/
1620
                                                else {
1621
                                                        t += t[1];
×
1622
                                                }
1623
                                          }
1624
                                        }
1625
                                        t = r5; pow = 1;
32✔
1626
                                        while ( t < r3 ) {
36✔
1627
                                                t += *t; if ( t[-1] > 0 ) { pow = 0; break; }
32✔
1628
                                        }
1629
/*
1630
                                        We have to add here the code for computing the GCD
1631
                                        and to divide it out.
1632
*/
1633
/*
1634
                        #[ Numerical factor :
1635
*/
1636
                                        t = r5;
32✔
1637
                                        EAscrat = (UWORD *)(TermMalloc("execarg"));
32✔
1638
                                        if ( t + *t == r3 ) goto oneterm;
32✔
1639
                                        GETSTOP(t,r6);
×
1640
                                        ngcd = t[t[0]-1];
×
1641
                                        i = abs(ngcd)-1;
×
1642
                                        while ( --i >= 0 ) EAscrat[i] = r6[i];
×
1643
                                        t += *t;
×
1644
                                        while ( t < r3 ) {
×
1645
                                                GETSTOP(t,r6);
×
1646
                                                i = t[t[0]-1];
×
1647
                                                if ( AccumGCD(BHEAD EAscrat,&ngcd,(UWORD *)r6,i) ) goto execargerr;
×
1648
                                                if ( ngcd == 3 && EAscrat[0] == 1 && EAscrat[1] == 1 ) break;
×
1649
                                                t += *t;
×
1650
                                        }
1651
                                         if ( ngcd != 3 || EAscrat[0] != 1 || EAscrat[1] != 1 ) {
×
1652
                                                if ( pow ) ngcd = -ngcd;
×
1653
                                                t = r5; r9 = r1; *r1++ = t[-ARGHEAD]; *r1++ = 1;
×
1654
                                                FILLARG(r1); ngcd = REDLENG(ngcd);
×
1655
                                                while ( t < r3 ) {
×
1656
                                                        GETSTOP(t,r6);
×
1657
                                                        r7 = t; r8 = r1;
×
1658
                                                        while ( r7 < r6) *r1++ = *r7++;
×
1659
                                                        t += *t;
×
1660
                                                        i = REDLENG(t[-1]);
×
1661
                                                        if ( DivRat(BHEAD (UWORD *)r6,i,EAscrat,ngcd,(UWORD *)r1,&nq) ) goto execargerr;
×
1662
                                                        nq = INCLENG(nq);
×
1663
                                                        i = ABS(nq)-1;
×
1664
                                                        r1 += i; *r1++ = nq; *r8 = r1-r8;
×
1665
                                                }
1666
                                                *r9 = r1-r9;
×
1667
                                                ngcd = INCLENG(ngcd);
×
1668
                                                i = ABS(ngcd)-1;
×
1669
                                                if ( factor && *factor == 0 ) {}
×
1670
                                                else if ( ( factor && factor[0] == 4 && factor[2] == 1
×
1671
                                                && factor[3] == -3 ) || pow == 0 ) {
×
1672
                                                        r9 = r1; *r1++ = ARGHEAD+2+i; *r1++ = 0;
×
1673
                                                        FILLARG(r1); *r1++ = i+2;
×
1674
                                                        for ( j = 0; j < i; j++ ) *r1++ = EAscrat[j];
×
1675
                                                        *r1++ = ngcd;
×
1676
                                                        if ( ToFast(r9,r9) ) r1 = r9+2;
×
1677
                                                }
1678
                                                else if ( factor && factor[0] == 4 && factor[2] == 1
×
1679
                                                && factor[3] > 0 && pow ) {
×
1680
                                                        if ( ngcd < 0 ) ngcd = -ngcd;
×
1681
                                                        *r1++ = -SNUMBER; *r1++ = -1;
×
1682
                                                        r9 = r1; *r1++ = ARGHEAD+2+i; *r1++ = 0;
×
1683
                                                        FILLARG(r1); *r1++ = i+2;
×
1684
                                                        for ( j = 0; j < i; j++ ) *r1++ = EAscrat[j];
×
1685
                                                        *r1++ = ngcd;
×
1686
                                                        if ( ToFast(r9,r9) ) r1 = r9+2;
×
1687
                                                }
1688
                                                else {
1689
                                                        if ( ngcd < 0 ) ngcd = -ngcd;
×
1690
                                                        if ( pow ) { *r1++ = -SNUMBER; *r1++ = -1; }
×
1691
                                                        if ( ngcd != 3 || EAscrat[0] != 1 || EAscrat[1] != 1 ) {
×
1692
                                                                r9 = r1; *r1++ = ARGHEAD+2+i; *r1++ = 0;
×
1693
                                                                FILLARG(r1); *r1++ = i+2;
×
1694
                                                                for ( j = 0; j < i; j++ ) *r1++ = EAscrat[j];
×
1695
                                                                *r1++ = ngcd;
×
1696
                                                                if ( ToFast(r9,r9) ) r1 = r9+2;
×
1697
                                                        }
1698
                                                }
1699
                                         }
1700
/*
1701
                        #] Numerical factor : 
1702
*/
1703
                                        else {
1704
oneterm:;
×
1705
                                                if ( factor == 0 || *factor > 2 ) {
32✔
1706
                                                if ( pow > 0 ) {
32✔
1707
                                                        *r1++ = -SNUMBER; *r1++ = -1;
4✔
1708
                                                        t = r5;
4✔
1709
                                                        while ( t < r3 ) {
8✔
1710
                                                                t += *t; t[-1] = -t[-1];
4✔
1711
                                                        }
1712
                                                }
1713
                                                t = rr; *r1++ = *t++; *r1++ = 1; t++;
32✔
1714
                                                COPYARG(r1,t);
32✔
1715
                                                while ( t < m ) *r1++ = *t++;
416✔
1716
                                                }
1717
                                        }
1718
                                        TermFree(EAscrat,"execarg");
32✔
1719
                                        }
1720
                        } /* AC.OldFactArgFlag */
1721
                                }
1722
/* r1 is fout in ons voorbeeld. */
1723
                                r2[1] = r1 - r2;
5,155✔
1724
                                action = 1;
5,155✔
1725
                                v[2] = DIRTYFLAG;
5,155✔
1726
                        }
1727
                        else {
1728
                                r = t + t[1];
10,448✔
1729
                                while ( t < r ) *r1++ = *t++;
132,472✔
1730
                        }
1731
                }
1732
                r = term + *term;
5,139✔
1733
                while ( t < r ) *r1++ = *t++;
20,556✔
1734
                m = AT.WorkPointer;
5,139✔
1735
                i = m[0] = r1 - m;
5,139✔
1736
                t = term;
5,139✔
1737
                while ( --i >= 0 ) *t++ = *m++;
387,618✔
1738
                if ( AT.WorkPointer < t ) AT.WorkPointer = t;
5,139✔
1739
        }
1740
/*
1741
          #] FACTARG : 
1742
*/
1743
        AR.Cnumlhs = oldnumlhs;
302,450✔
1744
        if ( action && Normalize(BHEAD term) ) goto execargerr;
302,450✔
1745
        AT.WorkPointer = oldwork;
302,450✔
1746
        if ( AT.WorkPointer < term + *term ) AT.WorkPointer = term + *term;
302,450✔
1747
        AT.pWorkPointer = oldppointer;
302,450✔
1748
        return(action);
302,450✔
1749
execargerr:
×
1750
        AT.WorkPointer = oldwork;
×
1751
        AT.pWorkPointer = oldppointer;
×
1752
        MLOCK(ErrorMessageLock);
×
1753
        MesCall("execarg");
×
1754
        MUNLOCK(ErrorMessageLock);
×
1755
        return(-1);
1756
}
1757

1758
/*
1759
          #] execarg : 
1760
          #[ execterm :
1761
*/
1762

1763
WORD execterm(PHEAD WORD *term, WORD level)
320✔
1764
{
1765
        GETBIDENTITY
1766
        CBUF *C = cbuf+AM.rbufnum;
320✔
1767
        WORD oldnumlhs = AR.Cnumlhs;
320✔
1768
        WORD maxisat = C->lhs[level][2];
320✔
1769
        WORD *buffer1 = 0;
320✔
1770
        WORD *oldworkpointer = AT.WorkPointer;
320✔
1771
        WORD *t1, i;
320✔
1772
        WORD olddeferflag = AR.DeferFlag, tryterm = 0;
320✔
1773
        AR.DeferFlag = 0;
320✔
1774
        do {
2,528✔
1775
                AR.Cnumlhs = C->lhs[level][3];
2,528✔
1776
                NewSort(BHEAD0);
2,528✔
1777
/*
1778
                Normally for function arguments we do not use PolyFun/PolyRatFun.
1779
                Hence NewSort sets the corresponding variables to zero.
1780
                Here we overwrite that.
1781
*/
1782
                AN.FunSorts[AR.sLevel]->PolyFlag = ( AR.PolyFun != 0 ) ? AR.PolyFunType: 0;
2,528✔
1783
                if ( AR.PolyFun == 0 ) { AN.FunSorts[AR.sLevel]->PolyFlag = 0; }
2,528✔
1784
                else if ( AR.PolyFunType == 1 ) { AN.FunSorts[AR.sLevel]->PolyFlag = 1; }
2,524✔
1785
                else if ( AR.PolyFunType == 2 ) {
2,524✔
1786
                        if ( AR.PolyFunExp == 2 ) AN.FunSorts[AR.sLevel]->PolyFlag = 1;
2,524✔
1787
                        else                      AN.FunSorts[AR.sLevel]->PolyFlag = 2;
2,524✔
1788
                }
1789
                if ( buffer1 ) {
2,528✔
1790
                        term = buffer1;
1791
                        while ( *term ) {
23,536✔
1792
                                t1 = oldworkpointer;
1793
                                i = *term; while ( --i >= 0 ) *t1++ = *term++;
5,340,520✔
1794
                                AT.WorkPointer = t1;
21,328✔
1795
                                if ( Generator(BHEAD oldworkpointer,level) ) goto exectermerr;
21,328✔
1796
                        }
1797
                }
1798
                else {
1799
                        if ( Generator(BHEAD term,level) ) goto exectermerr;
320✔
1800
                }
1801
                if ( buffer1 ) {
2,528✔
1802
                        if ( tryterm ) { TermFree(buffer1,"buffer in sort statement"); tryterm = 0; }
2,208✔
1803
                        else { M_free((void *)buffer1,"buffer in sort statement"); }
52✔
1804
                        buffer1 = 0;
2,208✔
1805
                }
1806
                AN.tryterm = 1;
2,528✔
1807
                if ( EndSort(BHEAD (WORD *)((VOID *)(&buffer1)),2) < 0 ) goto exectermerr;
2,528✔
1808
                tryterm = AN.tryterm; AN.tryterm = 0;
2,528✔
1809
                level = AR.Cnumlhs;
2,528✔
1810
        } while ( AR.Cnumlhs < maxisat );
2,528✔
1811
        AR.Cnumlhs = oldnumlhs;
320✔
1812
        AR.DeferFlag = olddeferflag;
320✔
1813
        term = buffer1;
320✔
1814
        while ( *term ) {
2,556✔
1815
                t1 = oldworkpointer;
1816
                i = *term; while ( --i >= 0 ) *t1++ = *term++;
537,912✔
1817
                AT.WorkPointer = t1;
2,236✔
1818
                if ( Generator(BHEAD oldworkpointer,level) ) goto exectermerr;
2,236✔
1819
        }
1820
        if ( tryterm ) { TermFree(buffer1,"buffer in term statement"); tryterm = 0; }
320✔
1821
        else { M_free(buffer1,"buffer in term statement"); }
4✔
1822
        buffer1 = 0;
320✔
1823
        AT.WorkPointer = oldworkpointer;
320✔
1824
        return(0);
320✔
1825
exectermerr:
×
1826
        AT.WorkPointer = oldworkpointer;
×
1827
        AR.DeferFlag = olddeferflag;
×
1828
        MLOCK(ErrorMessageLock);
×
1829
        MesCall("execterm");
×
1830
        MUNLOCK(ErrorMessageLock);
×
1831
        return(-1);
1832
}
1833

1834
/*
1835
          #] execterm : 
1836
          #[ ArgumentImplode :
1837
*/
1838

1839
int ArgumentImplode(PHEAD WORD *term, WORD *thelist)
16✔
1840
{
1841
        GETBIDENTITY
1842
        WORD *liststart, *liststop, *inlist;
16✔
1843
        WORD *w, *t, *tend, *tstop, *tt, *ttstop, *ttt, ncount, i;
16✔
1844
        int action = 0;
16✔
1845
        liststop = thelist + thelist[1];
16✔
1846
        liststart = thelist + 2;
16✔
1847
        t = term;
16✔
1848
        tend = t + *t;
16✔
1849
        tstop = tend - ABS(tend[-1]);
16✔
1850
        t++;
16✔
1851
        while ( t < tstop ) {
48✔
1852
                if ( *t >= FUNCTION ) {
32✔
1853
                        inlist = liststart;
1854
                        while ( inlist < liststop && *inlist != *t ) inlist += inlist[1];
28✔
1855
                        if ( inlist < liststop ) {
16✔
1856
                                tt = t; ttstop = t + t[1]; w = AT.WorkPointer;
4✔
1857
                                for ( i = 0; i < FUNHEAD; i++ ) *w++ = *tt++;
16✔
1858
                                while ( tt < ttstop ) {
12✔
1859
                                        ncount = 0;
8✔
1860
                                        if ( *tt == -SNUMBER && tt[1] == 0 ) {
8✔
1861
                                                ncount = 1; ttt = tt; tt += 2;
8✔
1862
                                                while ( tt < ttstop && *tt == -SNUMBER && tt[1] == 0 ) {
20✔
1863
                                                        ncount++; tt += 2;
12✔
1864
                                                }
1865
                                        }
1866
                                        if ( ncount > 0 ) {
8✔
1867
                                                if ( tt < ttstop && *tt == -SNUMBER && ( tt[1] == 1 || tt[1] == -1 ) ) {
8✔
1868
                                                        *w++ = -SNUMBER;
8✔
1869
                                                        *w++ = (ncount+1) * tt[1];
8✔
1870
                                                        tt += 2;
8✔
1871
                                                        action = 1;
8✔
1872
                                                }
1873
                                                else if ( ( tt[0] == tt[ARGHEAD] + ARGHEAD )
×
1874
                                                && ( ABS(tt[tt[0]-1]) == 3 )
×
1875
                                                && ( tt[tt[0]-2] == 1 )
×
1876
                                                && ( tt[tt[0]-3] == 1 ) ) { /* Single term with coef +/- 1 */
×
1877
                                                        i = *tt; NCOPY(w,tt,i)
×
1878
                                                        w[-3] = ncount+1;
×
1879
                                                        action = 1;
×
1880
                                                }
1881
                                                else if ( *tt == -SYMBOL ) {
×
1882
                                                        *w++ = ARGHEAD+8;
×
1883
                                                        *w++ = 0;
×
1884
                                                        FILLARG(w)
1885
                                                        *w++ = 8;
×
1886
                                                        *w++ = SYMBOL;
×
1887
                                                        *w++ = tt[1];
×
1888
                                                        *w++ = 1;
×
1889
                                                        *w++ = ncount+1; *w++ = 1; *w++ = 3;
×
1890
                                                        tt += 2;
×
1891
                                                        action = 1;
×
1892
                                                }
1893
                                                else if ( *tt <= -FUNCTION ) {
×
1894
                                                        *w++ = ARGHEAD+FUNHEAD+4;
×
1895
                                                        *w++ = 0;
×
1896
                                                        FILLARG(w)
1897
                                                        *w++ = -*tt++;
×
1898
                                                        *w++ = FUNHEAD+4;
×
1899
                                                        FILLFUN(w)
×
1900
                                                        *w++ = ncount+1; *w++ = 1; *w++ = 3;
×
1901
                                                        action = 1;
×
1902
                                                }
1903
                                                else {
1904
                                                        while ( ttt < tt ) *w++ = *ttt++;
×
1905
                                                        if ( tt < ttstop && *tt == -SNUMBER ) {
×
1906
                                                                *w++ = *tt++; *w++ = *tt++;
×
1907
                                                        }
1908
                                                }
1909
                                        }
1910
                                        else if ( *tt <= -FUNCTION ) {
×
1911
                                                *w++ = *tt++;
×
1912
                                        }
1913
                                        else if ( *tt < 0 ) {
×
1914
                                                *w++ = *tt++;
×
1915
                                                *w++ = *tt++;
×
1916
                                        }
1917
                                        else {
1918
                                                i = *tt; NCOPY(w,tt,i)
×
1919
                                        }
1920
                                }
1921
                                AT.WorkPointer[1] = w - AT.WorkPointer;
4✔
1922
                                while ( tt < tend ) *w++ = *tt++;
32✔
1923
                                ttt = AT.WorkPointer; tt = t;
4✔
1924
                                while ( ttt < w ) *tt++ = *ttt++;
60✔
1925
                                term[0] = tt - term;
4✔
1926
                                AT.WorkPointer = tt;
4✔
1927
                                tend = tt; tstop = tt - ABS(tt[-1]);
4✔
1928
                        }
1929
                }
1930
                t += t[1];
32✔
1931
        }
1932
        if ( action ) {
16✔
1933
                if ( Normalize(BHEAD term) ) return(-1);
4✔
1934
        }
1935
        return(0);
1936
}
1937

1938
/*
1939
          #] ArgumentImplode : 
1940
          #[ ArgumentExplode :
1941
*/
1942

1943
int ArgumentExplode(PHEAD WORD *term, WORD *thelist)
16✔
1944
{
1945
        GETBIDENTITY
1946
        WORD *liststart, *liststop, *inlist, *old;
16✔
1947
        WORD *w, *t, *tend, *tstop, *tt, *ttstop, *ttt, ncount, i;
16✔
1948
        int action = 0;
16✔
1949
        LONG x;
16✔
1950
        liststop = thelist + thelist[1];
16✔
1951
        liststart = thelist + 2;
16✔
1952
        t = term;
16✔
1953
        tend = t + *t;
16✔
1954
        tstop = tend - ABS(tend[-1]);
16✔
1955
        t++;
16✔
1956
        while ( t < tstop ) {
48✔
1957
                if ( *t >= FUNCTION ) {
32✔
1958
                        inlist = liststart;
1959
                        while ( inlist < liststop && *inlist != *t ) inlist += inlist[1];
28✔
1960
                        if ( inlist < liststop ) {
16✔
1961
                                tt = t; ttstop = t + t[1]; w = AT.WorkPointer;
4✔
1962
                                for ( i = 0; i < FUNHEAD; i++ ) *w++ = *tt++;
16✔
1963
                                while ( tt < ttstop ) {
20✔
1964
                                        if ( *tt == -SNUMBER && tt[1] != 0 ) {
16✔
1965
                                                if ( tt[1] < AM.MaxTer/((WORD)sizeof(WORD)*4)
16✔
1966
                                                        && tt[1] > -(AM.MaxTer/((WORD)sizeof(WORD)*4))
16✔
1967
                                                        && ( tt[1] > 1 || tt[1] < -1 ) ) {
16✔
1968
                                                        ncount = ABS(tt[1]);
8✔
1969
                                                        while ( ncount > 1 ) {
40✔
1970
                                                                *w++ = -SNUMBER; *w++ = 0; ncount--;
32✔
1971
                                                        }
1972
                                                        *w++ = -SNUMBER;
8✔
1973
                                                        if ( tt[1] < 0 ) *w++ = -1;
8✔
1974
                                                        else             *w++ =  1;
4✔
1975
                                                        tt += 2;
8✔
1976
                                                        action = 1;
8✔
1977
                                                }
1978
                                                else {
1979
                                                        *w++ = *tt++; *w++ = *tt++;
8✔
1980
                                                }
1981
                                        }
1982
                                        else if ( *tt <= -FUNCTION ) {
×
1983
                                                *w++ = *tt++;
×
1984
                                        }
1985
                                        else if ( *tt < 0 ) {
×
1986
                                                *w++ = *tt++;
×
1987
                                                *w++ = *tt++;
×
1988
                                        }
1989
                                        else if ( tt[0] == tt[ARGHEAD]+ARGHEAD ) {
×
1990
                                                ttt = tt + tt[0] - 1;
×
1991
                                                i = (ABS(ttt[0])-1)/2; 
×
1992
                                                if ( i > 1 ) {
×
1993
TooMany:                                        old = AN.currentTerm;
×
1994
                                                        AN.currentTerm = term;
×
1995
                                                        MesPrint("Too many arguments in output of ArgExplode");
×
1996
                                                        MesPrint("Term = %t");
×
1997
                                                        AN.currentTerm = old;
×
1998
                                                        return(-1);
×
1999
                                                }
2000
                                                if ( ttt[-1] != 1 ) goto NoExplode;
×
2001
                                                x = ttt[-2];
×
2002
                                                if ( 2*x > (AT.WorkTop-w)-*term ) goto TooMany;
×
2003
                                                ncount = x - 1;
×
2004
                                                while ( ncount > 0 ) {
×
2005
                                                        *w++ = -SNUMBER; *w++ = 0; ncount--;
×
2006
                                                }
2007
                                                ttt[-2] = 1;
×
2008
                                                i = *tt; NCOPY(w,tt,i)
×
2009
                                                action = 1;
2010
                                        }
2011
                                        else {
2012
NoExplode:
×
2013
                                                i = *tt; NCOPY(w,tt,i)
×
2014
                                        }
2015
                                }
2016
                                AT.WorkPointer[1] = w - AT.WorkPointer;
4✔
2017
                                while ( tt < tend ) *w++ = *tt++;
32✔
2018
                                ttt = AT.WorkPointer; tt = t;
4✔
2019
                                while ( ttt < w ) *tt++ = *ttt++;
140✔
2020
                                term[0] = tt - term;
4✔
2021
                                AT.WorkPointer = tt;
4✔
2022
                                tend = tt; tstop = tt - ABS(tt[-1]);
4✔
2023
                        }
2024
                }
2025
                t += t[1];
32✔
2026
        }
2027
        if ( action ) {
16✔
2028
                if ( Normalize(BHEAD term) ) return(-1);
4✔
2029
        }
2030
        return(0);
2031
}
2032

2033
/*
2034
          #] ArgumentExplode : 
2035
          #[ ArgFactorize :
2036
*/
2037
/**
2038
 *        Factorizes an argument in general notation (meaning that the first
2039
 *        word of the argument is a positive size indicator)
2040
 *        Input (argin):   pointer to the complete argument
2041
 *        Output (argout): Pointer to where the output should be written.
2042
 *                         This is in the WorkSpace
2043
 *        Return value should be negative if anything goes wrong.
2044
 *
2045
 *        The notation of the output should be a string of arguments terminated
2046
 *        by the number zero.
2047
 *
2048
 *        Originally we sorted in a way that the constants came last. This gave
2049
 *        conflicts with the dollar and expression factorizations (in the expressions
2050
 *        we wanted the zero first and then followed by the constants).
2051
 */
2052
#define NEWORDER
2053

2054
int ArgFactorize(PHEAD WORD *argin, WORD *argout)
5,083✔
2055
{
2056
/*
2057
          #[ step 0 : Declarations and initializations
2058
*/
2059
        WORD *argfree, *argextra, *argcopy, *t, *tstop, *a, *a1, *a2;
5,083✔
2060
#ifdef NEWORDER
2061
        WORD *tt;
5,083✔
2062
#endif
2063
        WORD startebuf = cbuf[AT.ebufnum].numrhs,oldword;
5,083✔
2064
        WORD oldsorttype = AR.SortType, numargs;
5,083✔
2065
        int error = 0, action = 0, i, ii, number, sign = 1;
5,083✔
2066

2067
        *argout = 0;
5,083✔
2068
/*
2069
          #] step 0 : 
2070
          #[ step 1 : Take care of ordering
2071
*/
2072
        AR.SortType = SORTHIGHFIRST;
5,083✔
2073
        if ( oldsorttype != AR.SortType ) {
5,083✔
2074
                NewSort(BHEAD0);
19✔
2075
                oldword = argin[*argin]; argin[*argin] = 0;
19✔
2076
                t = argin+ARGHEAD;
19✔
2077
                while ( *t ) {
1,324✔
2078
                        tstop = t + *t;
1,305✔
2079
                        if ( AN.ncmod != 0 ) {
1,305✔
2080
                                if ( AN.ncmod != 1 || ( (WORD)AN.cmod[0] < 0 ) ) {
×
2081
                                        MLOCK(ErrorMessageLock);
×
2082
                                        MesPrint("Factorization modulus a number, greater than a WORD not implemented.");
×
2083
                                        MUNLOCK(ErrorMessageLock);
×
2084
                                        Terminate(-1);
×
2085
                                }
2086
                                if ( Modulus(t) ) {
×
2087
                                        MLOCK(ErrorMessageLock);
×
2088
                                        MesCall("ArgFactorize");
×
2089
                                        MUNLOCK(ErrorMessageLock);
×
2090
                                        Terminate(-1);
×
2091
                                }
2092
                                if ( !*t) { t = tstop; continue; }
×
2093
                        }
2094
                        StoreTerm(BHEAD t);
1,305✔
2095
                        t = tstop;
1,305✔
2096
                }
2097
                /* par = 1, in case the arg has more than SubTermsInSmall terms */
2098
                EndSort(BHEAD argin+ARGHEAD,1);
19✔
2099
                argin[*argin] = oldword;
19✔
2100
        }
2101
/*
2102
          #] step 1 : 
2103
          #[ step 2 : take out the 'content'.
2104
*/
2105
        argfree = TakeArgContent(BHEAD argin,argout);
5,083✔
2106
        {
2107
                a1 = argout;
5,083✔
2108
                while ( *a1 ) {
5,083✔
2109
                        if ( a1[0] == -SNUMBER && ( a1[1] == 1 || a1[1] == -1 ) ) {
5,941✔
2110
                                if ( a1[1] == -1 ) { sign = -sign; a1[1] = 1; }
5,083✔
2111
                                if ( a1[2] ) {
5,083✔
2112
                                        a = t = a1+2; while ( *t ) NEXTARG(t);
×
2113
                                        i = t - a1-2;
×
2114
                                        t = a1; NCOPY(t,a,i);
×
2115
                                        *t = 0;
×
2116
                                        continue;
×
2117
                                }
2118
                                else {
2119
                                        a1[0] = 0;
5,083✔
2120
                                }
2121
                                break;
5,083✔
2122
                        }
2123
                        else if ( a1[0] == FUNHEAD+ARGHEAD+4 && a1[ARGHEAD] == FUNHEAD+4
858✔
2124
                        && a1[*a1-1] == 3 && a1[*a1-2] == 1 && a1[*a1-3] == 1
×
2125
                        && a1[ARGHEAD+1] >= FUNCTION ) {
×
2126
                                a = t = a1+*a1; while ( *t ) NEXTARG(t);
×
2127
                                i = t - a;
×
2128
                                *a1 = -a1[ARGHEAD+1]; t = a1+1; NCOPY(t,a,i);
×
2129
                                *t = 0;
×
2130
                        }
2131
                        NEXTARG(a1);
6,799✔
2132
                }
2133
        }
2134
        if ( argfree == 0 ) {
5,083✔
2135
                argfree = argin;
2136
        }
2137
        else if ( argfree[0] == ( argfree[ARGHEAD]+ARGHEAD ) ) {
5,083✔
2138
                Normalize(BHEAD argfree+ARGHEAD);
32✔
2139
                argfree[0] = argfree[ARGHEAD]+ARGHEAD;
32✔
2140
                argfree[1] = 0;
32✔
2141
                if ( ( argfree[0] == ARGHEAD+4 ) && ( argfree[ARGHEAD+3] == 3 )
32✔
2142
                        && ( argfree[ARGHEAD+1] == 1 ) && ( argfree[ARGHEAD+2] == 1 ) ) {
32✔
2143
                        goto return0;
32✔
2144
                }
2145
        }
2146
        else {
2147
/*
2148
                The way we took out objects is rather brutish. We have to
2149
                normalize
2150
*/
2151
                NewSort(BHEAD0);
5,051✔
2152
                t = argfree+ARGHEAD;
5,051✔
2153
                while ( *t ) {
28,376✔
2154
                        tstop = t + *t;
23,325✔
2155
                        Normalize(BHEAD t);
23,325✔
2156
                        StoreTerm(BHEAD t);
23,325✔
2157
                        t = tstop;
23,325✔
2158
                }
2159
                /* par = 1, in case the arg has more than SubTermsInSmall terms */
2160
                EndSort(BHEAD argfree+ARGHEAD,1);
5,051✔
2161
                t = argfree+ARGHEAD;
5,051✔
2162
                while ( *t ) t += *t;
28,376✔
2163
                *argfree = t - argfree;
5,051✔
2164
        }
2165
/*
2166
          #] step 2 : 
2167
          #[ step 3 : look whether we have done this one already.
2168
*/
2169
        if ( ( number = FindArg(BHEAD argfree) ) != 0 ) {
5,051✔
2170
                if ( number > 0 ) t = cbuf[AT.fbufnum].rhs[number-1];
4,847✔
2171
                else              t = cbuf[AC.ffbufnum].rhs[-number-1];
×
2172
/*
2173
                Now position on the result. Remember we have in the cache:
2174
                                        inputarg,0,outputargs,0
2175
                t is currently at inputarg. *inputarg is always positive.
2176
                in principle this holds also for the arguments in the output
2177
                but we take no risks here (in case of future developments).
2178
*/
2179
                t += *t; t++;
4,847✔
2180
                tstop = t;
4,847✔
2181
                ii = 0;
4,847✔
2182
                while ( *tstop ) {
4,847✔
2183
                        if ( *tstop == -SNUMBER && tstop[1] == -1 ) {
4,865✔
2184
                                sign = -sign; ii += 2;
4✔
2185
                        }
2186
                        NEXTARG(tstop);
14,577✔
2187
                }
2188
                a = argout; while ( *a ) NEXTARG(a);
5,283✔
2189
#ifndef NEWORDER
2190
                if ( sign == -1 ) { *a++ = -SNUMBER; *a++ = -1; *a = 0; sign = 1; }
2191
#endif
2192
                i = tstop - t - ii;
4,847✔
2193
                ii = a - argout;
4,847✔
2194
                a2 = a; a1 = a + i;
4,847✔
2195
                *a1 = 0;
4,847✔
2196
                while ( ii > 0 ) { *--a1 = *--a2; ii--; }
5,719✔
2197
                a = argout;
2198
                while ( *t ) {
9,712✔
2199
                        if ( *t == -SNUMBER && t[1] == -1 ) { t += 2; }
4,865✔
2200
                        else { COPY1ARG(a,t) }
214,863✔
2201
                }
2202
                goto return0;
4,847✔
2203
        }
2204
/*
2205
          #] step 3 : 
2206
          #[ step 4 : invoke ConvertToPoly
2207

2208
                                We make a copy first in case there are no factors
2209
*/
2210
        argcopy = TermMalloc("argcopy");
204✔
2211
        for ( i = 0; i <= *argfree; i++ ) argcopy[i] = argfree[i];
23,322✔
2212

2213
        tstop = argfree + *argfree;
204✔
2214
        {
2215
                WORD sumcommu = 0;
204✔
2216
                t = argfree + ARGHEAD;
204✔
2217
                while ( t < tstop ) {
2,205✔
2218
                        sumcommu += DoesCommu(t);
2,001✔
2219
                        t += *t;
2,001✔
2220
                }
2221
                if ( sumcommu > 1 ) {
204✔
2222
                        MesPrint("ERROR: Cannot factorize an argument with more than one noncommuting object");
×
2223
                        Terminate(-1);
×
2224
                }
2225
        }
2226
        t = argfree + ARGHEAD;
204✔
2227

2228
        while ( t < tstop ) {
1,689✔
2229
                if ( ( t[1] != SYMBOL ) && ( *t != (ABS(t[*t-1])+1) ) ) {
1,489✔
2230
                        action = 1; break;
2231
                }
2232
                t += *t;
1,485✔
2233
        }
2234
        if ( action ) {
204✔
2235
                t = argfree + ARGHEAD;
4✔
2236
                argextra = AT.WorkPointer;
4✔
2237
                NewSort(BHEAD0);
4✔
2238
                while ( t < tstop ) {
520✔
2239
                        if ( LocalConvertToPoly(BHEAD t,argextra,startebuf,0) < 0 ) {
516✔
2240
                                error = -1;
×
2241
getout:
×
2242
                                AR.SortType = oldsorttype;
×
2243
                                TermFree(argcopy,"argcopy");
×
2244
                                if ( argfree != argin ) TermFree(argfree,"argfree");
×
2245
                                MesCall("ArgFactorize");
×
2246
                                Terminate(-1);
×
2247
                                return(-1);
×
2248
                        }
2249
                        StoreTerm(BHEAD argextra);
516✔
2250
                        t += *t; argextra += *argextra;
516✔
2251
                }
2252
                /* par = 1, in case the arg has more than SubTermsInSmall terms */
2253
                if ( EndSort(BHEAD argfree+ARGHEAD,1) ) { error = -2; goto getout; }
4✔
2254
                t = argfree + ARGHEAD;
2255
                while ( *t > 0 ) t += *t;
520✔
2256
                *argfree = t - argfree;
4✔
2257
        }
2258
/*
2259
          #] step 4 : 
2260
          #[ step 5 : If not in the tables, we have to do this by hard work.
2261
*/
2262

2263
        a = argout;
204✔
2264
        while ( *a ) NEXTARG(a);
418✔
2265
        if ( poly_factorize_argument(BHEAD argfree,a) < 0 ) {
204✔
2266
                MesCall("ArgFactorize");
×
2267
                error = -1;
×
2268
        }
2269
/*
2270
          #] step 5 : 
2271
          #[ step 6 : use now ConvertFromPoly
2272

2273
                        Be careful: there should be more than one argument now.
2274
*/
2275
        if ( error == 0 && action ) {
204✔
2276
                a1 = a; NEXTARG(a1);
4✔
2277
                if ( *a1 != 0 ) {
4✔
2278
                        CBUF *C = cbuf+AC.cbufnum;
4✔
2279
                        CBUF *CC = cbuf+AT.ebufnum;
4✔
2280
                        WORD *oldworkpointer = AT.WorkPointer;
4✔
2281
                        WORD *argcopy2 = TermMalloc("argcopy2"), *a1, *a2;
4✔
2282
                        a1 = a; a2 = argcopy2;
4✔
2283
                        while ( *a1 ) {
12✔
2284
                                if ( *a1 < 0 ) {
8✔
NEW
2285
                                        if ( *a1 > -FUNCTION ) *a2++ = *a1++;
×
NEW
2286
                                        *a2++ = *a1++; *a2 = 0;
×
NEW
2287
                                        continue;
×
2288
                                }
2289
                                t = a1 + ARGHEAD;
8✔
2290
                                tstop = a1 + *a1;
8✔
2291
                                argextra = AT.WorkPointer;
8✔
2292
                                NewSort(BHEAD0);
8✔
2293
                                while ( t < tstop ) {
276✔
2294
                                        if ( ConvertFromPoly(BHEAD t,argextra,numxsymbol,CC->numrhs-startebuf+numxsymbol
268✔
2295
                                        ,startebuf-numxsymbol,1) <= 0 ) {
268✔
NEW
2296
                                                TermFree(argcopy2,"argcopy2");
×
NEW
2297
                                                LowerSortLevel();
×
NEW
2298
                                                error = -3;
×
NEW
2299
                                                goto getout;
×
2300
                                        }
2301
                                        t += *t;
268✔
2302
                                        AT.WorkPointer = argextra + *argextra;
268✔
2303
/*
2304
                                        ConvertFromPoly leaves terms with subexpressions. Hence:
2305
*/
2306
                                        if ( Generator(BHEAD argextra,C->numlhs) ) {
268✔
NEW
2307
                                                TermFree(argcopy2,"argcopy2");
×
NEW
2308
                                                LowerSortLevel();
×
NEW
2309
                                                error = -4;
×
NEW
2310
                                                goto getout;
×
2311
                                        }
2312
                                }
2313
                                AT.WorkPointer = oldworkpointer;
8✔
2314
                                /* par = 1, in case the factor has more than SubTermsInSmall terms */
2315
                                if ( EndSort(BHEAD a2+ARGHEAD,1) ) { error = -5; goto getout; }
8✔
2316
                                t = a2+ARGHEAD; while ( *t ) t += *t;
276✔
2317
                                *a2 = t - a2; a2[1] = 0; ZEROARG(a2);
8✔
2318
                                ToFast(a2,a2); NEXTARG(a2);
8✔
2319
                                a1 = tstop;
2320
                        }
2321
                        i = a2 - argcopy2;
4✔
2322
                        a2 = argcopy2; a1 = a;
4✔
2323
                        NCOPY(a1,a2,i);
2,432✔
2324
                        *a1 = 0;
4✔
2325
                        TermFree(argcopy2,"argcopy2");
4✔
2326
/*
2327
                        Erase the entries we made temporarily in cbuf[AT.ebufnum]
2328
*/
2329
                        CC->numrhs = startebuf;
4✔
2330
                }
2331
                else {        /* no factorization. recover the argument from before step 3. */
NEW
2332
                        for ( i = 0; i <= *argcopy; i++ ) a[i] = argcopy[i];
×
2333
                }
2334
        }
2335
/*
2336
          #] step 6 : 
2337
          #[ step 7 : Add this one to the tables.
2338

2339
                                Possibly drop some elements in the tables
2340
                                when they become too full.
2341
*/
2342
        if ( error == 0 && AN.ncmod == 0 ) {
204✔
2343
                if ( InsertArg(BHEAD argcopy,a,0) < 0 ) { error = -1; }
204✔
2344
        }
2345
/*
2346
          #] step 7 : 
2347
          #[ step 8 : Clean up and return.
2348

2349
                Change the order of the arguments in argout and a.
2350
                Use argcopy as spare space.
2351
*/
2352
        ii = a - argout;
204✔
2353
        for ( i = 0; i < ii; i++ ) argcopy[i] = argout[i];
650✔
2354
        a1 = a;
204✔
2355
        while ( *a1 ) {
204✔
2356
                if ( *a1 == -SNUMBER && a1[1] < 0 ) {
204✔
2357
                        sign = -sign; a1[1] = -a1[1];
8✔
2358
                        if ( a1[1] == 1 ) {
8✔
2359
                                a2 = a1+2; while ( *a2 ) NEXTARG(a2);
32✔
2360
                                i = a2-a1-2; a2 = a1+2;
8✔
2361
                                NCOPY(a1,a2,i);
440✔
2362
                                *a1 = 0;
8✔
2363
                        }
2364
                        while ( *a1 ) NEXTARG(a1);
8✔
2365
                        break;
2366
                }
2367
                else {
2368
                        if ( *a1 > 0 && *a1 == a1[ARGHEAD]+ARGHEAD && a1[*a1-1] < 0 ) {
196✔
2369
                                a1[*a1-1] = -a1[*a1-1]; sign = -sign;
×
2370
                        }
2371
                        if ( *a1 == ARGHEAD+4 && a1[ARGHEAD+1] == 1 && a1[ARGHEAD+2] == 1 ) {
196✔
2372
                                a2 = a1+ARGHEAD+4; while ( *a2 ) NEXTARG(a2);
×
2373
                                i = a2-a1-ARGHEAD-4; a2 = a1+ARGHEAD+4;
×
2374
                                NCOPY(a1,a2,i);
×
2375
                                *a1 = 0;
×
2376
                                break;
×
2377
                        }
2378
                        while ( *a1 ) NEXTARG(a1);
415✔
2379
                        break;
2380
                }
2381
                NEXTARG(a1);
204✔
2382
        }
2383
        i = a1 - a;
204✔
2384
        a2 = argout;
204✔
2385
        NCOPY(a2,a,i);
11,462✔
2386
        for ( i = 0; i < ii; i++ ) *a2++ = argcopy[i];
650✔
2387
#ifndef NEWORDER
2388
        if ( sign == -1 ) { *a2++ = -SNUMBER; *a2++ = -1; sign = 1; }
2389
#endif
2390
        *a2 = 0;
204✔
2391
        TermFree(argcopy,"argcopy");
204✔
2392
return0:
5,083✔
2393
        if ( argfree != argin ) TermFree(argfree,"argfree");
5,083✔
2394
        if ( oldsorttype != AR.SortType ) {
5,083✔
2395
                AR.SortType = oldsorttype;
19✔
2396
                a = argout;
19✔
2397
                while ( *a ) {
19✔
2398
                        if ( *a > 0 ) {
226✔
2399
                                NewSort(BHEAD0);
59✔
2400
                                oldword = a[*a]; a[*a] = 0;
59✔
2401
                                t = a+ARGHEAD;
59✔
2402
                                while ( *t ) {
579✔
2403
                                        tstop = t + *t;
520✔
2404
                                        StoreTerm(BHEAD t);
520✔
2405
                                        t = tstop;
520✔
2406
                                }
2407
                                /* par = 1, in case the factor has more than SubTermsInSmall terms */
2408
                                EndSort(BHEAD a+ARGHEAD,1);
59✔
2409
                                a[*a] = oldword;
59✔
2410
                                a += *a;
59✔
2411
                        }
2412
                        else { NEXTARG(a); }
412✔
2413
                }
2414
        }
2415
#ifdef NEWORDER
2416
        t = argout; numargs = 0;
2417
        while ( *t ) {
11,045✔
2418
                tt = t;
5,962✔
2419
                NEXTARG(t);
5,962✔
2420
                if ( *tt == ABS(t[-1])+1+ARGHEAD && sign == -1 ) { t[-1] = -t[-1]; sign = 1; }
5,962✔
2421
                else if ( *tt == -SNUMBER && sign == -1 ) { tt[1] = -tt[1]; sign = 1; }
5,959✔
2422
                numargs++;
5,962✔
2423
        }
2424
        if ( sign == -1 ) {
5,083✔
2425
                *t++ = -SNUMBER; *t++ = -1; *t = 0; sign = 1; numargs++;
4✔
2426
        }
2427
#else
2428
/*
2429
        Now we have to sort the arguments
2430
        First have the number of 'nontrivial/nonnumerical' arguments
2431
        Then make a piece of code like in FullSymmetrize with that number
2432
        of arguments to be symmetrized.
2433
        Put a function in front
2434
        Call the Symmetrize routine
2435
*/
2436
        t = argout; numargs = 0;
2437
        while ( *t && *t != -SNUMBER && ( *t < 0 || ( ABS(t[*t-1]) != *t-1 ) ) ) {
2438
                NEXTARG(t);
2439
                numargs++;
2440
        }
2441
#endif
2442
        if ( numargs > 1 ) {
5,083✔
2443
                WORD *Lijst;
387✔
2444
                WORD x[3];
387✔
2445
                x[0] = argout[-FUNHEAD];
387✔
2446
                x[1] = argout[-FUNHEAD+1];
387✔
2447
                x[2] = argout[-FUNHEAD+2];
387✔
2448
                while ( *t ) { NEXTARG(t); }
387✔
2449
                argout[-FUNHEAD] = SQRTFUNCTION;
387✔
2450
                argout[-FUNHEAD+1] = t-argout+FUNHEAD;
387✔
2451
                argout[-FUNHEAD+2] = 0;
387✔
2452
                AT.WorkPointer = t+1;
387✔
2453
                Lijst = AT.WorkPointer;
387✔
2454
                for ( i = 0; i < numargs; i++ ) Lijst[i] = i;
1,657✔
2455
                AT.WorkPointer += numargs;
387✔
2456
                error = Symmetrize(BHEAD argout-FUNHEAD,Lijst,numargs,1,SYMMETRIC);
387✔
2457
                AT.WorkPointer = Lijst;
387✔
2458
                argout[-FUNHEAD] = x[0];
387✔
2459
                argout[-FUNHEAD+1] = x[1];
387✔
2460
                argout[-FUNHEAD+2] = x[2];
387✔
2461
#ifdef NEWORDER
2462
/*
2463
                Now we have to get a potential numerical argument to the first position
2464
*/
2465
                tstop = argout; while ( *tstop ) { NEXTARG(tstop); }
1,657✔
2466
                t = argout; number = 0;
2467
                while ( *t ) {
1,594✔
2468
                        tt = t; NEXTARG(t);
1,222✔
2469
                        if ( *tt == -SNUMBER ) {
1,222✔
2470
                                if ( number == 0 ) break;
12✔
2471
                                x[0] = tt[1];
×
2472
                                while ( tt > argout ) { *--t = *--tt; }
×
2473
                                argout[0] = -SNUMBER; argout[1] = x[0];
×
2474
                                break;
×
2475
                        }
2476
                        else if ( *tt == ABS(t[-1])+1+ARGHEAD ) {
1,210✔
2477
                                if ( number == 0 ) break;
3✔
2478
                                ii = t - tt;
3✔
2479
                                for ( i = 0; i < ii; i++ ) tstop[i] = tt[i];
27✔
2480
                                while ( tt > argout ) { *--t = *--tt; }
321✔
2481
                                for ( i = 0; i < ii; i++ ) argout[i] = tstop[i];
27✔
2482
                                *tstop = 0;
3✔
2483
                                break;
3✔
2484
                        }
2485
                        number++;
1,207✔
2486
                }
2487
#endif
2488
        }
2489
/*
2490
          #] step 8 : 
2491
*/
2492
        return(error);
2493
}
2494

2495
/*
2496
          #] ArgFactorize : 
2497
          #[ FindArg :
2498
*/
2499
/**
2500
 *        Looks the argument up in the (workers) table.
2501
 *        If it is found the number in the table is returned (plus one to make it positive).
2502
 *        If it is not found we look in the compiler provided table.
2503
 *        If it is found - the number in the table is returned (minus one to make it negative).
2504
 *        If in neither table we return zero.
2505
 */
2506

2507
WORD FindArg(PHEAD WORD *a)
5,051✔
2508
{
2509
        int number;
5,051✔
2510
        if ( AN.ncmod != 0 ) return(0);        /* no room for mod stuff */
5,051✔
2511
        number = FindTree(AT.fbufnum,a);
5,051✔
2512
        if ( number >= 0 ) return(number+1);
5,051✔
2513
        number = FindTree(AC.ffbufnum,a);
204✔
2514
        if ( number >= 0 ) return(-number-1);
204✔
2515
        return(0);
2516
}
2517

2518
/*
2519
          #] FindArg : 
2520
          #[ InsertArg :
2521
*/
2522
/**
2523
 *        Inserts the argument into the (workers) table.
2524
 *        If the table is too full we eliminate half of it.
2525
 *        The eliminated elements are the ones that have not been used
2526
 *        most recently, weighted by their total use and age(?).
2527
 *        If par == 0 it inserts in the regular factorization cache
2528
 *        If par == 1 it inserts in the cache defined with the FactorCache statement
2529
 */
2530

2531
WORD InsertArg(PHEAD WORD *argin, WORD *argout,int par)
204✔
2532
{
2533
        CBUF *C;
204✔
2534
        WORD *a, i, bufnum;
204✔
2535
        if ( par == 0 ) {
204✔
2536
                bufnum = AT.fbufnum;
204✔
2537
                C = cbuf+bufnum;
204✔
2538
                if ( C->numrhs >= (C->maxrhs-2) ) CleanupArgCache(BHEAD AT.fbufnum);
204✔
2539
        }
2540
        else if ( par == 1 ) {
×
2541
                bufnum = AC.ffbufnum;
×
2542
                C = cbuf+bufnum;
×
2543
        }
2544
        else { return(-1); }
2545
        AddRHS(bufnum,1);
204✔
2546
        AddNtoC(bufnum,*argin,argin,1);
204✔
2547
        AddToCB(C,0)
204✔
2548
        a = argout; while ( *a ) NEXTARG(a);
455✔
2549
        i = a - argout;
204✔
2550
        AddNtoC(bufnum,i,argout,2);
204✔
2551
        AddToCB(C,0)
204✔
2552
        return(InsTree(bufnum,C->numrhs));
204✔
2553
}
2554

2555
/*
2556
          #] InsertArg : 
2557
          #[ CleanupArgCache :
2558
*/
2559
/**
2560
 *        Cleans up the argument factorization cache.
2561
 *        We throw half the elements.
2562
 *        For a weight of what we want to keep we use the product of
2563
 *        usage and the number in the buffer.
2564
 */
2565

2566
int CleanupArgCache(PHEAD WORD bufnum)
×
2567
{
2568
        CBUF *C = cbuf + bufnum;
×
2569
        COMPTREE *boomlijst = C->boomlijst;
×
2570
        LONG *weights = (LONG *)Malloc1(2*(C->numrhs+1)*sizeof(LONG),"CleanupArgCache");
×
2571
        LONG w, whalf, *extraweights;
×
2572
        WORD *a, *to, *from;
×
2573
        int i,j,k;
×
2574
        for ( i = 1; i <= C->numrhs; i++ ) {
×
2575
                weights[i] = ((LONG)i) * (boomlijst[i].usage);
×
2576
        }
2577
/*
2578
                Now sort the weights and determine the halfway weight
2579
*/
2580
        extraweights = weights+C->numrhs+1;
×
2581
        SortWeights(weights+1,extraweights,C->numrhs);
×
2582
        whalf = weights[C->numrhs/2+1];
×
2583
/*
2584
                We should drop everybody with a weight < whalf.
2585
*/
2586
        to = C->Buffer;
×
2587
        k = 1;
×
2588
        for ( i = 1; i <= C->numrhs; i++ ) {
×
2589
                from = C->rhs[i]; w = ((LONG)i) * (boomlijst[i].usage);
×
2590
                if ( w >= whalf ) {
×
2591
                        if ( i < C->numrhs-1 ) {
×
2592
                                if ( to == from ) {
×
2593
                                        to = C->rhs[i+1];
×
2594
                                }
2595
                                else {
2596
                                        j = C->rhs[i+1] - from;
×
2597
                                        C->rhs[k] = to;
×
2598
                                        NCOPY(to,from,j)
×
2599
                                }
2600
                        }
2601
                        else if ( to == from ) {
×
2602
                                to += *to + 1; while ( *to ) NEXTARG(to); to++;
×
2603
                        }
2604
                        else {
2605
                                a = from; a += *a+1; while ( *a ) NEXTARG(a); a++;
×
2606
                                j = a - from;
×
2607
                                C->rhs[k] = to;
×
2608
                                NCOPY(to,from,j)
×
2609
                        }
2610
                        weights[k++] = boomlijst[i].usage;
×
2611
                }
2612
        }
2613
        C->numrhs = --k;
×
2614
        C->Pointer = to;
×
2615
/*
2616
                Next we need to rebuild the tree.
2617
                Note that this can probably be done much faster by using the
2618
                remains of the old tree !!!!!!!!!!!!!!!!
2619
*/
2620
        ClearTree(AT.fbufnum);
×
2621
        for ( i = 1; i <= k; i++ ) {
×
2622
                InsTree(AT.fbufnum,i);
×
2623
                boomlijst[i].usage = weights[i];
×
2624
        }
2625
/*
2626
                And cleanup
2627
*/
2628
        M_free(weights,"CleanupArgCache");
×
2629
        return(0);
×
2630
}
2631

2632
/*
2633
          #] CleanupArgCache : 
2634
          #[ ArgSymbolMerge :
2635
*/
2636

2637
int ArgSymbolMerge(WORD *t1, WORD *t2)
18,274✔
2638
{
2639
        WORD *t1e = t1+t1[1];
18,274✔
2640
        WORD *t2e = t2+t2[1];
18,274✔
2641
        WORD *t1a = t1+2;
18,274✔
2642
        WORD *t2a = t2+2;
18,274✔
2643
        WORD *t3;
18,274✔
2644
        while ( t1a < t1e && t2a < t2e ) {
44,661✔
2645
                if ( *t1a < *t2a ) {
26,387✔
2646
                        if ( t1a[1] >= 0 ) {
4,443✔
2647
                                t3 = t1a+2;
4,443✔
2648
                                while ( t3 < t1e ) { t3[-2] = *t3; t3[-1] = t3[1]; t3 += 2; }
4,836✔
2649
                                t1e -= 2;
4,443✔
2650
                        }
2651
                        else t1a += 2;
×
2652
                }
2653
                else if ( *t1a > *t2a ) {
21,944✔
2654
                        if ( t2a[1] >= 0 ) t2a += 2;
4,861✔
2655
                        else {
2656
                                t3 = t1e;
2657
                                while ( t3 > t1a ) { *t3 = t3[-2]; t3[1] = t3[-1]; t3 -= 2; }
×
2658
                                *t1a++ = *t2a++;
×
2659
                                *t1a++ = *t2a++;
×
2660
                                t1e += 2;
×
2661
                        }
2662
                }
2663
                else {
2664
                        if ( t2a[1] < t1a[1] ) t1a[1] = t2a[1];
17,083✔
2665
                        t1a += 2; t2a += 2;
17,083✔
2666
                }
2667
        }
2668
        while ( t2a < t2e ) {
30,318✔
2669
                if ( t2a[1] < 0 ) {
12,044✔
2670
                        *t1a++ = *t2a++;
×
2671
                        *t1a++ = *t2a++;
×
2672
                }
2673
                else t2a += 2;
12,044✔
2674
        }
2675
        while ( t1a < t1e ) {
23,198✔
2676
                if ( t1a[1] >= 0 ) {
4,924✔
2677
                        t3 = t1a+2;
4,924✔
2678
                        while ( t3 < t1e ) { t3[-2] = *t3; t3[-1] = t3[1]; t3 += 2; }
4,924✔
2679
                        t1e -= 2;
4,924✔
2680
                }
2681
                else t1a += 2;
×
2682
        }
2683
        t1[1] = t1a - t1;
18,274✔
2684
        return(0);
18,274✔
2685
}
2686

2687
/*
2688
          #] ArgSymbolMerge : 
2689
          #[ ArgDotproductMerge :
2690
*/
2691

2692
int ArgDotproductMerge(WORD *t1, WORD *t2)
18,274✔
2693
{
2694
        WORD *t1e = t1+t1[1];
18,274✔
2695
        WORD *t2e = t2+t2[1];
18,274✔
2696
        WORD *t1a = t1+2;
18,274✔
2697
        WORD *t2a = t2+2;
18,274✔
2698
        WORD *t3;
18,274✔
2699
        while ( t1a < t1e && t2a < t2e ) {
18,274✔
2700
                if ( *t1a < *t2a || ( *t1a == *t2a && t1a[1] < t2a[1] ) ) {
×
2701
                        if ( t1a[2] >= 0 ) {
×
2702
                                t3 = t1a+3;
×
2703
                                while ( t3 < t1e ) { t3[-3] = *t3; t3[-2] = t3[1]; t3[-1] = t3[2]; t3 += 3; }
×
2704
                                t1e -= 3;
×
2705
                        }
2706
                        else t1a += 3;
×
2707
                }
2708
                else if ( *t1a > *t2a || ( *t1a == *t2a && t1a[1] > t2a[1] ) ) {
×
2709
                        if ( t2a[2] >= 0 ) t2a += 3;
×
2710
                        else {
2711
                                t3 = t1e;
2712
                                while ( t3 > t1a ) { *t3 = t3[-3]; t3[1] = t3[-2]; t3[2] = t3[-1]; t3 -= 3; }
×
2713
                                *t1a++ = *t2a++;
×
2714
                                *t1a++ = *t2a++;
×
2715
                                *t1a++ = *t2a++;
×
2716
                                t1e += 3;
×
2717
                        }
2718
                }
2719
                else {
2720
                        if ( t2a[2] < t1a[2] ) t1a[2] = t2a[2];
×
2721
                        t1a += 3; t2a += 3;
×
2722
                }
2723
        }
2724
        while ( t2a < t2e ) {
18,274✔
2725
                if ( t2a[2] < 0 ) {
×
2726
                        *t1a++ = *t2a++;
×
2727
                        *t1a++ = *t2a++;
×
2728
                        *t1a++ = *t2a++;
×
2729
                }
2730
                else t2a += 3;
×
2731
        }
2732
        while ( t1a < t1e ) {
18,274✔
2733
                if ( t1a[2] >= 0 ) {
×
2734
                        t3 = t1a+3;
×
2735
                        while ( t3 < t1e ) { t3[-3] = *t3; t3[-2] = t3[1]; t3[-1] = t3[2]; t3 += 3; }
×
2736
                        t1e -= 3;
×
2737
                }
2738
                else t1a += 2;
×
2739
        }
2740
        t1[1] = t1a - t1;
18,274✔
2741
        return(0);
18,274✔
2742
}
2743

2744
/*
2745
          #] ArgDotproductMerge : 
2746
          #[ TakeArgContent :
2747
*/
2748
/**
2749
 *        Implements part of the old ExecArg in which we take common factors
2750
 *        from arguments with more than one term.
2751
 *        The common pieces are put in argout as a sequence of arguments.
2752
 *        The part with the multiple terms that are now relative prime is
2753
 *        put in argfree which is allocated via TermMalloc and is given as the
2754
 *        return value.
2755
 *        The difference with the old code is that negative powers are always
2756
 *        removed. Hence it is as in MakeInteger in which only numerators will
2757
 *        be left: now only zero or positive powers will be remaining.
2758
 */
2759

2760
WORD *TakeArgContent(PHEAD WORD *argin, WORD *argout)
5,083✔
2761
{
2762
        GETBIDENTITY
2763
        WORD *t, *rnext, *r1, *r2, *r3, *r5, *r6, *r7, *r8, *r9;
5,083✔
2764
        WORD pow, *mm, *mnext, *mstop, *argin2 = argin, *argin3 = argin, *argfree;
5,083✔
2765
        WORD ncom;
5,083✔
2766
        int j, i, act;
5,083✔
2767
        r5 = t = argin + ARGHEAD;
5,083✔
2768
        r3 = argin + *argin;
5,083✔
2769
        rnext = t + *t;
5,083✔
2770
        GETSTOP(t,r6);
5,083✔
2771
        r1 = argout;
5,083✔
2772
        t++;
5,083✔
2773
/*
2774
                First pass: arrange everything but the symbols and dotproducts.
2775
                They need separate treatment because we have to take out negative
2776
                powers.
2777
*/
2778
        while ( t < r6 ) {
10,170✔
2779
/*
2780
                        #[ DELTA/VECTOR :
2781
*/
2782
                if ( *t == DELTA || *t == VECTOR ) {
5,087✔
2783
                        r7 = t; r8 = t + t[1]; t += 2;
×
2784
                        while ( t < r8 ) {
×
2785
                                mm = rnext;
2786
                                pow = 1;
2787
                                while ( mm < r3 ) {
×
2788
                                        mnext = mm + *mm;
×
2789
                                        GETSTOP(mm,mstop); mm++;
×
2790
                                        while ( mm < mstop ) {
×
2791
                                                if ( *mm != *r7 ) mm += mm[1];
×
2792
                                                else break;
2793
                                        }
2794
                                        if ( *mm == *r7 ) {
×
2795
                                                mstop = mm + mm[1]; mm += 2;
×
2796
                                                while ( ( *mm != *t || mm[1] != t[1] )
×
2797
                                                        && mm < mstop ) mm += 2;
×
2798
                                                if ( mm >= mstop ) pow = 0;
×
2799
                                        }
2800
                                        else pow = 0;
2801
                                        if ( pow == 0 ) break;
×
2802
                                        mm = mnext;
2803
                                }
2804
                                if ( pow == 0 ) { t += 2; continue; }
×
2805
/*
2806
                                We have a factor
2807
*/
2808
                                *r1++ = 8 + ARGHEAD;
×
2809
                                for ( j = 1; j < ARGHEAD; j++ ) *r1++ = 0;
×
2810
                                *r1++ = 8; *r1++ = *r7;
×
2811
                                *r1++ = 4; *r1++ = *t; *r1++ = t[1];
×
2812
                                *r1++ = 1; *r1++ = 1; *r1++ = 3;
×
2813
                                argout = r1;
×
2814
/*
2815
                                Now we have to remove the delta's/vectors
2816
*/
2817
                                mm = rnext;
×
2818
                                while ( mm < r3 ) {
×
2819
                                        mnext = mm + *mm;
×
2820
                                        GETSTOP(mm,mstop); mm++;
×
2821
                                        while ( mm < mstop ) {
×
2822
                                                if ( *mm != *r7 ) mm += mm[1];
×
2823
                                                else break;
2824
                                        }
2825
                                        mstop = mm + mm[1]; mm += 2;
×
2826
                                        while ( mm < mstop && (
×
2827
                                         *mm != *t || mm[1] != t[1] ) ) mm += 2;
×
2828
                                        *mm = mm[1] = NOINDEX;
×
2829
                                        mm = mnext;
×
2830
                                }
2831
                                *t = t[1] = NOINDEX;
×
2832
                                t += 2;
×
2833
                        }
2834
                }
2835
/*
2836
                        #] DELTA/VECTOR : 
2837
                        #[ INDEX :
2838
*/
2839
                else if ( *t == INDEX ) {
5,087✔
2840
                        r7 = t; r8 = t + t[1]; t += 2;
×
2841
                        while ( t < r8 ) {
×
2842
                                mm = rnext;
2843
                                pow = 1;
2844
                                while ( mm < r3 ) {
×
2845
                                        mnext = mm + *mm;
×
2846
                                        GETSTOP(mm,mstop); mm++;
×
2847
                                        while ( mm < mstop ) {
×
2848
                                                if ( *mm != *r7 ) mm += mm[1];
×
2849
                                                else break;
2850
                                        }
2851
                                        if ( *mm == *r7 ) {
×
2852
                                                mstop = mm + mm[1]; mm += 2;
×
2853
                                                while ( *mm != *t 
×
2854
                                                        && mm < mstop ) mm++;
×
2855
                                                if ( mm >= mstop ) pow = 0;
×
2856
                                        }
2857
                                        else pow = 0;
2858
                                        if ( pow == 0 ) break;
×
2859
                                        mm = mnext;
2860
                                }
2861
                                if ( pow == 0 ) { t++; continue; }
×
2862
/*
2863
                                We have a factor
2864
*/
2865
                                if ( *t < 0 ) { *r1++ = -VECTOR; }
×
2866
                                else          { *r1++ = -INDEX; }
×
2867
                                *r1++ = *t;
×
2868
                                argout = r1;
×
2869
/*
2870
                                Now we have to remove the index
2871
*/
2872
                                *t = NOINDEX;
×
2873
                                mm = rnext;
×
2874
                                while ( mm < r3 ) {
×
2875
                                        mnext = mm + *mm;
×
2876
                                        GETSTOP(mm,mstop); mm++;
×
2877
                                        while ( mm < mstop ) {
×
2878
                                                if ( *mm != *r7 ) mm += mm[1];
×
2879
                                                else break;
2880
                                        }
2881
                                        mstop = mm + mm[1]; mm += 2;
×
2882
                                        while ( mm < mstop && 
×
2883
                                         *mm != *t ) mm += 1;
×
2884
                                        *mm = NOINDEX;
×
2885
                                        mm = mnext;
×
2886
                                }
2887
                                t += 1;
×
2888
                        }
2889
                }
2890
/*
2891
                        #] INDEX : 
2892
                        #[ FUNCTION :
2893
*/
2894
                else if ( *t >= FUNCTION ) {
5,087✔
2895
/*
2896
                        In the next code we should actually look inside
2897
                        the DENOMINATOR or EXPONENT for noncommuting objects
2898
*/
2899
                        if ( *t >= FUNCTION &&
8✔
2900
                                functions[*t-FUNCTION].commute == 0 ) ncom = 0;
8✔
2901
                        else ncom = 1;
2902
                        if ( ncom ) {
2903
                                mm = r5 + 1;
2904
                                while ( mm < t && ( *mm == DUMMYFUN
×
2905
                                || *mm == DUMMYTEN ) ) mm += mm[1];
×
2906
                                if ( mm < t ) { t += t[1]; continue; }
×
2907
                        }
2908
                        mm = rnext; pow = 1;
2909
                        while ( mm < r3 ) {
520✔
2910
                                mnext = mm + *mm;
520✔
2911
                                GETSTOP(mm,mstop); mm++;
520✔
2912
                                while ( mm < mstop ) {
536✔
2913
                                        if ( *mm == *t && mm[1] == t[1] ) {
528✔
2914
                                                for ( i = 2; i < t[1]; i++ ) {
2,096✔
2915
                                                        if ( mm[i] != t[i] ) break;
1,584✔
2916
                                                }
2917
                                                if ( i >= t[1] )
528✔
2918
                                                        { mm += mm[1]; goto nextmterm; }
512✔
2919
                                        }
2920
                                        if ( ncom && *mm != DUMMYFUN && *mm != DUMMYTEN )
16✔
2921
                                                { pow = 0; break; }
2922
                                        mm += mm[1];
16✔
2923
                                }
2924
                                if ( mm >= mstop ) pow = 0;
8✔
2925
                                if ( pow == 0 ) break;
×
2926
nextmterm:                mm = mnext;
×
2927
                        }
2928
                        if ( pow == 0 ) { t += t[1]; continue; }
8✔
2929
/*
2930
                        Copy the function
2931
*/
2932
                        *r1++ = t[1] + 4 + ARGHEAD;
×
2933
                        for ( i = 1; i < ARGHEAD; i++ ) *r1++ = 0;
×
2934
                        *r1++ = t[1] + 4;
×
2935
                        for ( i = 0; i < t[1]; i++ ) *r1++ = t[i];
×
2936
                        *r1++ = 1; *r1++ = 1; *r1++ = 3;
×
2937
                        argout = r1;
×
2938
/*
2939
                        Now we have to take out the functions
2940
*/
2941
                        mm = rnext;
×
2942
                        while ( mm < r3 ) {
×
2943
                                mnext = mm + *mm;
×
2944
                                GETSTOP(mm,mstop); mm++;
×
2945
                                while ( mm < mstop ) {
×
2946
                                        if ( *mm == *t && mm[1] == t[1] ) {
×
2947
                                                for ( i = 2; i < t[1]; i++ ) {
×
2948
                                                        if ( mm[i] != t[i] ) break;
×
2949
                                                }
2950
                                                if ( i >= t[1] ) {
×
2951
                                                        if ( functions[*t-FUNCTION].spec > 0 )
×
2952
                                                                *mm = DUMMYTEN;
×
2953
                                                        else
2954
                                                                *mm = DUMMYFUN;
×
2955
                                                        mm += mm[1];
×
2956
                                                        goto nextterm;
×
2957
                                                }
2958
                                        }
2959
                                        mm += mm[1];
×
2960
                                }
2961
nextterm:                                                mm = mnext;
×
2962
                        }
2963
                        if ( functions[*t-FUNCTION].spec > 0 )
×
2964
                                        *t = DUMMYTEN;
×
2965
                        else
2966
                                        *t = DUMMYFUN;
×
2967
                        t += t[1];
×
2968
                }
2969
/*
2970
                        #] FUNCTION : 
2971
*/
2972
                else {
2973
                        t += t[1];
5,079✔
2974
                }
2975
        }
2976
/*
2977
                        #[ SYMBOL :
2978

2979
                Now collect all symbols. We can use the space after r1 as storage
2980
*/
2981
        t = argin+ARGHEAD;
5,083✔
2982
        rnext = t + *t;
5,083✔
2983
        r2 = r1;
5,083✔
2984
        while ( t < r3 ) {
28,440✔
2985
                GETSTOP(t,r6);
23,357✔
2986
                t++;
23,357✔
2987
                act = 0;
23,357✔
2988
                while ( t < r6 ) {
46,930✔
2989
                        if ( *t == SYMBOL ) {
23,573✔
2990
                                act = 1;
22,541✔
2991
                                i = t[1];
22,541✔
2992
                                NCOPY(r2,t,i)
155,079✔
2993
                        }
2994
                        else { t += t[1]; }
1,032✔
2995
                }
2996
                if ( act == 0 ) {
23,357✔
2997
                        *r2++ = SYMBOL; *r2++ = 2;
816✔
2998
                }
2999
                t = rnext; rnext = rnext + *rnext;
23,357✔
3000
        }
3001
        *r2 = 0;
5,083✔
3002
        argin2 = argin;
5,083✔
3003
/*
3004
                Now we have a list of all symbols as a sequence of SYMBOL subterms.
3005
                Any symbol that is absent in a subterm has power zero.
3006
                We now need a list of all minimum powers.
3007
                This can be done by subsequent merges.
3008
*/
3009
        r7 = r1;          /* The first object into which we merge. */        
5,083✔
3010
        r8 = r7 + r7[1];  /* The object that gets merged into r7.  */
5,083✔
3011
        while ( *r8 ) {
23,357✔
3012
                r2 = r8 + r8[1]; /* Next object */
18,274✔
3013
                ArgSymbolMerge(r7,r8);
18,274✔
3014
                r8 = r2;
18,274✔
3015
        }
3016
/*
3017
                Now we have to divide by the object in r7 and take it apart as factors.
3018
                The division can be simple if there are no negative powers.
3019
*/
3020
        if ( r7[1] > 2 ) {
5,083✔
3021
                r8 = r7+2;
355✔
3022
                r2 = r7 + r7[1];
355✔
3023
                act = 0;
355✔
3024
                pow = 0;
355✔
3025
                while ( r8 < r2 ) {
728✔
3026
                        if ( r8[1] < 0 ) { act = 1; pow += -r8[1]*(ARGHEAD+8); }
373✔
3027
                        else { pow += 2*r8[1]; }
373✔
3028
                        r8 += 2;
373✔
3029
                }
3030
/*
3031
                The amount of space we need to move r7 is given in pow
3032
*/
3033
                if ( act == 0 ) {        /* this can be done 'in situ' */
355✔
3034
                        t = argin + ARGHEAD;
3035
                        while ( t < r3 ) {
2,656✔
3036
                                rnext = t + *t;
2,301✔
3037
                                GETSTOP(t,r6);
2,301✔
3038
                                t++;
2,301✔
3039
                                while ( t < r6 ) {
4,602✔
3040
                                        if ( *t != SYMBOL ) { t += t[1]; continue; }
2,301✔
3041
                                        r8 = r7+2; r9 = t + t[1]; t += 2;
2,301✔
3042
                                        while ( ( t < r9 ) && ( r8 < r2 ) ) {
9,549✔
3043
                                                if ( *t == *r8 ) {
7,248✔
3044
                                                        t[1] -= r8[1]; t += 2; r8 += 2;
6,891✔
3045
                                                }
3046
                                                else { /* *t must be < than *r8 !!! */
3047
                                                        t += 2;
357✔
3048
                                                }
3049
                                        }
3050
                                        t = r9;
3051
                                }
3052
                                t = rnext;
3053
                        }
3054
/*
3055
                        And now the factors that go to argout.
3056
                        First we have to move r7 out of the way.
3057
*/
3058
                        r8 = r7+pow; i = r7[1];
355✔
3059
                        while ( --i >= 0 ) r8[i] = r7[i];
1,811✔
3060
                        r2 += pow;
355✔
3061
                        r8 += 2;
355✔
3062
                        while ( r8 < r2 ) {
728✔
3063
                                for ( i = 0; i < r8[1]; i++ ) { *r1++ = -SYMBOL; *r1++ = *r8; }
1,220✔
3064
                                r8 += 2;
373✔
3065
                        }
3066
                }
3067
                else {        /* this needs a new location */
3068
                        argin2 = TermMalloc("TakeArgContent2");
×
3069
/*
3070
                        We have to multiply the inverse of r7 into argin
3071
                        The answer should go to argin2.
3072
*/
3073
                        r5 = argin2; *r5++ = 0; *r5++ = 0; FILLARG(r5);
×
3074
                        t = argin+ARGHEAD;
×
3075
                        while ( t < r3 ) {
×
3076
                                rnext = t + *t;
×
3077
                                GETSTOP(t,r6);
×
3078
                                r9 = r5;
×
3079
                                *r5++ = *t++ + r7[1];
×
3080
                                while ( t < r6 ) *r5++ = *t++;
×
3081
                                i = r7[1] - 2; r8 = r7+2;
×
3082
                                *r5++ = r7[0]; *r5++ = r7[1];
×
3083
                                while ( i > 0 ) { *r5++ = *r8++; *r5++ = -*r8++; i -= 2; }
×
3084
                                while ( t < rnext ) *r5++ = *t++;
×
3085
                                Normalize(BHEAD r9);
×
3086
                                r5 = r9 + *r9;
×
3087
                        }
3088
                        *r5 = 0;
×
3089
                        *argin2 = r5-argin2;
×
3090
/*
3091
                        We may have to sort the terms in argin2.
3092
*/
3093
                        NewSort(BHEAD0);
×
3094
                        t = argin2+ARGHEAD;
×
3095
                        while ( *t ) {
×
3096
                                StoreTerm(BHEAD t);
×
3097
                                t += *t;
×
3098
                        }
3099
                        t = argin2+ARGHEAD;
×
3100
                        if ( EndSort(BHEAD t,0) < 0 ) goto Irreg;
×
3101
                        while ( *t ) t += *t;
×
3102
                        *argin2 = t - argin2;
×
3103
                        r3 = t;
×
3104
/*
3105
                        And now the factors that go to argout.
3106
                        First we have to move r7 out of the way.
3107
*/
3108
                        r8 = r7+pow; i = r7[1];
×
3109
                        while ( --i >= 0 ) r8[i] = r7[i];
×
3110
                        r2 += pow;
×
3111
                        r8 += 2;
×
3112
                        while ( r8 < r2 ) {
×
3113
                                if ( r8[1] >= 0 ) {
×
3114
                                        for ( i = 0; i < r8[1]; i++ ) { *r1++ = -SYMBOL; *r1++ = *r8; }
×
3115
                                }
3116
                                else {
3117
                                        for ( i = 0; i < -r8[1]; i++ ) {
×
3118
                                                *r1++ = ARGHEAD+8; *r1++ = 0;
×
3119
                                                FILLARG(r1);
×
3120
                                                *r1++ = 8; *r1++ = SYMBOL; *r1++ = 4; *r1++ = *r8;
×
3121
                                                *r1++ = -1; *r1++ = 1; *r1++ = 1; *r1++ = 3;
×
3122
                                        }
3123
                                }
3124
                                r8 += 2;
×
3125
                        }
3126
                        argout = r1;
5,083✔
3127
                }
3128
        }
3129
/*
3130
                        #] SYMBOL : 
3131
                        #[ DOTPRODUCT :
3132

3133
                Now collect all dotproducts. We can use the space after r1 as storage
3134
*/
3135
          t = argin2+ARGHEAD;
5,083✔
3136
          rnext = t + *t;
5,083✔
3137
          r2 = r1;
5,083✔
3138
          while ( t < r3 ) {
28,440✔
3139
                GETSTOP(t,r6);
23,357✔
3140
                t++;
23,357✔
3141
                act = 0;
23,357✔
3142
                while ( t < r6 ) {
46,930✔
3143
                        if ( *t == DOTPRODUCT ) {
23,573✔
3144
                                act = 1;
×
3145
                                i = t[1];
×
3146
                                NCOPY(r2,t,i)
×
3147
                        }
3148
                        else { t += t[1]; }
23,573✔
3149
                }
3150
                if ( act == 0 ) {
23,357✔
3151
                        *r2++ = DOTPRODUCT; *r2++ = 2;
23,357✔
3152
                }
3153
                t = rnext; rnext = rnext + *rnext;
23,357✔
3154
          }
3155
          *r2 = 0;
5,083✔
3156
          argin3 = argin2;
5,083✔
3157
/*
3158
                Now we have a list of all dotproducts as a sequence of DOTPRODUCT
3159
                subterms. Any dotproduct that is absent in a subterm has power zero.
3160
                We now need a list of all minimum powers.
3161
                This can be done by subsequent merges.
3162
*/
3163
          r7 = r1;          /* The first object into which we merge. */        
5,083✔
3164
          r8 = r7 + r7[1];  /* The object that gets merged into r7.  */
5,083✔
3165
          while ( *r8 ) {
23,357✔
3166
                r2 = r8 + r8[1]; /* Next object */
18,274✔
3167
                ArgDotproductMerge(r7,r8);
18,274✔
3168
                r8 = r2;
18,274✔
3169
          }
3170
/*
3171
                Now we have to divide by the object in r7 and take it apart as factors.
3172
                The division can be simple if there are no negative powers.
3173
*/
3174
          if ( r7[1] > 2 ) {
5,083✔
3175
                r8 = r7+2;
×
3176
                r2 = r7 + r7[1];
×
3177
                act = 0;
×
3178
                pow = 0;
×
3179
                while ( r8 < r2 ) {
×
3180
                        if ( r8[2] < 0 ) { pow += -r8[2]*(ARGHEAD+9); }
×
3181
                        else             { pow +=  r8[2]*(ARGHEAD+9); }
×
3182
                        r8 += 3;
×
3183
                }
3184
/*
3185
                The amount of space we need to move r7 is given in pow
3186
                For dotproducts we always need a new location
3187
*/
3188
                {
3189
                        argin3 = TermMalloc("TakeArgContent3");
×
3190
/*
3191
                        We have to multiply the inverse of r7 into argin
3192
                        The answer should go to argin2.
3193
*/
3194
                        r5 = argin3; *r5++ = 0; *r5++ = 0; FILLARG(r5);
×
3195
                        t = argin2+ARGHEAD;
×
3196
                        while ( t < r3 ) {
×
3197
                                rnext = t + *t;
×
3198
                                GETSTOP(t,r6);
×
3199
                                r9 = r5;
×
3200
                                *r5++ = *t++ + r7[1];
×
3201
                                while ( t < r6 ) *r5++ = *t++;
×
3202
                                i = r7[1] - 2; r8 = r7+2;
×
3203
                                *r5++ = r7[0]; *r5++ = r7[1];
×
3204
                                while ( i > 0 ) { *r5++ = *r8++; *r5++ = *r8++; *r5++ = -*r8++; i -= 3; }
×
3205
                                while ( t < rnext ) *r5++ = *t++;
×
3206
                                Normalize(BHEAD r9);
×
3207
                                r5 = r9 + *r9;
×
3208
                        }
3209
                        *r5 = 0;
×
3210
                        *argin3 = r5-argin3;
×
3211
/*
3212
                        We may have to sort the terms in argin3.
3213
*/
3214
                        NewSort(BHEAD0);
×
3215
                        t = argin3+ARGHEAD;
×
3216
                        while ( *t ) {
×
3217
                                StoreTerm(BHEAD t);
×
3218
                                t += *t;
×
3219
                        }
3220
                        t = argin3+ARGHEAD;
×
3221
                        if ( EndSort(BHEAD t,0) < 0 ) goto Irreg;
×
3222
                        while ( *t ) t += *t;
×
3223
                        *argin3 = t - argin3;
×
3224
                        r3 = t;
×
3225
/*
3226
                        And now the factors that go to argout.
3227
                        First we have to move r7 out of the way.
3228
*/
3229
                        r8 = r7+pow; i = r7[1];
×
3230
                        while ( --i >= 0 ) r8[i] = r7[i];
×
3231
                        r2 += pow;
×
3232
                        r8 += 2;
×
3233
                        while ( r8 < r2 ) {
×
3234
                                for ( i = ABS(r8[2]); i > 0; i-- ) {
×
3235
                                        *r1++ = ARGHEAD+9; *r1++ = 0; FILLARG(r1);
×
3236
                                        *r1++ = 9; *r1++ = DOTPRODUCT; *r1++ = 5; *r1++ = *r8;
×
3237
                                        *r1++ = r8[1]; *r1++ = r8[2] < 0 ? -1: 1;
×
3238
                                        *r1++ = 1; *r1++ = 1; *r1++ = 3;
×
3239
                                }
3240
                                r8 += 3;
×
3241
                        }
3242
                        argout = r1;
5,083✔
3243
                }
3244
          }
3245
/*
3246
                        #] DOTPRODUCT : 
3247

3248
        We have now in argin3 the argument stripped of negative powers and
3249
        common factors. The only thing left to deal with is to make the
3250
        coefficients integer. For that we have to find the LCM of the denominators
3251
        and the GCD of the numerators. And to start with, the sign.
3252
        We force the sign of the first term to be positive.
3253
*/
3254
        t = argin3 + ARGHEAD; pow = 1;
5,083✔
3255
        t += *t;
5,083✔
3256
        if ( t[-1] < 0 ) {
5,083✔
3257
                pow = 0;
11✔
3258
                t[-1] = -t[-1];
11✔
3259
                while ( t < r3 ) {
781✔
3260
                        t += *t; t[-1] = -t[-1];
770✔
3261
                }
3262
        }
3263
/*
3264
        Now the GCD of the numerators and the LCM of the denominators:
3265
*/
3266
        argfree = TermMalloc("TakeArgContent1");
5,083✔
3267
        if ( AN.cmod != 0 ) {
5,083✔
3268
                r1 = MakeMod(BHEAD argin3,r1,argfree);
×
3269
        }
3270
        else {
3271
                r1 = MakeInteger(BHEAD argin3,r1,argfree);
5,083✔
3272
        }
3273
        if ( pow == 0 ) {
5,083✔
3274
                *r1++ = -SNUMBER;
11✔
3275
                *r1++ = -1;
11✔
3276
        }
3277
        *r1 = 0;
5,083✔
3278
/*
3279
        Cleanup
3280
*/
3281
        if ( argin3 != argin2 ) TermFree(argin3,"TakeArgContent3");
5,083✔
3282
        if ( argin2 != argin  ) TermFree(argin2,"TakeArgContent2");
5,083✔
3283
        return(argfree);
3284
Irreg:
×
3285
        MesPrint("Irregularity while sorting argument in TakeArgContent");
×
3286
        if ( argin3 != argin2 ) TermFree(argin3,"TakeArgContent3");
×
3287
        if ( argin2 != argin  ) TermFree(argin2,"TakeArgContent2");
×
3288
        Terminate(-1);
×
3289
        return(0);
×
3290
}
3291

3292
/*
3293
          #] TakeArgContent : 
3294
          #[ MakeInteger :
3295
*/
3296
/**
3297
 *        For normalizing everything to integers we have to
3298
 *        determine for all elements of this argument the LCM of
3299
 *        the denominators and the GCD of the numerators.
3300
 *        The input argument is in argin.
3301
 *        The number that comes out should go to argout.
3302
 *        The new pointer in the argout buffer is the return value.
3303
 *        The normalized argument is in argfree.
3304
 */
3305

3306
WORD *MakeInteger(PHEAD WORD *argin,WORD *argout,WORD *argfree)
5,083✔
3307
{
3308
        UWORD *GCDbuffer, *GCDbuffer2, *LCMbuffer, *LCMb, *LCMc;
5,083✔
3309
        WORD *r, *r1, *r2, *r3, *r4, *r5, *rnext, i, k, j;
5,083✔
3310
        WORD kGCD, kLCM, kGCD2, kkLCM, jLCM, jGCD;
5,083✔
3311
        GCDbuffer = NumberMalloc("MakeInteger");
5,083✔
3312
        GCDbuffer2 = NumberMalloc("MakeInteger");
5,083✔
3313
        LCMbuffer = NumberMalloc("MakeInteger");
5,083✔
3314
        LCMb = NumberMalloc("MakeInteger");
5,083✔
3315
        LCMc = NumberMalloc("MakeInteger");
5,083✔
3316
        r4 = argin + *argin;
5,083✔
3317
        r = argin + ARGHEAD;
5,083✔
3318
/*
3319
        First take the first term to load up the LCM and the GCD
3320
*/
3321
        r2 = r + *r;
5,083✔
3322
        j = r2[-1];
5,083✔
3323
        r3 = r2 - ABS(j);
5,083✔
3324
        k = REDLENG(j);
5,083✔
3325
        if ( k < 0 ) k = -k;
5,083✔
3326
        while ( ( k > 1 ) && ( r3[k-1] == 0 ) ) k--;
5,083✔
3327
        for ( kGCD = 0; kGCD < k; kGCD++ ) GCDbuffer[kGCD] = r3[kGCD];
10,169✔
3328
        k = REDLENG(j);
5,083✔
3329
        if ( k < 0 ) k = -k;
5,083✔
3330
        r3 += k;
5,083✔
3331
        while ( ( k > 1 ) && ( r3[k-1] == 0 ) ) k--;
5,086✔
3332
        for ( kLCM = 0; kLCM < k; kLCM++ ) LCMbuffer[kLCM] = r3[kLCM];
10,166✔
3333
        r1 = r2;
3334
/*
3335
        Now go through the rest of the terms in this argument.
3336
*/
3337
        while ( r1 < r4 ) {
23,357✔
3338
                r2 = r1 + *r1;
18,274✔
3339
                j = r2[-1];
18,274✔
3340
                r3 = r2 - ABS(j);
18,274✔
3341
                k = REDLENG(j);
18,274✔
3342
                if ( k < 0 ) k = -k;
18,274✔
3343
                while ( ( k > 1 ) && ( r3[k-1] == 0 ) ) k--;
18,274✔
3344
                if ( ( ( GCDbuffer[0] == 1 ) && ( kGCD == 1 ) ) ) {
18,274✔
3345
/*
3346
                        GCD is already 1
3347
*/
3348
                }
3349
                else if ( ( ( k != 1 ) || ( r3[0] != 1 ) ) ) {
834✔
3350
                        if ( GcdLong(BHEAD GCDbuffer,kGCD,(UWORD *)r3,k,GCDbuffer2,&kGCD2) ) {
770✔
3351
                                NumberFree(GCDbuffer,"MakeInteger");
×
3352
                                NumberFree(GCDbuffer2,"MakeInteger");
×
3353
                                NumberFree(LCMbuffer,"MakeInteger");
×
3354
                                NumberFree(LCMb,"MakeInteger"); NumberFree(LCMc,"MakeInteger");
×
3355
                                goto MakeIntegerErr;
×
3356
                        }
3357
                        kGCD = kGCD2;
770✔
3358
                        for ( i = 0; i < kGCD; i++ ) GCDbuffer[i] = GCDbuffer2[i];
2,302✔
3359
                }
3360
                else {
3361
                        kGCD = 1; GCDbuffer[0] = 1;
64✔
3362
                }
3363
                k = REDLENG(j);
18,274✔
3364
                if ( k < 0 ) k = -k;
18,274✔
3365
                r3 += k;
18,274✔
3366
                while ( ( k > 1 ) && ( r3[k-1] == 0 ) ) k--;
19,036✔
3367
                if ( ( ( LCMbuffer[0] == 1 ) && ( kLCM == 1 ) ) ) {
18,274✔
3368
                        for ( kLCM = 0; kLCM < k; kLCM++ )
36,548✔
3369
                                LCMbuffer[kLCM] = r3[kLCM];
18,274✔
3370
                }
3371
                else if ( ( k != 1 ) || ( r3[0] != 1 ) ) {
×
3372
                        if ( GcdLong(BHEAD LCMbuffer,kLCM,(UWORD *)r3,k,LCMb,&kkLCM) ) {
×
3373
                                NumberFree(GCDbuffer,"MakeInteger"); NumberFree(GCDbuffer2,"MakeInteger");
×
3374
                                NumberFree(LCMbuffer,"MakeInteger"); NumberFree(LCMb,"MakeInteger"); NumberFree(LCMc,"MakeInteger");
×
3375
                                goto MakeIntegerErr;
×
3376
                        }
3377
                        DivLong((UWORD *)r3,k,LCMb,kkLCM,LCMb,&kkLCM,LCMc,&jLCM);
×
3378
                        MulLong(LCMbuffer,kLCM,LCMb,kkLCM,LCMc,&jLCM);
×
3379
                        for ( kLCM = 0; kLCM < jLCM; kLCM++ )
×
3380
                                LCMbuffer[kLCM] = LCMc[kLCM];
×
3381
                }
3382
                else {} /* LCM doesn't change */
3383
                r1 = r2;
3384
        }
3385
/*
3386
        Now put the factor together: GCD/LCM
3387
*/
3388
        r3 = (WORD *)(GCDbuffer);
5,083✔
3389
        if ( kGCD == kLCM ) {
5,083✔
3390
                for ( jGCD = 0; jGCD < kGCD; jGCD++ )
10,160✔
3391
                        r3[jGCD+kGCD] = LCMbuffer[jGCD];
5,080✔
3392
                k = kGCD;
3393
        }
3394
        else if ( kGCD > kLCM ) {
3✔
3395
                for ( jGCD = 0; jGCD < kLCM; jGCD++ )
6✔
3396
                        r3[jGCD+kGCD] = LCMbuffer[jGCD];
3✔
3397
                for ( jGCD = kLCM; jGCD < kGCD; jGCD++ )
6✔
3398
                        r3[jGCD+kGCD] = 0;
3✔
3399
                k = kGCD;
3400
        }
3401
        else {
3402
                for ( jGCD = kGCD; jGCD < kLCM; jGCD++ )
×
3403
                        r3[jGCD] = 0;
×
3404
                for ( jGCD = 0; jGCD < kLCM; jGCD++ )
×
3405
                        r3[jGCD+kLCM] = LCMbuffer[jGCD];
×
3406
                k = kLCM;
3407
        }
3408
        j = 2*k+1;
5,083✔
3409
/*
3410
        Now we have to write this to argout
3411
*/
3412
        if ( ( j == 3 ) && ( r3[1] == 1 ) && ( (WORD)(r3[0]) > 0 ) ) {
5,083✔
3413
                *argout = -SNUMBER;
5,080✔
3414
                argout[1] = r3[0];
5,080✔
3415
                r1 = argout+2;
5,080✔
3416
        }
3417
        else {
3418
                r1 = argout;
3✔
3419
                *r1++ = j+1+ARGHEAD; *r1++ = 0; FILLARG(r1);
3✔
3420
                *r1++ = j+1; r2 = r3;
3✔
3421
                for ( i = 0; i < k; i++ ) { *r1++ = *r2++; *r1++ = *r2++; }
9✔
3422
                *r1++ = j;
3✔
3423
        }
3424
/*
3425
        Next we have to take the factor out from the argument.
3426
        This cannot be done in location, because the denominator stuff can make
3427
        coefficients longer.
3428
*/
3429
        r2 = argfree + 2; FILLARG(r2)
5,083✔
3430
        while ( r < r4 ) {
28,440✔
3431
                rnext = r + *r;
23,357✔
3432
                j = ABS(rnext[-1]);
23,357✔
3433
                r5 = rnext - j;
23,357✔
3434
                r3 = r2;
23,357✔
3435
                while ( r < r5 ) *r2++ = *r++;
184,412✔
3436
                j = (j-1)/2;        /* reduced length. Remember, k is the other red length */
23,357✔
3437
                if ( DivRat(BHEAD (UWORD *)r5,j,GCDbuffer,k,(UWORD *)r2,&i) ) {
23,357✔
3438
                        goto MakeIntegerErr;
×
3439
                }
3440
                i = 2*i+1;
23,357✔
3441
                r2 = r2 + i;
23,357✔
3442
                if ( rnext[-1] < 0 ) r2[-1] = -i;
23,357✔
3443
                else                 r2[-1] =  i;
22,991✔
3444
                *r3 = r2-r3;
23,357✔
3445
                r = rnext;
23,357✔
3446
        }
3447
        *r2 = 0;
5,083✔
3448
        argfree[0] = r2-argfree;
5,083✔
3449
        argfree[1] = 0;
5,083✔
3450
/*
3451
        Cleanup
3452
*/
3453
        NumberFree(LCMc,"MakeInteger");
5,083✔
3454
        NumberFree(LCMb,"MakeInteger");
5,083✔
3455
        NumberFree(LCMbuffer,"MakeInteger");
5,083✔
3456
        NumberFree(GCDbuffer2,"MakeInteger");
5,083✔
3457
        NumberFree(GCDbuffer,"MakeInteger");
5,083✔
3458
        return(r1);
5,083✔
3459

3460
MakeIntegerErr:
×
3461
        MesCall("MakeInteger");
×
3462
        Terminate(-1);
×
3463
        return(0);
×
3464
}
3465

3466
/*
3467
          #] MakeInteger : 
3468
          #[ MakeMod :
3469
*/
3470
/**
3471
 *        Similar to MakeInteger but now with modulus arithmetic using only
3472
 *        a one WORD 'prime'. We make the coefficient of the first term in the
3473
 *        argument equal to one.
3474
 *        Already the coefficients are taken modulus AN.cmod and AN.ncmod == 1
3475
 */
3476

3477
WORD *MakeMod(PHEAD WORD *argin,WORD *argout,WORD *argfree)
×
3478
{
3479
        WORD *r, *instop, *r1, *m, x, xx, ix, ip;
×
3480
        int i;
×
3481
        r = argin; instop = r + *r; r += ARGHEAD;
×
3482
        x = r[*r-3];
×
3483
        if ( r[*r-1] < 0 ) x += AN.cmod[0];
×
3484
        if ( GetModInverses(x,(WORD)(AN.cmod[0]),&ix,&ip) ) {
×
3485
                Terminate(-1);
×
3486
        }
3487
        argout[0] = -SNUMBER;
×
3488
        argout[1] = x;
×
3489
        argout[2] = 0;
×
3490
        r1 = argout+2;
×
3491
/*
3492
        Now we have to multiply all coefficients by ix.
3493
        This does not make things longer, but we should keep to the conventions
3494
        of MakeInteger.
3495
*/
3496
        m = argfree + ARGHEAD;
×
3497
        while ( r < instop ) {
×
3498
                xx = r[*r-3]; if ( r[*r-1] < 0 ) xx += AN.cmod[0];
×
3499
                xx = (WORD)((((LONG)xx)*ix) % AN.cmod[0]);
×
3500
                if ( xx != 0 ) {
×
3501
                        i = *r; NCOPY(m,r,i);
×
3502
                        m[-3] = xx; m[-1] = 3;
×
3503
                }
3504
                else { r += *r; }
×
3505
        }
3506
        *m = 0;
×
3507
        *argfree = m - argfree;
×
3508
        argfree[1] = 0;
×
3509
        argfree += 2; FILLARG(argfree);
×
3510
        return(r1);
×
3511
}
3512

3513
/*
3514
          #] MakeMod : 
3515
          #[ SortWeights :
3516
*/
3517
/**
3518
 *        Sorts an array of LONGS in the same way SplitMerge (in sort.c) works
3519
 *        We use gradual division in two.
3520
 */
3521

3522
void SortWeights(LONG *weights,LONG *extraspace,WORD number)
×
3523
{
3524
        LONG w, *fill, *from1, *from2;
×
3525
        int n1,n2,i;
×
3526
        if ( number >= 4 ) {
×
3527
                n1 = number/2; n2 = number - n1;
×
3528
                SortWeights(weights,extraspace,n1);
×
3529
                SortWeights(weights+n1,extraspace,n2);
×
3530
/*
3531
                We copy the first patch to the extra space. Then we merge
3532
                Note that a potential remaining n2 objects are already in place.
3533
*/
3534
                for ( i = 0; i < n1; i++ ) extraspace[i] = weights[i];
×
3535
                fill = weights; from1 = extraspace; from2 = weights+n1;
3536
                while ( n1 > 0 && n2 > 0 ) {
×
3537
                        if ( *from1 <= *from2 ) { *fill++ = *from1++; n1--; }
×
3538
                        else                    { *fill++ = *from2++; n2--; }
×
3539
                }
3540
                while ( n1 > 0 ) { *fill++ = *from1++; n1--; }
×
3541
        }
3542
/*
3543
        Special cases
3544
*/
3545
        else if ( number == 3 ) { /* 6 permutations of which one is trivial */
×
3546
                if ( weights[0] > weights[1] ) {
×
3547
                        if ( weights[1] > weights[2] ) {
×
3548
                                w = weights[0]; weights[0] = weights[2]; weights[2] = w;
×
3549
                        }
3550
                        else if ( weights[0] > weights[2] ) {
×
3551
                                w = weights[0]; weights[0] = weights[1];
×
3552
                                weights[1] = weights[2]; weights[2] = w;
×
3553
                        }
3554
                        else {
3555
                                w = weights[0]; weights[0] = weights[1]; weights[1] = w;
×
3556
                        }
3557
                }
3558
                else if ( weights[0] > weights[2] ) {
×
3559
                        w = weights[0]; weights[0] = weights[2];
×
3560
                        weights[2] = weights[1]; weights[1] = w;
×
3561
                }
3562
                else if ( weights[1] > weights[2] ) {
×
3563
                        w = weights[1]; weights[1] = weights[2]; weights[2] = w;
×
3564
                }
3565
        }
3566
        else if ( number == 2 ) {
×
3567
                if ( weights[0] > weights[1] ) {
×
3568
                        w = weights[0]; weights[0] = weights[1]; weights[1] = w;
×
3569
                }
3570
        }
3571
        return;
×
3572
}
3573

3574
/*
3575
          #] SortWeights : 
3576
*/
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