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