1 #ifndef RING_H
2 #define RING_H
3 /****************************************
4 *  Computer Algebra System SINGULAR     *
5 ****************************************/
6 /*
7 * ABSTRACT - the interpreter related ring operations
8 */
9 
10 /* includes */
11 #include "misc/auxiliary.h"
12 #include "coeffs/coeffs.h"
13 #include "misc/intvec.h"
14 #include "misc/int64vec.h"
15 #include "coeffs/coeffs.h" // ring,number
16 #include "polys/monomials/monomials.h"
17 //#include "polys/monomials/polys-impl.h"
18 //
19 
20 /* forward declaration of types */
21 class idrec; typedef idrec *   idhdl; // _only_ for idhdl ip_sring::idroot
22 struct p_Procs_s;
23 typedef struct p_Procs_s p_Procs_s;
24 class kBucket;
25 typedef kBucket*           kBucket_pt;
26 
27 struct sip_sideal;
28 typedef struct sip_sideal *       ideal;
29 typedef struct sip_sideal const * const_ideal;
30 
31 struct sip_smap;
32 typedef struct sip_smap *         map;
33 typedef struct sip_smap const *   const_map;
34 
35 /* the function pointer types */
36 
37 typedef long     (*pLDegProc)(poly p, int *length, ring r);
38 typedef long     (*pFDegProc)(poly p, ring r);
39 typedef void     (*p_SetmProc)(poly p, const ring r);
40 
41 
42 /// returns a poly from dest_r which is a ShallowCopy of s_p from source_r
43 /// assumes that source_r->N == dest_r->N and that orderings are the same
44 typedef poly (*pShallowCopyDeleteProc)(poly s_p, ring source_r, ring dest_r,
45                                        omBin dest_bin);
46 
47 // ro_typ describes what to store at the corresping "data" place in p->exp
48 // none of the directly corresponds to a ring ordering (ringorder_*)
49 // as each ringorder_* blocks corrsponds to 0..2 sro-blocks
50 typedef enum
51 {
52   ro_dp, // total degree with weights 1
53   ro_wp, // total weighted degree with weights>0 in wvhdl
54   ro_am, // weights for vars + weights for gen
55   ro_wp64, // weighted64 degree weights in wvhdl
56   ro_wp_neg, // total weighted degree with weights in Z in wvhdl
57              // (with possibly negative weights)
58   ro_cp,    // ??ordering duplicates variables
59   ro_syzcomp, // ??ordering indicates "subset" of component number (ringorder_S)
60   ro_syz, // component number if <=syzcomp else 0 (ringorder_s)
61   ro_isTemp, ro_is, // ??Induced Syzygy (Schreyer) ordering (and prefix data placeholder dummy) (ringorder_IS)
62   ro_none
63 }
64 ro_typ;
65 
66 /// order stuff
67 typedef enum rRingOrder_t
68 {
69   ringorder_no = 0,
70   ringorder_a,
71   ringorder_a64, ///< for int64 weights
72   ringorder_c,
73   ringorder_C,
74   ringorder_M,
75   ringorder_S, ///< S?
76   ringorder_s, ///< s?
77   ringorder_lp,
78   ringorder_dp,
79   ringorder_rp,
80   ringorder_Dp,
81   ringorder_wp,
82   ringorder_Wp,
83   ringorder_ls,
84   ringorder_ds,
85   ringorder_Ds,
86   ringorder_ws,
87   ringorder_Ws,
88   ringorder_am,
89   ringorder_L,
90   // the following are only used internally
91   ringorder_aa, ///< for idElimination, like a, except pFDeg, pWeigths ignore it
92   ringorder_rs, ///< opposite of ls
93   ringorder_IS, ///< Induced (Schreyer) ordering
94   ringorder_unspec
95 } rRingOrder_t;
96 
97 typedef enum rOrderType_t
98 {
99   rOrderType_General = 0, ///< non-simple ordering as specified by currRing
100   rOrderType_CompExp,     ///< simple ordering, component has priority
101   rOrderType_ExpComp,     ///< simple ordering, exponent vector has priority
102                           ///< component not compatible with exp-vector order
103   rOrderType_Exp,         ///< simple ordering, exponent vector has priority
104                           ///< component is compatible with exp-vector order
105   rOrderType_Syz,         ///< syzygy ordering
106   rOrderType_Schreyer,    ///< Schreyer ordering
107   rOrderType_Syz2dpc,     ///< syzcomp2dpc
108   rOrderType_ExpNoComp    ///< simple ordering, differences in component are
109                           ///< not considered
110 } rOrderType_t;
111 
112 // ordering is a degree ordering
113 struct sro_dp
114 {
115   short place;  // where degree is stored (in L):
116   short start;  // bounds of ordering (in E):
117   short end;
118 };
119 typedef struct sro_dp sro_dp;
120 
121 // ordering is a weighted degree ordering
122 struct sro_wp
123 {
124   short place;  // where weighted degree is stored (in L)
125   short start;  // bounds of ordering (in E)
126   short end;
127   int *weights; // pointers into wvhdl field
128 };
129 typedef struct sro_wp sro_wp;
130 
131 // ordering is a weighted degree ordering
132 struct sro_am
133 {
134   short place;  // where weighted degree is stored (in L)
135   short start;  // bounds of ordering (in E)
136   short end;
137   short len_gen; // i>len_gen: weight(gen(i)):=0
138   int *weights; // pointers into wvhdl field of length (end-start+1) + len_gen + 1
139                 // contents w_{start},... w_{end}, len, mod_w_1, .. mod_w_len, 0
140   int *weights_m; // pointers into wvhdl field of length len_gen + 1
141                 // len_gen, mod_w_1, .. mod_w_len, 0
142 
143 };
144 typedef struct sro_am sro_am;
145 
146 // ordering is a weighted degree ordering
147 struct sro_wp64
148 {
149     short place;  // where weighted degree is stored (in L)
150     short start;  // bounds of ordering (in E)
151     short end;
152     int64 *weights64; // pointers into wvhdl field
153 };
154 typedef struct sro_wp64 sro_wp64;
155 
156 // ordering duplicates variables
157 struct sro_cp
158 {
159   short place;  // where start is copied to (in E)
160   short start;  // bounds of sources of copied variables (in E)
161   short end;
162 };
163 typedef struct sro_cp sro_cp;
164 
165 // ordering indicates "subset" of component number
166 struct sro_syzcomp
167 {
168   short place;  // where the index is stored (in L)
169   long *ShiftedComponents; // pointer into index field
170   int* Components;
171 #ifdef PDEBUG
172   long length;
173 #endif
174 };
175 typedef struct sro_syzcomp sro_syzcomp;
176 
177 // ordering  with component number >syzcomp is lower
178 struct sro_syz
179 {
180   short place;       // where the index is stored (in L)
181   int limit;         // syzcomp
182   int* syz_index;    // mapping Component -> SyzIndex for Comp <= limit
183   int  curr_index;   // SyzIndex for Component > limit
184 };
185 
186 typedef struct sro_syz sro_syz;
187 // Induced Syzygy (Schreyer) ordering is built inductively as follows:
188 // we look for changes made by ordering blocks which are between prefix/suffix markers:
189 // that is: which variables where placed by them and where (judging by v)
190 
191 // due to prefix/suffix nature we need some placeholder:
192 // prefix stores here initial state
193 // suffix cleares this up
194 struct sro_ISTemp
195 {
196   short start; // 1st member SHOULD be short "place"
197   int   suffixpos;
198   int*  pVarOffset; // copy!
199 };
200 
201 // So this is the actuall thing!
202 // suffix uses last sro_ISTemp (cleares it up afterwards) and
203 // creates this block
204 struct sro_IS
205 {
206   short start, end;  // which part of L we want to want to update...
207   int*  pVarOffset; // same as prefix!
208 
209   int limit; // first referenced component
210 
211   // reference poly set?? // Should it be owned by ring?!!!
212   ideal F; // reference leading (module)-monomials set. owned by ring...
213 };
214 
215 typedef struct sro_IS sro_IS;
216 typedef struct sro_ISTemp sro_ISTemp;
217 
218 struct sro_ord
219 {
220   ro_typ  ord_typ;
221   int     order_index; // comes from r->order[order_index]
222   union
223   {
224      sro_dp dp;
225      sro_wp wp;
226      sro_am am;
227      sro_wp64 wp64;
228      sro_cp cp;
229      sro_syzcomp syzcomp;
230      sro_syz syz;
231      sro_IS is;
232      sro_ISTemp isTemp;
233   } data;
234 };
235 
236 #ifdef HAVE_PLURAL
237 struct nc_struct;
238 typedef struct nc_struct   nc_struct;
239 #endif
240 class skStrategy;
241 typedef skStrategy * kStrategy;
242 
243 typedef poly (*NF_Proc)(ideal, ideal, poly, int, int, const ring _currRing);
244 typedef ideal (*BBA_Proc) (const ideal, const ideal, const intvec *, const intvec *, kStrategy strat, const ring);
245 
246 
247 struct ip_sring
248 {
249 // each entry must have a description and a procedure defining it,
250 // general ordering: pointer/structs, long, int, short, BOOLEAN/char/enum
251 // general defining procedures: rInit, rComplete, interpreter, ??
252   idhdl      idroot; /* local objects , interpreter*/
253   rRingOrder_t* order;  /* array of orderings, rInit/rSleftvOrdering2Ordering */
254   int*       block0; /* starting pos., rInit/rSleftvOrdering2Ordering*/
255   int*       block1; /* ending pos., rInit/rSleftvOrdering2Ordering*/
256 //  char**     parameter; /* names of parameters, rInit */
257   int**      wvhdl;  /* array of weight vectors, rInit/rSleftvOrdering2Ordering */
258   char **    names;  /* array of variable names, rInit */
259 
260   // what follows below here should be set by rComplete, _only_
261   long      *ordsgn;  /* array of +/- 1 (or 0) for comparing monomials */
262                        /*  ExpL_Size entries*/
263 
264   // is NULL for lp or N == 1, otherwise non-NULL (with OrdSize > 0 entries) */
265   sro_ord*   typ;   /* array of orderings + sizes, OrdSize entries */
266   /* if NegWeightL_Size > 0, then NegWeightL_Offset[0..size_1] is index of longs
267   in ExpVector whose values need an offset due to negative weights */
268   /* array of NegWeigtL_Size indicies */
269   int*      NegWeightL_Offset;
270 
271   int*     VarOffset;
272 
273 //  ideal      minideal;
274 //  number     minpoly;  /* replaced by minideal->m[0] */
275   ideal      qideal; /**< extension to the ring structure: qring, rInit, OR
276                           for Q_a/Zp_a, rInit (replaces minideal!);
277                           for a start, we assume that there is either no
278                           or exactly one generator in minideal, playing
279                           the role of the former minpoly; minideal may
280                           also be NULL which coincides with the
281                           no-generator-case **/
282 
283   int*     firstwv;
284 
285   omBin    PolyBin; /* Bin from where monoms are allocated */
286   intvec * pModW;   /* std: module weights */
287   poly     ppNoether; /*  variables, set by procedures from hecke/kstd1:
288                             the highest monomial below pHEdge */
289   void * ext_ref;   /* libsing GAP object */
290 // #ifdef HAVE_RINGS
291 //   unsigned int  cf->ringtype;  /* cring = 0 => coefficient field, cring = 1 => coeffs from Z/2^m */
292 //   mpz_ptr    cf->modBase; /* Z/(ringflag^cf->modExponent)=Z/cf->modNumber*/
293 //   unsigned long cf->modExponent;
294 //   unsigned long cf->modNumber;  /* Z/cf->modNumber */
295 //   mpz_ptr    cf->modNumber;
296 // #endif
297 
298   unsigned long options; /* ring dependent options */
299 
300 //  int        ch;  /* characteristic, rInit */
301   int        ref; /* reference counter to the ring, interpreter */
302 
303   short      N;      /* number of vars, rInit */
304 
305   short      OrdSgn; /* 1 for polynomial rings, -1 otherwise, rInit */
306 
307   short     firstBlockEnds;
308 #ifdef HAVE_PLURAL
309   short     real_var_start, real_var_end;
310 #endif
311 
312 #ifdef HAVE_SHIFTBBA
313   short          isLPring; /* 0 for non-letterplace rings, otherwise the number of LP blocks, at least 1, known also as lV */
314   short          LPncGenCount;
315 #endif
316 
317   BOOLEAN   VectorOut;
318   BOOLEAN   ShortOut;
319   BOOLEAN   CanShortOut;
320   BOOLEAN   LexOrder; // TRUE if the monomial ordering has polynomial and power series blocks
321   BOOLEAN   MixedOrder; // TRUE for global/local mixed orderings, FALSE otherwise
322   BOOLEAN   pLexOrder; /* TRUE if the monomial ordering is not compatible with pFDeg */
323 
324   BOOLEAN   ComponentOrder; // 1 if ringorder_c, -1 for ringorder_C,ringorder_S,ringorder_s
325 
326   // what follows below here should be set by rComplete, _only_
327   // contains component, but no weight fields in E */
328   short      ExpL_Size; // size of exponent vector in long
329   short      CmpL_Size; // portions which need to be compared
330   /* number of long vars in exp vector:
331      long vars are those longs in the exponent vector which are
332      occupied by variables, only */
333   short      VarL_Size;
334   short      BitsPerExp; /* number of bits per exponent */
335   short      ExpPerLong; /* maximal number of Exponents per long */
336   short      pCompIndex; /* p->exp.e[pCompIndex] is the component */
337   short      pOrdIndex; /* p->exp[pOrdIndex] is pGetOrd(p) */
338   short      OrdSize; /* size of ord vector (in sro_ord) */
339 
340   /* if >= 0, long vars in exp vector are consecutive and start there
341      if <  0, long vars in exp vector are not consecutive */
342   short     VarL_LowIndex;
343 
344   short     NegWeightL_Size;
345   /* array of size VarL_Size,
346      VarL_Offset[i] gets i-th long var in exp vector */
347   int*      VarL_Offset;
348 
349   /* mask for getting single exponents, also maxExp */
350   unsigned long bitmask;
351   /* wanted maxExp */
352   unsigned long wanted_maxExp;
353   /* mask used for divisiblity tests */
354   unsigned long divmask; // rComplete
355 
356   p_Procs_s*    p_Procs; // rComplete/p_ProcsSet
357 
358   /* FDeg and LDeg */
359   pFDegProc     pFDeg; // rComplete/rSetDegStuff
360   pLDegProc     pLDeg; // rComplete/rSetDegStuff
361 
362   /* as it was determined by rComplete */
363   pFDegProc     pFDegOrig;
364   /* and as it was determined before rOptimizeLDeg */
365   pLDegProc     pLDegOrig;
366 
367   p_SetmProc    p_Setm;
368   n_Procs_s*    cf;
369 #ifdef HAVE_PLURAL
370   private:
371     nc_struct*    _nc; // private
372   public:
GetNCip_sring373     inline const nc_struct* GetNC() const { return _nc; }; // public!!!
GetNCip_sring374     inline nc_struct*& GetNC() { return _nc; }; // public!!!
375 #endif
376  public:
coeffsip_sring377   operator coeffs() const { return cf; }
378 };
379 
380 ////////// DEPRECATED
381 /////// void   rChangeCurrRing(ring r);
382 
383 ring   rDefault(int ch, int N, char **n);
384 ring   rDefault(const coeffs cf, int N, char **n, const rRingOrder_t o=ringorder_lp);
385 ring   rDefault(int ch, int N, char **n,int ord_size, rRingOrder_t *ord, int *block0, int *block1, int **wvhdl=NULL);
386 ring   rDefault(const coeffs cf, int N, char **n,int ord_size, rRingOrder_t *ord, int *block0, int *block1, int **wvhdl=NULL, unsigned long bitmask=0);
387 unsigned long rGetExpSize(unsigned long bitmask, int & bits, int N);
388 
389 // #define rIsRingVar(A) r_IsRingVar(A,currRing)
390 int    r_IsRingVar(const char *n, char**names, int N);
391 void   rWrite(ring r, BOOLEAN details = FALSE);
392 ring   rCopy(ring r);
393 ring   rCopy0(const ring r, BOOLEAN copy_qideal = TRUE, BOOLEAN copy_ordering = TRUE);
394 ring rCopy0AndAddA(ring r, int64vec *wv64, BOOLEAN copy_qideal = TRUE,
395                    BOOLEAN copy_ordering = TRUE);
396 ring   rOpposite(ring r);
397 ring   rEnvelope(ring r);
398 
399 /// we must always have this test!
rIsPluralRing(const ring r)400 static inline BOOLEAN rIsPluralRing(const ring r)
401 {
402   assume(r != NULL);
403 #ifdef HAVE_PLURAL
404   nc_struct *n;
405   return ((n=r->GetNC()) != NULL) /*&& (n->type != nc_error)*/;
406 #else
407   return FALSE;
408 #endif
409 }
410 
rIsLPRing(const ring r)411 static inline BOOLEAN rIsLPRing(const ring r)
412 {
413   assume(r != NULL);
414 #ifdef HAVE_SHIFTBBA
415   return (r->isLPring!=0);
416 #else
417   return FALSE;
418 #endif
419 }
420 
rIsNCRing(const ring r)421 static inline BOOLEAN rIsNCRing(const ring r)
422 {
423   assume(r != NULL);
424   return rIsPluralRing(r) || rIsLPRing(r);
425 }
426 
rIsRatGRing(const ring r)427 static inline BOOLEAN rIsRatGRing(const ring r)
428 {
429   assume(r != NULL);
430 #ifdef HAVE_PLURAL
431   /* nc_struct *n; */
432   return (r != NULL) /* && ((n=r->GetNC()) != NULL) */
433           && (r->real_var_start>1);
434 #else
435   return FALSE;
436 #endif
437 }
438 
439 // The following are for LaScala3 only!
440 void rChangeSComps(int* currComponents, long* currShiftedComponents, int length, ring r);
441 void rGetSComps(int** currComponents, long** currShiftedComponents, int *length, ring r);
442 
443 
444 
445 const char * rSimpleOrdStr(int ord);
446 rRingOrder_t rOrderName(char * ordername);
447 char * rOrdStr(ring r);
448 char * rVarStr(ring r);
449 char * rCharStr(ring r);
450 char * rString(ring r);
451 int    rChar(ring r);
452 
453 char * rParStr(ring r);
454 
455 int    rSum(ring r1, ring r2, ring &sum);
456 /// returns -1 for not compatible, 1 for compatible (and sum)
457 /// dp_dp:0: block ordering, 1: dp,dp, 2: aa(...),dp
458 /// vartest: check for name conflicts
459 int rSumInternal(ring r1, ring r2, ring &sum, BOOLEAN vartest, BOOLEAN dp_dp);
460 
461 /// returns TRUE, if r1 equals r2 FALSE, otherwise Equality is
462 /// determined componentwise, if qr == 1, then qrideal equality is
463 /// tested, as well
464 BOOLEAN rEqual(ring r1, ring r2, BOOLEAN qr = TRUE);
465 
466 /// returns TRUE, if r1 and r2 represents the monomials in the same way
467 /// FALSE, otherwise
468 /// this is an analogue to rEqual but not so strict
469 BOOLEAN rSamePolyRep(ring r1, ring r2);
470 
471 void   rUnComplete(ring r);
472 
473 BOOLEAN rRing_is_Homog(const ring r);
474 BOOLEAN rRing_has_CompLastBlock(const ring r);
475 BOOLEAN rRing_ord_pure_dp(const ring r);
476 BOOLEAN rRing_ord_pure_Dp(const ring r);
477 BOOLEAN rRing_ord_pure_lp(const ring r);
478 
479 #ifdef HAVE_RINGS
rField_is_Ring_2toM(const ring r)480 static inline BOOLEAN rField_is_Ring_2toM(const ring r)
481 { assume(r != NULL); assume(r->cf != NULL); return ( nCoeff_is_Ring_2toM(r->cf) ); }
482 
rField_is_Ring_PtoM(const ring r)483 static inline BOOLEAN rField_is_Ring_PtoM(const ring r)
484 { assume(r != NULL); assume(r->cf != NULL); return ( nCoeff_is_Ring_PtoM(r->cf) ); }
485 
rField_is_Ring(const ring r)486 static inline BOOLEAN rField_is_Ring(const ring r)
487 { assume(r != NULL); assume(r->cf != NULL); return nCoeff_is_Ring(r->cf); }
488 
rField_is_Domain(const ring r)489 static inline BOOLEAN rField_is_Domain(const ring r)
490 { assume(r != NULL); assume(r->cf != NULL); return nCoeff_is_Domain(r->cf); }
491 
rField_has_Units(const ring r)492 static inline BOOLEAN rField_has_Units(const ring r)
493 { assume(r != NULL); assume(r->cf != NULL); return nCoeff_has_Units(r->cf); }
494 #else
495 #define rField_is_Ring(A) (0)
496 #define rField_is_Ring_2toM(A) (0)
497 #define rField_is_Ring_PtoM(A) (0)
498 #define rField_is_Domain(A) (1)
499 #define rField_has_Units(A) (1)
500 #endif
501 
rField_is_Zp(const ring r)502 static inline BOOLEAN rField_is_Zp(const ring r)
503 { assume(r != NULL); assume(r->cf != NULL); return (getCoeffType(r->cf) == n_Zp); }
504 
rField_is_Zp(const ring r,int p)505 static inline BOOLEAN rField_is_Zp(const ring r, int p)
506 { assume(r != NULL); assume(r->cf != NULL); return (getCoeffType(r->cf) == n_Zp) && (r->cf->ch == p); }
507 
rField_is_Q(const ring r)508 static inline BOOLEAN rField_is_Q(const ring r)
509 { assume(r != NULL); assume(r->cf != NULL); return nCoeff_is_Q(r->cf); }
510 
rField_is_Z(const ring r)511 static inline BOOLEAN rField_is_Z(const ring r)
512 { assume(r != NULL); assume(r->cf != NULL); return nCoeff_is_Z(r->cf); }
513 
rField_is_Zn(const ring r)514 static inline BOOLEAN rField_is_Zn(const ring r)
515 { assume(r != NULL); assume(r->cf != NULL); return nCoeff_is_Zn(r->cf); }
516 
rField_is_numeric(const ring r)517 static inline BOOLEAN rField_is_numeric(const ring r) /* R, long R, long C */
518 { assume(r != NULL); assume(r->cf != NULL); return nCoeff_is_numeric(r->cf); }
519 
rField_is_R(const ring r)520 static inline BOOLEAN rField_is_R(const ring r)
521 { assume(r != NULL); assume(r->cf != NULL); return nCoeff_is_R(r->cf); }
522 
rField_is_GF(const ring r)523 static inline BOOLEAN rField_is_GF(const ring r)
524 { assume(r != NULL); assume(r->cf != NULL); return nCoeff_is_GF(r->cf); }
525 
rField_is_GF(const ring r,int q)526 static inline BOOLEAN rField_is_GF(const ring r, int q)
527 { assume(r != NULL); assume(r->cf != NULL); return nCoeff_is_GF(r->cf, q); }
528 
529 /* DO NOT USE; just here for compatibility reasons towards
530    the SINGULAR svn trunk */
rField_is_Zp_a(const ring r)531 static inline BOOLEAN rField_is_Zp_a(const ring r)
532 { assume(r != NULL); assume(r->cf != NULL); return nCoeff_is_Zp_a(r->cf); }
533 
534 /* DO NOT USE; just here for compatibility reasons towards
535    the SINGULAR svn trunk */
rField_is_Zp_a(const ring r,int p)536 static inline BOOLEAN rField_is_Zp_a(const ring r, int p)
537 { assume(r != NULL); assume(r->cf != NULL); return nCoeff_is_Zp_a(r->cf, p); }
538 
539 /* DO NOT USE; just here for compatibility reasons towards
540    the SINGULAR svn trunk */
rField_is_Q_a(const ring r)541 static inline BOOLEAN rField_is_Q_a(const ring r)
542 { assume(r != NULL); assume(r->cf != NULL); return nCoeff_is_Q_a(r->cf); }
543 
rField_is_long_R(const ring r)544 static inline BOOLEAN rField_is_long_R(const ring r)
545 { assume(r != NULL); assume(r->cf != NULL); return nCoeff_is_long_R(r->cf); }
546 
rField_is_long_C(const ring r)547 static inline BOOLEAN rField_is_long_C(const ring r)
548 { assume(r != NULL); assume(r->cf != NULL); return nCoeff_is_long_C(r->cf); }
549 
rField_has_simple_inverse(const ring r)550 static inline BOOLEAN rField_has_simple_inverse(const ring r)
551 { assume(r != NULL); assume(r->cf != NULL); return nCoeff_has_simple_inverse(r->cf); }
552 
553 /// Z/p, GF(p,n), R: nCopy, nNew, nDelete are dummies
rField_has_simple_Alloc(const ring r)554 static inline BOOLEAN rField_has_simple_Alloc(const ring r)
555 { assume(r != NULL); assume(r->cf != NULL); return nCoeff_has_simple_Alloc(r->cf); }
556 
557 /// the type of the coefficient filed of r (n_Zp, n_Q, etc)
rFieldType(const ring r)558 static inline n_coeffType rFieldType(const ring r) { return (r->cf->type); }
559 
560 /// this needs to be called whenever a new ring is created: new fields
561 /// in ring are created (like VarOffset), unless they already exist
562 /// with force == 1, new fields are _always_ created (overwritten),
563 /// even if they exist
564 BOOLEAN rComplete(ring r, int force = 0);
565 // use this to free fields created by rComplete //?
566 
567 /// set all properties of a new ring - also called by rComplete
568 void p_SetGlobals(const ring r, BOOLEAN complete = TRUE);
569 
rBlocks(ring r)570 static inline int rBlocks(ring r)
571 {
572   assume(r != NULL);
573   int i=0;
574   while (r->order[i]!=0) i++;
575   return i+1;
576 }
577 
578 // misc things
rRingVar(short i,const ring r)579 static inline char* rRingVar(short i, const ring r)
580 {
581   assume(r != NULL); assume(r->cf != NULL); return r->names[i];
582 }
rShortOut(const ring r)583 static inline BOOLEAN rShortOut(const ring r)
584 {
585   assume(r != NULL); return (r->ShortOut);
586 }
587 
rCanShortOut(const ring r)588 static inline BOOLEAN rCanShortOut(const ring r)
589 {
590   assume(r != NULL); return (r->CanShortOut);
591 }
592 
593 /// #define rVar(r) (r->N)
rVar(const ring r)594 static inline short rVar(const ring r)
595 {
596   assume(r != NULL);
597   return r->N;
598 }
599 
600 /// (r->cf->P)
rPar(const ring r)601 static inline int rPar(const ring r)
602 {
603   assume(r != NULL);
604   const coeffs C = r->cf;
605   assume(C != NULL);
606 
607   return n_NumberOfParameters(C);
608 //   if( nCoeff_is_Extension(C) )
609 //   {
610 //     const ring R = C->extRing;
611 //     assume( R != NULL );
612 //     return rVar( R );
613 //   }
614 //   else if (nCoeff_is_GF(C))
615 //   {
616 //     return 1;
617 //   }
618 //   else if (nCoeff_is_long_C(C))
619 //   {
620 //     return 1;
621 //   }
622 //   return 0;
623 }
624 
625 
626 /// (r->cf->parameter)
rParameter(const ring r)627 static inline char const ** rParameter(const ring r)
628 {
629   assume(r != NULL);
630   const coeffs C = r->cf;
631   assume(C != NULL);
632 
633   return n_ParameterNames(C);
634 //   if( nCoeff_is_Extension(C) ) // only alg / trans. exts...
635 //   {
636 //     const ring R = C->extRing;
637 //     assume( R != NULL );
638 //     return R->names;
639 //   }
640 //   else if (nCoeff_is_GF(C))
641 //   {
642 //     return &(C->m_nfParameter);
643 //   }
644 //   else if (nCoeff_is_long_C(C))
645 //   {
646 //     return &(C->complex_parameter);
647 //   }
648 //   return NULL;
649 }
650 
651 /// return the specified parameter as a (new!) number in the given
652 /// polynomial ring, or NULL if invalid
653 /// parameters (as variables) begin with 1!
n_Param(const short iParameter,const ring r)654 static inline number n_Param(const short iParameter, const ring r)
655 {
656   assume(r != NULL);
657   const coeffs C = r->cf;
658   assume(C != NULL);
659   return n_Param(iParameter, C);
660 //   const n_coeffType _filed_type = getCoeffType(C);
661 //
662 //   if ( iParameter <= 0 || iParameter > rPar(r) )
663 //     // Wrong parameter
664 //     return NULL;
665 //
666 //   if( _filed_type == n_algExt )
667 //     return naParameter(iParameter, C);
668 //
669 //   if( _filed_type == n_transExt )
670 //     return ntParameter(iParameter, C);
671 //
672 //   if (_filed_type == n_GF)// if (nCoeff_is_GF(C))
673 //   {
674 //     number nfPar (int i, const coeffs);
675 //     return nfPar(iParameter, C);
676 //   }
677 //
678 //   if (_filed_type == n_long_C) // if (nCoeff_is_long_C(C))
679 //   {
680 //     number   ngcPar(int i, const coeffs r);
681 //     return ngcPar(iParameter, C);
682 //   }
683 //
684 //   return NULL;
685 }
686 
687 /// if m == var(i)/1 => return i,
688 int n_IsParam(number m, const ring r);
689 
690 //#define  rInternalChar(r) ((r)->cf->ch)
rInternalChar(const ring r)691 static inline int rInternalChar(const ring r)
692 {
693   assume(r != NULL);
694   const coeffs C = r->cf;
695   assume(C != NULL);
696   return C->ch;
697 }
698 
699 
700 /// Tests whether '(r->cf->minpoly) == NULL'
rMinpolyIsNULL(const ring r)701 static inline BOOLEAN rMinpolyIsNULL(const ring r)
702 {
703   assume(r != NULL);
704   const coeffs C = r->cf;
705   assume(C != NULL);
706 
707   const BOOLEAN ret = nCoeff_is_algExt(C); //  || nCoeff_is_GF(C) || nCoeff_is_long_C(C);
708 
709   if( ret )
710   {
711     assume( (C->extRing) != NULL );
712     BOOLEAN idIs0 (ideal h);
713     assume((!((C->extRing)->qideal==NULL)) && (!idIs0((C->extRing)->qideal)));
714   }
715 
716   // TODO: this leads to test fails (due to rDecompose?)
717   return !ret;
718 }
719 
720 
721 
rIsSyzIndexRing(const ring r)722 static inline BOOLEAN rIsSyzIndexRing(const ring r)
723 { assume(r != NULL); assume(r->cf != NULL); return r->order[0] == ringorder_s;}
724 
rGetCurrSyzLimit(const ring r)725 static inline int rGetCurrSyzLimit(const ring r)
726 { assume(r != NULL); assume(r->cf != NULL); return (rIsSyzIndexRing(r)? r->typ[0].data.syz.limit : 0);}
727 
728 void   rSetSyzComp(int k, const ring r);
729 
730 // Ring Manipulations
731 ring   rAssure_HasComp(const ring r);
732 ring   rAssure_SyzOrder(const ring r, BOOLEAN complete);
733 ring   rAssure_SyzComp(const ring r, BOOLEAN complete = TRUE);
734 ring   rAssure_InducedSchreyerOrdering(const ring r, BOOLEAN complete = TRUE, int sgn = 1);
735 
736 ring   rAssure_dp_S(const ring r);
737 ring   rAssure_dp_C(const ring r);
738 ring   rAssure_C_dp(const ring r);
739 ring   rAssure_c_dp(const ring r);
740 
741 /// makes sure that c/C ordering is last ordering
742 ring   rAssure_CompLastBlock(const ring r, BOOLEAN complete = TRUE);
743 
744 /// makes sure that c/C ordering is last ordering and SyzIndex is first
745 ring   rAssure_SyzComp_CompLastBlock(const ring r);
746 ring   rAssure_TDeg(const ring r, int &pos);
747 
748 /// return the max-comonent wchich has syzIndex i
749 /// Assume: i<= syzIndex_limit
750 int rGetMaxSyzComp(int i, const ring r);
751 
752 BOOLEAN rHasSimpleOrder(const ring r);
753 BOOLEAN rHas_c_Ordering(const ring r);
754 
755 /// returns TRUE, if simple lp or ls ordering
756 BOOLEAN rHasSimpleLexOrder(const ring r);
757 
758 //???? return TRUE if p->exp[r->pOrdIndex] holds total degree of p ???
759 
760 
rHasGlobalOrdering(const ring r)761 inline BOOLEAN rHasGlobalOrdering(const ring r){ return (r->OrdSgn==1); }
rHasLocalOrMixedOrdering(const ring r)762 inline BOOLEAN rHasLocalOrMixedOrdering(const ring r){ return (r->OrdSgn==-1); }
rHasMixedOrdering(const ring r)763 inline BOOLEAN rHasMixedOrdering(const ring r) { return (r->MixedOrder); }
764 
765 // #define rHasGlobalOrdering(R) ((R)->OrdSgn==1)
766 // #define rHasLocalOrMixedOrdering(R) ((R)->OrdSgn==-1)
767 
768 BOOLEAN rOrd_is_Totaldegree_Ordering(const ring r);
769 
770 /// return TRUE if p_SetComp requires p_Setm
771 BOOLEAN rOrd_SetCompRequiresSetm(const ring r);
772 rOrderType_t    rGetOrderType(ring r);
773 
774 /// returns TRUE if var(i) belongs to p-block
775 BOOLEAN rIsPolyVar(int i, const ring r);
776 
rOrd_is_Comp_dp(const ring r)777 static inline BOOLEAN rOrd_is_Comp_dp(const ring r)
778 {
779   assume(r != NULL);
780   assume(r->cf != NULL);
781   return ((r->order[0] == ringorder_c || r->order[0] == ringorder_C) &&
782           r->order[1] == ringorder_dp &&
783           r->order[2] == 0);
784 }
785 
786 #ifdef RDEBUG
787 #define rTest(r)  rDBTest(r, __FILE__, __LINE__)
788 extern BOOLEAN rDBTest(ring r, const char* fn, const int l);
789 #else
790 #define rTest(r) (TRUE)
791 #endif
792 
793 ring rModifyRing(ring r, BOOLEAN omit_degree,
794                          BOOLEAN omit_comp,
795                          unsigned long exp_limit);
796 
797 /// construct Wp, C ring
798 ring rModifyRing_Wp(ring r, int* weights);
799 void rModify_a_to_A(ring r);
800 
801 void rKillModifiedRing(ring r);
802 // also frees weights
803 void rKillModified_Wp_Ring(ring r);
804 
805 ring rModifyRing_Simple(ring r, BOOLEAN omit_degree, BOOLEAN omit_comp, unsigned long exp_limit, BOOLEAN &simple);
806 
807 #ifdef RDEBUG
808 void rDebugPrint(const ring r);
809 // void pDebugPrint(poly p);
810 void p_DebugPrint(poly p, const ring r);
811 #endif
812 
813 int64 * rGetWeightVec(const ring r);
814 void rSetWeightVec(ring r, int64 *wv);
815 
816 /////////////////////////////
817 // Auxillary functions
818 //
819 
820 /* return the varIndex-th ring variable as a poly;
821    varIndex starts at index 1 */
822 poly rGetVar(const int varIndex, const ring r);
823 
824 BOOLEAN rSetISReference(const ring r, const ideal F, const int i = 0, const int p = 0);
825 
826 /// return the position of the p^th IS block order block in r->typ[]...
827 int rGetISPos(const int p, const ring r);
828 void pISUpdateComponents(ideal F, const intvec *const V, const int MIN, const ring r);
829 
830 BOOLEAN rCheckIV(const intvec *iv);
831 int rTypeOfMatrixOrder(const intvec *order);
832 
833 void rDelete(ring r); // To be used instead of rKill!
834 
835 EXTERN_VAR omBin sip_sring_bin;
836 
837 // ring manipulation
838 /// K[x],"y" -> K[x,y] resp. K[y,x]
839 ring rPlusVar(const ring r, char *v,int left);
840 
841 /// undo rPlusVar
842 ring rMinusVar(const ring r, char *v);
843 
rIncRefCnt(ring r)844 static inline ring rIncRefCnt(ring r) { r->ref++; return r; }
rDecRefCnt(ring r)845 static inline void rDecRefCnt(ring r) { r->ref--; }
846 #endif
847