CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutSign UpSign In

Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.

| Download

GAP 4.8.9 installation with standard packages -- copy to your CoCalc project to get it

Path: gap4r8 / src / dteval.c
Views: 418346
1
/****************************************************************************
2
**
3
*W dteval.c GAP source Wolfgang Merkwitz
4
**
5
**
6
*Y Copyright (C) 1996, Lehrstuhl D für Mathematik, RWTH Aachen, Germany
7
*Y (C) 1998 School Math and Comp. Sci., University of St Andrews, Scotland
8
*Y Copyright (C) 2002 The GAP Group
9
**
10
** This file contains the part of the deep thought package which uses the
11
** deep thought polynomials to multiply in nilpotent groups.
12
**
13
** The deep thought polynomials are stored in the list <dtpols> where
14
** <dtpols>[i] contains the polynomials f_{i1},...,f_{in}.
15
** <dtpols>[i] is a record consisting of the components <evlist> and
16
** <evlistvec>. <evlist> is a list of all deep thought monomials occuring
17
** in the polynomials f_{i1},...,f_{in}. <evlistvec>is a list of vectors
18
** describing the coefficients of the corresponding deep thought monomials
19
** in the polynomials f_{i1},..,f_{in}. For example when a pair [j,k]
20
** occurs in <dtpols>[i].<evlistvec>[l] then the deep thought monomial
21
** <dtpols>[i].<evlist>[l] occurs in f_{ij} with the coefficient k.
22
** If the polynomials f_{i1},..,f_{in} are trivial i.e. f_{ii} = x_i + y_i
23
** and f_{ij} = x_j (j<>i), then <dtpols>[i] is either 1 or 0. <dtpols>[i]
24
** is 0 if also the polynomials f_{m1},...,f_{mn} for (m > i) are trivial .
25
*/
26
#include "system.h"
27
28
29
#include "gasman.h" /* garbage collector */
30
#include "objects.h" /* objects */
31
#include "scanner.h" /* scanner */
32
#include "bool.h" /* booleans */
33
#include "calls.h" /* generic call mechanism */
34
#include "gap.h" /* error handling, initialisation */
35
#include "gvars.h" /* global variables */
36
#include "precord.h" /* plain records */
37
#include "records.h" /* generic records */
38
#include "integer.h" /* integers */
39
#include "dt.h" /* deep thought */
40
#include "objcftl.h" /* from the left collect */
41
42
#include "dteval.h" /* deep though evaluation */
43
44
#define CELM(list, pos) ( INT_INTOBJ( ELM_PLIST(list, pos) ) )
45
46
#include "records.h" /* generic records */
47
#include "precord.h" /* plain records */
48
49
#include "lists.h" /* generic lists */
50
#include "listfunc.h" /* functions for generic lists */
51
#include "plist.h" /* plain lists */
52
#include "string.h" /* strings */
53
54
#include "code.h" /* coder */
55
#include "thread.h" /* threads */
56
#include "tls.h" /* thread-local storage */
57
58
59
static int evlist, evlistvec;
60
61
extern Obj ShallowCopyPlist( Obj list );
62
63
64
/****************************************************************************
65
**
66
67
*F MultGen( <xk>, <gen>, <power>, <dtpols> )
68
**
69
** MultGen multiplies the word given by the exponent vector <xk> with
70
** g_<gen>^<power> by evaluating the deep thought polynomials. The result
71
** is an ordered word and stored in <xk>.
72
*/
73
74
/* See below: */
75
Obj Evaluation( Obj vec, Obj xk, Obj power );
76
77
void MultGen(
78
Obj xk,
79
UInt gen,
80
Obj power,
81
Obj dtpols )
82
{
83
UInt i, j, len, len2;
84
Obj copy, sum, sum1, sum2, prod, ord, help;
85
86
if ( IS_INTOBJ(power) && INT_INTOBJ(power) == 0 )
87
return;
88
sum = SumInt(ELM_PLIST(xk, gen), power);
89
if ( IS_INTOBJ( ELM_PLIST(dtpols, gen) ) )
90
{
91
/* if f_{<gen>1},...,f_{<gen>n} are trivial we only have to add
92
** <power> to <xk>[ <gen> ]. */
93
SET_ELM_PLIST(xk, gen, sum);
94
CHANGED_BAG(xk);
95
return;
96
}
97
copy = ShallowCopyPlist(xk);
98
/* first add <power> to <xk>[ gen> ]. */
99
SET_ELM_PLIST(xk, gen, sum);
100
CHANGED_BAG(xk);
101
sum = ElmPRec( ELM_PLIST(dtpols, gen), evlist );
102
sum1 = ElmPRec( ELM_PLIST(dtpols, gen), evlistvec);
103
len = LEN_PLIST(sum);
104
for ( i=1;
105
i <= len;
106
i++ )
107
{
108
/* evaluate the deep thought monomial <sum>[<i>], */
109
ord = Evaluation( ELM_PLIST( sum, i), copy, power );
110
if ( !IS_INTOBJ(ord) || INT_INTOBJ(ord) != 0 )
111
{
112
help = ELM_PLIST(sum1, i);
113
len2 = LEN_PLIST(help);
114
for ( j=1;
115
j < len2;
116
j+=2 )
117
{
118
/* and add the result multiplicated with the right coefficient
119
** to <xk>[ <help>[j] ]. */
120
prod = ProdInt( ord, ELM_PLIST( help, j+1 ) );
121
sum2 = SumInt(ELM_PLIST( xk, CELM( help,j ) ),
122
prod);
123
SET_ELM_PLIST(xk, CELM( help, j ),
124
sum2 );
125
CHANGED_BAG(xk);
126
}
127
}
128
}
129
}
130
131
132
133
/****************************************************************************
134
**
135
*F Evaluation( <vec>, <xk>, <power>)
136
**
137
** Evaluation evaluates the deep thought monomial <vec> at the entries in
138
** <xk> and at <power>.
139
*/
140
141
Obj Evaluation(
142
Obj vec,
143
Obj xk,
144
Obj power )
145
{
146
UInt i, len;
147
Obj prod, help;
148
149
if ( IS_INTOBJ(power) && INT_INTOBJ(power) > 0 &&
150
power < ELM_PLIST(vec, 6) )
151
return INTOBJ_INT(0);
152
prod = binomial(power, ELM_PLIST(vec, 6) );
153
len = LEN_PLIST(vec);
154
for (i=7; i < len; i+=2)
155
{
156
help = ELM_PLIST(xk, CELM(vec, i) );
157
if ( IS_INTOBJ( help ) &&
158
( INT_INTOBJ(help) == 0 ||
159
( INT_INTOBJ(help) > 0 && help < ELM_PLIST(vec, i+1) ) ) )
160
return INTOBJ_INT(0);
161
prod = ProdInt( prod, binomial( help, ELM_PLIST(vec, i+1) ) );
162
}
163
return prod;
164
}
165
166
167
168
/****************************************************************************
169
**
170
*F Multbound( <xk>, <y>, <anf>, <end>, <dtpols> )
171
**
172
** Multbound multiplies the word given by the exponent vector <xk> with
173
** <y>{ [<anf>..<end>] } by evaluating the deep thought polynomials <dtpols>
174
** The result is an ordered word and is stored in <xk>.
175
*/
176
177
void Multbound(
178
Obj xk,
179
Obj y,
180
Int anf,
181
Int end,
182
Obj dtpols )
183
{
184
int i;
185
186
for (i=anf; i < end; i+=2)
187
MultGen(xk, CELM( y, i), ELM_PLIST( y, i+1) , dtpols);
188
}
189
190
191
192
/****************************************************************************
193
**
194
*F Multiplybound( <x>, <y>, <anf>, <end>, <dtpols> )
195
**
196
** Multiplybound returns the product of the word <x> with the word
197
** <y>{ [<anf>..<end>] } by evaluating the deep thought polynomials <dtpols>.
198
** The result is an ordered word.
199
*/
200
201
Obj Multiplybound(
202
Obj x,
203
Obj y,
204
Int anf,
205
Int end,
206
Obj dtpols )
207
{
208
UInt i, j, k, len, help;
209
Obj xk, res, sum;
210
211
if ( LEN_PLIST( x ) == 0 )
212
return y;
213
if ( anf > end )
214
return x;
215
/* first deal with the case that <y>{ [<anf>..<end>] } lies in the center
216
** of the group defined by <dtpols> */
217
if ( IS_INTOBJ( ELM_PLIST(dtpols, CELM(y, anf) ) ) &&
218
CELM(dtpols, CELM(y, anf) ) == 0 )
219
{
220
res = NEW_PLIST( T_PLIST, 2*LEN_PLIST( dtpols ) );
221
len = LEN_PLIST(x);
222
j = 1;
223
k = anf;
224
i = 1;
225
while ( j<len && k<end )
226
{
227
if ( ELM_PLIST(x, j) == ELM_PLIST(y, k) )
228
{
229
sum = SumInt( ELM_PLIST(x, j+1), ELM_PLIST(y, k+1) );
230
SET_ELM_PLIST(res, i, ELM_PLIST(x, j) );
231
SET_ELM_PLIST(res, i+1, sum );
232
j+=2;
233
k+=2;
234
}
235
else if ( ELM_PLIST(x, j) < ELM_PLIST(y, k) )
236
{
237
SET_ELM_PLIST(res, i, ELM_PLIST(x, j) );
238
SET_ELM_PLIST(res, i+1, ELM_PLIST(x, j+1) );
239
j+=2;
240
}
241
else
242
{
243
SET_ELM_PLIST(res, i, ELM_PLIST(y, k) );
244
SET_ELM_PLIST(res, i+1, ELM_PLIST(y, k+1) );
245
k+=2;
246
}
247
CHANGED_BAG(res);
248
i+=2;
249
}
250
if ( j>=len )
251
while ( k<end )
252
{
253
SET_ELM_PLIST(res, i, ELM_PLIST(y, k) );
254
SET_ELM_PLIST(res, i+1, ELM_PLIST(y, k+1 ) );
255
CHANGED_BAG(res);
256
k+=2;
257
i+=2;
258
}
259
else
260
while ( j<len )
261
{
262
SET_ELM_PLIST(res, i, ELM_PLIST(x, j) );
263
SET_ELM_PLIST(res, i+1, ELM_PLIST(x, j+1) );
264
CHANGED_BAG(res);
265
j+=2;
266
i+=2;
267
}
268
SET_LEN_PLIST(res, i-1);
269
SHRINK_PLIST(res, i-1);
270
return res;
271
}
272
len = LEN_PLIST(dtpols);
273
help = LEN_PLIST(x);
274
/* convert <x> into a exponent vector */
275
xk = NEW_PLIST( T_PLIST, len );
276
SET_LEN_PLIST(xk, len );
277
j = 1;
278
for (i=1; i <= len; i++)
279
{
280
if ( j >= help || i < CELM(x, j) )
281
SET_ELM_PLIST(xk, i, INTOBJ_INT(0) );
282
else
283
{
284
SET_ELM_PLIST(xk, i, ELM_PLIST(x, j+1) );
285
j+=2;
286
}
287
}
288
/* let Multbound do the work */
289
Multbound(xk, y, anf, end, dtpols);
290
/* finally convert the result back into a word */
291
res = NEW_PLIST(T_PLIST, 2*len);
292
j = 0;
293
for (i=1; i <= len; i++)
294
{
295
if ( !( IS_INTOBJ( ELM_PLIST(xk, i) ) && CELM(xk, i) == 0 ) )
296
{
297
j+=2;
298
SET_ELM_PLIST(res, j-1, INTOBJ_INT(i) );
299
SET_ELM_PLIST(res, j, ELM_PLIST(xk, i) );
300
}
301
}
302
SET_LEN_PLIST(res, j);
303
SHRINK_PLIST(res, j);
304
return res;
305
}
306
307
308
309
/****************************************************************************
310
**
311
*F Power( <x>, <n>, <dtpols> )
312
**
313
** Power returns the <n>-th power of the word <x> as ordered word by
314
** evaluating the deep thought polynomials <dtpols>.
315
*/
316
317
/* See below: */
318
Obj Solution( Obj x, Obj y, Obj dtpols );
319
320
Obj Power(
321
Obj x,
322
Obj n,
323
Obj dtpols )
324
{
325
Obj res, m, y;
326
UInt i,len;
327
328
if ( LEN_PLIST(x) == 0 )
329
return x;
330
/* first deal with the case that <x> lies in the centre of the group
331
** defined by <dtpols> */
332
if ( IS_INTOBJ( ELM_PLIST( dtpols, CELM(x, 1) ) ) &&
333
CELM( dtpols, CELM(x, 1) ) == 0 )
334
{
335
len = LEN_PLIST(x);
336
res = NEW_PLIST( T_PLIST, len );
337
SET_LEN_PLIST(res, len );
338
for (i=2;i<=len;i+=2)
339
{
340
m = ProdInt( ELM_PLIST(x, i), n );
341
SET_ELM_PLIST(res, i, m );
342
SET_ELM_PLIST(res, i-1, ELM_PLIST(x, i-1) );
343
CHANGED_BAG( res );
344
}
345
return res;
346
}
347
/* if <n> is a negative integer compute ( <x>^-1 )^(-<n>) */
348
if ( TNUM_OBJ(n) == T_INTNEG || INT_INTOBJ(n) < 0 )
349
{
350
y = NEW_PLIST( T_PLIST, 0);
351
SET_LEN_PLIST(y, 0);
352
return Power( Solution(x, y, dtpols),
353
ProdInt(INTOBJ_INT(-1), n), dtpols );
354
}
355
res = NEW_PLIST(T_PLIST, 2);
356
SET_LEN_PLIST(res, 0);
357
if ( IS_INTOBJ(n) && INT_INTOBJ(n) == 0 )
358
return res;
359
/* now use the russian peasant rule to get the result */
360
while( LtInt(INTOBJ_INT(0), n) )
361
{
362
len = LEN_PLIST(x);
363
if ( ModInt(n, INTOBJ_INT(2) ) == INTOBJ_INT(1) )
364
res = Multiplybound(res, x, 1, len, dtpols);
365
if ( LtInt(INTOBJ_INT(1), n) )
366
x = Multiplybound(x, x, 1, len, dtpols);
367
n = QuoInt(n, INTOBJ_INT(2) );
368
}
369
return res;
370
}
371
372
373
374
/****************************************************************************
375
**
376
*F Solution( <x>, <y>, <dtpols> )
377
**
378
** Solution returns a solution for the equation <x>*a = <y> by evaluating
379
** the deep thought polynomials <dtpols>. The result is an ordered word.
380
*/
381
382
Obj Solution( Obj x,
383
Obj y,
384
Obj dtpols )
385
386
{
387
Obj xk, res, m;
388
UInt i,j,k, len1, len2;
389
390
if ( LEN_PLIST(x) == 0)
391
return y;
392
/* first deal with the case that <x> and <y> ly in the centre of the
393
** group defined by <dtpols>. */
394
if ( IS_INTOBJ( ELM_PLIST( dtpols, CELM(x, 1) ) ) &&
395
CELM( dtpols, CELM(x, 1) ) == 0 &&
396
( LEN_PLIST(y) == 0 ||
397
( IS_INTOBJ( ELM_PLIST( dtpols, CELM(y, 1) ) ) &&
398
CELM( dtpols, CELM(y, 1) ) == 0 ) ) )
399
{
400
res = NEW_PLIST( T_PLIST, 2*LEN_PLIST( dtpols ) );
401
i = 1;
402
j = 1;
403
k = 1;
404
len1 = LEN_PLIST(x);
405
len2 = LEN_PLIST(y);
406
while ( j < len1 && k < len2 )
407
{
408
if ( ELM_PLIST(x, j) == ELM_PLIST(y, k) )
409
{
410
m = DiffInt( ELM_PLIST(y, k+1), ELM_PLIST(x, j+1) );
411
SET_ELM_PLIST( res, i, ELM_PLIST(x, j) );
412
SET_ELM_PLIST( res, i+1, m );
413
CHANGED_BAG( res );
414
i+=2; j+=2; k+=2;
415
}
416
else if ( CELM(x, j) < CELM(y, k) )
417
{
418
m = ProdInt( INTOBJ_INT(-1), ELM_PLIST(x, j+1) );
419
SET_ELM_PLIST( res, i, ELM_PLIST(x, j) );
420
SET_ELM_PLIST( res, i+1, m );
421
CHANGED_BAG( res );
422
i+=2; j+=2;
423
}
424
else
425
{
426
SET_ELM_PLIST( res, i, ELM_PLIST(y, k) );
427
SET_ELM_PLIST( res, i+1, ELM_PLIST(y, k+1) );
428
CHANGED_BAG( res );
429
i+=2; k+=2;
430
}
431
}
432
if ( j < len1 )
433
while( j < len1 )
434
{
435
m = ProdInt( INTOBJ_INT(-1), ELM_PLIST( x, j+1 ) );
436
SET_ELM_PLIST( res, i, ELM_PLIST(x, j) );
437
SET_ELM_PLIST( res, i+1, m );
438
CHANGED_BAG( res );
439
i+=2; j+=2;
440
}
441
else
442
while( k < len2 )
443
{
444
SET_ELM_PLIST( res, i ,ELM_PLIST(y, k) );
445
SET_ELM_PLIST( res, i+1, ELM_PLIST(y, k+1) );
446
CHANGED_BAG( res );
447
i+=2; k+=2;
448
}
449
SET_LEN_PLIST( res, i-1 );
450
SHRINK_PLIST( res, i-1);
451
return res;
452
}
453
/* convert <x> into an exponent vector */
454
xk = NEW_PLIST( T_PLIST, LEN_PLIST(dtpols) );
455
SET_LEN_PLIST(xk, LEN_PLIST(dtpols) );
456
j = 1;
457
for (i=1; i <= LEN_PLIST(dtpols); i++)
458
{
459
if ( j >= LEN_PLIST(x) || i < CELM(x, j) )
460
SET_ELM_PLIST(xk, i, INTOBJ_INT(0) );
461
else
462
{
463
SET_ELM_PLIST(xk, i, ELM_PLIST(x, j+1) );
464
j+=2;
465
}
466
}
467
res = NEW_PLIST( T_PLIST, 2*LEN_PLIST( xk ) );
468
j = 1;
469
k = 1;
470
len1 = LEN_PLIST(xk);
471
len2 = LEN_PLIST(y);
472
for (i=1; i <= len1; i++)
473
{
474
if ( k < len2 && i == CELM(y, k) )
475
{
476
if ( !EqInt( ELM_PLIST(xk, i), ELM_PLIST(y, k+1) ) )
477
{
478
m = DiffInt( ELM_PLIST(y, k+1), ELM_PLIST(xk, i) );
479
SET_ELM_PLIST(res, j, INTOBJ_INT(i) );
480
SET_ELM_PLIST(res, j+1, m);
481
CHANGED_BAG(res);
482
MultGen(xk, i, m, dtpols);
483
j+=2;
484
}
485
k+=2;
486
}
487
else if ( !IS_INTOBJ( ELM_PLIST(xk, i) ) || CELM( xk, i ) != 0 )
488
{
489
m = ProdInt( INTOBJ_INT(-1), ELM_PLIST(xk, i) );
490
SET_ELM_PLIST( res, j, INTOBJ_INT(i) );
491
SET_ELM_PLIST( res, j+1, m );
492
CHANGED_BAG(res);
493
MultGen(xk, i, m, dtpols);
494
j+=2;
495
}
496
}
497
SET_LEN_PLIST(res, j-1);
498
SHRINK_PLIST(res, j-1);
499
return res;
500
}
501
502
503
504
/****************************************************************************
505
**
506
*F Commutator( <x>, <y>, <dtpols> )
507
**
508
** Commutator returns the commutator of the word <x> and <y> by evaluating
509
** the deep thought polynomials <dtpols>.
510
*/
511
512
Obj Commutator( Obj x,
513
Obj y,
514
Obj dtpols )
515
{
516
Obj res, help;
517
518
res = Multiplybound(x, y, 1, LEN_PLIST(y), dtpols);
519
help = Multiplybound(y, x, 1, LEN_PLIST(x), dtpols);
520
res = Solution(help, res, dtpols);
521
return res;
522
}
523
524
525
526
/****************************************************************************
527
**
528
*F Conjugate( <x>, <y>, <dtpols> )
529
**
530
** Conjugate returns <x>^<y> for the words <x> and <y> by evaluating the
531
** deep thought polynomials <dtpols>. The result is an ordered word.
532
*/
533
534
Obj Conjugate( Obj x,
535
Obj y,
536
Obj dtpols )
537
{
538
Obj res;
539
540
res = Multiplybound(x, y, 1, LEN_PLIST(y), dtpols);
541
res = Solution(y, res, dtpols);
542
return res;
543
}
544
545
546
547
/****************************************************************************
548
**
549
*F Multiplyboundred( <x>, <y>, <anf>, <end>, <pcp> )
550
**
551
** Multiplyboundred returns the product of the words <x> and <y>. The result
552
** is an ordered word with the additional property that all word exponents
553
** are reduced modulo the corresponding generator orders given by the
554
** deep thought rewriting system <pcp>..
555
*/
556
557
Obj Multiplyboundred( Obj x,
558
Obj y,
559
UInt anf,
560
UInt end,
561
Obj pcp )
562
{
563
Obj orders, res, mod, c;
564
UInt i, len, len2, help;
565
566
orders = ELM_PLIST(pcp, PC_ORDERS);
567
res = Multiplybound(x,y,anf, end, ELM_PLIST( pcp, PC_DEEP_THOUGHT_POLS) );
568
len = LEN_PLIST(res);
569
len2 = LEN_PLIST(orders);
570
for (i=2; i<=len; i+=2)
571
if ( (help=CELM(res, i-1)) <= len2 &&
572
( c=ELM_PLIST( orders, help )) != 0 )
573
{
574
mod = ModInt( ELM_PLIST(res, i), c );
575
SET_ELM_PLIST( res, i, mod);
576
CHANGED_BAG(res);
577
}
578
return res;
579
}
580
581
582
583
/****************************************************************************
584
**
585
*F Powerred( <x>, <n>, <pcp>
586
**
587
** Powerred returns the <n>-th power of the word <x>. The result is an
588
** ordered word with the additional property that all word exponents are
589
** reduced modulo the generator orders given by the deep thought rewriting
590
** system <pcp>.
591
*/
592
593
Obj Powerred( Obj x,
594
Obj n,
595
Obj pcp )
596
{
597
Obj orders, res, mod, c;
598
UInt i, len, len2,help;
599
600
orders = ELM_PLIST(pcp, PC_ORDERS);
601
res = Power(x, n, ELM_PLIST( pcp, PC_DEEP_THOUGHT_POLS) );
602
len = LEN_PLIST(res);
603
len2 = LEN_PLIST(orders);
604
for (i=2; i<=len; i+=2)
605
if ( (help=CELM(res, i-1)) <= len2 &&
606
( c=ELM_PLIST( orders, help )) != 0 )
607
{
608
mod = ModInt( ELM_PLIST(res, i), c );
609
SET_ELM_PLIST( res, i, mod);
610
CHANGED_BAG(res);
611
}
612
return res;
613
}
614
615
616
617
/****************************************************************************
618
**
619
*F Solutionred( <x>, <y>, <pcp> )
620
**
621
** Solutionred returns the solution af the equation <x>*a = <y>. The result
622
** is an ordered word with the additional property that all word exponents
623
** are reduced modulo the generator orders given by the deep thought
624
** rewriting system <pcp>.
625
*/
626
627
Obj Solutionred( Obj x,
628
Obj y,
629
Obj pcp )
630
{
631
Obj orders, res, mod, c;
632
UInt i, len, len2, help;
633
634
orders = ELM_PLIST(pcp, PC_ORDERS);
635
res = Solution(x, y, ELM_PLIST( pcp, PC_DEEP_THOUGHT_POLS) );
636
len = LEN_PLIST(res);
637
len2 = LEN_PLIST(orders);
638
for (i=2; i<=len; i+=2)
639
if ( (help=CELM(res, i-1)) <= len2 &&
640
( c=ELM_PLIST( orders, help )) != 0 )
641
{
642
mod = ModInt( ELM_PLIST(res, i), c );
643
SET_ELM_PLIST( res, i, mod);
644
CHANGED_BAG(res);
645
}
646
return res;
647
}
648
649
650
651
/****************************************************************************
652
**
653
** Commutatorred( <x>, <y>, <pcp> )
654
**
655
** Commutatorred returns the commutator of the words <x> and <y>. The result
656
** is an ordered word with the additional property that all word exponents
657
** are reduced modulo the corresponding generator orders given by the deep
658
** thought rewriting system <pcp>.
659
*/
660
661
Obj Commutatorred( Obj x,
662
Obj y,
663
Obj pcp )
664
{
665
Obj orders, mod, c, res;
666
UInt i, len, len2, help;
667
668
orders = ELM_PLIST(pcp, PC_ORDERS);
669
res = Commutator(x, y, ELM_PLIST( pcp, PC_DEEP_THOUGHT_POLS) );
670
len = LEN_PLIST(res);
671
len2 = LEN_PLIST(orders);
672
for (i=2; i<=len; i+=2)
673
if ( (help=CELM(res, i-1)) <= len2 &&
674
( c=ELM_PLIST( orders, help )) != 0 )
675
{
676
mod = ModInt( ELM_PLIST(res, i), c );
677
SET_ELM_PLIST( res, i, mod);
678
CHANGED_BAG(res);
679
}
680
return res;
681
}
682
683
684
685
/****************************************************************************
686
**
687
*F Conjugate( <x>, <y>, <pcp> )
688
**
689
** Conjugate returns <x>^<y> for the words <x> and <y>. The result is an
690
** ordered word with the additional property that all word exponents are
691
** reduced modulo the corresponding generator orders given by the deep
692
** thought rewriting system <pcp>.
693
*/
694
695
Obj Conjugatered( Obj x,
696
Obj y,
697
Obj pcp )
698
{
699
Obj orders, mod, c, res;
700
UInt i, len, len2, help;
701
702
orders = ELM_PLIST(pcp, PC_ORDERS);
703
res = Conjugate(x, y, ELM_PLIST( pcp, PC_DEEP_THOUGHT_POLS) );
704
len = LEN_PLIST(res);
705
len2 = LEN_PLIST(orders);
706
for (i=2; i<=len; i+=2)
707
if ( (help=CELM(res, i-1)) <= len2 &&
708
( c=ELM_PLIST( orders, help )) != 0 )
709
{
710
mod = ModInt( ELM_PLIST(res, i), c );
711
SET_ELM_PLIST( res, i, mod);
712
CHANGED_BAG(res);
713
}
714
return res;
715
}
716
717
718
719
/****************************************************************************
720
**
721
** compress( <list> )
722
**
723
** compress removes pairs (n,0) from the list of GAP integers <list>.
724
*/
725
726
void compress( Obj list )
727
{
728
UInt i, skip, len;
729
730
skip = 0;
731
i = 2;
732
len = LEN_PLIST( list );
733
while ( i <= len )
734
{
735
while ( i<=len && CELM(list, i) == 0)
736
{
737
skip+=2;
738
i+=2;
739
}
740
if ( i <= len )
741
{
742
SET_ELM_PLIST(list, i-skip, ELM_PLIST(list, i) );
743
SET_ELM_PLIST(list, i-1-skip, ELM_PLIST( list, i-1 ) );
744
}
745
i+=2;
746
}
747
SET_LEN_PLIST( list, len-skip );
748
CHANGED_BAG( list );
749
SHRINK_PLIST( list, len-skip );
750
}
751
752
753
754
/****************************************************************************
755
**
756
*F FuncDTCompress( <self>, <list> )
757
**
758
** FuncDTCompress implements the internal function DTCompress.
759
*/
760
761
Obj FuncDTCompress( Obj self,
762
Obj list )
763
{
764
compress(list);
765
return (Obj)0;
766
}
767
768
769
770
/****************************************************************************
771
**
772
*F ReduceWord( <x>, <pcp> )
773
**
774
** ReduceWord reduces the ordered word <x> with respect to the deep thought
775
** rewriting system <pcp> i.e after applying ReduceWord <x> is an ordered
776
** word with exponents less than the corresponding relative orders given
777
** by <pcp>.
778
*/
779
780
void ReduceWord( Obj x,
781
Obj pcp )
782
{
783
Obj powers, exponent;
784
Obj deepthoughtpols, help, potenz, quo, mod, prel;
785
UInt i,j,flag, len, gen, lenexp, lenpow;
786
787
powers = ELM_PLIST(pcp, PC_POWERS);
788
exponent = ELM_PLIST(pcp, PC_EXPONENTS);
789
deepthoughtpols = ELM_PLIST(pcp, PC_DEEP_THOUGHT_POLS);
790
len = **deepthoughtpols;
791
lenexp = LEN_PLIST(exponent);
792
lenpow = LEN_PLIST(powers);
793
GROW_PLIST(x, 2*len );
794
flag = LEN_PLIST(x);
795
for (i=1; i<flag; i+=2)
796
{
797
if ( (gen = CELM(x, i) ) <= lenexp &&
798
(potenz = ELM_PLIST(exponent, gen) ) != 0 )
799
{
800
quo = ELM_PLIST(x, i+1);
801
if ( !IS_INTOBJ(quo) || INT_INTOBJ(quo) >= INT_INTOBJ(potenz) ||
802
INT_INTOBJ(quo)<0 )
803
{
804
/* reduce the exponent of the generator <gen> */
805
mod = ModInt( quo, potenz );
806
SET_ELM_PLIST(x, i+1, mod);
807
CHANGED_BAG(x);
808
if ( gen <= lenpow &&
809
(prel = ELM_PLIST( powers, gen) ) != 0 )
810
{
811
if ( ( IS_INTOBJ(quo) && INT_INTOBJ(quo) >= INT_INTOBJ(potenz) ) ||
812
TNUM_OBJ(quo) == T_INTPOS )
813
{
814
help = Powerred( prel,
815
QuoInt(quo, potenz),
816
pcp );
817
help = Multiplyboundred( help, x, i+2, flag, pcp);
818
}
819
else
820
{
821
quo = INT_INTOBJ(mod) == 0? QuoInt(quo,potenz):SumInt(QuoInt(quo, potenz),INTOBJ_INT(-1));
822
help = Powerred( prel,
823
quo,
824
pcp );
825
help = Multiplyboundred( help, x, i+2, flag, pcp);
826
}
827
len = LEN_PLIST(help);
828
for (j=1; j<=len; j++)
829
SET_ELM_PLIST(x, j+i+1, ELM_PLIST(help, j) );
830
CHANGED_BAG(x);
831
flag = i+len+1;
832
/*SET_LEN_PLIST(x, flag);*/
833
}
834
}
835
}
836
}
837
SET_LEN_PLIST(x, flag);
838
SHRINK_PLIST(x, flag);
839
/* remove all syllables with exponent 0 from <x>. */
840
compress(x);
841
}
842
843
844
845
/****************************************************************************
846
**
847
*F FuncDTMultiply( <self>, <x>, <y>, <pcp> )
848
**
849
** FuncDTMultiply implements the internal function
850
**
851
*F DTMultiply( <x>, <y>, <pcp> ).
852
**
853
** DTMultiply returns the product of <x> and <y>. The result is reduced
854
** with respect to the deep thought rewriting system <pcp>.
855
*/
856
857
Obj FuncDTMultiply( Obj self,
858
Obj x,
859
Obj y,
860
Obj pcp )
861
{
862
Obj res;
863
864
if ( LEN_PLIST(x) == 0 )
865
return y;
866
if ( LEN_PLIST(y) == 0 )
867
return x;
868
res = Multiplyboundred(x, y, 1, LEN_PLIST(y), pcp);
869
ReduceWord(res, pcp);
870
return res;
871
}
872
873
874
875
/****************************************************************************
876
**
877
*F FuncDTPower( <self>, <x>, <n>, <pcp> )
878
**
879
** FuncDTPower implements the internal function
880
**
881
*F DTPower( <x>, <n>, <pcp> ).
882
**
883
** DTPower returns the <n>-th power of the word <x>. The result is reduced
884
** with respect to the deep thought rewriting system <pcp>.
885
*/
886
887
Obj FuncDTPower( Obj self,
888
Obj x,
889
Obj n,
890
Obj pcp )
891
{
892
Obj res;
893
894
res = Powerred(x, n, pcp);
895
ReduceWord(res, pcp);
896
return res;
897
}
898
899
900
901
/****************************************************************************
902
**
903
*F FuncDTSolution( <self>, <x>, <y>, <pcp> )
904
**
905
** FuncDTSolution implements the internal function
906
**
907
*F DTSolution( <x>, <y>, <pcp> ).
908
**
909
** DTSolution returns the solution of the equation <x>*a = <y>. The result
910
** is reduced with respect to the deep thought rewriting system <pcp>.
911
*/
912
913
Obj FuncDTSolution( Obj self,
914
Obj x,
915
Obj y,
916
Obj pcp )
917
{
918
Obj res;
919
920
if ( LEN_PLIST(x) == 0 )
921
return y;
922
res = Solutionred(x, y, pcp);
923
ReduceWord(res, pcp);
924
return res;
925
}
926
927
928
929
/****************************************************************************
930
**
931
*F FuncDTCommutator( <self>, <x>, <y>. <pcp> )
932
**
933
** FuncDTCommutator implements the internal function
934
**
935
*F DTCommutator( <x>, <y>, <pcp> )
936
**
937
** DTCommutator returns the commutator of the words <x> and <y>. The result
938
** is reduced with respect to the deep thought rewriting sytem <pcp>.
939
*/
940
941
Obj FuncDTCommutator( Obj self,
942
Obj x,
943
Obj y,
944
Obj pcp )
945
{
946
Obj res;
947
948
res = Commutatorred(x, y, pcp);
949
ReduceWord(res, pcp);
950
return res;
951
}
952
953
954
955
/****************************************************************************
956
**
957
*F FuncConjugate( <self>, <x>, <y>, <pcp> )
958
**
959
** FuncConjugate implements the internal function
960
**
961
*F Conjugate( <x>, <y>, <pcp> ).
962
**
963
** Conjugate returns <x>^<y> for the words <x> and <y>. The result is
964
** ewduced with respect to the deep thought rewriting system <pcp>.
965
*/
966
967
Obj FuncDTConjugate( Obj self,
968
Obj x,
969
Obj y,
970
Obj pcp )
971
{
972
Obj res;
973
974
if ( LEN_PLIST(y) == 0 )
975
return x;
976
res = Conjugatered(x, y, pcp);
977
ReduceWord(res, pcp);
978
return res;
979
}
980
981
982
983
/****************************************************************************
984
**
985
*F FuncDTQuotient( <self>, <x>, <y>, <pcp> )
986
**
987
** FuncDTQuotient implements the internal function
988
**
989
*F DTQuotient( <x>, <y>, <pcp> ).
990
**
991
*F DTQuotient returns the <x>/<y> for the words <x> and <y>. The result is
992
** reduced with respect to the deep thought rewriting system <pcp>.
993
*/
994
995
Obj FuncDTQuotient( Obj self,
996
Obj x,
997
Obj y,
998
Obj pcp )
999
{
1000
Obj help, res;
1001
1002
if ( LEN_PLIST(y) == 0 )
1003
return x;
1004
help = NEW_PLIST( T_PLIST, 0 );
1005
SET_LEN_PLIST(help, 0);
1006
res = Solutionred(y, help, pcp);
1007
res = Multiplyboundred(x, res, 1, LEN_PLIST(res), pcp);
1008
ReduceWord(res, pcp);
1009
return(res);
1010
}
1011
1012
1013
1014
/****************************************************************************
1015
**
1016
1017
*F * * * * * * * * * * * * * initialize package * * * * * * * * * * * * * * *
1018
*/
1019
1020
1021
/****************************************************************************
1022
**
1023
1024
*V GVarFuncs . . . . . . . . . . . . . . . . . . list of functions to export
1025
*/
1026
static StructGVarFunc GVarFuncs [] = {
1027
1028
{ "DTCompress", 1, "list",
1029
FuncDTCompress, "src/dteval.c:DTCompress" },
1030
1031
{ "DTMultiply", 3, "lword, rword, rws",
1032
FuncDTMultiply, "src/dteval.c:DTMultiply" },
1033
1034
{ "DTPower", 3, "word, exponent, rws",
1035
FuncDTPower, "src/dteval.c:DTPower" },
1036
1037
{ "DTSolution", 3, "lword, rword, rws",
1038
FuncDTSolution, "src/dteval.c:DTSolution" },
1039
1040
{ "DTCommutator", 3, "lword, rword, rws",
1041
FuncDTCommutator, "src/dteval.c:DTCommutator" },
1042
1043
{ "DTQuotient", 3, "lword, rword, rws",
1044
FuncDTQuotient, "src/dteval.c:DTQuotient" },
1045
1046
{ "DTConjugate", 3, "lword, rword, rws",
1047
FuncDTConjugate, "src/dteval.c:DTConjugate" },
1048
1049
{ 0 }
1050
1051
};
1052
1053
1054
/****************************************************************************
1055
**
1056
1057
*F InitKernel( <module> ) . . . . . . . . initialise kernel data structures
1058
*/
1059
static Int InitKernel (
1060
StructInitInfo * module )
1061
{
1062
/* init filters and functions */
1063
InitHdlrFuncsFromTable( GVarFuncs );
1064
1065
/* return success */
1066
return 0;
1067
}
1068
1069
1070
/****************************************************************************
1071
**
1072
*F PostRestore( <module> ) . . . . . . . . . . . . . after restore workspace
1073
*/
1074
static Int PostRestore (
1075
StructInitInfo * module )
1076
{
1077
evlist = RNamName("evlist");
1078
evlistvec = RNamName("evlistvec");
1079
1080
/* return success */
1081
return 0;
1082
}
1083
1084
1085
/****************************************************************************
1086
**
1087
*F InitLibrary( <module> ) . . . . . . . initialise library data structures
1088
*/
1089
static Int InitLibrary (
1090
StructInitInfo * module )
1091
{
1092
/* init filters and functions */
1093
InitGVarFuncsFromTable( GVarFuncs );
1094
1095
/* return success */
1096
return PostRestore( module );
1097
}
1098
1099
1100
/****************************************************************************
1101
**
1102
*F InitInfoDTEvaluation() . . . . . . . . . . . . . table of init functions
1103
*/
1104
static StructInitInfo module = {
1105
MODULE_BUILTIN, /* type */
1106
"dteval", /* name */
1107
0, /* revision entry of c file */
1108
0, /* revision entry of h file */
1109
0, /* version */
1110
0, /* crc */
1111
InitKernel, /* initKernel */
1112
InitLibrary, /* initLibrary */
1113
0, /* checkInit */
1114
0, /* preSave */
1115
0, /* postSave */
1116
PostRestore /* postRestore */
1117
};
1118
1119
StructInitInfo * InitInfoDTEvaluation ( void )
1120
{
1121
return &module;
1122
}
1123
1124
1125
/****************************************************************************
1126
**
1127
1128
*E dteval.c . . . . . . . . . . . . . . . . . . . . . . . . . . . ends here
1129
**
1130
*/
1131
1132