1 /****************************************************************************
2 **
3 **  This file is part of GAP, a system for computational discrete algebra.
4 **
5 **  Copyright of GAP belongs to its developers, whose names are too numerous
6 **  to list here. Please refer to the COPYRIGHT file for details.
7 **
8 **  SPDX-License-Identifier: GPL-2.0-or-later
9 **
10 **  This file declares the functions of the  arithmetic  operations  package.
11 */
12 
13 #ifndef GAP_ARITHS_H
14 #define GAP_ARITHS_H
15 
16 #include "objects.h"
17 
18 /****************************************************************************
19 **
20 *T  CompaMethod . . . . . . . . . . type of methods for comparison operations
21 **
22 **  'CompaMethod'  is the type of methods  for comparison operations, i.e., a
23 **  function accepting two arguments of type 'Obj' and returning an 'Int'.
24 */
25 typedef Int (* CompaMethod) ( Obj opL, Obj opR );
26 
27 
28 /****************************************************************************
29 **
30 *T  ArithMethod1  . . . . . . . . . type of methods for arithmetic operations
31 **
32 **  'ArithMethod1'  is the type of  methods  for unary arithmetic operations,
33 **  i.e.,  a function accepting  one argument of type  'Obj' and returning an
34 **  'Obj'.
35 */
36 typedef Obj (* ArithMethod1) ( Obj op );
37 
38 
39 /****************************************************************************
40 **
41 *T  ArithMethod2  . . . . . . . . . type of methods for arithmetic operations
42 **
43 **  'ArithMethod2' is the type  of methods for binary arithmetic  operations,
44 **  i.e., a function  accepting two arguments  of type 'Obj' and returning an
45 **  'Obj'.
46 */
47 typedef Obj (* ArithMethod2) ( Obj opL, Obj opR );
48 
49 
50 /****************************************************************************
51 **
52 *F * * * * * * * * * * *  unary arithmetic operations * * * * * * * * * * * *
53 */
54 
55 
56 /****************************************************************************
57 **
58 *V  ZeroFuncs[<type>] . . . . . . . . . . . . . . . . . table of zero methods
59 */
60 extern ArithMethod1 ZeroFuncs[LAST_REAL_TNUM + 1];
61 
62 
63 /****************************************************************************
64 **
65 *F  ZERO( <op> )  . . . . . . . . . . . . . . . . . . . . . zero of an object
66 **
67 **  'ZERO' returns the zero of the object <op>.
68 */
ZERO(Obj op)69 EXPORT_INLINE Obj ZERO(Obj op)
70 {
71     UInt tnum = TNUM_OBJ(op);
72     return (*ZeroFuncs[tnum])(op);
73 }
74 
75 
76 /****************************************************************************
77 **
78 *V  ZeroMutFuncs[<type>] . . . . . . . . . . . . . . .  table of zero methods
79 */
80 extern ArithMethod1 ZeroMutFuncs[LAST_REAL_TNUM + 1];
81 
82 
83 /****************************************************************************
84 **
85 *F  ZERO_MUT( <op> )  . . . . . . . . . . . . . . . . . . . zero of an object
86 **
87 **  'ZERO_MUT' returns the mutable zero of the object <op>.
88 */
ZERO_MUT(Obj op)89 EXPORT_INLINE Obj ZERO_MUT(Obj op)
90 {
91     UInt tnum = TNUM_OBJ(op);
92     return (*ZeroMutFuncs[tnum])(op);
93 }
94 
95 
96 /****************************************************************************
97 **
98 *V  AInvFuncs[<type>] . . . . . . . . . . . table of additive inverse methods
99 */
100 extern ArithMethod1 AInvFuncs[LAST_REAL_TNUM + 1];
101 
102 
103 /****************************************************************************
104 **
105 *F  AINV( <op> )  . . . . . . . . . . . . . . . additive inverse of an object
106 **
107 **  'AINV' returns the additive inverse of the object <op>.
108 */
AINV(Obj op)109 EXPORT_INLINE Obj AINV(Obj op)
110 {
111     UInt tnum = TNUM_OBJ(op);
112     return (*AInvFuncs[tnum])(op);
113 }
114 
115 
116 /****************************************************************************
117 **
118 *V  AInvMutFuncs[<type>] . . . . . . . . .  table of additive inverse methods
119 */
120 extern ArithMethod1 AInvMutFuncs[LAST_REAL_TNUM + 1];
121 
122 
123 /****************************************************************************
124 **
125 *F  AINV_MUT( <op> )  . . . . . . . . . . . . . additive inverse of an object
126 **
127 **  'AINV_MUT' returns the mutable additive inverse of the object <op>.
128 */
AINV_MUT(Obj op)129 EXPORT_INLINE Obj AINV_MUT(Obj op)
130 {
131     UInt tnum = TNUM_OBJ(op);
132     return (*AInvMutFuncs[tnum])(op);
133 }
134 
135 
136 /****************************************************************************
137 **
138 *F  C_AINV( <val>, <left> ) . . . . . . . . . . . . . . . . . .  compute ainv
139 */
140 #define C_AINV(val,left) \
141  val = AINV_MUT( left );
142 
143 
144 /****************************************************************************
145 **
146 *F  C_AINV_FIA( <val>, <left> ) . . . . . . . . .  compute ainv, fast integer
147 */
148 #define C_AINV_FIA(val,left) \
149  val = AINV_MUT( left );
150 
151 
152 /****************************************************************************
153 **
154 *F  C_AINV_INTOBJS( <val>, <left> ) . . . . . . .  compute ainv of an integer
155 */
156 #define C_AINV_INTOBJS(val,left) \
157  val = AINV_MUT( left );
158 
159 
160 /****************************************************************************
161 **
162 *V  OneFuncs[<type>]  . . . . . . . . . . . . . . . . .  table of one methods
163 */
164 extern ArithMethod1 OneFuncs[LAST_REAL_TNUM + 1];
165 
166 
167 /****************************************************************************
168 **
169 *F  ONE( <op> ) . . . . . . . . . . . . . . . . . . . . . .  one of an object
170 **
171 **  'ONE' returns the one of the object <op>.
172 */
ONE(Obj op)173 EXPORT_INLINE Obj ONE(Obj op)
174 {
175     UInt tnum = TNUM_OBJ(op);
176     return (*OneFuncs[tnum])(op);
177 }
178 
179 
180 /****************************************************************************
181 **
182 *V  OneMutFuncs[<type>]  . . . . . .table of mutability preservingone methods
183 */
184 extern ArithMethod1 OneMutFuncs[LAST_REAL_TNUM + 1];
185 
186 
187 /****************************************************************************
188 **
189 *F  ONE_MUT( <op> )    . . . . . . . .  one of an object retaining mutability
190 **
191 **  'ONE_MUT' returns the one of the object <op> with the same
192 **  mutability level as <op>.
193 */
ONE_MUT(Obj op)194 EXPORT_INLINE Obj ONE_MUT(Obj op)
195 {
196     UInt tnum = TNUM_OBJ(op);
197     return (*OneMutFuncs[tnum])(op);
198 }
199 
200 
201 /****************************************************************************
202 **
203 *V  InvFuncs[<type>]  . . . . . . . . . . . . . .  table of inverse functions
204 */
205 extern ArithMethod1 InvFuncs[LAST_REAL_TNUM + 1];
206 
207 
208 /****************************************************************************
209 **
210 *F  INV( <op> ) . . . . . . . . . . . . . . . . . . . .  inverse of an object
211 **
212 **  'INV' returns the multiplicative inverse of the object <op>.
213 */
INV(Obj op)214 EXPORT_INLINE Obj INV(Obj op)
215 {
216     UInt tnum = TNUM_OBJ(op);
217     return (*InvFuncs[tnum])(op);
218 }
219 
220 
221 /****************************************************************************
222 **
223 *V  InvMutFuncs[<type>]  .. .table of mutability preserving inverse functions
224 */
225 extern ArithMethod1 InvMutFuncs[LAST_REAL_TNUM + 1];
226 
227 
228 /****************************************************************************
229 **
230 *F  INV_MUT( <op> ) . . . . . . . . inverse of an object retaining mutability
231 **
232 **  'INV_MUT' returns the multiplicative inverse of the object <op>.
233 */
INV_MUT(Obj op)234 EXPORT_INLINE Obj INV_MUT(Obj op)
235 {
236     UInt tnum = TNUM_OBJ(op);
237     return (*InvMutFuncs[tnum])(op);
238 }
239 
240 
241 /****************************************************************************
242 **
243 *F * * * * * * * * * * * * * comparison operations  * * * * * * * * * * * * *
244 */
245 
246 
247 /****************************************************************************
248 **
249 *V  EqFuncs[<typeL>][<typeR>] . . . . . . . . . . table of comparison methods
250 */
251 extern CompaMethod EqFuncs[LAST_REAL_TNUM + 1][LAST_REAL_TNUM + 1];
252 
253 
254 /****************************************************************************
255 **
256 *F  EQ( <opL>, <opR> )  . . . . . . . . . . . . . . comparison of two objects
257 **
258 **  'EQ' returns a nonzero value  if the object <opL>  is equal to the object
259 **  <opR>, and zero otherwise.
260 */
EQ(Obj opL,Obj opR)261 EXPORT_INLINE Int EQ(Obj opL, Obj opR)
262 {
263     if (opL == opR)
264         return 1;
265     if (ARE_INTOBJS(opL, opR))
266         return 0;
267     UInt tnumL = TNUM_OBJ(opL);
268     UInt tnumR = TNUM_OBJ(opR);
269     return (*EqFuncs[tnumL][tnumR])(opL, opR);
270 }
271 
272 extern Obj EqOper;
273 
274 Int EqObject(Obj opL, Obj opR);
275 
276 
277 /****************************************************************************
278 **
279 *V  LtFuncs[<typeL>][<typeR>] . . . . . . . . . . table of comparison methods
280 */
281 extern CompaMethod LtFuncs[LAST_REAL_TNUM + 1][LAST_REAL_TNUM + 1];
282 
283 
284 /****************************************************************************
285 **
286 *F  LT( <opL>, <opR> )  . . . . . . . . . . . . . . comparison of two objects
287 **
288 **  'LT' returns a nonzero value if the object <opL> is  less than the object
289 **  <opR>, and zero otherwise.
290 */
LT(Obj opL,Obj opR)291 EXPORT_INLINE Int LT(Obj opL, Obj opR)
292 {
293     if (opL == opR)
294         return 0;
295     if (ARE_INTOBJS(opL, opR))
296         return (Int)(opL) < (Int)(opR);
297     UInt tnumL = TNUM_OBJ(opL);
298     UInt tnumR = TNUM_OBJ(opR);
299     return (*LtFuncs[tnumL][tnumR])(opL, opR);
300 }
301 
302 extern Obj LtOper;
303 
304 
305 /****************************************************************************
306 **
307 *V  InFuncs[<typeL>][<typeR>] . . . . . . . . . . table of membership methods
308 */
309 extern CompaMethod InFuncs[LAST_REAL_TNUM + 1][LAST_REAL_TNUM + 1];
310 
311 
312 /****************************************************************************
313 **
314 *F  IN( <opL>, <opR> )  . . . . . . . . . . .  membership test of two objects
315 **
316 **  'IN' returns a nonzero   value if the object  <opL>  is a member  of  the
317 **  object <opR>, and zero otherwise.
318 */
IN(Obj opL,Obj opR)319 EXPORT_INLINE Int IN(Obj opL, Obj opR)
320 {
321     UInt tnumL = TNUM_OBJ(opL);
322     UInt tnumR = TNUM_OBJ(opR);
323     return (*InFuncs[tnumL][tnumR])(opL, opR);
324 }
325 
326 
327 /****************************************************************************
328 **
329 *F * * * * * * * * * * * binary arithmetic operations * * * * * * * * * * * *
330 */
331 
332 /****************************************************************************
333 **
334 *V  SumFuncs[<typeL>][<typeR>]  . . . . . . . . . . . .  table of sum methods
335 */
336 extern ArithMethod2 SumFuncs[LAST_REAL_TNUM + 1][LAST_REAL_TNUM + 1];
337 
338 
339 /****************************************************************************
340 **
341 *F  SUM( <opL>, <opR> ) . . . . . . . . . . . . . . . . .  sum of two objects
342 **
343 **  'SUM' returns the sum of the two objects <opL> and <opR>.
344 **
345 **  At places where performance matters one should use the following code
346 **
347 **      if ( ! ARE_INTOBJS( <opL>, <opR> )
348 **        || ! SUM_INTOBJS( <res>, <opL>, <opR> ) )
349 **          <res> = SUM( <opL>, <opR> );
350 */
SUM(Obj opL,Obj opR)351 EXPORT_INLINE Obj SUM(Obj opL, Obj opR)
352 {
353     UInt tnumL = TNUM_OBJ(opL);
354     UInt tnumR = TNUM_OBJ(opR);
355     return (*SumFuncs[tnumL][tnumR])(opL, opR);
356 }
357 
358 
359 extern Obj SumOper;
360 
361 
362 /****************************************************************************
363 **
364 *F  C_SUM( <val>, <left>, <right> ) . . . . . . . . . . . . . . . compute sum
365 */
366 #define C_SUM(val,left,right) \
367  val = SUM( left, right );
368 
369 
370 /****************************************************************************
371 **
372 *F  C_SUM_FIA( <val>, <left>, <right> ) . . . . .  compute sum, fast integers
373 */
374 #define C_SUM_FIA(val,left,right) \
375  if ( ! ARE_INTOBJS(left,right) || ! SUM_INTOBJS(val,left,right) ) { \
376   val = SUM( left, right ); \
377  }
378 
379 
380 /****************************************************************************
381 **
382 *F  C_SUM_INTOBJS( <val>, <left>, <right> ) . . . compute sum of two integers
383 */
384 #define C_SUM_INTOBJS(val,left,right) \
385  if ( ! SUM_INTOBJS(val,left,right) ) { \
386   val = SUM( left, right ); \
387  }
388 
389 
390 /****************************************************************************
391 **
392 *V  DiffFuncs[<typeL>][<typeR>] . . . . . . . . . table of difference methods
393 */
394 extern ArithMethod2 DiffFuncs[LAST_REAL_TNUM + 1][LAST_REAL_TNUM + 1];
395 
396 
397 /****************************************************************************
398 **
399 *F  DIFF( <opL>, <opR> )  . . . . . . . . . . . . . difference of two objects
400 **
401 **  'DIFF' returns the difference of the two objects <opL> and <opR>.
402 **
403 **  At places where performance matters one should use the following code
404 **
405 **      if ( ! ARE_INTOBJS( <opL>, <opR> )
406 **        || ! DIFF_INTOBJS( <res>, <opL>, <opR> ) )
407 **          <res> = DIFF( <opL>, <opR> );
408 */
DIFF(Obj opL,Obj opR)409 EXPORT_INLINE Obj DIFF(Obj opL, Obj opR)
410 {
411     UInt tnumL = TNUM_OBJ(opL);
412     UInt tnumR = TNUM_OBJ(opR);
413     return (*DiffFuncs[tnumL][tnumR])(opL, opR);
414 }
415 
416 
417 /****************************************************************************
418 **
419 *F  C_DIFF( <val>, <left>, <right> )  . . . . . . . . . . . . .  compute diff
420 */
421 #define C_DIFF(val,left,right) \
422  val = DIFF( left, right );
423 
424 
425 /****************************************************************************
426 **
427 *F  C_DIFF_FIA( <val>, <left>, <right> )  . . . . compute diff, fast integers
428 */
429 #define C_DIFF_FIA(val,left,right) \
430  if ( ! ARE_INTOBJS(left,right) || ! DIFF_INTOBJS(val,left,right) ) { \
431   val = DIFF( left, right ); \
432  }
433 
434 
435 /****************************************************************************
436 **
437 *F  C_DIFF_INTOBJS( <val>, <left>, <right> )  .  compute diff of two integers
438 */
439 #define C_DIFF_INTOBJS(val,left,right) \
440  if ( ! DIFF_INTOBJS(val,left,right) ) { \
441   val = DIFF( left, right ); \
442  }
443 
444 
445 /****************************************************************************
446 **
447 *V  ProdFuncs[<typeL>][<typeR>] . . . . . . . . . .  table of product methods
448 */
449 extern ArithMethod2 ProdFuncs[LAST_REAL_TNUM + 1][LAST_REAL_TNUM + 1];
450 
451 
452 /****************************************************************************
453 **
454 *F  PROD( <opL>, <opR> )  . . . . . . . . . . . . . .  product of two objects
455 **
456 **  'PROD' returns the product of the two objects <opL> and <opR>.
457 **
458 **  At places where performance matters one should use the following code
459 **
460 **      if ( ! ARE_INTOBJS( <opL>, <opR> )
461 **        || ! PROD_INTOBJS( <res>, <opL>, <opR> ) )
462 **          <res> = PROD( <opL>, <opR> );
463 */
PROD(Obj opL,Obj opR)464 EXPORT_INLINE Obj PROD(Obj opL, Obj opR)
465 {
466     UInt tnumL = TNUM_OBJ(opL);
467     UInt tnumR = TNUM_OBJ(opR);
468     return (*ProdFuncs[tnumL][tnumR])(opL, opR);
469 }
470 
471 
472 /****************************************************************************
473 **
474 *F  C_PROD( <val>, <left>, <right> )  . . . . . . . . . . . . compute product
475 */
476 #define C_PROD(val,left,right) \
477  val = PROD( left, right );
478 
479 
480 /****************************************************************************
481 **
482 *F  C_PROD_FIA( <val>, <left>, <right> )  . .  compute product, fast integers
483 */
484 #define C_PROD_FIA(val,left,right) \
485  if ( ! ARE_INTOBJS(left,right) || ! PROD_INTOBJS(val,left,right) ) { \
486   val = PROD( left, right ); \
487  }
488 
489 
490 /****************************************************************************
491 **
492 *F  C_PROD_INTOBJS( <val>, <left>, <right> )  compute product of two integers
493 */
494 #define C_PROD_INTOBJS(val,left,right) \
495  if ( ! PROD_INTOBJS(val,left,right) ) { \
496   val = PROD( left, right ); \
497  }
498 
499 
500 /****************************************************************************
501 **
502 *V  QuoFuncs[<typeL>][<typeR>]  . . . . . . . . . . table of quotient methods
503 */
504 extern ArithMethod2 QuoFuncs[LAST_REAL_TNUM + 1][LAST_REAL_TNUM + 1];
505 
506 
507 /****************************************************************************
508 **
509 *F  QUO( <opL>, <opR> ) . . . . . . . . . . . . . . . quotient of two objects
510 **
511 **  'QUO' returns the quotient of the object <opL> by the object <opR>.
512 */
QUO(Obj opL,Obj opR)513 EXPORT_INLINE Obj QUO(Obj opL, Obj opR)
514 {
515     UInt tnumL = TNUM_OBJ(opL);
516     UInt tnumR = TNUM_OBJ(opR);
517     return (*QuoFuncs[tnumL][tnumR])(opL, opR);
518 }
519 
520 
521 /****************************************************************************
522 **
523 *V  LQuoFuncs[<typeL>][<typeR>] . . . . . . .  table of left quotient methods
524 */
525 extern ArithMethod2 LQuoFuncs[LAST_REAL_TNUM + 1][LAST_REAL_TNUM + 1];
526 
527 
528 /****************************************************************************
529 **
530 *F  LQUO( <opL>, <opR> )  . . . . . . . . . . .  left quotient of two operand
531 **
532 **  'LQUO' returns the left quotient of the object <opL> by the object <opR>.
533 */
LQUO(Obj opL,Obj opR)534 EXPORT_INLINE Obj LQUO(Obj opL, Obj opR)
535 {
536     UInt tnumL = TNUM_OBJ(opL);
537     UInt tnumR = TNUM_OBJ(opR);
538     return (*LQuoFuncs[tnumL][tnumR])(opL, opR);
539 }
540 
541 
542 /****************************************************************************
543 **
544 *V  PowFuncs[<typeL>][<typeR>]  . . . . . . . . . . .  table of power methods
545 */
546 extern ArithMethod2 PowFuncs[LAST_REAL_TNUM + 1][LAST_REAL_TNUM + 1];
547 
548 
549 /****************************************************************************
550 **
551 *F  POW( <opL>, <opR> ) . . . . . . . . . . . . . . . .  power of two objects
552 **
553 **  'POW' returns the power of the object <opL> by the object <opL>.
554 */
POW(Obj opL,Obj opR)555 EXPORT_INLINE Obj POW(Obj opL, Obj opR)
556 {
557     UInt tnumL = TNUM_OBJ(opL);
558     UInt tnumR = TNUM_OBJ(opR);
559     return (*PowFuncs[tnumL][tnumR])(opL, opR);
560 }
561 
562 
563 /****************************************************************************
564 **
565 *V  CommFuncs[<typeL>][<typeR>] . . . . . . . . . table of commutator methods
566 */
567 extern ArithMethod2 CommFuncs[LAST_REAL_TNUM + 1][LAST_REAL_TNUM + 1];
568 
569 
570 /****************************************************************************
571 **
572 *F  COMM( <opL>, <opR> )  . . . . . . . . . . . . . commutator of two objects
573 **
574 **  'COMM' returns the commutator of the two objects <opL> and <opR>.
575 */
COMM(Obj opL,Obj opR)576 EXPORT_INLINE Obj COMM(Obj opL, Obj opR)
577 {
578     UInt tnumL = TNUM_OBJ(opL);
579     UInt tnumR = TNUM_OBJ(opR);
580     return (*CommFuncs[tnumL][tnumR])(opL, opR);
581 }
582 
583 
584 /****************************************************************************
585 **
586 *V  ModFuncs[<typeL>][<typeR>]  . . . . . . . . .  table of remainder methods
587 */
588 extern ArithMethod2 ModFuncs[LAST_REAL_TNUM + 1][LAST_REAL_TNUM + 1];
589 
590 
591 /****************************************************************************
592 **
593 *F  MOD( <opL>, <opR> ) . . . . . . . . . . . . . .  remainder of two objects
594 **
595 **  'MOD' returns the remainder of the object <opL> by the object <opR>.
596 */
MOD(Obj opL,Obj opR)597 EXPORT_INLINE Obj MOD(Obj opL, Obj opR)
598 {
599     UInt tnumL = TNUM_OBJ(opL);
600     UInt tnumR = TNUM_OBJ(opR);
601     return (*ModFuncs[tnumL][tnumR])(opL, opR);
602 }
603 
604 
605 /****************************************************************************
606 **
607 *F  ChangeArithDoOperations( <oper>, <verb> )
608 */
609 void ChangeArithDoOperations(Obj oper, Int verb);
610 
611 
612 /****************************************************************************
613 **
614 *F * * * * * * * * * * * * * initialize module * * * * * * * * * * * * * * *
615 */
616 
617 /****************************************************************************
618 **
619 *F  InitInfoAriths()  . . . . . . . . . . . . . . . . table of init functions
620 */
621 StructInitInfo * InitInfoAriths ( void );
622 
623 
624 #endif // GAP_ARITHS_H
625