source: git/Singular/p_Procs.cc @ a29995

fieker-DuValspielwiese
Last change on this file since a29995 was a29995, checked in by Olaf Bachmann <obachman@…>, 24 years ago
* towards tailRings for local case git-svn-id: file:///usr/local/Singular/svn/trunk@4777 2c84dea3-7e68-4137-9b89-c4e89433aadc
  • Property mode set to 100644
File size: 28.4 KB
Line 
1/****************************************
2*  Computer Algebra System SINGULAR     *
3****************************************/
4/***************************************************************
5 *  File:    p_Procs.cc
6 *  Purpose: implementation of primitive procs for polys
7 *  Author:  obachman (Olaf Bachmann)
8 *  Created: 8/00
9 *  Version: $Id: p_Procs.cc,v 1.23 2000-11-28 11:50:55 obachman Exp $
10 *******************************************************************/
11#include <string.h>
12
13#include "mod2.h"
14
15
16/***************************************************************
17 * 
18 * Configurations
19 *
20 *******************************************************************/
21
22/***************************************************************
23 Here is how it works:
24 At run-time, SetProcs is used to choose the appropriate PolyProcs
25              based on the ring properies.
26 At generate-time, SetProcs is used to generate all
27              possible PolyProcs.
28 Which PolyProcs are generated/used can be controled by values of
29 HAVE_FAST_P_PROCS, HAVE_FAST_LENGTH, HAVE_FAST_ORD, and FAST_FIELD
30 
31 At generate-time, the file p_Procs.inc is generated,
32 which provides implementations of the p_Procs, based on
33 the p_*_Templates.cc and header files which provide the respective
34 macros.
35
36 At run-time, a fast proc is set/choosen if found/generated, else
37 a general proc is set/choosen.
38 *******************************************************************/
39
40// Set HAVE_FAST_P_PROCS to:
41//   0 -- only FieldGeneral_LengthGeneral_OrdGeneral
42//   1 -- plus FieldZp_Length*_OrdGeneral procs
43//   2 -- plus FieldZp_Length*_Ord* procs
44//   3 -- plus FieldQ_Length*_Ord*
45//   4 -- plus FieldGeneral_Length*_OrdGeneral procs
46//   5 -- all Field*_Length*_Ord* procs
47#ifdef NDEBUG
48#ifdef __hpux
49const int HAVE_FAST_P_PROCS = 2;
50#else
51const int HAVE_FAST_P_PROCS = 3;
52#endif
53#else
54const int HAVE_FAST_P_PROCS = 0;
55#endif
56
57#define inline
58
59// Set HAVE_FAST_FIELD to:
60//   0 -- only FieldGeneral
61//   1 -- special cases for FieldZp
62//   2 -- plus special cases for FieldQ
63//   nothing else is implemented, yet
64const int HAVE_FAST_FIELD = 2;
65
66// Set HAVE_FAST_LENGTH to:
67//   0 -- only LengthGeneral
68//   1 -- special cases for length <= 1
69//   2 -- special cases for length <= 2
70//   3 -- special cases for length <= 4
71//   4 -- special cases for length <= 8
72const int HAVE_FAST_LENGTH = 3;
73
74// Set HAVE_FAST_ORD to:
75//  0  -- only OrdGeneral
76//  1  -- special for ords with n_min <= 1
77//  2  -- special for ords with n_min <= 2
78//  3  -- special ords for with n_min <= 3
79//  4  -- special for all ords
80const int HAVE_FAST_ORD = 4;
81
82// undefine this, if ExpL_Size always equals CompLSize
83#define HAVE_LENGTH_DIFF
84// Set HAVE_FAST_ZERO_ORD to:
85//  0 -- no zero ords are considered
86//  1 -- only ZeroOrds for OrdPosNomogPosZero, OrdNomogPosZero, OrdPomogNegZero
87//  2 -- ZeroOrds for all
88const int HAVE_FAST_ZERO_ORD = 2;
89
90// Predicate which returns true if alloc/copy/free of numbers is
91// like that of Zp
92#define ZP_COPY_FIELD(field) \
93  (field == FieldZp || field == FieldGF || field == FieldR)
94
95/***************************************************************
96 * 
97 * Definitions of our fields, lengths, ords, procs we work with
98 *
99 *******************************************************************/
100
101// Here are the different parameters for setting the PolyProcs:
102
103// If you add/remove things from here, also remeber to adjust the
104// respective *_2_String
105typedef enum p_Field
106{
107  FieldGeneral = 0,
108  FieldZp,         
109  FieldR,
110  FieldGF,
111  FieldQ,
112#if HAVE_MORE_FIELDS_IMPLEMENTED
113  FieldLong_R,
114  FieldLong_C,
115  FieldZp_a,
116  FieldQ_a,
117#endif
118  FieldUnknown
119};
120typedef enum p_Length // Length of exponent vector in words
121{
122  LengthGeneral = 0, // n >= 1
123  LengthEight,       // n == 8   
124  LengthSeven,
125  LengthSix,
126  LengthFive,
127  LengthFour,
128  LengthThree,
129  LengthTwo,
130  LengthOne,
131  LengthUnknown
132};
133typedef enum p_Ord 
134{                   
135  OrdGeneral = 0,   
136                    //     ordsgn   
137                    //  0   1   i   n-1 n   n_min   Example
138  OrdPomog,         //  +   +   +   +   +   1       (lp,C)
139  OrdNomog,         //  -   -   -   -   -   1       (ls, c), (ds, c)
140#define ORD_MAX_N_1 OrdNomog
141
142#ifdef HAVE_LENGTH_DIFF
143  OrdPomogZero,     //  +   +   +   +   0   2       (Dp, C), Even vars
144  OrdNomogZero,     //  -   -   -   -   0   2       (ds, c), Even vars
145#endif
146
147  OrdNegPomog,      //  -   +   +   +   +   2       (c, lp), (Ds, c)
148  OrdPomogNeg,      //  +   +   +   +   -   2       (lp, c)
149#define ORD_MAX_N_2 OrdPomogNeg
150
151  OrdPosNomog,      //  +   -   -   -   +   3       (dp, c) (for n == 2, use PomogNeg)
152  OrdNomogPos,      //  -   -   -   -   +   3       (ls, C) (for n == 2, use NegPomog)
153
154#ifdef HAVE_LENGTH_DIFF
155  OrdNegPomogZero,  //  -   +   +   +   0   3       (c, lp), (Ds, c)
156  OrdPomogNegZero,  //  +   +   +   -   0   3       (lp, c)
157#endif
158
159  OrdPosPosNomog,   //  +   +   -   -   -   3       (C, dp)
160  OrdPosNomogPos,   //  +   -   -   -   +   3       (dp, C)
161  OrdNegPosNomog,   //  -   +   -   -   -   3       (c, dp)
162#define ORD_MAX_N_3 OrdNegPosNomog
163
164#ifdef HAVE_LENGTH_DIFF
165  OrdNomogPosZero,  //  -   -   -   +   0   4       (ls, C) (for n == 3, use NegPomogZero)
166  OrdPosNomogZero,  //  +   -   -   -   0   4       (dp, c) (for n == 3, use PomogNegZero)
167
168  OrdPosPosNomogZero,// +   +   -   -   0   4       (C, dp)
169  OrdPosNomogPosZero,// +   -   -   +   0   4       (dp, C)
170  OrdNegPosNomogZero,// -   +   -   -   0   4       (c, dp)
171#endif
172
173  OrdUnknown
174};
175
176typedef enum p_Proc
177{
178  p_Copy_Proc = 0,
179  p_Delete_Proc,
180  p_ShallowCopyDelete_Proc,
181  p_Mult_nn_Proc,
182  pp_Mult_nn_Proc,
183  pp_Mult_mm_Proc,
184  pp_Mult_mm_Noether_Proc,
185  p_Mult_mm_Proc,
186  p_Add_q_Proc,
187  p_Minus_mm_Mult_qq_Proc,
188  p_Neg_Proc,
189  pp_Mult_Coeff_mm_DivSelect_Proc,
190  p_Merge_q_Proc,
191  p_kBucketSetLm_Proc,
192  p_Unknown_Proc
193};
194
195// *_2_String conversions of these enums
196// they are only needed at for GENERATE_P_PROCS or RDEBUG
197#if defined(GENERATE_P_PROCS) || defined(RDEBUG)
198char* p_FieldEnum_2_String(p_Field field)
199{
200  switch(field)
201  {
202      case FieldGeneral: return "FieldGeneral";
203      case FieldZp: return "FieldZp";         
204      case FieldR: return "FieldR";
205      case FieldGF: return "FieldGF";
206      case FieldQ: return "FieldQ";
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 FieldUnknown: return "FieldUnknown";
214  }
215  return "NoField_2_String";
216}
217
218char* p_LengthEnum_2_String(p_Length length)
219{
220  switch(length)
221  {
222      case LengthGeneral: return "LengthGeneral"; 
223      case LengthEight: return "LengthEight";       
224      case LengthSeven: return "LengthSeven";
225      case LengthSix: return "LengthSix";
226      case LengthFive: return "LengthFive";
227      case LengthFour: return "LengthFour";
228      case LengthThree: return "LengthThree";
229      case LengthTwo: return "LengthTwo";
230      case LengthOne: return "LengthOne";
231      case LengthUnknown: return "LengthUnknown";
232  }
233  return "NoLength_2_String";
234}
235
236char* p_OrdEnum_2_String(p_Ord ord)
237{
238  switch(ord)
239  {
240      case OrdGeneral: return "OrdGeneral";   
241      case OrdPomog: return "OrdPomog";         
242      case OrdNomog: return "OrdNomog";         
243      case OrdNegPomog: return "OrdNegPomog";     
244      case OrdPomogNeg: return "OrdPomogNeg";     
245      case OrdPosNomog: return "OrdPosNomog";     
246      case OrdNomogPos: return "OrdNomogPos";     
247      case OrdPosPosNomog: return "OrdPosPosNomog";   
248      case OrdPosNomogPos: return "OrdPosNomogPos";   
249      case OrdNegPosNomog: return "OrdNegPosNomog";   
250#ifdef HAVE_LENGTH_DIFF
251      case OrdNegPomogZero: return "OrdNegPomogZero"; 
252      case OrdPomogNegZero: return "OrdPomogNegZero"; 
253      case OrdPomogZero: return "OrdPomogZero";     
254      case OrdNomogZero: return "OrdNomogZero";     
255      case OrdNomogPosZero: return "OrdNomogPosZero"; 
256      case OrdPosNomogZero: return "OrdPosNomogZero"; 
257      case OrdPosPosNomogZero: return "OrdPosPosNomogZero";
258      case OrdPosNomogPosZero: return "OrdPosNomogPosZero";
259      case OrdNegPosNomogZero: return "OrdNegPosNomogZero";
260#endif
261      case OrdUnknown: return "OrdUnknown";
262  }
263  return "NoOrd_2_String";
264}
265
266char* p_ProcEnum_2_String(p_Proc proc)
267{
268  switch(proc)
269  {
270      case p_Copy_Proc: return "p_Copy_Proc";
271      case p_Delete_Proc: return "p_Delete_Proc";
272      case p_ShallowCopyDelete_Proc: return "p_ShallowCopyDelete_Proc";
273      case p_Mult_nn_Proc: return "p_Mult_nn_Proc";
274      case pp_Mult_nn_Proc: return "pp_Mult_nn_Proc";
275      case pp_Mult_mm_Proc: return "pp_Mult_mm_Proc";
276      case pp_Mult_mm_Noether_Proc: return "pp_Mult_mm_Noether_Proc";
277      case p_Mult_mm_Proc: return "p_Mult_mm_Proc";
278      case p_Add_q_Proc: return "p_Add_q_Proc";
279      case p_Minus_mm_Mult_qq_Proc: return "p_Minus_mm_Mult_qq_Proc";
280      case p_Neg_Proc: return "p_Neg_Proc";
281      case pp_Mult_Coeff_mm_DivSelect_Proc: return "pp_Mult_Coeff_mm_DivSelect_Proc";
282      case p_Merge_q_Proc: return "p_Merge_q_Proc";
283      case p_kBucketSetLm_Proc: return "p_kBucketSetLm_Proc";
284      case p_Unknown_Proc: return "p_Unknown_Proc";
285  }
286  return "NoProc_2_String";
287}
288#endif // defined(GENERATE_P_PROCS) || defined(RDEBUG)
289
290
291#ifdef GENERATE_P_PROCS
292#include "dError.c"
293#endif
294
295/***************************************************************
296 * 
297 *
298 * Deal with OrdZero
299 *
300 *******************************************************************/
301#ifdef HAVE_LENGTH_DIFF
302static inline int IsZeroOrd(p_Ord ord)
303{
304  return (ord == OrdPomogZero || ord == OrdNomogZero ||
305          ord == OrdNegPomogZero || ord == OrdPosNomogZero ||
306          ord == OrdPomogNegZero || ord == OrdNomogPosZero ||
307          ord == OrdPosNomogPosZero || ord == OrdPosPosNomogZero ||
308          ord == OrdNegPosNomogZero);
309}
310
311static inline p_Ord ZeroOrd_2_NonZeroOrd(p_Ord ord, int strict)
312{
313  if (IsZeroOrd(ord))
314  {
315    switch (ord)
316    {
317        case OrdPomogZero:      return OrdPomog;
318        case OrdNomogZero:      return OrdNomog;
319        case OrdNegPomogZero:   return OrdNegPomog;
320        case OrdPosNomogZero:   return OrdPosNomog;
321        case OrdPosPosNomogZero:    return OrdPosPosNomog;
322        case OrdNegPosNomogZero:    return OrdNegPosNomog;
323        default:   
324          if (strict) return OrdGeneral;
325          else if (ord == OrdPomogNegZero) return OrdPomogNeg;
326          else if (ord == OrdNomogPosZero) return OrdNomogPos;
327          else if (ord == OrdPosNomogPosZero) return OrdPosNomogPos;
328          else return OrdGeneral;
329    }
330  }
331  else
332  {
333    return ord;
334  }
335}
336#else
337#define IsZeroOrd(ord) 0
338#define ZeroOrd_2_NonZeroOrd(ord) (ord)
339#endif
340
341/***************************************************************
342 * 
343 * Filters which are applied to field/length/ord, before a proc is
344 * choosen
345 *
346 *******************************************************************/
347static inline void FastP_ProcsFilter(p_Field &field, p_Length &length, p_Ord &ord, const p_Proc proc)
348{
349  if (HAVE_FAST_P_PROCS >= 5) return;
350 
351  if (HAVE_FAST_P_PROCS < 3 && field == FieldQ)
352    field = FieldGeneral;
353 
354  if ((HAVE_FAST_P_PROCS == 0) ||
355      (HAVE_FAST_P_PROCS <= 4 && field != FieldZp && field != FieldQ &&
356       proc != p_Merge_q_Proc))
357  {
358    field = FieldGeneral;
359    length = LengthGeneral;
360    ord = OrdGeneral;
361    return;
362  }
363  if (HAVE_FAST_P_PROCS == 1 || 
364      (HAVE_FAST_P_PROCS == 4 && field != FieldZp && proc != p_Merge_q_Proc))
365    ord = OrdGeneral;
366}
367
368static inline void FastFieldFilter(p_Field &field)
369{
370  if (HAVE_FAST_FIELD <= 0 || 
371      (HAVE_FAST_FIELD == 1 && field != FieldZp) ||
372      (field != FieldZp && field != FieldQ))
373    field = FieldGeneral;
374}
375     
376static inline void FastLengthFilter(p_Length &length)
377{
378  if ((HAVE_FAST_LENGTH == 3 && length <= LengthFive) ||
379      (HAVE_FAST_LENGTH == 2 && length <= LengthFour) ||
380      (HAVE_FAST_LENGTH == 1 && length <= LengthTwo) ||
381      (HAVE_FAST_LENGTH <= 0))
382  {
383    length = LengthGeneral;
384  }
385}
386
387static inline void FastOrdFilter(p_Ord &ord)
388{
389  if ((HAVE_FAST_ORD == 3 && ord >= OrdNomogPosZero) ||
390      (HAVE_FAST_ORD == 2 && ord >= OrdPosNomog) ||
391      (HAVE_FAST_ORD == 1 && ord >= OrdPomogZero) ||
392      (HAVE_FAST_ORD <= 0))
393    ord = OrdGeneral;
394}
395
396static inline void FastOrdZeroFilter(p_Ord &ord)
397{
398  if (IsZeroOrd(ord))
399  {
400    if ((HAVE_FAST_ZERO_ORD == 1 && (ord != OrdPosNomogPosZero && 
401                                     ord != OrdNomogPosZero && 
402                                     ord != OrdPomogNegZero)) ||
403        (HAVE_FAST_ZERO_ORD <= 0))
404      ord = ZeroOrd_2_NonZeroOrd(ord, 1);
405  }
406}
407
408static inline void NCopy__Filter(p_Field &field)
409{
410  if (ZP_COPY_FIELD(field)) field = FieldZp;
411}
412
413// in p_Add_q, p_MemCmp works with CompLSize,
414// hence, we do not need to consider ZeroOrds
415static inline void p_Add_q__Filter(p_Length &length, p_Ord &ord)
416{
417  if (IsZeroOrd(ord))
418  {
419    ord = ZeroOrd_2_NonZeroOrd(ord, 0);
420    if (length > LengthGeneral)
421    {
422      length = (p_Length) ((int)length + 1);
423    }
424  }
425}
426
427static inline void pp_Mult_mm_Noether_Filter(p_Field &field, 
428                                             p_Length &length, p_Ord &ord)
429{
430  if (ord == OrdPomog
431      || ord == OrdPomogZero
432      || (ord == OrdPomogNeg && length > LengthTwo) 
433#ifdef HAVE_LENGTH_DIFF
434      || (ord == OrdPomogZero)
435      || (ord == OrdPomogNegZero && length > LengthThree)
436#endif
437      )
438  {
439    // all the other orderings might occur (remeber Mixed Orderings!)
440    field = FieldGeneral;
441    ord = OrdGeneral;
442    length = LengthGeneral;
443  }
444}
445     
446static inline void FastProcFilter(p_Proc proc, p_Field &field, 
447                                  p_Length &length, p_Ord &ord)
448{
449  switch(proc)
450  {
451      case p_Add_q_Proc:
452      case p_Merge_q_Proc:
453        p_Add_q__Filter(length, ord);
454        break;
455       
456      case p_Copy_Proc:
457      case p_Delete_Proc:
458        NCopy__Filter(field);
459        break;
460       
461      case pp_Mult_mm_Noether_Proc:
462        pp_Mult_mm_Noether_Filter(field, length, ord);
463        break;
464       
465      case p_kBucketSetLm_Proc:
466      {
467        if (field != FieldZp)
468        {
469          field = FieldGeneral;
470          length = LengthGeneral;
471          ord = OrdGeneral;
472          return;
473        }
474      }
475
476      default: break;
477  }
478
479  FastOrdFilter(ord);
480  FastOrdZeroFilter(ord);
481  FastLengthFilter(length);
482  FastFieldFilter(field);
483  FastP_ProcsFilter(field, length, ord, proc);
484}
485
486// returns 1 if combination of field/length/ord is invalid
487static inline int IsValidSpec(p_Field field, p_Length length, p_Ord ord)
488{
489  if (field == FieldUnknown || length == LengthUnknown || ord == OrdUnknown)
490    return 0;
491
492  if (length >= LengthThree && // i.e. 1, 2, or 3
493      ord > ORD_MAX_N_3)       //  i.e. OrdNomogPosZero and below
494    return 0;
495 
496  if (length >= LengthTwo &&    // i.e. 1 or 2
497      ord > ORD_MAX_N_2)        // i.e. PosNomog and below
498    return 0;
499
500  if (length == LengthOne && 
501      ord > ORD_MAX_N_1)           // i.e. PosPomogZero and below
502    return 0;
503
504  // we cover everything for length <= two
505  if (ord == OrdGeneral && length >= LengthTwo)
506    return 0;
507  return 1;
508}
509
510 
511static inline int index(p_Length length, p_Ord ord)
512{
513  return length*OrdUnknown + ord;
514}
515
516static inline int index(p_Field field, p_Length length)
517{
518  return field*LengthUnknown + length;
519}
520
521static inline int index(p_Field field, p_Length length, p_Ord ord)
522{
523  return field*LengthUnknown*OrdUnknown + length*OrdUnknown + ord;
524}
525
526static inline int index(p_Proc proc, p_Field field, p_Length length, p_Ord ord)
527{
528  switch(proc)
529  {
530      case p_Delete_Proc:
531      case p_Mult_nn_Proc:
532      case p_Neg_Proc:
533        return field;
534       
535      case p_ShallowCopyDelete_Proc:
536        return length;
537       
538      case p_Copy_Proc:
539      case pp_Mult_mm_Proc:
540      case p_Mult_mm_Proc:
541      case pp_Mult_nn_Proc:
542      case pp_Mult_Coeff_mm_DivSelect_Proc:
543        return index(field, length);
544
545      case p_Add_q_Proc:
546      case p_Minus_mm_Mult_qq_Proc:
547      case pp_Mult_mm_Noether_Proc:
548      case p_kBucketSetLm_Proc:
549        return index(field, length, ord);
550       
551      case p_Merge_q_Proc:
552        return index(length, ord);
553       
554      default:
555        assume(0);
556        return -1;
557  }
558}
559
560// The procedure which does the work of choosing/generating a
561// set of poly procs
562static void SetProcs(p_Field field, p_Length length, p_Ord ord);
563
564
565#ifndef GENERATE_P_PROCS
566
567/***************************************************************
568 *
569 * Runtime stuff
570 *
571 ***************************************************************/
572#include "structs.h"
573#include "p_polys.h"
574#include "ring.h"
575#include "p_Procs.h"
576#include "p_Numbers.h"
577#include "p_MemCmp.h"
578#include "p_MemAdd.h"
579#include "p_MemCopy.h"
580#include "kbuckets.h"
581
582#ifdef NDEBUG
583#include "p_Procs.inc"
584#else
585#include "p_Procs_debug.inc"
586#endif
587
588
589// the rest is related to getting the procs
590static inline p_Field p_FieldIs(ring r)
591{
592  if (rField_is_Zp(r)) return FieldZp;         
593  if (rField_is_R(r)) return FieldR;
594  if (rField_is_GF(r)) return FieldGF;
595  if (rField_is_Q(r)) return FieldQ;
596#ifdef HAVE_MORE_FIELDS_IMPLEMENTED
597  if (rField_is_long_R(r)) return FieldLong_R;
598  if (rField_is_long_C(r)) return FieldLong_C;
599  if (rField_is_Zp_a(r)) return FieldZp_a;
600  if (rField_is_Q_a(r)) return FieldQ_a;
601#endif
602  return FieldGeneral;
603}
604
605static inline p_Length p_LengthIs(ring r)
606{
607  assume(r->ExpL_Size > 0);
608  // here is a quick hack to take care of p_MemAddAdjust
609  if (r->NegWeightL_Offset != NULL) return LengthGeneral;
610  if (r->ExpL_Size == 1) return LengthOne;
611  if (r->ExpL_Size == 2) return LengthTwo;
612  if (r->ExpL_Size == 3) return LengthThree;
613  if (r->ExpL_Size == 4) return LengthFour;
614  if (r->ExpL_Size == 5) return LengthFive;
615  if (r->ExpL_Size == 6) return LengthSix;
616  if (r->ExpL_Size == 7) return LengthSeven;
617  if (r->ExpL_Size == 8) return LengthEight;
618  return LengthGeneral;
619}
620
621static inline int p_IsNomog(long* sgn, int l)
622{
623  int i;
624  for (i=0;i<l;i++)
625    if (sgn[i] > 0) return 0;
626 
627  return 1;
628}
629
630static inline int p_IsPomog(long* sgn, int l)
631{
632  int i;
633  for (i=0;i<l;i++)
634    if (sgn[i] < 0) return 0;
635  return 1;
636}
637
638static inline p_Ord p_OrdIs(ring r)
639{
640  long* sgn = r->ordsgn;
641  long l = r->ExpL_Size;
642  int zero = 0;
643 
644  if (sgn[l-1] == 0) 
645  {
646    l--;
647    zero = 1;
648  }
649 
650  // we always favour the pomog cases
651  if (p_IsPomog(sgn,l)) return (zero ? OrdPomogZero : OrdPomog);
652  if (p_IsNomog(sgn,l)) return (zero ? OrdNomogZero : OrdNomog);
653 
654  assume(l > 1);
655 
656  if (sgn[0] == -1 && p_IsPomog(&sgn[1], l-1))
657    return (zero ? OrdNegPomogZero : OrdNegPomog);
658  if (sgn[l-1] == -1 && p_IsPomog(sgn, l-1))
659    return (zero ? OrdPomogNegZero : OrdPomogNeg);
660
661  if (sgn[0] == 1 && p_IsNomog(&sgn[1], l-1)) 
662    return (zero ? OrdPosNomogZero : OrdPosNomog);
663  if (sgn[l-1] == 1 && p_IsNomog(sgn, l-1))
664    return (zero ? OrdNomogPosZero : OrdNomogPos);
665
666  assume(l > 2);
667 
668  if (sgn[0] == 1 && sgn[1] == 1 && p_IsNomog(&sgn[2], l-2))
669    return (zero ? OrdPosPosNomogZero : OrdPosPosNomog);
670
671  if (sgn[0] == 1 && sgn[l-1] == 1 && p_IsNomog(&sgn[1], l-2))
672    return (zero ? OrdPosNomogPosZero : OrdPosNomogPos);
673
674  if (sgn[0] == -1 && sgn[1] == 1 && p_IsNomog(&sgn[2], l-2))
675    return (zero ? OrdNegPosNomogZero : OrdNegPosNomog);
676
677  return OrdGeneral;
678}
679 
680static p_Procs_s *_p_procs;
681// Choose a set of p_Procs
682void p_SetProcs(ring r, p_Procs_s* p_Procs)
683{
684  p_Field     field = p_FieldIs(r);
685  p_Length    length = p_LengthIs(r);
686  p_Ord       ord = p_OrdIs(r);
687 
688  assume(p_Procs != NULL);
689#ifdef RDEBUG
690  memset(p_Procs, 0, sizeof(p_Procs_s));
691#endif
692  _p_procs = p_Procs;
693  assume(IsValidSpec(field, length, ord));
694
695  SetProcs(field, length, ord);
696  assume(
697    (p_Procs->p_Delete != NULL) &&
698    (p_Procs->p_ShallowCopyDelete != NULL) &&
699    (p_Procs->p_Mult_nn != NULL) &&
700    (p_Procs->pp_Mult_nn != NULL) &&
701    (p_Procs->p_Copy != NULL) &&
702    (p_Procs->pp_Mult_mm != NULL) &&
703    (p_Procs->pp_Mult_mm_Noether != NULL) &&
704    (p_Procs->p_Mult_mm != NULL) &&
705    (p_Procs->p_Add_q != NULL) &&
706    (p_Procs->p_Neg != NULL) &&
707    (p_Procs->pp_Mult_Coeff_mm_DivSelect != NULL) &&
708    (p_Procs->p_Merge_q != NULL) &&
709    (p_Procs->p_kBucketSetLm != NULL) &&
710    (p_Procs->p_Minus_mm_Mult_qq != NULL));
711  assume(p_Procs->pp_Mult_mm_Noether != pp_Mult_mm_Noether__FieldGeneral_LengthGeneral_OrdGeneral || 
712         p_Procs->p_Minus_mm_Mult_qq == p_Minus_mm_Mult_qq__FieldGeneral_LengthGeneral_OrdGeneral || 
713         r->OrdSgn == 1 || r->LexOrder);
714}
715
716#ifdef RDEBUG
717void p_Debug_GetSpecNames(const ring r, char* &field, char* &length, char* &ord)
718{
719  p_Field     e_field = p_FieldIs(r);
720  p_Length    e_length = p_LengthIs(r);
721  p_Ord       e_ord = p_OrdIs(r);
722 
723  field  = p_FieldEnum_2_String(p_FieldIs(r));
724  length = p_LengthEnum_2_String(p_LengthIs(r));
725  ord    = p_OrdEnum_2_String(p_OrdIs(r));
726}
727// like SetProcs, only that names are set
728static int set_names = 0;
729void p_Debug_GetProcNames(const ring r, p_Procs_s* p_Procs)
730{
731  set_names = 1;
732  p_SetProcs(r, p_Procs);
733  set_names = 0;
734}
735#endif // RDEBUG
736
737#define __SetProc(what, type, field, length, ord) \
738  _p_procs->what = (what##_Proc_Ptr) what##_Proc_##type [index(what##_Proc, field, length, ord)]
739
740#define ___SetProc(what, field, length, ord) __SetProc(what, funcs, field, length, ord)
741
742#ifdef RDEBUG
743#define _SetProc(what, field, length, ord)      \
744do                                              \
745{                                               \
746  if (set_names)                                \
747    __SetProc(what, names, field, length, ord); \
748  else                                          \
749    ___SetProc(what, field, length, ord);       \
750}                                               \
751while(0)
752#else
753#define _SetProc ___SetProc
754#endif
755
756#else /* GENERATE_P_PROCS */
757/***************************************************************
758 *
759 * generate time stuff
760 *
761 ***************************************************************/
762#include <stdio.h>
763#include <stdlib.h>
764#include <string.h>
765
766char*** generated_p_procs;
767
768inline int AlreadyHaveProc(p_Proc proc, p_Field field, p_Length length, p_Ord ord)
769{
770  return (generated_p_procs[proc])[index(proc, field, length, ord)] != 0;
771}
772
773const char* macros_field[] = {"n_Copy","n_Delete", "n_Mult", "n_Add", "n_Sub", "n_IsZero", "n_Equal" , "n_Neg", NULL};
774
775const char* macros_length[] =
776{"p_MemCopy", "p_MemAdd", "p_MemSum", NULL};
777
778const char* macros_length_ord[] = {"p_MemCmp", NULL};
779int DummyProcs = 0;
780
781void AddProc(const char* s_what, p_Proc proc, p_Field field, p_Length length, p_Ord ord)
782{
783  int i;
784  const char* s_length = p_LengthEnum_2_String(length);
785  const char* s_ord = p_OrdEnum_2_String(ord);
786  const char* s_field = p_FieldEnum_2_String(field);
787  char* s_full_proc_name = (char*) malloc(200);
788 
789  sprintf(s_full_proc_name, "%s__%s_%s_%s", s_what, s_field, s_length, s_ord);
790             
791  (generated_p_procs[proc])[index(proc, field, length, ord)] = s_full_proc_name;
792 
793  // define all macros
794  printf("\n// definition of %s\n", s_full_proc_name);
795  i = 0;
796  while (macros_field[i] != NULL)
797  {
798    printf("#undef %s\n#define %s\t%s_%s\n", 
799           macros_field[i], macros_field[i],  macros_field[i], s_field);
800    i++;
801  }
802  i = 0;
803  while (macros_length[i] != NULL)
804  {
805    printf("#undef %s\n#define %s\t%s_%s\n", 
806           macros_length[i], macros_length[i], macros_length[i], s_length);
807    i++;
808  }
809  i = 0;
810  while (macros_length_ord[i] != NULL)
811  {
812    printf("#undef %s\n#define %s\t%s_%s_%s\n", 
813           macros_length_ord[i], macros_length_ord[i], macros_length_ord[i], s_length, s_ord);
814    i++;
815  }
816
817  // define DECLARE_LENGTH
818  printf("#undef DECLARE_LENGTH\n");
819  printf("#undef p_MemAddAdjust\n");
820  if (length != LengthGeneral)
821  {
822    printf("#define DECLARE_LENGTH(what) ((void)0)\n");
823    printf("#define p_MemAddAdjust(p, r) ((void)0)\n");
824  }
825  else
826  {
827    printf("#define DECLARE_LENGTH(what) what\n");
828    printf("#define p_MemAddAdjust(p, r) p_MemAdd_NegWeightAdjust(p, r)\n");
829  }
830 
831  // define DECLARE_ORDSGN
832  printf("#undef DECLARE_ORDSGN\n");
833  if (ord != OrdGeneral)
834    printf("#define DECLARE_ORDSGN(what) ((void)0)\n");
835  else
836    printf("#define DECLARE_ORDSGN(what) what\n");
837
838  printf("#undef %s\n#define %s %s\n", s_what, s_what, s_full_proc_name);
839  printf("#include \"%s__Template.cc\"\n", s_what);
840  printf("#undef %s\n", s_what);
841}
842
843void GenerateProc(const char* s_what, p_Proc proc, p_Field field, p_Length length, p_Ord ord)
844{
845  if (! AlreadyHaveProc(proc, field, length, ord))
846    AddProc(s_what, proc, field, length, ord);
847}
848
849int main()
850{
851  int field;
852  int length; 
853  int ord;
854  int i, j;
855  int NumberOfHaveProcs = 0;
856 
857 
858  printf("/* -*-c++-*- */\n");
859  printf("/***************************************************************\n");
860  printf(" This file was generated automatically by p_Procs.cc: DO NOT EDIT\n\n");
861  printf(" This file provides the needed implementation of p_Procs\n");
862  printf(" See the end for a summary. \n");
863  printf("*******************************************************************/\n");
864
865  generated_p_procs = (char***) malloc(p_Unknown_Proc*sizeof(char**));
866  for (i=0; i<p_Unknown_Proc; i++)
867  {
868    generated_p_procs[i] = 
869      (char**) calloc(index((p_Proc)i, FieldUnknown, LengthUnknown, OrdUnknown), sizeof(char*));
870  }
871 
872  // set default procs
873  for (field = 0; field < (int) FieldUnknown; field++)
874  {
875    for (length=0; length < (int) LengthUnknown; length++)
876    {
877      for (ord=0; ord < (int)OrdUnknown; ord++)
878      {
879        if (IsValidSpec((p_Field) field, (p_Length) length, (p_Ord) ord))
880            SetProcs((p_Field) field, (p_Length) length, (p_Ord) ord);
881      }
882    }
883  }
884
885  printf("
886/***************************************************************
887  Names of procs for RDEBUG */
888#ifdef RDEBUG\n");
889
890  for (i=0; i<p_Unknown_Proc; i++)
891  {
892    printf("static const char* %s_names[] = {", p_ProcEnum_2_String((p_Proc)i));
893    for (j=0;j<index((p_Proc)i, FieldUnknown, LengthUnknown, OrdUnknown); j++)
894    {
895      char* s = (generated_p_procs[i])[j];
896      if (s != 0)
897      {
898        printf("\n\"%s\",", s);
899      }
900      else
901        printf("0,");
902         
903    }
904    printf("\n};\n");
905  }
906  printf("
907#endif // RDEBUG
908
909
910/***************************************************************/
911/* Tables for lookup of procedures: */\n");
912
913  for (i=0; i<p_Unknown_Proc; i++)
914  {
915    printf("static const %s_Ptr %s_funcs[] = {", p_ProcEnum_2_String((p_Proc)i), p_ProcEnum_2_String((p_Proc)i));
916    for (j=0;j<index((p_Proc)i, FieldUnknown, LengthUnknown, OrdUnknown); j++)
917    {
918      char* s = (generated_p_procs[i])[j];
919      if (s != 0)
920      {
921        NumberOfHaveProcs++;
922        printf("\n%s,", s);
923      }
924      else
925        printf("0,");
926         
927    }
928    printf("\n};\n");
929  }
930  printf("
931/***************************************************************
932 * Summary:
933 *   HAVE_FAST_P_PROCS  = %d,
934 *   HAVE_FAST_FIELD    = %d,
935 *   HAVE_FAST_LENGTH   = %d,
936 *   HAVE_FAST_ORD      = %d,
937 *   HAVE_FAST_ZERO_ORD = %d
938 *   
939 *   Generated PolyProcs= %d
940 *
941 *******************************************************************/\n",
942         HAVE_FAST_P_PROCS, HAVE_FAST_FIELD, HAVE_FAST_LENGTH, HAVE_FAST_ORD, HAVE_FAST_ZERO_ORD,
943         NumberOfHaveProcs);
944}
945
946#define _SetProc(what, field, length, ord) \
947      GenerateProc(#what, what##_Proc, field, length, ord)
948#endif // GENERATE_P_PROCS
949
950/***************************************************************
951 *
952 * Setting the procedures
953 *
954 ***************************************************************/
955
956#define SetProc(what, field, length, ord)              \
957do                                                          \
958{                                                           \
959  p_Field t_field = field;                                  \
960  p_Ord t_ord = ord;                                        \
961  p_Length t_length = length;                               \
962  FastProcFilter(what##_Proc, t_field, t_length, t_ord);\
963  _SetProc(what, t_field, t_length, t_ord);                 \
964}                                                           \
965while (0)
966 
967static void SetProcs(p_Field field, p_Length length, p_Ord ord)
968{
969  SetProc(p_Delete, field, LengthGeneral, OrdGeneral);
970  SetProc(p_Mult_nn, field, LengthGeneral, OrdGeneral);
971  SetProc(pp_Mult_nn, field, length, OrdGeneral);
972  SetProc(p_ShallowCopyDelete, FieldGeneral, length, OrdGeneral);
973  SetProc(p_Copy, field, length, OrdGeneral);
974  SetProc(pp_Mult_mm, field, length, OrdGeneral);
975  SetProc(pp_Mult_mm_Noether, field, length, ord);
976  SetProc(p_Mult_mm, field, length, OrdGeneral);
977  SetProc(p_Add_q, field, length, ord);
978  SetProc(p_Minus_mm_Mult_qq, field, length, ord);
979  SetProc(p_kBucketSetLm, field, length, ord);
980  SetProc(p_Neg, field, LengthGeneral, OrdGeneral);
981  SetProc(pp_Mult_Coeff_mm_DivSelect, field, length, OrdGeneral);
982  SetProc(p_Merge_q, FieldGeneral, length, ord);
983}
Note: See TracBrowser for help on using the repository browser.