1 /****************************************
2 *  Computer Algebra System SINGULAR     *
3 ****************************************/
4 /***************************************************************
5  *  File:    p_Procs_Impl.h
6  *  Purpose: implementation of primitive procs for polys
7  *  Author:  obachman (Olaf Bachmann)
8  *  Created: 12/00
9  *******************************************************************/
10 #ifndef P_PROCS_IMPL_H
11 #define P_PROCS_IMPL_H
12 
13 #include "misc/auxiliary.h"
14 
15 /***************************************************************
16  *
17  * Configurations
18  *
19  *******************************************************************/
20 
21 /***************************************************************
22  Here is how it works:
23  At run-time, SetProcs is used to choose the appropriate PolyProcs
24               based on the ring properies.
25  At generate-time, SetProcs is used to generate all
26               possible PolyProcs.
27  Which PolyProcs are generated/used can be controled by values of
28  HAVE_FAST_P_PROCS, HAVE_FAST_LENGTH, HAVE_FAST_ORD, and FAST_FIELD
29 
30  At generate-time, the file p_Procs.inc is generated,
31  which provides implementations of the p_Procs, based on
32  the p_*_Templates.cc and header files which provide the respective
33  macros.
34 
35  At run-time, a fast proc is set/chosen if found/generated, else
36  a general proc is set/chosen.
37  *******************************************************************/
38 
39 // Define HAVE_FAST_P_PROCS to:
40 //   0 -- only FieldGeneral_LengthGeneral_OrdGeneral
41 //   1 -- plus FieldZp_Length*_OrdGeneral procs
42 //   2 -- plus FieldZp_Length*_Ord* procs
43 //   3 -- plus FieldQ_Length*_Ord*
44 //   4 -- plus FieldGeneral_Length*_OrdGeneral procs
45 //   5 -- all Field*_Length*_Ord* procs
46 #ifndef HAVE_FAST_P_PROCS
47 #define HAVE_FAST_P_PROCS 0
48 #endif
49 
50 // Define HAVE_FAST_FIELD to:
51 //   0 -- only FieldGeneral
52 //   1 -- special cases for FieldZp
53 //   2 -- plus special cases for FieldQ
54 //   nothing else is implemented, yet
55 #ifndef HAVE_FAST_FIELD
56 #define HAVE_FAST_FIELD 0
57 #endif
58 
59 // Define HAVE_FAST_LENGTH to:
60 //   0 -- only LengthGeneral
61 //   1 -- special cases for length <= 1
62 //   2 -- special cases for length <= 2
63 //   3 -- special cases for length <= 4
64 //   4 -- special cases for length <= 8
65 #ifndef HAVE_FAST_LENGTH
66 #define HAVE_FAST_LENGTH 0
67 #endif
68 
69 // Define HAVE_FAST_ORD to:
70 //  0  -- only OrdGeneral
71 //  1  -- special for ords with n_min <= 1
72 //  2  -- special for ords with n_min <= 2
73 //  3  -- special ords for with n_min <= 3
74 //  4  -- special for all ords
75 #ifndef HAVE_FAST_ORD
76 #define HAVE_FAST_ORD 0
77 #endif
78 
79 // Define HAVE_FAST_ZERO_ORD to:
80 //  0 -- no zero ords are considered
81 //  1 -- only ZeroOrds for OrdPosNomogPosZero, OrdNomogPosZero, OrdPomogNegZero
82 //  2 -- ZeroOrds for all
83 #ifndef HAVE_FAST_ZERO_ORD
84 #define HAVE_FAST_ZERO_ORD 0
85 #endif
86 
87 // undefine this, if ExpL_Size always equals CompLSize
88 #define HAVE_LENGTH_DIFF
89 
90 
91 // Predicate which returns true if alloc/copy/free of numbers is
92 // like that of Zp (rings should use GMP in future)
93 #define ZP_COPY_FIELD(field) \
94   (field == FieldZp || field == FieldGF || field == FieldR)
95 
96 /***************************************************************
97  *
98  * Definitions of our fields, lengths, ords, procs we work with
99  *
100  *******************************************************************/
101 
102 // Here are the different parameters for setting the PolyProcs:
103 
104 // If you add/remove things from here, also remeber to adjust the
105 // respective *_2_String
106 typedef enum p_Field
107 {
108   FieldGeneral = 0,
109   FieldZp,
110   FieldQ,
111   FieldR,
112   FieldGF,
113 #if HAVE_MORE_FIELDS_IMPLEMENTED
114   FieldLong_R,
115   FieldLong_C,
116   FieldZp_a,
117   FieldQ_a,
118 #endif
119   RingGeneral,
120   FieldUnknown
121 } p_Field;
122 typedef enum p_Length // Length of exponent vector in words
123 {
124   LengthGeneral = 0, // n >= 1
125   LengthEight,       // n == 8
126   LengthSeven,
127   LengthSix,
128   LengthFive,
129   LengthFour,
130   LengthThree,
131   LengthTwo,
132   LengthOne,
133   LengthUnknown
134 } p_Length;
135 typedef enum p_Ord
136 {
137   OrdGeneral = 0,
138                     //     ordsgn
139                     //  0   1   i   n-1 n   n_min   Example
140   OrdPomog,         //  +   +   +   +   +   1       (lp,C)
141   OrdNomog,         //  -   -   -   -   -   1       (ls, c), (ds, c)
142 #define ORD_MAX_N_1 OrdNomog
143 
144 #ifdef HAVE_LENGTH_DIFF
145   OrdPomogZero,     //  +   +   +   +   0   2       (Dp, C), Even vars
146   OrdNomogZero,     //  -   -   -   -   0   2       (ds, c), Even vars
147 #endif
148 
149   OrdNegPomog,      //  -   +   +   +   +   2       (c, lp), (Ds, c)
150   OrdPomogNeg,      //  +   +   +   +   -   2       (lp, c)
151 #define ORD_MAX_N_2 OrdPomogNeg
152 
153   OrdPosNomog,      //  +   -   -   -   +   3       (dp, c) (for n == 2, use PomogNeg)
154   OrdNomogPos,      //  -   -   -   -   +   3       (ls, C) (for n == 2, use NegPomog)
155 
156 #ifdef HAVE_LENGTH_DIFF
157   OrdNegPomogZero,  //  -   +   +   +   0   3       (c, lp), (Ds, c)
158   OrdPomogNegZero,  //  +   +   +   -   0   3       (lp, c)
159 #endif
160 
161   OrdPosPosNomog,   //  +   +   -   -   -   3       (C, dp)
162   OrdPosNomogPos,   //  +   -   -   -   +   3       (dp, C)
163   OrdNegPosNomog,   //  -   +   -   -   -   3       (c, dp)
164 #define ORD_MAX_N_3 OrdNegPosNomog
165 
166 #ifdef HAVE_LENGTH_DIFF
167   OrdNomogPosZero,  //  -   -   -   +   0   4       (ls, C) (for n == 3, use NegPomogZero)
168   OrdPosNomogZero,  //  +   -   -   -   0   4       (dp, c) (for n == 3, use PomogNegZero)
169 
170   OrdPosPosNomogZero,// +   +   -   -   0   4       (C, dp)
171   OrdPosNomogPosZero,// +   -   -   +   0   4       (dp, C)
172   OrdNegPosNomogZero,// -   +   -   -   0   4       (c, dp)
173 #endif
174 
175   OrdUnknown
176 } p_Ord;
177 
178 typedef enum p_Proc
179 {
180   p_Copy_Proc = 0,
181   p_Delete_Proc,
182   p_ShallowCopyDelete_Proc,
183   p_Mult_nn_Proc,
184   pp_Mult_nn_Proc,
185   pp_Mult_mm_Proc,
186   pp_Mult_mm_Noether_Proc,
187   p_Mult_mm_Proc,
188   p_Add_q_Proc,
189   p_Minus_mm_Mult_qq_Proc,
190   p_Neg_Proc,
191   pp_Mult_Coeff_mm_DivSelect_Proc,
192   pp_Mult_Coeff_mm_DivSelectMult_Proc,
193   p_Merge_q_Proc,
194   p_kBucketSetLm_Proc,
195   p_Unknown_Proc
196 } p_Proc;
197 
p_FieldEnum_2_String(p_Field field)198 static inline const char* p_FieldEnum_2_String(p_Field field)
199 {
200   switch(field)
201   {
202       case FieldGeneral: return "FieldGeneral";
203       case FieldZp: return "FieldZp";
204       case FieldQ: return "FieldQ";
205       case FieldR: return "FieldR";
206       case FieldGF: return "FieldGF";
207 #if HAVE_MORE_FIELDS_IMPLEMENTED
208       case FieldLong_R: return "FieldLong_R";
209       case FieldLong_C: return "FieldLong_C";
210       case FieldZp_a: return "FieldZp_a";
211       case FieldQ_a: return "FieldQ_a";
212 #endif
213       case RingGeneral: return "RingGeneral";
214       case FieldUnknown: return "FieldUnknown";
215   }
216   return "NoField_2_String";
217 }
218 
p_LengthEnum_2_String(p_Length length)219 static inline const char* p_LengthEnum_2_String(p_Length length)
220 {
221   switch(length)
222   {
223       case LengthGeneral: return "LengthGeneral";
224       case LengthEight: return "LengthEight";
225       case LengthSeven: return "LengthSeven";
226       case LengthSix: return "LengthSix";
227       case LengthFive: return "LengthFive";
228       case LengthFour: return "LengthFour";
229       case LengthThree: return "LengthThree";
230       case LengthTwo: return "LengthTwo";
231       case LengthOne: return "LengthOne";
232       case LengthUnknown: return "LengthUnknown";
233   }
234   return "NoLength_2_String";
235 }
236 
p_OrdEnum_2_String(p_Ord ord)237 static inline const char* p_OrdEnum_2_String(p_Ord ord)
238 {
239   switch(ord)
240   {
241       case OrdGeneral: return "OrdGeneral";
242       case OrdPomog: return "OrdPomog";
243       case OrdNomog: return "OrdNomog";
244       case OrdNegPomog: return "OrdNegPomog";
245       case OrdPomogNeg: return "OrdPomogNeg";
246       case OrdPosNomog: return "OrdPosNomog";
247       case OrdNomogPos: return "OrdNomogPos";
248       case OrdPosPosNomog: return "OrdPosPosNomog";
249       case OrdPosNomogPos: return "OrdPosNomogPos";
250       case OrdNegPosNomog: return "OrdNegPosNomog";
251 #ifdef HAVE_LENGTH_DIFF
252       case OrdNegPomogZero: return "OrdNegPomogZero";
253       case OrdPomogNegZero: return "OrdPomogNegZero";
254       case OrdPomogZero: return "OrdPomogZero";
255       case OrdNomogZero: return "OrdNomogZero";
256       case OrdNomogPosZero: return "OrdNomogPosZero";
257       case OrdPosNomogZero: return "OrdPosNomogZero";
258       case OrdPosPosNomogZero: return "OrdPosPosNomogZero";
259       case OrdPosNomogPosZero: return "OrdPosNomogPosZero";
260       case OrdNegPosNomogZero: return "OrdNegPosNomogZero";
261 #endif
262       case OrdUnknown: return "OrdUnknown";
263   }
264   return "NoOrd_2_String";
265 }
266 
p_ProcEnum_2_String(p_Proc proc)267 static inline const char* p_ProcEnum_2_String(p_Proc proc)
268 {
269   switch(proc)
270   {
271       case p_Copy_Proc: return "p_Copy_Proc";
272       case p_Delete_Proc: return "p_Delete_Proc";
273       case p_ShallowCopyDelete_Proc: return "p_ShallowCopyDelete_Proc";
274       case p_Mult_nn_Proc: return "p_Mult_nn_Proc";
275       case pp_Mult_nn_Proc: return "pp_Mult_nn_Proc";
276       case pp_Mult_mm_Proc: return "pp_Mult_mm_Proc";
277       case pp_Mult_mm_Noether_Proc: return "pp_Mult_mm_Noether_Proc";
278       case p_Mult_mm_Proc: return "p_Mult_mm_Proc";
279       case p_Add_q_Proc: return "p_Add_q_Proc";
280       case p_Minus_mm_Mult_qq_Proc: return "p_Minus_mm_Mult_qq_Proc";
281       case p_Neg_Proc: return "p_Neg_Proc";
282       case pp_Mult_Coeff_mm_DivSelect_Proc: return "pp_Mult_Coeff_mm_DivSelect_Proc";
283       case pp_Mult_Coeff_mm_DivSelectMult_Proc: return "pp_Mult_Coeff_mm_DivSelectMult_Proc";
284       case p_Merge_q_Proc: return "p_Merge_q_Proc";
285       case p_kBucketSetLm_Proc: return "p_kBucketSetLm_Proc";
286       case p_Unknown_Proc: return "p_Unknown_Proc";
287   }
288   return "NoProc_2_String";
289 }
290 
p_ProcDependsOn_Field(p_Proc proc)291 static inline int p_ProcDependsOn_Field(p_Proc proc)
292 {
293   if (proc == p_ShallowCopyDelete_Proc ||
294       proc == p_Merge_q_Proc)
295     return 0;
296   return 1;
297 }
298 
p_ProcDependsOn_Ord(p_Proc proc)299 static inline int p_ProcDependsOn_Ord(p_Proc proc)
300 {
301   switch(proc)
302   {
303       case p_Add_q_Proc:
304       case p_Minus_mm_Mult_qq_Proc:
305       case pp_Mult_mm_Noether_Proc:
306       case p_kBucketSetLm_Proc:
307       case p_Merge_q_Proc:
308         return 1;
309 
310       default:
311         return 0;
312   }
313 }
314 
p_ProcDependsOn_Length(p_Proc proc)315 static inline int p_ProcDependsOn_Length(p_Proc proc)
316 {
317   switch(proc)
318   {
319       case p_Delete_Proc:
320       case p_Mult_nn_Proc:
321       case p_Neg_Proc:
322         return 0;
323 
324       default:
325         return 1;
326   }
327 }
328 
329 // returns string specifying the module into which the p_Proc
330 // should go
p_ProcField_2_Module(p_Proc proc,p_Field field)331 static inline const char* p_ProcField_2_Module(p_Proc proc,  p_Field field)
332 {
333   if (! p_ProcDependsOn_Field(proc))
334     return "FieldIndep";
335   else
336   {
337     if (field > FieldQ) field = FieldGeneral;
338     return p_FieldEnum_2_String(field);
339   }
340 }
341 
342 /***************************************************************
343  *
344  *
345  * Deal with OrdZero
346  *
347  *******************************************************************/
348 #ifdef HAVE_LENGTH_DIFF
IsZeroOrd(p_Ord ord)349 static inline int IsZeroOrd(p_Ord ord)
350 {
351   return (ord == OrdPomogZero || ord == OrdNomogZero ||
352           ord == OrdNegPomogZero || ord == OrdPosNomogZero ||
353           ord == OrdPomogNegZero || ord == OrdNomogPosZero ||
354           ord == OrdPosNomogPosZero || ord == OrdPosPosNomogZero ||
355           ord == OrdNegPosNomogZero);
356 }
357 
ZeroOrd_2_NonZeroOrd(p_Ord ord,int strict)358 static inline p_Ord ZeroOrd_2_NonZeroOrd(p_Ord ord, int strict)
359 {
360   if (IsZeroOrd(ord))
361   {
362     switch (ord)
363     {
364         case OrdPomogZero:      return OrdPomog;
365         case OrdNomogZero:      return OrdNomog;
366         case OrdNegPomogZero:   return OrdNegPomog;
367         case OrdPosNomogZero:   return OrdPosNomog;
368         case OrdPosPosNomogZero:    return OrdPosPosNomog;
369         case OrdNegPosNomogZero:    return OrdNegPosNomog;
370         default:
371           if (strict) return OrdGeneral;
372           else if (ord == OrdPomogNegZero) return OrdPomogNeg;
373           else if (ord == OrdNomogPosZero) return OrdNomogPos;
374           else if (ord == OrdPosNomogPosZero) return OrdPosNomogPos;
375           else return OrdGeneral;
376     }
377   }
378   else
379   {
380     return ord;
381   }
382 }
383 #else
384 #define IsZeroOrd(ord) 0
385 #define ZeroOrd_2_NonZeroOrd(ord) (ord)
386 #endif
387 
388 /***************************************************************
389  *
390  * Filters which are applied to field/length/ord, before a proc is
391  * chosen
392  *
393  *******************************************************************/
394 #ifdef p_Procs_Static
StaticKernelFilter(p_Field & field,p_Length & length,p_Ord & ord,const p_Proc proc)395 static inline void StaticKernelFilter(p_Field &field, p_Length &length,
396                                       p_Ord &ord, const p_Proc proc)
397 {
398   // simply exclude some things
399   if ((proc == pp_Mult_mm_Noether_Proc || proc == p_kBucketSetLm_Proc) &&
400       (field != RingGeneral) &&
401       (field != FieldZp))
402   {
403     field = FieldGeneral;
404     length = LengthGeneral;
405     ord = OrdGeneral;
406   }
407 }
408 #endif
409 
FastP_ProcsFilter(p_Field & field,p_Length & length,p_Ord & ord,const p_Proc proc)410 static inline void FastP_ProcsFilter(p_Field &field, p_Length &length, p_Ord &ord, const p_Proc proc)
411 {
412   if (HAVE_FAST_P_PROCS >= 5) return;
413 
414   if (HAVE_FAST_P_PROCS < 3 && field == FieldQ)
415     field = FieldGeneral;
416 
417   if ((HAVE_FAST_P_PROCS == 0) ||
418       (HAVE_FAST_P_PROCS <= 4 && field != FieldZp && field != FieldQ &&
419        proc != p_Merge_q_Proc))
420   {
421     if (field != RingGeneral) field = FieldGeneral;
422     length = LengthGeneral;
423     ord = OrdGeneral;
424     return;
425   }
426   if (HAVE_FAST_P_PROCS == 1 ||
427       (HAVE_FAST_P_PROCS == 4 && field != FieldZp && proc != p_Merge_q_Proc))
428     ord = OrdGeneral;
429 }
430 
FastFieldFilter(p_Field & field)431 static inline void FastFieldFilter(p_Field &field)
432 {
433   if (HAVE_FAST_FIELD <= 0 ||
434       (HAVE_FAST_FIELD == 1 && field != FieldZp) ||
435       (field != FieldZp && field != FieldQ))
436     if (field != RingGeneral) field = FieldGeneral;
437 }
438 
FastLengthFilter(p_Length & length)439 static inline void FastLengthFilter(p_Length &length)
440 {
441   if ((HAVE_FAST_LENGTH == 3 && length <= LengthFive) ||
442       (HAVE_FAST_LENGTH == 2 && length <= LengthFour) ||
443       (HAVE_FAST_LENGTH == 1 && length <= LengthTwo) ||
444       (HAVE_FAST_LENGTH <= 0))
445   {
446     length = LengthGeneral;
447   }
448 }
449 
FastOrdFilter(p_Ord & ord)450 static inline void FastOrdFilter(p_Ord &ord)
451 {
452   if ((HAVE_FAST_ORD == 3 && ord >= OrdNomogPosZero) ||
453       (HAVE_FAST_ORD == 2 && ord >= OrdPosNomog) ||
454       (HAVE_FAST_ORD == 1 && ord >= OrdPomogZero) ||
455       (HAVE_FAST_ORD <= 0))
456     ord = OrdGeneral;
457 }
458 
FastOrdZeroFilter(p_Ord & ord)459 static inline void FastOrdZeroFilter(p_Ord &ord)
460 {
461   if (IsZeroOrd(ord))
462   {
463     if ((HAVE_FAST_ZERO_ORD == 1 && (ord != OrdPosNomogPosZero &&
464                                      ord != OrdNomogPosZero &&
465                                      ord != OrdPomogNegZero)) ||
466         (HAVE_FAST_ZERO_ORD <= 0))
467       ord = ZeroOrd_2_NonZeroOrd(ord, 1);
468   }
469 }
470 
NCopy__Filter(p_Field & field)471 static inline void NCopy__Filter(p_Field &field)
472 {
473   if (ZP_COPY_FIELD(field)) field = FieldZp;
474   else if (field == RingGeneral) field = FieldGeneral;
475 }
476 
477 // in p_Add_q, p_MemCmp works with CompLSize,
478 // hence, we do not need to consider ZeroOrds
p_Add_q__Filter(p_Field & field,p_Length & length,p_Ord & ord)479 static inline void p_Add_q__Filter(p_Field &field,p_Length &length, p_Ord &ord)
480 {
481   if (IsZeroOrd(ord))
482   {
483     ord = ZeroOrd_2_NonZeroOrd(ord, 0);
484     if (length > LengthGeneral)
485     {
486       length = (p_Length) ((int)length + 1);
487     }
488   }
489   if (field == RingGeneral) field = FieldGeneral;
490 }
491 
p_Neg__Filter(p_Field & field,p_Length & length,p_Ord & ord)492 static inline void p_Neg__Filter(p_Field &field,p_Length &length, p_Ord &ord)
493 {
494   if (field == RingGeneral) field = FieldGeneral;
495   length =LengthGeneral;
496   ord =OrdGeneral;
497 }
498 
pp_Mult_mm_Noether_Filter(p_Field & field,p_Length & length,p_Ord & ord)499 static inline void pp_Mult_mm_Noether_Filter(p_Field &field,
500                                              p_Length &length, p_Ord &ord)
501 {
502   if (ord == OrdPomog
503       || ord == OrdPomogZero
504       || (ord == OrdPomogNeg && length > LengthTwo)
505 #ifdef HAVE_LENGTH_DIFF
506       || (ord == OrdPomogZero)
507       || (ord == OrdPomogNegZero && length > LengthThree)
508 #endif
509       )
510   {
511     // all the other orderings might occur (remember Mixed Orderings!)
512     if (field != RingGeneral) field = FieldGeneral;
513     ord = OrdGeneral;
514     length = LengthGeneral;
515   }
516 }
517 
FastProcFilter(p_Proc proc,p_Field & field,p_Length & length,p_Ord & ord)518 static inline void FastProcFilter(p_Proc proc, p_Field &field,
519                                   p_Length &length, p_Ord &ord)
520 {
521   switch(proc)
522   {
523       case p_Add_q_Proc:
524       case p_Merge_q_Proc:
525         p_Add_q__Filter(field, length, ord);
526         break;
527 
528       case p_Neg_Proc:
529         p_Neg__Filter(field, length, ord);
530         break;
531 
532       case p_Copy_Proc:
533       case p_Delete_Proc:
534         NCopy__Filter(field);
535         break;
536 
537       case pp_Mult_mm_Noether_Proc:
538         pp_Mult_mm_Noether_Filter(field, length, ord);
539         break;
540 
541         case pp_Mult_Coeff_mm_DivSelectMult_Proc:
542           if (length == LengthOne || length == LengthTwo)
543           {
544             if (field != RingGeneral) field = FieldGeneral;
545             length = LengthGeneral;
546             ord = OrdGeneral;
547             return;
548           }
549           break;
550 
551       default: break;
552   }
553 
554   FastOrdFilter(ord);
555   FastOrdZeroFilter(ord);
556   FastLengthFilter(length);
557   FastFieldFilter(field);
558   FastP_ProcsFilter(field, length, ord, proc);
559 #ifdef p_Procs_Static
560   StaticKernelFilter(field, length, ord, proc);
561 #endif
562 }
563 
564 // returns 0 if combination of field/length/ord is invalid
IsValidSpec(p_Field field,p_Length length,p_Ord ord)565 static inline int IsValidSpec(p_Field field, p_Length length, p_Ord ord)
566 {
567   if (field == FieldUnknown || length == LengthUnknown || ord == OrdUnknown)
568     return 0;
569 
570   if (length >= LengthThree && // i.e. 1, 2, or 3
571       ord > ORD_MAX_N_3)       //  i.e. OrdNomogPosZero and below
572     return 0;
573 
574   if (length >= LengthTwo &&    // i.e. 1 or 2
575       ord > ORD_MAX_N_2)        // i.e. PosNomog and below
576     return 0;
577 
578   if (length == LengthOne &&
579       ord > ORD_MAX_N_1)           // i.e. PosPomogZero and below
580     return 0;
581 
582   // we cover everything for length <= two
583   if (ord == OrdGeneral && length > LengthTwo)
584     return 0;
585 #ifndef HAVE_RINGS
586   if (field == RingGeneral) return 0;
587 #endif
588   return 1;
589 }
590 
591 
index(p_Length length,p_Ord ord)592 static inline int index(p_Length length, p_Ord ord)
593 {
594   return length*OrdUnknown + ord;
595 }
596 
index(p_Field field,p_Length length)597 static inline int index(p_Field field, p_Length length)
598 {
599   return field*LengthUnknown + length;
600 }
601 
index(p_Field field,p_Length length,p_Ord ord)602 static inline int index(p_Field field, p_Length length, p_Ord ord)
603 {
604   return field*LengthUnknown*OrdUnknown + length*OrdUnknown + ord;
605 }
606 
index(p_Proc proc,p_Field field,p_Length length,p_Ord ord)607 static inline int index(p_Proc proc, p_Field field, p_Length length, p_Ord ord)
608 {
609   switch(proc)
610   {
611       case p_Delete_Proc:
612       case p_Mult_nn_Proc:
613       case p_Neg_Proc:
614         return field;
615 
616       case p_ShallowCopyDelete_Proc:
617         return length;
618 
619       case p_Copy_Proc:
620       case pp_Mult_mm_Proc:
621       case p_Mult_mm_Proc:
622       case pp_Mult_nn_Proc:
623       case pp_Mult_Coeff_mm_DivSelect_Proc:
624       case pp_Mult_Coeff_mm_DivSelectMult_Proc:
625         return index(field, length);
626 
627       case p_Add_q_Proc:
628       case p_Minus_mm_Mult_qq_Proc:
629       case pp_Mult_mm_Noether_Proc:
630       case p_kBucketSetLm_Proc:
631         return index(field, length, ord);
632 
633       case p_Merge_q_Proc:
634         return index(length, ord);
635 
636       default:
637         printf("error in index (%d)- should not happen", (int)proc);
638         return -1;
639   }
640 }
641 
642 
643 
644 /***************************************************************
645  *
646  * Macros for setting procs -- these are used for
647  * generation and setting
648  *
649  ***************************************************************/
650 
651 #define SetProc(what, field, length, ord)                   \
652 do                                                          \
653 {                                                           \
654   p_Field t_field = field;                                  \
655   p_Ord t_ord = ord;                                        \
656   p_Length t_length = length;                               \
657   FastProcFilter(what##_Proc, t_field, t_length, t_ord);    \
658   DoSetProc(what, t_field, t_length, t_ord);                \
659 }                                                           \
660 while (0)                                                   \
661 
662 #define SetProcs(field, length, ord)                                    \
663 do                                                                      \
664 {                                                                       \
665   SetProc(p_Copy, field, length, OrdGeneral);                           \
666   SetProc(p_Delete, field, LengthGeneral, OrdGeneral);                  \
667   SetProc(p_ShallowCopyDelete, FieldGeneral, length, OrdGeneral);       \
668   SetProc(p_Mult_nn, field, LengthGeneral, OrdGeneral);                 \
669   SetProc(pp_Mult_nn, field, length, OrdGeneral);                       \
670   SetProc(pp_Mult_mm, field, length, OrdGeneral);                       \
671   SetProc(p_Mult_mm, field, length, OrdGeneral);                        \
672   SetProc(p_Minus_mm_Mult_qq, field, length, ord);                      \
673   SetProc(pp_Mult_mm_Noether, field, length, ord);                      \
674   SetProc(p_Add_q, field, length, ord);                                 \
675   SetProc(p_Neg, field, LengthGeneral, OrdGeneral);                     \
676   SetProc(pp_Mult_Coeff_mm_DivSelect, field, length, OrdGeneral);       \
677   SetProc(pp_Mult_Coeff_mm_DivSelectMult, field, length, OrdGeneral);   \
678   SetProc(p_Merge_q, FieldGeneral, length, ord);                        \
679   SetProc(p_kBucketSetLm, field, length, ord);                          \
680 }                                                                       \
681 while (0)
682 
683 #ifdef NV_OPS
684 #define SetProcs_nv(field, length, ord)                                 \
685 do                                                                      \
686 {                                                                       \
687   SetProc(p_Delete, field, LengthGeneral, OrdGeneral);                  \
688   SetProc(p_ShallowCopyDelete, FieldGeneral, length, OrdGeneral);       \
689   SetProc(p_Copy, field, length, OrdGeneral);                           \
690   SetProc(p_Add_q, field, length, ord);                                 \
691   SetProc(p_kBucketSetLm, field, length, ord);                          \
692   SetProc(p_Neg, field, LengthGeneral, OrdGeneral);                     \
693   SetProc(p_Merge_q, FieldGeneral, length, ord);                        \
694 }                                                                       \
695 while (0)
696 #endif
697 
698 #define SetProcs_ring(field, length, ord)                               \
699 do                                                                      \
700 {                                                                       \
701   SetProc(p_Copy, FieldGeneral, length, OrdGeneral);                    \
702   SetProc(p_Delete, FieldGeneral, LengthGeneral, OrdGeneral);           \
703   SetProc(p_ShallowCopyDelete, FieldGeneral, length, OrdGeneral);       \
704   SetProc(p_Add_q, FieldGeneral, length, ord);                          \
705   SetProc(p_Neg, FieldGeneral, LengthGeneral, OrdGeneral);              \
706   SetProc(p_Merge_q, FieldGeneral, length, ord);                        \
707   SetProc(p_Mult_nn, field, LengthGeneral, OrdGeneral);                 \
708   SetProc(pp_Mult_nn, field, LengthGeneral, OrdGeneral);                \
709   SetProc(pp_Mult_mm, field, length, OrdGeneral);                       \
710   SetProc(p_Mult_mm, field, length, OrdGeneral);                        \
711   SetProc(p_Minus_mm_Mult_qq, field, length, ord);                      \
712   SetProc(pp_Mult_mm_Noether, field, length, ord);                      \
713   SetProc(pp_Mult_Coeff_mm_DivSelect, field, length, OrdGeneral);       \
714   SetProc(pp_Mult_Coeff_mm_DivSelectMult, field, length, OrdGeneral);   \
715 }                                                                       \
716 while (0)
717 
718 #endif // P_PROCS_IMPL_H
719 
720