ring.cc
Go to the documentation of this file.
1 /****************************************
2 * Computer Algebra System SINGULAR *
3 ****************************************/
4 /*
5 * ABSTRACT - the interpreter related ring operations
6 */
7 
8 /* includes */
9 #include <math.h>
10 
11 
12 
13 
14 
15 #include <omalloc/omalloc.h>
16 
17 #include <misc/auxiliary.h>
18 #include <misc/mylimits.h>
19 #include <misc/options.h>
20 #include <misc/int64vec.h>
21 
22 #include <coeffs/numbers.h>
23 #include <coeffs/coeffs.h>
24 
26 #include <polys/simpleideals.h>
27 // #include <???/febase.h>
28 // #include <???/intvec.h>
29 // #include <coeffs/ffields.h>
30 #include <polys/monomials/ring.h>
31 #include <polys/monomials/maps.h>
32 #include <polys/prCopy.h>
33 // #include "../Singular/ipshell.h"
35 
36 #include <polys/matpol.h>
37 
38 #include <polys/monomials/ring.h>
39 
40 #ifdef HAVE_PLURAL
41 #include <polys/nc/nc.h>
42 #include <polys/nc/sca.h>
43 #endif
44 // #include <???/maps.h>
45 // #include <???/matpol.h>
46 
47 
48 #include "ext_fields/algext.h"
49 #include "ext_fields/transext.h"
50 
51 
52 #define BITS_PER_LONG 8*SIZEOF_LONG
53 
55 omBin char_ptr_bin = omGetSpecBin(sizeof(char*));
56 
57 
58 static const char * const ringorder_name[] =
59 {
60  " ?", ///< ringorder_no = 0,
61  "a", ///< ringorder_a,
62  "A", ///< ringorder_a64,
63  "c", ///< ringorder_c,
64  "C", ///< ringorder_C,
65  "M", ///< ringorder_M,
66  "S", ///< ringorder_S,
67  "s", ///< ringorder_s,
68  "lp", ///< ringorder_lp,
69  "dp", ///< ringorder_dp,
70  "rp", ///< ringorder_rp,
71  "Dp", ///< ringorder_Dp,
72  "wp", ///< ringorder_wp,
73  "Wp", ///< ringorder_Wp,
74  "ls", ///< ringorder_ls,
75  "ds", ///< ringorder_ds,
76  "Ds", ///< ringorder_Ds,
77  "ws", ///< ringorder_ws,
78  "Ws", ///< ringorder_Ws,
79  "am", ///< ringorder_am,
80  "L", ///< ringorder_L,
81  "aa", ///< ringorder_aa
82  "rs", ///< ringorder_rs,
83  "IS", ///< ringorder_IS
84  " _" ///< ringorder_unspec
85 };
86 
87 
88 const char * rSimpleOrdStr(int ord)
89 {
90  return ringorder_name[ord];
91 }
92 
93 /// unconditionally deletes fields in r
94 void rDelete(ring r);
95 /// set r->VarL_Size, r->VarL_Offset, r->VarL_LowIndex
96 static void rSetVarL(ring r);
97 /// get r->divmask depending on bits per exponent
98 static unsigned long rGetDivMask(int bits);
99 /// right-adjust r->VarOffset
100 static void rRightAdjustVarOffset(ring r);
101 static void rOptimizeLDeg(ring r);
102 
103 /*0 implementation*/
104 //BOOLEAN rField_is_R(ring r)
105 //{
106 // if (r->cf->ch== -1)
107 // {
108 // if (r->float_len==(short)0) return TRUE;
109 // }
110 // return FALSE;
111 //}
112 
113 ring rDefault(const coeffs cf, int N, char **n,int ord_size, rRingOrder_t *ord, int *block0, int *block1, int** wvhdl)
114 {
115  assume( cf != NULL);
116  ring r=(ring) omAlloc0Bin(sip_sring_bin);
117  r->N = N;
118  r->cf = cf;
119  /*rPar(r) = 0; Alloc0 */
120  /*names*/
121  r->names = (char **) omAlloc0(N * sizeof(char *));
122  int i;
123  for(i=0;i<N;i++)
124  {
125  r->names[i] = omStrDup(n[i]);
126  }
127  /*weights: entries for 2 blocks: NULL*/
128  if (wvhdl==NULL)
129  r->wvhdl = (int **)omAlloc0((ord_size+1) * sizeof(int *));
130  else
131  r->wvhdl=wvhdl;
132  r->order = ord;
133  r->block0 = block0;
134  r->block1 = block1;
135 
136  /* complete ring intializations */
137  rComplete(r);
138  return r;
139 }
140 ring rDefault(int ch, int N, char **n,int ord_size, rRingOrder_t *ord, int *block0, int *block1,int ** wvhdl)
141 {
142  coeffs cf;
143  if (ch==0) cf=nInitChar(n_Q,NULL);
144  else cf=nInitChar(n_Zp,(void*)(long)ch);
145  assume( cf != NULL);
146  return rDefault(cf,N,n,ord_size,ord,block0,block1,wvhdl);
147 }
148 ring rDefault(const coeffs cf, int N, char **n, const rRingOrder_t o)
149 {
150  assume( cf != NULL);
151  /*order: o=lp,0*/
152  rRingOrder_t *order = (rRingOrder_t *) omAlloc(2* sizeof(rRingOrder_t));
153  int *block0 = (int *)omAlloc0(2 * sizeof(int));
154  int *block1 = (int *)omAlloc0(2 * sizeof(int));
155  /* ringorder o=lp for the first block: var 1..N */
156  order[0] = o;
157  block0[0] = 1;
158  block1[0] = N;
159  /* the last block: everything is 0 */
160  order[1] = (rRingOrder_t)0;
161 
162  return rDefault(cf,N,n,2,order,block0,block1);
163 }
164 
165 ring rDefault(int ch, int N, char **n)
166 {
167  coeffs cf;
168  if (ch==0) cf=nInitChar(n_Q,NULL);
169  else cf=nInitChar(n_Zp,(void*)(long)ch);
170  assume( cf != NULL);
171  return rDefault(cf,N,n);
172 }
173 
174 ///////////////////////////////////////////////////////////////////////////
175 //
176 // rInit: define a new ring from sleftv's
177 //
178 //-> ipshell.cc
179 
180 /////////////////////////////
181 // Auxillary functions
182 //
183 
184 // check intvec, describing the ordering
186 {
187  if ((iv->length()!=2)&&(iv->length()!=3))
188  {
189  WerrorS("weights only for orderings wp,ws,Wp,Ws,a,M");
190  return TRUE;
191  }
192  return FALSE;
193 }
194 
195 int rTypeOfMatrixOrder(const intvec* order)
196 {
197  int i=0,j,typ=1;
198  int sz = (int)sqrt((double)(order->length()-2));
199  if ((sz*sz)!=(order->length()-2))
200  {
201  WerrorS("Matrix order is not a square matrix");
202  typ=0;
203  }
204  while ((i<sz) && (typ==1))
205  {
206  j=0;
207  while ((j<sz) && ((*order)[j*sz+i+2]==0)) j++;
208  if (j>=sz)
209  {
210  typ = 0;
211  WerrorS("Matrix order not complete");
212  }
213  else if ((*order)[j*sz+i+2]<0)
214  typ = -1;
215  else
216  i++;
217  }
218  return typ;
219 }
220 
221 
222 int r_IsRingVar(const char *n, char**names,int N)
223 {
224  if (names!=NULL)
225  {
226  for (int i=0; i<N; i++)
227  {
228  if (names[i]==NULL) return -1;
229  if (strcmp(n,names[i]) == 0) return (int)i;
230  }
231  }
232  return -1;
233 }
234 
235 
236 void rWrite(ring r, BOOLEAN details)
237 {
238  if ((r==NULL)||(r->order==NULL))
239  return; /*to avoid printing after errors....*/
240 
241  assume(r != NULL);
242  const coeffs C = r->cf;
243  assume(C != NULL);
244 
245  int nblocks=rBlocks(r);
246 
247  // omCheckAddrSize(r,sizeof(ip_sring));
248  omCheckAddrSize(r->order,nblocks*sizeof(int));
249  omCheckAddrSize(r->block0,nblocks*sizeof(int));
250  omCheckAddrSize(r->block1,nblocks*sizeof(int));
251  omCheckAddrSize(r->wvhdl,nblocks*sizeof(int *));
252  omCheckAddrSize(r->names,r->N*sizeof(char *));
253 
254  nblocks--;
255 
256 
257  PrintS("// coefficients: ");
258  if( nCoeff_is_algExt(C) )
259  {
260  // NOTE: the following (non-thread-safe!) UGLYNESS
261  // (changing naRing->ShortOut for a while) is due to Hans!
262  // Just think of other ring using the VERY SAME naRing and possible
263  // side-effects...
264  ring R = C->extRing;
265  const BOOLEAN bSaveShortOut = rShortOut(R); R->ShortOut = rShortOut(r) & rCanShortOut(R);
266 
267  n_CoeffWrite(C, details); // for correct printing of minpoly... WHAT AN UGLYNESS!!!
268 
269  R->ShortOut = bSaveShortOut;
270  }
271  else
272  n_CoeffWrite(C, details);
273  PrintLn();
274 // {
275 // PrintS("// characteristic : ");
276 //
277 // char const * const * const params = rParameter(r);
278 //
279 // if (params!=NULL)
280 // {
281 // Print ("// %d parameter : ",rPar(r));
282 //
283 // char const * const * sp= params;
284 // int nop=0;
285 // while (nop<rPar(r))
286 // {
287 // PrintS(*sp);
288 // PrintS(" ");
289 // sp++; nop++;
290 // }
291 // PrintS("\n// minpoly : ");
292 // if ( rField_is_long_C(r) )
293 // {
294 // // i^2+1:
295 // Print("(%s^2+1)\n", params[0]);
296 // }
297 // else if (rMinpolyIsNULL(r))
298 // {
299 // PrintS("0\n");
300 // }
301 // else
302 // {
303 // StringSetS(""); n_Write(r->cf->minpoly, r); PrintS(StringEndS("\n")); // NOTE/TODO: use StringAppendS("\n"); omFree(s);
304 // }
305 // //if (r->qideal!=NULL)
306 // //{
307 // // iiWriteMatrix((matrix)r->qideal,"// minpolys",1,r,0);
308 // // PrintLn();
309 // //}
310 // }
311 // }
312  Print("// number of vars : %d",r->N);
313 
314  //for (nblocks=0; r->order[nblocks]; nblocks++);
315  nblocks=rBlocks(r)-1;
316 
317  for (int l=0, nlen=0 ; l<nblocks; l++)
318  {
319  int i;
320  Print("\n// block %3d : ",l+1);
321 
322  Print("ordering %s", rSimpleOrdStr(r->order[l]));
323 
324 
325  if (r->order[l] == ringorder_IS)
326  {
327  assume( r->block0[l] == r->block1[l] );
328  const int s = r->block0[l];
329  assume( (-2 < s) && (s < 2) );
330  Print("(%d)", s); // 0 => prefix! +/-1 => suffix!
331  continue;
332  }
333  else if (r->order[l]==ringorder_s)
334  {
335  assume( l == 0 );
336  Print(" syz_comp: %d",r->block0[l]);
337  continue;
338  }
339  else if (
340  ( (r->order[l] >= ringorder_lp)
341  ||(r->order[l] == ringorder_M)
342  ||(r->order[l] == ringorder_a)
343  ||(r->order[l] == ringorder_am)
344  ||(r->order[l] == ringorder_a64)
345  ||(r->order[l] == ringorder_aa) ) && (r->order[l] < ringorder_IS) )
346  {
347  PrintS("\n// : names ");
348  for (i = r->block0[l]-1; i<r->block1[l]; i++)
349  {
350  nlen = strlen(r->names[i]);
351  Print(" %s",r->names[i]);
352  }
353  }
354 
355  if (r->wvhdl[l]!=NULL)
356  {
357  for (int j= 0;
358  j<(r->block1[l]-r->block0[l]+1)*(r->block1[l]-r->block0[l]+1);
359  j+=i)
360  {
361  PrintS("\n// : weights ");
362  for (i = 0; i<=r->block1[l]-r->block0[l]; i++)
363  {
364  if (r->order[l] == ringorder_a64)
365  {
366  int64 *w=(int64 *)r->wvhdl[l];
367  #if SIZEOF_LONG == 4
368  Print("%*lld " ,nlen,w[i+j]);
369  #else
370  Print(" %*ld" ,nlen,w[i+j]);
371  #endif
372  }
373  else
374  Print(" %*d" ,nlen,r->wvhdl[l][i+j]);
375  }
376  if (r->order[l]!=ringorder_M) break;
377  }
378  if (r->order[l]==ringorder_am)
379  {
380  int m=r->wvhdl[l][i];
381  Print("\n// : %d module weights ",m);
382  m+=i;i++;
383  for(;i<=m;i++) Print(" %*d" ,nlen,r->wvhdl[l][i]);
384  }
385  }
386  }
387 #ifdef HAVE_PLURAL
388  if(rIsPluralRing(r))
389  {
390  PrintS("\n// noncommutative relations:");
391  if( details )
392  {
393  poly pl=NULL;
394  int nl;
395  int i,j;
396  for (i = 1; i<r->N; i++)
397  {
398  for (j = i+1; j<=r->N; j++)
399  {
400  nl = n_IsOne(p_GetCoeff(MATELEM(r->GetNC()->C,i,j),r), r->cf);
401  if ( (MATELEM(r->GetNC()->D,i,j)!=NULL) || (!nl) )
402  {
403  Print("\n// %s%s=",r->names[j-1],r->names[i-1]);
404  pl = MATELEM(r->GetNC()->MT[UPMATELEM(i,j,r->N)],1,1);
405  p_Write0(pl, r, r);
406  }
407  }
408  }
409  } else
410  PrintS(" ...");
411 
412 #if MYTEST /*Singularg should not differ from Singular except in error case*/
413  Print("\n// noncommutative type:%d", (int)ncRingType(r));
414  Print("\n// is skew constant:%d",r->GetNC()->IsSkewConstant);
415  if( rIsSCA(r) )
416  {
417  Print("\n// alternating variables: [%d, %d]", scaFirstAltVar(r), scaLastAltVar(r));
418  const ideal Q = SCAQuotient(r); // resides within r!
419  PrintS("\n// quotient of sca by ideal");
420 
421  if (Q!=NULL)
422  {
423 // if (r==currRing)
424 // {
425 // PrintLn();
426  iiWriteMatrix((matrix)Q,"scaQ",1,r,0);
427 // }
428 // else
429 // PrintS(" ...");
430  }
431  else
432  PrintS(" (NULL)");
433  }
434 #endif
435  }
436 #endif
437  if (r->qideal!=NULL)
438  {
439  PrintS("\n// quotient ring from ideal");
440  if( details )
441  {
442  PrintLn();
443  iiWriteMatrix((matrix)r->qideal,"_",1,r,0);
444  } else PrintS(" ...");
445  }
446 }
447 
448 void rDelete(ring r)
449 {
450  int i, j;
451 
452  if (r == NULL) return;
453 
454  assume( r->ref <= 0 );
455 
456  if( r->ref > 0 ) // ->ref means the number of Interpreter objects referring to the ring...
457  return; // this should never happen.
458 
459  if( r->qideal != NULL )
460  {
461  ideal q = r->qideal;
462  r->qideal = NULL;
463  id_Delete(&q, r);
464  }
465 
466 #ifdef HAVE_PLURAL
467  if (rIsPluralRing(r))
468  nc_rKill(r);
469 #endif
470 
471  rUnComplete(r); // may need r->cf for p_Delete
472  nKillChar(r->cf); r->cf = NULL;
473  // delete order stuff
474  if (r->order != NULL)
475  {
476  i=rBlocks(r);
477  assume(r->block0 != NULL && r->block1 != NULL && r->wvhdl != NULL);
478  // delete order
479  omFreeSize((ADDRESS)r->order,i*sizeof(rRingOrder_t));
480  omFreeSize((ADDRESS)r->block0,i*sizeof(int));
481  omFreeSize((ADDRESS)r->block1,i*sizeof(int));
482  // delete weights
483  for (j=0; j<i; j++)
484  {
485  if (r->wvhdl[j]!=NULL)
486  omFree(r->wvhdl[j]);
487  }
488  omFreeSize((ADDRESS)r->wvhdl,i*sizeof(int *));
489  }
490  else
491  {
492  assume(r->block0 == NULL && r->block1 == NULL && r->wvhdl == NULL);
493  }
494 
495  // delete varnames
496  if(r->names!=NULL)
497  {
498  for (i=0; i<r->N; i++)
499  {
500  if (r->names[i] != NULL) omFree((ADDRESS)r->names[i]);
501  }
502  omFreeSize((ADDRESS)r->names,r->N*sizeof(char *));
503  }
504 
506 }
507 
508 rRingOrder_t rOrderName(char * ordername)
509 {
510  int order=ringorder_unspec;
511  while (order!= 0)
512  {
513  if (strcmp(ordername,rSimpleOrdStr(order))==0)
514  break;
515  order--;
516  }
517  if (order==0) Werror("wrong ring order `%s`",ordername);
518  omFree((ADDRESS)ordername);
519  return (rRingOrder_t)order;
520 }
521 
522 char * rOrdStr(ring r)
523 {
524  if ((r==NULL)||(r->order==NULL)) return omStrDup("");
525  int nblocks,l,i;
526 
527  for (nblocks=0; r->order[nblocks]; nblocks++);
528  nblocks--;
529 
530  StringSetS("");
531  for (l=0; ; l++)
532  {
533  StringAppendS((char *)rSimpleOrdStr(r->order[l]));
534  if (r->order[l] == ringorder_s)
535  {
536  StringAppend("(%d)",r->block0[l]);
537  }
538  else if (
539  (r->order[l] != ringorder_c)
540  && (r->order[l] != ringorder_C)
541  && (r->order[l] != ringorder_s)
542  && (r->order[l] != ringorder_S)
543  && (r->order[l] != ringorder_IS)
544  )
545  {
546  if (r->wvhdl[l]!=NULL)
547  {
548  StringAppendS("(");
549  for (int j= 0;
550  j<(r->block1[l]-r->block0[l]+1)*(r->block1[l]-r->block0[l]+1);
551  j+=i+1)
552  {
553  char c=',';
554  if(r->order[l]==ringorder_a64)
555  {
556  int64 * w=(int64 *)r->wvhdl[l];
557  for (i = 0; i<r->block1[l]-r->block0[l]; i++)
558  {
559  StringAppend("%lld," ,w[i]);
560  }
561  StringAppend("%lld)" ,w[i]);
562  break;
563  }
564  else
565  {
566  for (i = 0; i<r->block1[l]-r->block0[l]; i++)
567  {
568  StringAppend("%d," ,r->wvhdl[l][i+j]);
569  }
570  }
571  if (r->order[l]!=ringorder_M)
572  {
573  StringAppend("%d)" ,r->wvhdl[l][i+j]);
574  break;
575  }
576  if (j+i+1==(r->block1[l]-r->block0[l]+1)*(r->block1[l]-r->block0[l]+1))
577  c=')';
578  StringAppend("%d%c" ,r->wvhdl[l][i+j],c);
579  }
580  }
581  else
582  StringAppend("(%d)",r->block1[l]-r->block0[l]+1);
583  }
584  else if (r->order[l] == ringorder_IS)
585  {
586  assume( r->block0[l] == r->block1[l] );
587  const int s = r->block0[l];
588  assume( (-2 < s) && (s < 2) );
589 
590  StringAppend("(%d)", s);
591  }
592 
593  if (l==nblocks) return StringEndS();
594  StringAppendS(",");
595  }
596 }
597 
598 char * rVarStr(ring r)
599 {
600  if ((r==NULL)||(r->names==NULL)) return omStrDup("");
601  int i;
602  int l=2;
603  char *s;
604 
605  for (i=0; i<r->N; i++)
606  {
607  l+=strlen(r->names[i])+1;
608  }
609  s=(char *)omAlloc((long)l);
610  s[0]='\0';
611  for (i=0; i<r->N-1; i++)
612  {
613  strcat(s,r->names[i]);
614  strcat(s,",");
615  }
616  strcat(s,r->names[i]);
617  return s;
618 }
619 
620 /// TODO: make it a virtual method of coeffs, together with:
621 /// Decompose & Compose, rParameter & rPar
622 char * rCharStr(const ring r){ assume( r != NULL ); return nCoeffString(r->cf); }
623 
624 char * rParStr(ring r)
625 {
626  if ((r==NULL)||(rParameter(r)==NULL)) return omStrDup("");
627 
628  char const * const * const params = rParameter(r);
629 
630  int i;
631  int l=2;
632 
633  for (i=0; i<rPar(r); i++)
634  {
635  l+=strlen(params[i])+1;
636  }
637  char *s=(char *)omAlloc((long)l);
638  s[0]='\0';
639  for (i=0; i<rPar(r)-1; i++)
640  {
641  strcat(s, params[i]);
642  strcat(s,",");
643  }
644  strcat(s, params[i]);
645  return s;
646 }
647 
648 char * rString(ring r)
649 {
650  if ((r!=NULL)&&(r->cf!=NULL))
651  {
652  char *ch=rCharStr(r);
653  char *var=rVarStr(r);
654  char *ord=rOrdStr(r);
655  char *res=(char *)omAlloc(strlen(ch)+strlen(var)+strlen(ord)+9);
656  sprintf(res,"(%s),(%s),(%s)",ch,var,ord);
657  omFree((ADDRESS)ch);
658  omFree((ADDRESS)var);
659  omFree((ADDRESS)ord);
660  return res;
661  }
662  else
663  return omStrDup("undefined");
664 }
665 
666 
667 /*
668 // The fowolling function seems to be never used. Remove?
669 static int binaryPower (const int a, const int b)
670 {
671  // computes a^b according to the binary representation of b,
672  // i.e., a^7 = a^4 * a^2 * a^1. This saves some multiplications.
673  int result = 1;
674  int factor = a;
675  int bb = b;
676  while (bb != 0)
677  {
678  if (bb % 2 != 0) result = result * factor;
679  bb = bb / 2;
680  factor = factor * factor;
681  }
682  return result;
683 }
684 */
685 
686 /* we keep this otherwise superfluous method for compatibility reasons
687  towards the SINGULAR svn trunk */
688 int rChar(ring r) { return r->cf->ch; }
689 
690 // typedef char * char_ptr;
691 // omBin char_ptr_bin = omGetSpecBin(sizeof(char_ptr)); // deallocation?
692 
693 
694 // creates a commutative nc extension; "converts" comm.ring to a Plural ring
695 #ifdef HAVE_PLURAL
697 {
698  r = rCopy(r);
699  if (rIsPluralRing(r))
700  return r;
701 
702  matrix C = mpNew(r->N,r->N); // ring-independent!?!
703  matrix D = mpNew(r->N,r->N);
704 
705  for(int i=1; i<r->N; i++)
706  for(int j=i+1; j<=r->N; j++)
707  MATELEM(C,i,j) = p_One( r);
708 
709  if (nc_CallPlural(C, D, NULL, NULL, r, false, true, false, r/*??currRing??*/, TRUE)) // TODO: what about quotient ideal?
710  WarnS("Error initializing multiplication!"); // No reaction!???
711 
712  return r;
713 }
714 #endif
715 
716 
717 /*2
718  *returns -1 for not compatible, (sum is undefined)
719  * 1 for compatible (and sum)
720  */
721 /* vartest: test for variable/paramter names
722 * dp_dp: 0:block ordering
723 * 1:for comm. rings: use block order dp + dp/ds/wp
724 * 2:order aa(..),dp
725 */
726 int rSumInternal(ring r1, ring r2, ring &sum, BOOLEAN vartest, BOOLEAN dp_dp)
727 {
728 
729  ip_sring tmpR;
730  memset(&tmpR,0,sizeof(tmpR));
731  /* check coeff. field =====================================================*/
732 
733  if (r1->cf==r2->cf)
734  {
735  tmpR.cf=nCopyCoeff(r1->cf);
736  }
737  else /* different type */
738  {
739  if (getCoeffType(r1->cf)==n_Zp)
740  {
741  if (getCoeffType(r2->cf)==n_Q)
742  {
743  tmpR.cf=nCopyCoeff(r1->cf);
744  }
745  else if (nCoeff_is_Extension(r2->cf) && rChar(r2) == rChar(r1))
746  {
747  /*AlgExtInfo extParam;
748  extParam.r = r2->cf->extRing;
749  extParam.i = r2->cf->extRing->qideal;*/
750  tmpR.cf=nCopyCoeff(r2->cf);
751  }
752  else
753  {
754  WerrorS("Z/p+...");
755  return -1;
756  }
757  }
758  else if (getCoeffType(r1->cf)==n_R)
759  {
760  WerrorS("R+..");
761  return -1;
762  }
763  else if (getCoeffType(r1->cf)==n_Q)
764  {
765  if (getCoeffType(r2->cf)==n_Zp)
766  {
767  tmpR.cf=nCopyCoeff(r2->cf);
768  }
769  else if (nCoeff_is_Extension(r2->cf))
770  {
771  tmpR.cf=nCopyCoeff(r2->cf);
772  }
773  else
774  {
775  WerrorS("Q+...");
776  return -1;
777  }
778  }
779  else if (nCoeff_is_Extension(r1->cf))
780  {
781  if (r1->cf->extRing->cf==r2->cf)
782  {
783  tmpR.cf=nCopyCoeff(r1->cf);
784  }
785  else if (getCoeffType(r1->cf->extRing->cf)==n_Zp && getCoeffType(r2->cf)==n_Q) //r2->cf == n_Zp should have been handled above
786  {
787  tmpR.cf=nCopyCoeff(r1->cf);
788  }
789  else
790  {
791  WerrorS ("coeff sum of two extension fields not implemented");
792  return -1;
793  }
794  }
795  else
796  {
797  WerrorS("coeff sum not yet implemented");
798  return -1;
799  }
800  }
801  /* variable names ========================================================*/
802  int i,j,k;
803  int l=r1->N+r2->N;
804  char **names=(char **)omAlloc0(l*sizeof(char *));
805  k=0;
806 
807  // collect all varnames from r1, except those which are parameters
808  // of r2, or those which are the empty string
809  for (i=0;i<r1->N;i++)
810  {
811  BOOLEAN b=TRUE;
812 
813  if (*(r1->names[i]) == '\0')
814  b = FALSE;
815  else if ((rParameter(r2)!=NULL) && (strlen(r1->names[i])==1))
816  {
817  if (vartest)
818  {
819  for(j=0;j<rPar(r2);j++)
820  {
821  if (strcmp(r1->names[i],rParameter(r2)[j])==0)
822  {
823  b=FALSE;
824  break;
825  }
826  }
827  }
828  }
829 
830  if (b)
831  {
832  //Print("name : %d: %s\n",k,r1->names[i]);
833  names[k]=omStrDup(r1->names[i]);
834  k++;
835  }
836  //else
837  // Print("no name (par1) %s\n",r1->names[i]);
838  }
839  // Add variables from r2, except those which are parameters of r1
840  // those which are empty strings, and those which equal a var of r1
841  for(i=0;i<r2->N;i++)
842  {
843  BOOLEAN b=TRUE;
844 
845  if (*(r2->names[i]) == '\0')
846  b = FALSE;
847  else if ((rParameter(r1)!=NULL) && (strlen(r2->names[i])==1))
848  {
849  if (vartest)
850  {
851  for(j=0;j<rPar(r1);j++)
852  {
853  if (strcmp(r2->names[i],rParameter(r1)[j])==0)
854  {
855  b=FALSE;
856  break;
857  }
858  }
859  }
860  }
861 
862  if (b)
863  {
864  if (vartest)
865  {
866  for(j=0;j<r1->N;j++)
867  {
868  if (strcmp(r1->names[j],r2->names[i])==0)
869  {
870  b=FALSE;
871  break;
872  }
873  }
874  }
875  if (b)
876  {
877  //Print("name : %d : %s\n",k,r2->names[i]);
878  names[k]=omStrDup(r2->names[i]);
879  k++;
880  }
881  //else
882  // Print("no name (var): %s\n",r2->names[i]);
883  }
884  //else
885  // Print("no name (par): %s\n",r2->names[i]);
886  }
887  // check whether we found any vars at all
888  if (k == 0)
889  {
890  names[k]=omStrDup("");
891  k=1;
892  }
893  tmpR.N=k;
894  tmpR.names=names;
895  /* ordering *======================================================== */
896  tmpR.OrdSgn=0;
897  if ((dp_dp==2)
898  && (r1->OrdSgn==1)
899  && (r2->OrdSgn==1)
900 #ifdef HAVE_PLURAL
901  && !rIsPluralRing(r1) && !rIsPluralRing(r2)
902 #endif
903  )
904  {
905  tmpR.order=(rRingOrder_t*)omAlloc0(4*sizeof(rRingOrder_t));
906  tmpR.block0=(int*)omAlloc0(4*sizeof(int));
907  tmpR.block1=(int*)omAlloc0(4*sizeof(int));
908  tmpR.wvhdl=(int**) omAlloc0(4*sizeof(int**));
909  // ----
910  tmpR.block0[0] = 1;
911  tmpR.block1[0] = rVar(r1)+rVar(r2);
912  tmpR.order[0] = ringorder_aa;
913  tmpR.wvhdl[0]=(int*)omAlloc0((rVar(r1)+rVar(r2) + 1)*sizeof(int));
914  for(int i=0;i<rVar(r1);i++) tmpR.wvhdl[0][i]=1;
915  // ----
916  tmpR.block0[1] = 1;
917  tmpR.block1[1] = rVar(r1)+rVar(r2);
918  tmpR.order[1] = ringorder_dp;
919  // ----
920  tmpR.order[2] = ringorder_C;
921  }
922  else if (dp_dp
923 #ifdef HAVE_PLURAL
924  && !rIsPluralRing(r1) && !rIsPluralRing(r2)
925 #endif
926  )
927  {
928  tmpR.order=(rRingOrder_t*)omAlloc(4*sizeof(rRingOrder_t));
929  tmpR.block0=(int*)omAlloc0(4*sizeof(int));
930  tmpR.block1=(int*)omAlloc0(4*sizeof(int));
931  tmpR.wvhdl=(int**)omAlloc0(4*sizeof(int *));
932  tmpR.order[0]=ringorder_dp;
933  tmpR.block0[0]=1;
934  tmpR.block1[0]=rVar(r1);
935  if (r2->OrdSgn==1)
936  {
937  if ((r2->block0[0]==1)
938  && (r2->block1[0]==rVar(r2))
939  && ((r2->order[0]==ringorder_wp)
940  || (r2->order[0]==ringorder_Wp)
941  || (r2->order[0]==ringorder_Dp))
942  )
943  {
944  tmpR.order[1]=r2->order[0];
945  if (r2->wvhdl[0]!=NULL)
946  tmpR.wvhdl[1]=(int *)omMemDup(r2->wvhdl[0]);
947  }
948  else
949  tmpR.order[1]=ringorder_dp;
950  }
951  else
952  {
953  tmpR.order[1]=ringorder_ds;
954  tmpR.OrdSgn=-1;
955  }
956  tmpR.block0[1]=rVar(r1)+1;
957  tmpR.block1[1]=rVar(r1)+rVar(r2);
958  tmpR.order[2]=ringorder_C;
959  tmpR.order[3]=(rRingOrder_t)0;
960  }
961  else
962  {
963  if ((r1->order[0]==ringorder_unspec)
964  && (r2->order[0]==ringorder_unspec))
965  {
966  tmpR.order=(rRingOrder_t*)omAlloc(3*sizeof(rRingOrder_t));
967  tmpR.block0=(int*)omAlloc(3*sizeof(int));
968  tmpR.block1=(int*)omAlloc(3*sizeof(int));
969  tmpR.wvhdl=(int**)omAlloc0(3*sizeof(int *));
970  tmpR.order[0]=ringorder_unspec;
971  tmpR.order[1]=ringorder_C;
972  tmpR.order[2]=(rRingOrder_t)0;
973  tmpR.block0[0]=1;
974  tmpR.block1[0]=tmpR.N;
975  }
976  else if (l==k) /* r3=r1+r2 */
977  {
978  int b;
979  ring rb;
980  if (r1->order[0]==ringorder_unspec)
981  {
982  /* extend order of r2 to r3 */
983  b=rBlocks(r2);
984  rb=r2;
985  tmpR.OrdSgn=r2->OrdSgn;
986  }
987  else if (r2->order[0]==ringorder_unspec)
988  {
989  /* extend order of r1 to r3 */
990  b=rBlocks(r1);
991  rb=r1;
992  tmpR.OrdSgn=r1->OrdSgn;
993  }
994  else
995  {
996  b=rBlocks(r1)+rBlocks(r2)-2; /* for only one order C, only one 0 */
997  rb=NULL;
998  }
999  tmpR.order=(rRingOrder_t*)omAlloc0(b*sizeof(rRingOrder_t));
1000  tmpR.block0=(int*)omAlloc0(b*sizeof(int));
1001  tmpR.block1=(int*)omAlloc0(b*sizeof(int));
1002  tmpR.wvhdl=(int**)omAlloc0(b*sizeof(int *));
1003  /* weights not implemented yet ...*/
1004  if (rb!=NULL)
1005  {
1006  for (i=0;i<b;i++)
1007  {
1008  tmpR.order[i]=rb->order[i];
1009  tmpR.block0[i]=rb->block0[i];
1010  tmpR.block1[i]=rb->block1[i];
1011  if (rb->wvhdl[i]!=NULL)
1012  WarnS("rSum: weights not implemented");
1013  }
1014  tmpR.block0[0]=1;
1015  }
1016  else /* ring sum for complete rings */
1017  {
1018  for (i=0;r1->order[i]!=0;i++)
1019  {
1020  tmpR.order[i]=r1->order[i];
1021  tmpR.block0[i]=r1->block0[i];
1022  tmpR.block1[i]=r1->block1[i];
1023  if (r1->wvhdl[i]!=NULL)
1024  tmpR.wvhdl[i] = (int*) omMemDup(r1->wvhdl[i]);
1025  }
1026  j=i;
1027  i--;
1028  if ((r1->order[i]==ringorder_c)
1029  ||(r1->order[i]==ringorder_C))
1030  {
1031  j--;
1032  tmpR.order[b-2]=r1->order[i];
1033  }
1034  for (i=0;r2->order[i]!=0;i++)
1035  {
1036  if ((r2->order[i]!=ringorder_c)
1037  &&(r2->order[i]!=ringorder_C))
1038  {
1039  tmpR.order[j]=r2->order[i];
1040  tmpR.block0[j]=r2->block0[i]+rVar(r1);
1041  tmpR.block1[j]=r2->block1[i]+rVar(r1);
1042  if (r2->wvhdl[i]!=NULL)
1043  {
1044  tmpR.wvhdl[j] = (int*) omMemDup(r2->wvhdl[i]);
1045  }
1046  j++;
1047  }
1048  }
1049  if((r1->OrdSgn==-1)||(r2->OrdSgn==-1))
1050  tmpR.OrdSgn=-1;
1051  }
1052  }
1053  else if ((k==rVar(r1)) && (k==rVar(r2))) /* r1 and r2 are "quite"
1054  the same ring */
1055  /* copy r1, because we have the variables from r1 */
1056  {
1057  int b=rBlocks(r1);
1058 
1059  tmpR.order=(rRingOrder_t*)omAlloc0(b*sizeof(rRingOrder_t));
1060  tmpR.block0=(int*)omAlloc0(b*sizeof(int));
1061  tmpR.block1=(int*)omAlloc0(b*sizeof(int));
1062  tmpR.wvhdl=(int**)omAlloc0(b*sizeof(int *));
1063  /* weights not implemented yet ...*/
1064  for (i=0;i<b;i++)
1065  {
1066  tmpR.order[i]=r1->order[i];
1067  tmpR.block0[i]=r1->block0[i];
1068  tmpR.block1[i]=r1->block1[i];
1069  if (r1->wvhdl[i]!=NULL)
1070  {
1071  tmpR.wvhdl[i] = (int*) omMemDup(r1->wvhdl[i]);
1072  }
1073  }
1074  tmpR.OrdSgn=r1->OrdSgn;
1075  }
1076  else
1077  {
1078  for(i=0;i<k;i++) omFree((ADDRESS)tmpR.names[i]);
1079  omFreeSize((ADDRESS)names,tmpR.N*sizeof(char *));
1080  Werror("variables must not overlap (# of vars: %d,%d -> %d)",rVar(r1),rVar(r2),k);
1081  return -1;
1082  }
1083  }
1084  tmpR.bitmask=si_max(r1->bitmask,r2->bitmask);
1085  sum=(ring)omAllocBin(sip_sring_bin);
1086  memcpy(sum,&tmpR,sizeof(ip_sring));
1087  rComplete(sum);
1088 
1089 //#ifdef RDEBUG
1090 // rDebugPrint(sum);
1091 //#endif
1092 
1093 
1094 
1095 #ifdef HAVE_PLURAL
1096  if(1)
1097  {
1098 // ring old_ring = currRing;
1099 
1100  BOOLEAN R1_is_nc = rIsPluralRing(r1);
1101  BOOLEAN R2_is_nc = rIsPluralRing(r2);
1102 
1103  if ( (R1_is_nc) || (R2_is_nc))
1104  {
1105  ring R1 = nc_rCreateNCcomm_rCopy(r1);
1106  assume( rIsPluralRing(R1) );
1107 
1108 #if 0
1109 #ifdef RDEBUG
1110  rWrite(R1);
1111  rDebugPrint(R1);
1112 #endif
1113 #endif
1114  ring R2 = nc_rCreateNCcomm_rCopy(r2);
1115 #if 0
1116 #ifdef RDEBUG
1117  rWrite(R2);
1118  rDebugPrint(R2);
1119 #endif
1120 #endif
1121 
1122 // rChangeCurrRing(sum); // ?
1123 
1124  // Projections from R_i into Sum:
1125  /* multiplication matrices business: */
1126  /* find permutations of vars and pars */
1127  int *perm1 = (int *)omAlloc0((rVar(R1)+1)*sizeof(int));
1128  int *par_perm1 = NULL;
1129  if (rPar(R1)!=0) par_perm1=(int *)omAlloc0((rPar(R1)+1)*sizeof(int));
1130 
1131  int *perm2 = (int *)omAlloc0((rVar(R2)+1)*sizeof(int));
1132  int *par_perm2 = NULL;
1133  if (rPar(R2)!=0) par_perm2=(int *)omAlloc0((rPar(R2)+1)*sizeof(int));
1134 
1135  maFindPerm(R1->names, rVar(R1), rParameter(R1), rPar(R1),
1136  sum->names, rVar(sum), rParameter(sum), rPar(sum),
1137  perm1, par_perm1, sum->cf->type);
1138 
1139  maFindPerm(R2->names, rVar(R2), rParameter(R2), rPar(R2),
1140  sum->names, rVar(sum), rParameter(sum), rPar(sum),
1141  perm2, par_perm2, sum->cf->type);
1142 
1143 
1144  matrix C1 = R1->GetNC()->C, C2 = R2->GetNC()->C;
1145  matrix D1 = R1->GetNC()->D, D2 = R2->GetNC()->D;
1146 
1147  // !!!! BUG? C1 and C2 might live in different baserings!!!
1148 
1149  int l = rVar(R1) + rVar(R2);
1150 
1151  matrix C = mpNew(l,l);
1152  matrix D = mpNew(l,l);
1153 
1154  for (i = 1; i <= rVar(R1); i++)
1155  for (j= rVar(R1)+1; j <= l; j++)
1156  MATELEM(C,i,j) = p_One(sum); // in 'sum'
1157 
1158  id_Test((ideal)C, sum);
1159 
1160  nMapFunc nMap1 = n_SetMap(R1->cf,sum->cf); /* can change something global: not usable
1161  after the next nSetMap call :( */
1162  // Create blocked C and D matrices:
1163  for (i=1; i<= rVar(R1); i++)
1164  for (j=i+1; j<=rVar(R1); j++)
1165  {
1166  assume(MATELEM(C1,i,j) != NULL);
1167  MATELEM(C,i,j) = p_PermPoly(MATELEM(C1,i,j), perm1, R1, sum, nMap1, par_perm1, rPar(R1)); // need ADD + CMP ops.
1168 
1169  if (MATELEM(D1,i,j) != NULL)
1170  MATELEM(D,i,j) = p_PermPoly(MATELEM(D1,i,j), perm1, R1, sum, nMap1, par_perm1, rPar(R1));
1171  }
1172 
1173  id_Test((ideal)C, sum);
1174  id_Test((ideal)D, sum);
1175 
1176 
1177  nMapFunc nMap2 = n_SetMap(R2->cf,sum->cf); /* can change something global: not usable
1178  after the next nSetMap call :( */
1179  for (i=1; i<= rVar(R2); i++)
1180  for (j=i+1; j<=rVar(R2); j++)
1181  {
1182  assume(MATELEM(C2,i,j) != NULL);
1183  MATELEM(C,rVar(R1)+i,rVar(R1)+j) = p_PermPoly(MATELEM(C2,i,j),perm2,R2,sum, nMap2,par_perm2,rPar(R2));
1184 
1185  if (MATELEM(D2,i,j) != NULL)
1186  MATELEM(D,rVar(R1)+i,rVar(R1)+j) = p_PermPoly(MATELEM(D2,i,j),perm2,R2,sum, nMap2,par_perm2,rPar(R2));
1187  }
1188 
1189  id_Test((ideal)C, sum);
1190  id_Test((ideal)D, sum);
1191 
1192  // Now sum is non-commutative with blocked structure constants!
1193  if (nc_CallPlural(C, D, NULL, NULL, sum, false, false, true, sum))
1194  WarnS("Error initializing non-commutative multiplication!");
1195 
1196  /* delete R1, R2*/
1197 
1198 #if 0
1199 #ifdef RDEBUG
1200  rWrite(sum);
1201  rDebugPrint(sum);
1202 
1203  Print("\nRefs: R1: %d, R2: %d\n", R1->GetNC()->ref, R2->GetNC()->ref);
1204 
1205 #endif
1206 #endif
1207 
1208 
1209  rDelete(R1);
1210  rDelete(R2);
1211 
1212  /* delete perm arrays */
1213  if (perm1!=NULL) omFree((ADDRESS)perm1);
1214  if (perm2!=NULL) omFree((ADDRESS)perm2);
1215  if (par_perm1!=NULL) omFree((ADDRESS)par_perm1);
1216  if (par_perm2!=NULL) omFree((ADDRESS)par_perm2);
1217 
1218 // rChangeCurrRing(old_ring);
1219  }
1220 
1221  }
1222 #endif
1223 
1224  ideal Q=NULL;
1225  ideal Q1=NULL, Q2=NULL;
1226  if (r1->qideal!=NULL)
1227  {
1228 // rChangeCurrRing(sum);
1229 // if (r2->qideal!=NULL)
1230 // {
1231 // WerrorS("todo: qring+qring");
1232 // return -1;
1233 // }
1234 // else
1235 // {}
1236  /* these were defined in the Plural Part above... */
1237  int *perm1 = (int *)omAlloc0((rVar(r1)+1)*sizeof(int));
1238  int *par_perm1 = NULL;
1239  if (rPar(r1)!=0) par_perm1=(int *)omAlloc0((rPar(r1)+1)*sizeof(int));
1240  maFindPerm(r1->names, rVar(r1), rParameter(r1), rPar(r1),
1241  sum->names, rVar(sum), rParameter(sum), rPar(sum),
1242  perm1, par_perm1, sum->cf->type);
1243  nMapFunc nMap1 = n_SetMap(r1->cf,sum->cf);
1244  Q1 = idInit(IDELEMS(r1->qideal),1);
1245 
1246  for (int for_i=0;for_i<IDELEMS(r1->qideal);for_i++)
1247  Q1->m[for_i] = p_PermPoly(
1248  r1->qideal->m[for_i], perm1,
1249  r1, sum,
1250  nMap1,
1251  par_perm1, rPar(r1));
1252 
1253  omFree((ADDRESS)perm1);
1254  }
1255 
1256  if (r2->qideal!=NULL)
1257  {
1258  //if (currRing!=sum)
1259  // rChangeCurrRing(sum);
1260  int *perm2 = (int *)omAlloc0((rVar(r2)+1)*sizeof(int));
1261  int *par_perm2 = NULL;
1262  if (rPar(r2)!=0) par_perm2=(int *)omAlloc0((rPar(r2)+1)*sizeof(int));
1263  maFindPerm(r2->names, rVar(r2), rParameter(r2), rPar(r2),
1264  sum->names, rVar(sum), rParameter(sum), rPar(sum),
1265  perm2, par_perm2, sum->cf->type);
1266  nMapFunc nMap2 = n_SetMap(r2->cf,sum->cf);
1267  Q2 = idInit(IDELEMS(r2->qideal),1);
1268 
1269  for (int for_i=0;for_i<IDELEMS(r2->qideal);for_i++)
1270  Q2->m[for_i] = p_PermPoly(
1271  r2->qideal->m[for_i], perm2,
1272  r2, sum,
1273  nMap2,
1274  par_perm2, rPar(r2));
1275 
1276  omFree((ADDRESS)perm2);
1277  }
1278  if (Q1!=NULL)
1279  {
1280  if ( Q2!=NULL)
1281  Q = id_SimpleAdd(Q1,Q2,sum);
1282  else
1283  Q=id_Copy(Q1,sum);
1284  }
1285  else
1286  {
1287  if ( Q2!=NULL)
1288  Q = id_Copy(Q2,sum);
1289  else
1290  Q=NULL;
1291  }
1292  sum->qideal = Q;
1293 
1294 #ifdef HAVE_PLURAL
1295  if( rIsPluralRing(sum) )
1296  nc_SetupQuotient( sum );
1297 #endif
1298  return 1;
1299 }
1300 
1301 /*2
1302  *returns -1 for not compatible, (sum is undefined)
1303  * 0 for equal, (and sum)
1304  * 1 for compatible (and sum)
1305  */
1306 int rSum(ring r1, ring r2, ring &sum)
1307 {
1308  if ((r1==NULL)||(r2==NULL)
1309  ||(r1->cf==NULL)||(r2->cf==NULL))
1310  return -1;
1311  if (r1==r2)
1312  {
1313  sum=r1;
1314  r1->ref++;
1315  return 0;
1316  }
1317  return rSumInternal(r1,r2,sum,TRUE,FALSE);
1318 }
1319 
1320 /*2
1321  * create a copy of the ring r
1322  * used for qring definition,..
1323  * DOES NOT CALL rComplete
1324  */
1325 ring rCopy0(const ring r, BOOLEAN copy_qideal, BOOLEAN copy_ordering)
1326 {
1327  if (r == NULL) return NULL;
1328  int i,j;
1329  ring res=(ring)omAlloc0Bin(sip_sring_bin);
1330  //memset: res->idroot=NULL; /* local objects */
1331  //ideal minideal;
1332  res->options=r->options; /* ring dependent options */
1333 
1334  //memset: res->ordsgn=NULL;
1335  //memset: res->typ=NULL;
1336  //memset: res->VarOffset=NULL;
1337  //memset: res->firstwv=NULL;
1338 
1339  //struct omBin PolyBin; /* Bin from where monoms are allocated */
1340  //memset: res->PolyBin=NULL; // rComplete
1341  res->cf=nCopyCoeff(r->cf); /* coeffs */
1342 
1343  //memset: res->ref=0; /* reference counter to the ring */
1344 
1345  res->N=rVar(r); /* number of vars */
1346 
1347  res->firstBlockEnds=r->firstBlockEnds;
1348 #ifdef HAVE_PLURAL
1349  res->real_var_start=r->real_var_start;
1350  res->real_var_end=r->real_var_end;
1351 #endif
1352 
1353 #ifdef HAVE_SHIFTBBA
1354  res->isLPring=r->isLPring; /* 0 for non-letterplace rings, otherwise the number of LP blocks, at least 1, known also as lV */
1355 #endif
1356 
1357  res->VectorOut=r->VectorOut;
1358  res->ShortOut=r->ShortOut;
1359  res->CanShortOut=r->CanShortOut;
1360 
1361  //memset: res->ExpL_Size=0;
1362  //memset: res->CmpL_Size=0;
1363  //memset: res->VarL_Size=0;
1364  //memset: res->pCompIndex=0;
1365  //memset: res->pOrdIndex=0;
1366  //memset: res->OrdSize=0;
1367  //memset: res->VarL_LowIndex=0;
1368  //memset: res->NegWeightL_Size=0;
1369  //memset: res->NegWeightL_Offset=NULL;
1370  //memset: res->VarL_Offset=NULL;
1371 
1372  // the following are set by rComplete unless predefined
1373  // therefore, we copy these values: maybe they are non-standard
1374  /* mask for getting single exponents */
1375  res->bitmask=r->bitmask;
1376  res->divmask=r->divmask;
1377  res->BitsPerExp = r->BitsPerExp;
1378  res->ExpPerLong = r->ExpPerLong;
1379 
1380  //memset: res->p_Procs=NULL;
1381  //memset: res->pFDeg=NULL;
1382  //memset: res->pLDeg=NULL;
1383  //memset: res->pFDegOrig=NULL;
1384  //memset: res->pLDegOrig=NULL;
1385  //memset: res->p_Setm=NULL;
1386  //memset: res->cf=NULL;
1387 
1388 /*
1389  if (r->extRing!=NULL)
1390  r->extRing->ref++;
1391 
1392  res->extRing=r->extRing;
1393  //memset: res->qideal=NULL;
1394 */
1395 
1396 
1397  if (copy_ordering == TRUE)
1398  {
1399  res->LexOrder=r->LexOrder; // TRUE if the monomial ordering has polynomial and power series blocks
1400  res->MixedOrder=r->MixedOrder; // TRUE for mixed (global/local) ordering, FALSE otherwise,
1401  i=rBlocks(r);
1402  res->wvhdl = (int **)omAlloc(i * sizeof(int *));
1403  res->order = (rRingOrder_t *) omAlloc(i * sizeof(rRingOrder_t));
1404  res->block0 = (int *) omAlloc(i * sizeof(int));
1405  res->block1 = (int *) omAlloc(i * sizeof(int));
1406  for (j=0; j<i; j++)
1407  {
1408  if (r->wvhdl[j]!=NULL)
1409  {
1410  res->wvhdl[j] = (int*) omMemDup(r->wvhdl[j]);
1411  }
1412  else
1413  res->wvhdl[j]=NULL;
1414  }
1415  memcpy(res->order,r->order,i * sizeof(rRingOrder_t));
1416  memcpy(res->block0,r->block0,i * sizeof(int));
1417  memcpy(res->block1,r->block1,i * sizeof(int));
1418  }
1419  //memset: else
1420  //memset: {
1421  //memset: res->wvhdl = NULL;
1422  //memset: res->order = NULL;
1423  //memset: res->block0 = NULL;
1424  //memset: res->block1 = NULL;
1425  //memset: }
1426 
1427  res->names = (char **)omAlloc0(rVar(r) * sizeof(char *));
1428  for (i=0; i<rVar(res); i++)
1429  {
1430  res->names[i] = omStrDup(r->names[i]);
1431  }
1432  if (r->qideal!=NULL)
1433  {
1434  if (copy_qideal)
1435  {
1436  #ifndef SING_NDEBUG
1437  if (!copy_ordering)
1438  WerrorS("internal error: rCopy0(Q,TRUE,FALSE)");
1439  else
1440  #endif
1441  {
1442  #ifndef SING_NDEBUG
1443  WarnS("internal bad stuff: rCopy0(Q,TRUE,TRUE)");
1444  #endif
1445  rComplete(res);
1446  res->qideal= idrCopyR_NoSort(r->qideal, r, res);
1447  rUnComplete(res);
1448  }
1449  }
1450  //memset: else res->qideal = NULL;
1451  }
1452  //memset: else res->qideal = NULL;
1453  //memset: res->GetNC() = NULL; // copy is purely commutative!!!
1454  return res;
1455 }
1456 
1457 /*2
1458  * create a copy of the ring r
1459  * used for qring definition,..
1460  * DOES NOT CALL rComplete
1461  */
1462 ring rCopy0AndAddA(const ring r, int64vec *wv64, BOOLEAN copy_qideal, BOOLEAN copy_ordering)
1463 {
1464  if (r == NULL) return NULL;
1465  int i,j;
1466  ring res=(ring)omAlloc0Bin(sip_sring_bin);
1467  //memcpy(res,r,sizeof(ip_sring));
1468  //memset: res->idroot=NULL; /* local objects */
1469  //ideal minideal;
1470  res->options=r->options; /* ring dependent options */
1471 
1472  //memset: res->ordsgn=NULL;
1473  //memset: res->typ=NULL;
1474  //memset: res->VarOffset=NULL;
1475  //memset: res->firstwv=NULL;
1476 
1477  //struct omBin PolyBin; /* Bin from where monoms are allocated */
1478  //memset: res->PolyBin=NULL; // rComplete
1479  res->cf=nCopyCoeff(r->cf); /* coeffs */
1480 
1481  //memset: res->ref=0; /* reference counter to the ring */
1482 
1483  res->N=rVar(r); /* number of vars */
1484 
1485  res->firstBlockEnds=r->firstBlockEnds;
1486 #ifdef HAVE_PLURAL
1487  res->real_var_start=r->real_var_start;
1488  res->real_var_end=r->real_var_end;
1489 #endif
1490 
1491 #ifdef HAVE_SHIFTBBA
1492  res->isLPring=r->isLPring; /* 0 for non-letterplace rings, otherwise the number of LP blocks, at least 1, known also as lV */
1493 #endif
1494 
1495  res->VectorOut=r->VectorOut;
1496  res->ShortOut=r->ShortOut;
1497  res->CanShortOut=r->CanShortOut;
1498  res->LexOrder=r->LexOrder; // TRUE if the monomial ordering has polynomial and power series blocks
1499  res->MixedOrder=r->MixedOrder; // TRUE for mixed (global/local) ordering, FALSE otherwise,
1500 
1501  //memset: res->ExpL_Size=0;
1502  //memset: res->CmpL_Size=0;
1503  //memset: res->VarL_Size=0;
1504  //memset: res->pCompIndex=0;
1505  //memset: res->pOrdIndex=0;
1506  //memset: res->OrdSize=0;
1507  //memset: res->VarL_LowIndex=0;
1508  //memset: res->NegWeightL_Size=0;
1509  //memset: res->NegWeightL_Offset=NULL;
1510  //memset: res->VarL_Offset=NULL;
1511 
1512  // the following are set by rComplete unless predefined
1513  // therefore, we copy these values: maybe they are non-standard
1514  /* mask for getting single exponents */
1515  res->bitmask=r->bitmask;
1516  res->divmask=r->divmask;
1517  res->BitsPerExp = r->BitsPerExp;
1518  res->ExpPerLong = r->ExpPerLong;
1519 
1520  //memset: res->p_Procs=NULL;
1521  //memset: res->pFDeg=NULL;
1522  //memset: res->pLDeg=NULL;
1523  //memset: res->pFDegOrig=NULL;
1524  //memset: res->pLDegOrig=NULL;
1525  //memset: res->p_Setm=NULL;
1526  //memset: res->cf=NULL;
1527 
1528 /*
1529  if (r->extRing!=NULL)
1530  r->extRing->ref++;
1531 
1532  res->extRing=r->extRing;
1533  //memset: res->qideal=NULL;
1534 */
1535 
1536 
1537  if (copy_ordering == TRUE)
1538  {
1539  i=rBlocks(r)+1; // DIFF to rCopy0
1540  res->wvhdl = (int **)omAlloc(i * sizeof(int *));
1541  res->order = (rRingOrder_t *) omAlloc(i * sizeof(rRingOrder_t));
1542  res->block0 = (int *) omAlloc(i * sizeof(int));
1543  res->block1 = (int *) omAlloc(i * sizeof(int));
1544  for (j=0; j<i-1; j++)
1545  {
1546  if (r->wvhdl[j]!=NULL)
1547  {
1548  res->wvhdl[j+1] = (int*) omMemDup(r->wvhdl[j]); //DIFF
1549  }
1550  else
1551  res->wvhdl[j+1]=NULL; //DIFF
1552  }
1553  memcpy(&(res->order[1]),r->order,(i-1) * sizeof(rRingOrder_t)); //DIFF
1554  memcpy(&(res->block0[1]),r->block0,(i-1) * sizeof(int)); //DIFF
1555  memcpy(&(res->block1[1]),r->block1,(i-1) * sizeof(int)); //DIFF
1556  }
1557  //memset: else
1558  //memset: {
1559  //memset: res->wvhdl = NULL;
1560  //memset: res->order = NULL;
1561  //memset: res->block0 = NULL;
1562  //memset: res->block1 = NULL;
1563  //memset: }
1564 
1565  //the added A
1566  res->order[0]=ringorder_a64;
1567  int length=wv64->rows();
1568  int64 *A=(int64 *)omAlloc(length*sizeof(int64));
1569  for(j=length-1;j>=0;j--)
1570  {
1571  A[j]=(*wv64)[j];
1572  }
1573  res->wvhdl[0]=(int *)A;
1574  res->block0[0]=1;
1575  res->block1[0]=length;
1576  //
1577 
1578  res->names = (char **)omAlloc0(rVar(r) * sizeof(char *));
1579  for (i=0; i<rVar(res); i++)
1580  {
1581  res->names[i] = omStrDup(r->names[i]);
1582  }
1583  if (r->qideal!=NULL)
1584  {
1585  if (copy_qideal)
1586  {
1587  #ifndef SING_NDEBUG
1588  if (!copy_ordering)
1589  WerrorS("internal error: rCopy0(Q,TRUE,FALSE)");
1590  else
1591  #endif
1592  {
1593  #ifndef SING_NDEBUG
1594  WarnS("internal bad stuff: rCopy0(Q,TRUE,TRUE)");
1595  #endif
1596  rComplete(res);
1597  res->qideal= idrCopyR_NoSort(r->qideal, r, res);
1598  rUnComplete(res);
1599  }
1600  }
1601  //memset: else res->qideal = NULL;
1602  }
1603  //memset: else res->qideal = NULL;
1604  //memset: res->GetNC() = NULL; // copy is purely commutative!!!
1605  return res;
1606 }
1607 
1608 /*2
1609  * create a copy of the ring r, which must be equivalent to currRing
1610  * used for qring definition,..
1611  * (i.e.: normal rings: same nCopy as currRing;
1612  * qring: same nCopy, same idCopy as currRing)
1613  */
1614 ring rCopy(ring r)
1615 {
1616  if (r == NULL) return NULL;
1617  ring res=rCopy0(r,FALSE,TRUE);
1618  rComplete(res, 1); // res is purely commutative so far
1619  if (r->qideal!=NULL) res->qideal=idrCopyR_NoSort(r->qideal, r, res);
1620 
1621 #ifdef HAVE_PLURAL
1622  if (rIsPluralRing(r))
1623  if( nc_rCopy(res, r, true) ) {}
1624 #endif
1625 
1626  return res;
1627 }
1628 
1629 BOOLEAN rEqual(ring r1, ring r2, BOOLEAN qr)
1630 {
1631  if (r1 == r2) return TRUE;
1632  if (r1 == NULL || r2 == NULL) return FALSE;
1633  if (r1->cf!=r2->cf) return FALSE;
1634  if (rVar(r1)!=rVar(r2)) return FALSE;
1635 
1636  if( !rSamePolyRep(r1, r2) )
1637  return FALSE;
1638 
1639  int i/*, j*/;
1640 
1641  for (i=0; i<rVar(r1); i++)
1642  {
1643  if ((r1->names[i] != NULL) && (r2->names[i] != NULL))
1644  {
1645  if (strcmp(r1->names[i], r2->names[i])) return FALSE;
1646  }
1647  else if ((r1->names[i] != NULL) ^ (r2->names[i] != NULL))
1648  {
1649  return FALSE;
1650  }
1651  }
1652 
1653  if (qr)
1654  {
1655  if (r1->qideal != NULL)
1656  {
1657  ideal id1 = r1->qideal, id2 = r2->qideal;
1658  int i, n;
1659  poly *m1, *m2;
1660 
1661  if (id2 == NULL) return FALSE;
1662  if ((n = IDELEMS(id1)) != IDELEMS(id2)) return FALSE;
1663 
1664  {
1665  m1 = id1->m;
1666  m2 = id2->m;
1667  for (i=0; i<n; i++)
1668  if (! p_EqualPolys(m1[i],m2[i], r1, r2)) return FALSE;
1669  }
1670  }
1671  else if (r2->qideal != NULL) return FALSE;
1672  }
1673 
1674  return TRUE;
1675 }
1676 
1677 BOOLEAN rSamePolyRep(ring r1, ring r2)
1678 {
1679  int i, j;
1680 
1681  if (r1 == r2) return TRUE;
1682 
1683  if (r1 == NULL || r2 == NULL) return FALSE;
1684 
1685  if ((r1->cf != r2->cf)
1686  || (rVar(r1) != rVar(r2))
1687  || (r1->OrdSgn != r2->OrdSgn))
1688  return FALSE;
1689 
1690  i=0;
1691  while (r1->order[i] != 0)
1692  {
1693  if (r2->order[i] == 0) return FALSE;
1694  if ((r1->order[i] != r2->order[i])
1695  || (r1->block0[i] != r2->block0[i])
1696  || (r1->block1[i] != r2->block1[i]))
1697  return FALSE;
1698  if (r1->wvhdl[i] != NULL)
1699  {
1700  if (r2->wvhdl[i] == NULL)
1701  return FALSE;
1702  for (j=0; j<r1->block1[i]-r1->block0[i]+1; j++)
1703  if (r2->wvhdl[i][j] != r1->wvhdl[i][j])
1704  return FALSE;
1705  }
1706  else if (r2->wvhdl[i] != NULL) return FALSE;
1707  i++;
1708  }
1709  if (r2->order[i] != 0) return FALSE;
1710 
1711  // we do not check variable names
1712  // we do not check minpoly/minideal
1713  // we do not check qideal
1714 
1715  return TRUE;
1716 }
1717 
1719 {
1720  // check for simple ordering
1721  if (rHasSimpleOrder(r))
1722  {
1723  if ((r->order[1] == ringorder_c)
1724  || (r->order[1] == ringorder_C))
1725  {
1726  switch(r->order[0])
1727  {
1728  case ringorder_dp:
1729  case ringorder_wp:
1730  case ringorder_ds:
1731  case ringorder_ws:
1732  case ringorder_ls:
1733  case ringorder_unspec:
1734  if (r->order[1] == ringorder_C
1735  || r->order[0] == ringorder_unspec)
1736  return rOrderType_ExpComp;
1737  return rOrderType_Exp;
1738 
1739  default:
1740  assume(r->order[0] == ringorder_lp ||
1741  r->order[0] == ringorder_rs ||
1742  r->order[0] == ringorder_Dp ||
1743  r->order[0] == ringorder_Wp ||
1744  r->order[0] == ringorder_Ds ||
1745  r->order[0] == ringorder_Ws);
1746 
1747  if (r->order[1] == ringorder_c) return rOrderType_ExpComp;
1748  return rOrderType_Exp;
1749  }
1750  }
1751  else
1752  {
1753  assume((r->order[0]==ringorder_c)||(r->order[0]==ringorder_C));
1754  return rOrderType_CompExp;
1755  }
1756  }
1757  else
1758  return rOrderType_General;
1759 }
1760 
1762 {
1763  return (r->order[0] == ringorder_c);
1764 }
1766 {
1767  if (r->order[0] == ringorder_unspec) return TRUE;
1768  int blocks = rBlocks(r) - 1;
1769  assume(blocks >= 1);
1770  if (blocks == 1) return TRUE;
1771 
1772  int s = 0;
1773  while( (s < blocks) && (r->order[s] == ringorder_IS) && (r->order[blocks-1] == ringorder_IS) )
1774  {
1775  s++;
1776  blocks--;
1777  }
1778 
1779  if ((blocks - s) > 2) return FALSE;
1780 
1781  assume( blocks == s + 2 );
1782 
1783  if (
1784  (r->order[s] != ringorder_c)
1785  && (r->order[s] != ringorder_C)
1786  && (r->order[s+1] != ringorder_c)
1787  && (r->order[s+1] != ringorder_C)
1788  )
1789  return FALSE;
1790  if ((r->order[s+1] == ringorder_M)
1791  || (r->order[s] == ringorder_M))
1792  return FALSE;
1793  return TRUE;
1794 }
1795 
1796 // returns TRUE, if simple lp or ls ordering
1798 {
1799  return rHasSimpleOrder(r) &&
1800  (r->order[0] == ringorder_ls ||
1801  r->order[0] == ringorder_lp ||
1802  r->order[1] == ringorder_ls ||
1803  r->order[1] == ringorder_lp);
1804 }
1805 
1807 {
1808  switch(order)
1809  {
1810  case ringorder_dp:
1811  case ringorder_Dp:
1812  case ringorder_ds:
1813  case ringorder_Ds:
1814  case ringorder_Ws:
1815  case ringorder_Wp:
1816  case ringorder_ws:
1817  case ringorder_wp:
1818  return TRUE;
1819 
1820  default:
1821  return FALSE;
1822  }
1823 }
1824 
1826 {
1827  switch(order)
1828  {
1829  case ringorder_Ws:
1830  case ringorder_Wp:
1831  case ringorder_ws:
1832  case ringorder_wp:
1833  return TRUE;
1834 
1835  default:
1836  return FALSE;
1837  }
1838 }
1839 
1841 {
1842  if (r->order[0] == ringorder_unspec) return TRUE;
1843  int blocks = rBlocks(r) - 1;
1844  assume(blocks >= 1);
1845  if (blocks == 1) return TRUE;
1846 
1847  int s = 0;
1848  while( (s < blocks) && (r->order[s] == ringorder_IS) && (r->order[blocks-1] == ringorder_IS) )
1849  {
1850  s++;
1851  blocks--;
1852  }
1853 
1854  if ((blocks - s) > 3) return FALSE;
1855 
1856 // if ((blocks > 3) || (blocks < 2)) return FALSE;
1857  if ((blocks - s) == 3)
1858  {
1859  return (((r->order[s] == ringorder_aa) && (r->order[s+1] != ringorder_M) &&
1860  ((r->order[s+2] == ringorder_c) || (r->order[s+2] == ringorder_C))) ||
1861  (((r->order[s] == ringorder_c) || (r->order[s] == ringorder_C)) &&
1862  (r->order[s+1] == ringorder_aa) && (r->order[s+2] != ringorder_M)));
1863  }
1864  else
1865  {
1866  return ((r->order[s] == ringorder_aa) && (r->order[s+1] != ringorder_M));
1867  }
1868 }
1869 
1870 // return TRUE if p_SetComp requires p_Setm
1872 {
1873  if (r->typ != NULL)
1874  {
1875  int pos;
1876  for (pos=0;pos<r->OrdSize;pos++)
1877  {
1878  sro_ord* o=&(r->typ[pos]);
1879  if ( (o->ord_typ == ro_syzcomp)
1880  || (o->ord_typ == ro_syz)
1881  || (o->ord_typ == ro_is)
1882  || (o->ord_typ == ro_am)
1883  || (o->ord_typ == ro_isTemp))
1884  return TRUE;
1885  }
1886  }
1887  return FALSE;
1888 }
1889 
1890 // return TRUE if p->exp[r->pOrdIndex] holds total degree of p */
1892 {
1893  // Hmm.... what about Syz orderings?
1894  return (rVar(r) > 1 &&
1895  ((rHasSimpleOrder(r) &&
1896  (rOrder_is_DegOrdering((rRingOrder_t)r->order[0]) ||
1897  rOrder_is_DegOrdering(( rRingOrder_t)r->order[1]))) ||
1898  (rHasSimpleOrderAA(r) &&
1899  (rOrder_is_DegOrdering((rRingOrder_t)r->order[1]) ||
1900  rOrder_is_DegOrdering((rRingOrder_t)r->order[2])))));
1901 }
1902 
1903 // return TRUE if p->exp[r->pOrdIndex] holds a weighted degree of p */
1905 {
1906  // Hmm.... what about Syz orderings?
1907  return ((rVar(r) > 1) &&
1908  rHasSimpleOrder(r) &&
1909  (rOrder_is_WeightedOrdering((rRingOrder_t)r->order[0]) ||
1910  rOrder_is_WeightedOrdering(( rRingOrder_t)r->order[1])));
1911 }
1912 
1913 BOOLEAN rIsPolyVar(int v,const ring r)
1914 {
1915  int i=0;
1916  while(r->order[i]!=0)
1917  {
1918  if((r->block0[i]<=v)
1919  && (r->block1[i]>=v))
1920  {
1921  switch(r->order[i])
1922  {
1923  case ringorder_a:
1924  return (r->wvhdl[i][v-r->block0[i]]>0);
1925  case ringorder_M:
1926  return 2; /*don't know*/
1927  case ringorder_a64: /* assume: all weight are non-negative!*/
1928  case ringorder_lp:
1929  case ringorder_rs:
1930  case ringorder_dp:
1931  case ringorder_Dp:
1932  case ringorder_wp:
1933  case ringorder_Wp:
1934  return TRUE;
1935  case ringorder_ls:
1936  case ringorder_ds:
1937  case ringorder_Ds:
1938  case ringorder_ws:
1939  case ringorder_Ws:
1940  return FALSE;
1941  default:
1942  break;
1943  }
1944  }
1945  i++;
1946  }
1947  return 3; /* could not find var v*/
1948 }
1949 
1950 #ifdef RDEBUG
1951 // This should eventually become a full-fledge ring check, like pTest
1952 BOOLEAN rDBTest(ring r, const char* fn, const int l)
1953 {
1954  int i,j;
1955 
1956  if (r == NULL)
1957  {
1958  dReportError("Null ring in %s:%d", fn, l);
1959  return FALSE;
1960  }
1961 
1962 
1963  if (r->N == 0) return TRUE;
1964 
1965  if ((r->OrdSgn!=1) && (r->OrdSgn!= -1))
1966  {
1967  dReportError("missing OrdSgn in %s:%d", fn, l);
1968  return FALSE;
1969  }
1970 
1971 // omCheckAddrSize(r,sizeof(ip_sring));
1972 #if OM_CHECK > 0
1973  i=rBlocks(r);
1974  omCheckAddrSize(r->order,i*sizeof(int));
1975  omCheckAddrSize(r->block0,i*sizeof(int));
1976  omCheckAddrSize(r->block1,i*sizeof(int));
1977  for(int j=0;j<=i;j++)
1978  {
1979  if((r->order[j]<0)||(r->order[j]>ringorder_unspec))
1980  dError("wrong order in r->order");
1981  }
1982  if (r->wvhdl!=NULL)
1983  {
1984  omCheckAddrSize(r->wvhdl,i*sizeof(int *));
1985  for (j=0;j<i; j++)
1986  {
1987  if (r->wvhdl[j] != NULL) omCheckAddr(r->wvhdl[j]);
1988  }
1989  }
1990 #endif
1991  if (r->VarOffset == NULL)
1992  {
1993  dReportError("Null ring VarOffset -- no rComplete (?) in n %s:%d", fn, l);
1994  return FALSE;
1995  }
1996  omCheckAddrSize(r->VarOffset,(r->N+1)*sizeof(int));
1997 
1998  if ((r->OrdSize==0)!=(r->typ==NULL))
1999  {
2000  dReportError("mismatch OrdSize and typ-pointer in %s:%d");
2001  return FALSE;
2002  }
2003  omcheckAddrSize(r->typ,r->OrdSize*sizeof(*(r->typ)));
2004  omCheckAddrSize(r->VarOffset,(r->N+1)*sizeof(*(r->VarOffset)));
2005  // test assumptions:
2006  for(i=0;i<=r->N;i++) // for all variables (i = 0..N)
2007  {
2008  if(r->typ!=NULL)
2009  {
2010  for(j=0;j<r->OrdSize;j++) // for all ordering blocks (j =0..OrdSize-1)
2011  {
2012  if(r->typ[j].ord_typ == ro_isTemp)
2013  {
2014  const int p = r->typ[j].data.isTemp.suffixpos;
2015 
2016  if(p <= j)
2017  dReportError("ordrec prefix %d is unmatched",j);
2018 
2019  assume( p < r->OrdSize );
2020 
2021  if(r->typ[p].ord_typ != ro_is)
2022  dReportError("ordrec prefix %d is unmatched (suffix: %d is wrong!!!)",j, p);
2023 
2024  // Skip all intermediate blocks for undone variables:
2025  if(r->typ[j].data.isTemp.pVarOffset[i] != -1) // Check i^th variable
2026  {
2027  j = p - 1; // SKIP ALL INTERNAL BLOCKS...???
2028  continue; // To make for check OrdSize bound...
2029  }
2030  }
2031  else if (r->typ[j].ord_typ == ro_is)
2032  {
2033  // Skip all intermediate blocks for undone variables:
2034  if(r->typ[j].data.is.pVarOffset[i] != -1)
2035  {
2036  // TODO???
2037  }
2038 
2039  }
2040  else
2041  {
2042  if (r->typ[j].ord_typ==ro_cp)
2043  {
2044  if(((short)r->VarOffset[i]) == r->typ[j].data.cp.place)
2045  dReportError("ordrec %d conflicts with var %d",j,i);
2046  }
2047  else
2048  if ((r->typ[j].ord_typ!=ro_syzcomp)
2049  && (r->VarOffset[i] == r->typ[j].data.dp.place))
2050  dReportError("ordrec %d conflicts with var %d",j,i);
2051  }
2052  }
2053  }
2054  int tmp;
2055  tmp=r->VarOffset[i] & 0xffffff;
2056  #if SIZEOF_LONG == 8
2057  if ((r->VarOffset[i] >> 24) >63)
2058  #else
2059  if ((r->VarOffset[i] >> 24) >31)
2060  #endif
2061  dReportError("bit_start out of range:%d",r->VarOffset[i] >> 24);
2062  if (i > 0 && ((tmp<0) ||(tmp>r->ExpL_Size-1)))
2063  {
2064  dReportError("varoffset out of range for var %d: %d",i,tmp);
2065  }
2066  }
2067  if(r->typ!=NULL)
2068  {
2069  for(j=0;j<r->OrdSize;j++)
2070  {
2071  if ((r->typ[j].ord_typ==ro_dp)
2072  || (r->typ[j].ord_typ==ro_wp)
2073  || (r->typ[j].ord_typ==ro_wp_neg))
2074  {
2075  if (r->typ[j].data.dp.start > r->typ[j].data.dp.end)
2076  dReportError("in ordrec %d: start(%d) > end(%d)",j,
2077  r->typ[j].data.dp.start, r->typ[j].data.dp.end);
2078  if ((r->typ[j].data.dp.start < 1)
2079  || (r->typ[j].data.dp.end > r->N))
2080  dReportError("in ordrec %d: start(%d)<1 or end(%d)>vars(%d)",j,
2081  r->typ[j].data.dp.start, r->typ[j].data.dp.end,r->N);
2082  }
2083  }
2084  }
2085 
2086  assume(r != NULL);
2087  assume(r->cf != NULL);
2088 
2089  if (nCoeff_is_algExt(r->cf))
2090  {
2091  assume(r->cf->extRing != NULL);
2092  assume(r->cf->extRing->qideal != NULL);
2093  omCheckAddr(r->cf->extRing->qideal->m[0]);
2094  }
2095 
2096  //assume(r->cf!=NULL);
2097 
2098  return TRUE;
2099 }
2100 #endif
2101 
2102 static void rO_Align(int &place, int &bitplace)
2103 {
2104  // increment place to the next aligned one
2105  // (count as Exponent_t,align as longs)
2106  if (bitplace!=BITS_PER_LONG)
2107  {
2108  place++;
2109  bitplace=BITS_PER_LONG;
2110  }
2111 }
2112 
2113 static void rO_TDegree(int &place, int &bitplace, int start, int end,
2114  long *o, sro_ord &ord_struct)
2115 {
2116  // degree (aligned) of variables v_start..v_end, ordsgn 1
2117  rO_Align(place,bitplace);
2118  ord_struct.ord_typ=ro_dp;
2119  ord_struct.data.dp.start=start;
2120  ord_struct.data.dp.end=end;
2121  ord_struct.data.dp.place=place;
2122  o[place]=1;
2123  place++;
2124  rO_Align(place,bitplace);
2125 }
2126 
2127 static void rO_TDegree_neg(int &place, int &bitplace, int start, int end,
2128  long *o, sro_ord &ord_struct)
2129 {
2130  // degree (aligned) of variables v_start..v_end, ordsgn -1
2131  rO_Align(place,bitplace);
2132  ord_struct.ord_typ=ro_dp;
2133  ord_struct.data.dp.start=start;
2134  ord_struct.data.dp.end=end;
2135  ord_struct.data.dp.place=place;
2136  o[place]=-1;
2137  place++;
2138  rO_Align(place,bitplace);
2139 }
2140 
2141 static void rO_WDegree(int &place, int &bitplace, int start, int end,
2142  long *o, sro_ord &ord_struct, int *weights)
2143 {
2144  // weighted degree (aligned) of variables v_start..v_end, ordsgn 1
2145  while((start<end) && (weights[0]==0)) { start++; weights++; }
2146  while((start<end) && (weights[end-start]==0)) { end--; }
2147  int i;
2148  int pure_tdeg=1;
2149  for(i=start;i<=end;i++)
2150  {
2151  if(weights[i-start]!=1)
2152  {
2153  pure_tdeg=0;
2154  break;
2155  }
2156  }
2157  if (pure_tdeg)
2158  {
2159  rO_TDegree(place,bitplace,start,end,o,ord_struct);
2160  return;
2161  }
2162  rO_Align(place,bitplace);
2163  ord_struct.ord_typ=ro_wp;
2164  ord_struct.data.wp.start=start;
2165  ord_struct.data.wp.end=end;
2166  ord_struct.data.wp.place=place;
2167  ord_struct.data.wp.weights=weights;
2168  o[place]=1;
2169  place++;
2170  rO_Align(place,bitplace);
2171  for(i=start;i<=end;i++)
2172  {
2173  if(weights[i-start]<0)
2174  {
2175  ord_struct.ord_typ=ro_wp_neg;
2176  break;
2177  }
2178  }
2179 }
2180 
2181 static void rO_WMDegree(int &place, int &bitplace, int start, int end,
2182  long *o, sro_ord &ord_struct, int *weights)
2183 {
2184  assume(weights != NULL);
2185 
2186  // weighted degree (aligned) of variables v_start..v_end, ordsgn 1
2187 // while((start<end) && (weights[0]==0)) { start++; weights++; }
2188 // while((start<end) && (weights[end-start]==0)) { end--; }
2189  rO_Align(place,bitplace);
2190  ord_struct.ord_typ=ro_am;
2191  ord_struct.data.am.start=start;
2192  ord_struct.data.am.end=end;
2193  ord_struct.data.am.place=place;
2194  ord_struct.data.am.weights=weights;
2195  ord_struct.data.am.weights_m = weights + (end-start+1);
2196  ord_struct.data.am.len_gen=weights[end-start+1];
2197  assume( ord_struct.data.am.weights_m[0] == ord_struct.data.am.len_gen );
2198  o[place]=1;
2199  place++;
2200  rO_Align(place,bitplace);
2201 }
2202 
2203 static void rO_WDegree64(int &place, int &bitplace, int start, int end,
2204  long *o, sro_ord &ord_struct, int64 *weights)
2205 {
2206  // weighted degree (aligned) of variables v_start..v_end, ordsgn 1,
2207  // reserved 2 places
2208  rO_Align(place,bitplace);
2209  ord_struct.ord_typ=ro_wp64;
2210  ord_struct.data.wp64.start=start;
2211  ord_struct.data.wp64.end=end;
2212  ord_struct.data.wp64.place=place;
2213  ord_struct.data.wp64.weights64=weights;
2214  o[place]=1;
2215  place++;
2216  o[place]=1;
2217  place++;
2218  rO_Align(place,bitplace);
2219 }
2220 
2221 static void rO_WDegree_neg(int &place, int &bitplace, int start, int end,
2222  long *o, sro_ord &ord_struct, int *weights)
2223 {
2224  // weighted degree (aligned) of variables v_start..v_end, ordsgn -1
2225  while((start<end) && (weights[0]==0)) { start++; weights++; }
2226  while((start<end) && (weights[end-start]==0)) { end--; }
2227  rO_Align(place,bitplace);
2228  ord_struct.ord_typ=ro_wp;
2229  ord_struct.data.wp.start=start;
2230  ord_struct.data.wp.end=end;
2231  ord_struct.data.wp.place=place;
2232  ord_struct.data.wp.weights=weights;
2233  o[place]=-1;
2234  place++;
2235  rO_Align(place,bitplace);
2236  int i;
2237  for(i=start;i<=end;i++)
2238  {
2239  if(weights[i-start]<0)
2240  {
2241  ord_struct.ord_typ=ro_wp_neg;
2242  break;
2243  }
2244  }
2245 }
2246 
2247 static void rO_LexVars(int &place, int &bitplace, int start, int end,
2248  int &prev_ord, long *o,int *v, int bits, int opt_var)
2249 {
2250  // a block of variables v_start..v_end with lex order, ordsgn 1
2251  int k;
2252  int incr=1;
2253  if(prev_ord==-1) rO_Align(place,bitplace);
2254 
2255  if (start>end)
2256  {
2257  incr=-1;
2258  }
2259  for(k=start;;k+=incr)
2260  {
2261  bitplace-=bits;
2262  if (bitplace < 0) { bitplace=BITS_PER_LONG-bits; place++; }
2263  o[place]=1;
2264  v[k]= place | (bitplace << 24);
2265  if (k==end) break;
2266  }
2267  prev_ord=1;
2268  if (opt_var!= -1)
2269  {
2270  assume((opt_var == end+1) ||(opt_var == end-1));
2271  if((opt_var != end+1) &&(opt_var != end-1)) WarnS("hier-2");
2272  int save_bitplace=bitplace;
2273  bitplace-=bits;
2274  if (bitplace < 0)
2275  {
2276  bitplace=save_bitplace;
2277  return;
2278  }
2279  // there is enough space for the optional var
2280  v[opt_var]=place | (bitplace << 24);
2281  }
2282 }
2283 
2284 static void rO_LexVars_neg(int &place, int &bitplace, int start, int end,
2285  int &prev_ord, long *o,int *v, int bits, int opt_var)
2286 {
2287  // a block of variables v_start..v_end with lex order, ordsgn -1
2288  int k;
2289  int incr=1;
2290  if(prev_ord==1) rO_Align(place,bitplace);
2291 
2292  if (start>end)
2293  {
2294  incr=-1;
2295  }
2296  for(k=start;;k+=incr)
2297  {
2298  bitplace-=bits;
2299  if (bitplace < 0) { bitplace=BITS_PER_LONG-bits; place++; }
2300  o[place]=-1;
2301  v[k]=place | (bitplace << 24);
2302  if (k==end) break;
2303  }
2304  prev_ord=-1;
2305 // #if 0
2306  if (opt_var!= -1)
2307  {
2308  assume((opt_var == end+1) ||(opt_var == end-1));
2309  if((opt_var != end+1) &&(opt_var != end-1)) WarnS("hier-1");
2310  int save_bitplace=bitplace;
2311  bitplace-=bits;
2312  if (bitplace < 0)
2313  {
2314  bitplace=save_bitplace;
2315  return;
2316  }
2317  // there is enough space for the optional var
2318  v[opt_var]=place | (bitplace << 24);
2319  }
2320 // #endif
2321 }
2322 
2323 static void rO_Syzcomp(int &place, int &bitplace, int &prev_ord,
2324  long *o, sro_ord &ord_struct)
2325 {
2326  // ordering is derived from component number
2327  rO_Align(place,bitplace);
2328  ord_struct.ord_typ=ro_syzcomp;
2329  ord_struct.data.syzcomp.place=place;
2330  ord_struct.data.syzcomp.Components=NULL;
2331  ord_struct.data.syzcomp.ShiftedComponents=NULL;
2332  o[place]=1;
2333  prev_ord=1;
2334  place++;
2335  rO_Align(place,bitplace);
2336 }
2337 
2338 static void rO_Syz(int &place, int &bitplace, int &prev_ord,
2339  int syz_comp, long *o, sro_ord &ord_struct)
2340 {
2341  // ordering is derived from component number
2342  // let's reserve one Exponent_t for it
2343  if ((prev_ord== 1) || (bitplace!=BITS_PER_LONG))
2344  rO_Align(place,bitplace);
2345  ord_struct.ord_typ=ro_syz;
2346  ord_struct.data.syz.place=place;
2347  ord_struct.data.syz.limit=syz_comp;
2348  if (syz_comp>0)
2349  ord_struct.data.syz.syz_index = (int*) omAlloc0((syz_comp+1)*sizeof(int));
2350  else
2351  ord_struct.data.syz.syz_index = NULL;
2352  ord_struct.data.syz.curr_index = 1;
2353  o[place]= -1;
2354  prev_ord=-1;
2355  place++;
2356 }
2357 
2358 #ifndef SING_NDEBUG
2359 # define MYTEST 0
2360 #else /* ifndef SING_NDEBUG */
2361 # define MYTEST 0
2362 #endif /* ifndef SING_NDEBUG */
2363 
2364 static void rO_ISPrefix(int &place, int &bitplace, int &prev_ord,
2365  long *o, int /*N*/, int *v, sro_ord &ord_struct)
2366 {
2367  if ((prev_ord== 1) || (bitplace!=BITS_PER_LONG))
2368  rO_Align(place,bitplace);
2369  // since we add something afterwards - it's better to start with anew!?
2370 
2371  ord_struct.ord_typ = ro_isTemp;
2372  ord_struct.data.isTemp.start = place;
2373  ord_struct.data.isTemp.pVarOffset = (int *)omMemDup(v);
2374  ord_struct.data.isTemp.suffixpos = -1;
2375 
2376  // We will act as rO_Syz on our own!!!
2377  // Here we allocate an exponent as a level placeholder
2378  o[place]= -1;
2379  prev_ord=-1;
2380  place++;
2381 }
2382 static void rO_ISSuffix(int &place, int &bitplace, int &prev_ord, long *o,
2383  int N, int *v, sro_ord *tmp_typ, int &typ_i, int sgn)
2384 {
2385 
2386  // Let's find previous prefix:
2387  int typ_j = typ_i - 1;
2388  while(typ_j >= 0)
2389  {
2390  if( tmp_typ[typ_j].ord_typ == ro_isTemp)
2391  break;
2392  typ_j --;
2393  }
2394 
2395  assume( typ_j >= 0 );
2396 
2397  if( typ_j < 0 ) // Found NO prefix!!! :(
2398  return;
2399 
2400  assume( tmp_typ[typ_j].ord_typ == ro_isTemp );
2401 
2402  // Get saved state:
2403  const int start = tmp_typ[typ_j].data.isTemp.start;
2404  int *pVarOffset = tmp_typ[typ_j].data.isTemp.pVarOffset;
2405 
2406 /*
2407  // shift up all blocks
2408  while(typ_j < (typ_i-1))
2409  {
2410  tmp_typ[typ_j] = tmp_typ[typ_j+1];
2411  typ_j++;
2412  }
2413  typ_j = typ_i - 1; // No increment for typ_i
2414 */
2415  tmp_typ[typ_j].data.isTemp.suffixpos = typ_i;
2416 
2417  // Let's keep that dummy for now...
2418  typ_j = typ_i; // the typ to change!
2419  typ_i++; // Just for now...
2420 
2421 
2422  for( int i = 0; i <= N; i++ ) // Note [0] == component !!! No Skip?
2423  {
2424  // Was i-th variable allocated inbetween?
2425  if( v[i] != pVarOffset[i] )
2426  {
2427  pVarOffset[i] = v[i]; // Save for later...
2428  v[i] = -1; // Undo!
2429  assume( pVarOffset[i] != -1 );
2430  }
2431  else
2432  pVarOffset[i] = -1; // No change here...
2433  }
2434 
2435  if( pVarOffset[0] != -1 )
2436  pVarOffset[0] &= 0x0fff;
2437 
2438  sro_ord &ord_struct = tmp_typ[typ_j];
2439 
2440 
2441  ord_struct.ord_typ = ro_is;
2442  ord_struct.data.is.start = start;
2443  ord_struct.data.is.end = place;
2444  ord_struct.data.is.pVarOffset = pVarOffset;
2445 
2446 
2447  // What about component???
2448 // if( v[0] != -1 ) // There is a component already...???
2449 // if( o[ v[0] & 0x0fff ] == sgn )
2450 // {
2451 // pVarOffset[0] = -1; // NEVER USED Afterwards...
2452 // return;
2453 // }
2454 
2455 
2456  // Moreover: we need to allocate the module component (v[0]) here!
2457  if( v[0] == -1) // It's possible that there was module component v0 at the begining (before prefix)!
2458  {
2459  // Start with a whole long exponent
2460  if( bitplace != BITS_PER_LONG )
2461  rO_Align(place, bitplace);
2462 
2463  assume( bitplace == BITS_PER_LONG );
2464  bitplace -= BITS_PER_LONG;
2465  assume(bitplace == 0);
2466  v[0] = place | (bitplace << 24); // Never mind whether pVarOffset[0] > 0!!!
2467  o[place] = sgn; // Singnum for component ordering
2468  prev_ord = sgn;
2469  }
2470 }
2471 
2472 
2473 static unsigned long rGetExpSize(unsigned long bitmask, int & bits)
2474 {
2475  if (bitmask == 0)
2476  {
2477  bits=16; bitmask=0xffff;
2478  }
2479  else if (bitmask <= 1L)
2480  {
2481  bits=1; bitmask = 1L;
2482  }
2483  else if (bitmask <= 3L)
2484  {
2485  bits=2; bitmask = 3L;
2486  }
2487  else if (bitmask <= 7L)
2488  {
2489  bits=3; bitmask=7L;
2490  }
2491  else if (bitmask <= 0xfL)
2492  {
2493  bits=4; bitmask=0xfL;
2494  }
2495  else if (bitmask <= 0x1fL)
2496  {
2497  bits=5; bitmask=0x1fL;
2498  }
2499  else if (bitmask <= 0x3fL)
2500  {
2501  bits=6; bitmask=0x3fL;
2502  }
2503 #if SIZEOF_LONG == 8
2504  else if (bitmask <= 0x7fL)
2505  {
2506  bits=7; bitmask=0x7fL; /* 64 bit longs only */
2507  }
2508 #endif
2509  else if (bitmask <= 0xffL)
2510  {
2511  bits=8; bitmask=0xffL;
2512  }
2513 #if SIZEOF_LONG == 8
2514  else if (bitmask <= 0x1ffL)
2515  {
2516  bits=9; bitmask=0x1ffL; /* 64 bit longs only */
2517  }
2518 #endif
2519  else if (bitmask <= 0x3ffL)
2520  {
2521  bits=10; bitmask=0x3ffL;
2522  }
2523 #if SIZEOF_LONG == 8
2524  else if (bitmask <= 0xfffL)
2525  {
2526  bits=12; bitmask=0xfff; /* 64 bit longs only */
2527  }
2528 #endif
2529  else if (bitmask <= 0xffffL)
2530  {
2531  bits=16; bitmask=0xffffL;
2532  }
2533 #if SIZEOF_LONG == 8
2534  else if (bitmask <= 0xfffffL)
2535  {
2536  bits=20; bitmask=0xfffffL; /* 64 bit longs only */
2537  }
2538  else if (bitmask <= 0xffffffffL)
2539  {
2540  bits=32; bitmask=0xffffffffL;
2541  }
2542  else if (bitmask <= 0x7fffffffffffffffL)
2543  {
2544  bits=63; bitmask=0x7fffffffffffffffL; /* for overflow tests*/
2545  }
2546  else
2547  {
2548  bits=63; bitmask=0x7fffffffffffffffL; /* for overflow tests*/
2549  }
2550 #else
2551  else if (bitmask <= 0x7fffffff)
2552  {
2553  bits=31; bitmask=0x7fffffff; /* for overflow tests*/
2554  }
2555  else
2556  {
2557  bits=31; bitmask=0x7fffffffL; /* for overflow tests*/
2558  }
2559 #endif
2560  return bitmask;
2561 }
2562 
2563 /*2
2564 * optimize rGetExpSize for a block of N variables, exp <=bitmask
2565 */
2566 static unsigned long rGetExpSize(unsigned long bitmask, int & bits, int N)
2567 {
2568 #if SIZEOF_LONG == 8
2569  if (N<4) N=4;
2570 #else
2571  if (N<2) N=2;
2572 #endif
2573  bitmask =rGetExpSize(bitmask, bits);
2574  int vars_per_long=BIT_SIZEOF_LONG/bits;
2575  int bits1;
2576  loop
2577  {
2578  if (bits == BIT_SIZEOF_LONG-1)
2579  {
2580  bits = BIT_SIZEOF_LONG - 1;
2581  return LONG_MAX;
2582  }
2583  unsigned long bitmask1 =rGetExpSize(bitmask+1, bits1);
2584  int vars_per_long1=BIT_SIZEOF_LONG/bits1;
2585  if ((((N+vars_per_long-1)/vars_per_long) ==
2586  ((N+vars_per_long1-1)/vars_per_long1)))
2587  {
2588  vars_per_long=vars_per_long1;
2589  bits=bits1;
2590  bitmask=bitmask1;
2591  }
2592  else
2593  {
2594  return bitmask; /* and bits */
2595  }
2596  }
2597 }
2598 
2599 
2600 /*2
2601  * create a copy of the ring r, which must be equivalent to currRing
2602  * used for std computations
2603  * may share data structures with currRing
2604  * DOES CALL rComplete
2605  */
2606 ring rModifyRing(ring r, BOOLEAN omit_degree,
2607  BOOLEAN try_omit_comp,
2608  unsigned long exp_limit)
2609 {
2610  assume (r != NULL );
2611  assume (exp_limit > 1);
2612  BOOLEAN need_other_ring;
2613  BOOLEAN omitted_degree = FALSE;
2614 
2615  int iNeedInducedOrderingSetup = 0; ///< How many induced ordering block do we have?
2616  int bits;
2617 
2618  exp_limit=rGetExpSize(exp_limit, bits, r->N);
2619  need_other_ring = (exp_limit != r->bitmask);
2620 
2621  int nblocks=rBlocks(r);
2622  rRingOrder_t *order=(rRingOrder_t*)omAlloc0((nblocks+1)*sizeof(rRingOrder_t));
2623  int *block0=(int*)omAlloc0((nblocks+1)*sizeof(int));
2624  int *block1=(int*)omAlloc0((nblocks+1)*sizeof(int));
2625  int **wvhdl=(int**)omAlloc0((nblocks+1)*sizeof(int *));
2626 
2627  int i=0;
2628  int j=0; /* i index in r, j index in res */
2629 
2630  for( rRingOrder_t r_ord=r->order[i]; (r_ord != (rRingOrder_t)0) && (i < nblocks); j++, r_ord=r->order[++i])
2631  {
2632  BOOLEAN copy_block_index=TRUE;
2633 
2634  if (r->block0[i]==r->block1[i])
2635  {
2636  switch(r_ord)
2637  {
2638  case ringorder_wp:
2639  case ringorder_dp:
2640  case ringorder_Wp:
2641  case ringorder_Dp:
2642  r_ord=ringorder_lp;
2643  break;
2644  case ringorder_Ws:
2645  case ringorder_Ds:
2646  case ringorder_ws:
2647  case ringorder_ds:
2648  r_ord=ringorder_ls;
2649  break;
2650  default:
2651  break;
2652  }
2653  }
2654  switch(r_ord)
2655  {
2656  case ringorder_S:
2657  {
2658 #ifndef SING_NDEBUG
2659  Warn("Error: unhandled ordering in rModifyRing: ringorder_S = [%d]", r_ord);
2660 #endif
2661  order[j]=r_ord; /*r->order[i];*/
2662  break;
2663  }
2664  case ringorder_C:
2665  case ringorder_c:
2666  if (!try_omit_comp)
2667  {
2668  order[j]=r_ord; /*r->order[i]*/;
2669  }
2670  else
2671  {
2672  j--;
2673  need_other_ring=TRUE;
2674  try_omit_comp=FALSE;
2675  copy_block_index=FALSE;
2676  }
2677  break;
2678  case ringorder_wp:
2679  case ringorder_dp:
2680  case ringorder_ws:
2681  case ringorder_ds:
2682  if(!omit_degree)
2683  {
2684  order[j]=r_ord; /*r->order[i]*/;
2685  }
2686  else
2687  {
2688  order[j]=ringorder_rs;
2689  need_other_ring=TRUE;
2690  omit_degree=FALSE;
2691  omitted_degree = TRUE;
2692  }
2693  break;
2694  case ringorder_Wp:
2695  case ringorder_Dp:
2696  case ringorder_Ws:
2697  case ringorder_Ds:
2698  if(!omit_degree)
2699  {
2700  order[j]=r_ord; /*r->order[i];*/
2701  }
2702  else
2703  {
2704  order[j]=ringorder_lp;
2705  need_other_ring=TRUE;
2706  omit_degree=FALSE;
2707  omitted_degree = TRUE;
2708  }
2709  break;
2710  case ringorder_IS:
2711  {
2712  if (try_omit_comp)
2713  {
2714  // tried, but cannot omit component due to the ordering block [%d]: %d (ringorder_IS)", i, r_ord
2715  try_omit_comp = FALSE;
2716  }
2717  order[j]=r_ord; /*r->order[i];*/
2718  iNeedInducedOrderingSetup++;
2719  break;
2720  }
2721  case ringorder_s:
2722  {
2723  assume((i == 0) && (j == 0));
2724  if (try_omit_comp)
2725  {
2726  // tried, but cannot omit component due to the ordering block [%d]: %d (ringorder_s)", i, r_ord
2727  try_omit_comp = FALSE;
2728  }
2729  order[j]=r_ord; /*r->order[i];*/
2730  break;
2731  }
2732  default:
2733  order[j]=r_ord; /*r->order[i];*/
2734  break;
2735  }
2736  if (copy_block_index)
2737  {
2738  block0[j]=r->block0[i];
2739  block1[j]=r->block1[i];
2740  wvhdl[j]=r->wvhdl[i];
2741  }
2742 
2743  // order[j]=ringorder_no; // done by omAlloc0
2744  }
2745  if(!need_other_ring)
2746  {
2747  omFreeSize(order,(nblocks+1)*sizeof(rRingOrder_t));
2748  omFreeSize(block0,(nblocks+1)*sizeof(int));
2749  omFreeSize(block1,(nblocks+1)*sizeof(int));
2750  omFreeSize(wvhdl,(nblocks+1)*sizeof(int *));
2751  return r;
2752  }
2753  ring res=(ring)omAlloc0Bin(sip_sring_bin);
2754  *res = *r;
2755 
2756 #ifdef HAVE_PLURAL
2757  res->GetNC() = NULL;
2758 #endif
2759 
2760  // res->qideal, res->idroot ???
2761  res->wvhdl=wvhdl;
2762  res->order=order;
2763  res->block0=block0;
2764  res->block1=block1;
2765  res->bitmask=exp_limit;
2766  //int tmpref=r->cf->ref0;
2767  rComplete(res, 1);
2768  //r->cf->ref=tmpref;
2769 
2770  // adjust res->pFDeg: if it was changed globally, then
2771  // it must also be changed for new ring
2772  if (r->pFDegOrig != res->pFDegOrig &&
2774  {
2775  // still might need adjustment for weighted orderings
2776  // and omit_degree
2777  res->firstwv = r->firstwv;
2778  res->firstBlockEnds = r->firstBlockEnds;
2779  res->pFDeg = res->pFDegOrig = p_WFirstTotalDegree;
2780  }
2781  if (omitted_degree)
2782  res->pLDeg = r->pLDegOrig;
2783 
2784  rOptimizeLDeg(res); // also sets res->pLDegOrig
2785 
2786  // set syzcomp
2787  if (res->typ != NULL)
2788  {
2789  if( res->typ[0].ord_typ == ro_syz) // "s" Always on [0] place!
2790  {
2791  res->typ[0] = r->typ[0]; // Copy struct!? + setup the same limit!
2792 
2793  if (r->typ[0].data.syz.limit > 0)
2794  {
2795  res->typ[0].data.syz.syz_index
2796  = (int*) omAlloc((r->typ[0].data.syz.limit +1)*sizeof(int));
2797  memcpy(res->typ[0].data.syz.syz_index, r->typ[0].data.syz.syz_index,
2798  (r->typ[0].data.syz.limit +1)*sizeof(int));
2799  }
2800  }
2801 
2802  if( iNeedInducedOrderingSetup > 0 )
2803  {
2804  for(j = 0, i = 0; (i < nblocks) && (iNeedInducedOrderingSetup > 0); i++)
2805  if( res->typ[i].ord_typ == ro_is ) // Search for suffixes!
2806  {
2807  ideal F = idrHeadR(r->typ[i].data.is.F, r, res); // Copy F from r into res!
2808  assume(
2810  F, // WILL BE COPIED!
2811  r->typ[i].data.is.limit,
2812  j++
2813  )
2814  );
2815  id_Delete(&F, res);
2816  iNeedInducedOrderingSetup--;
2817  }
2818  } // Process all induced Ordering blocks! ...
2819  }
2820  // the special case: homog (omit_degree) and 1 block rs: that is global:
2821  // it comes from dp
2822  res->OrdSgn=r->OrdSgn;
2823 
2824 
2825 #ifdef HAVE_PLURAL
2826  if (rIsPluralRing(r))
2827  {
2828  if ( nc_rComplete(r, res, false) ) // no qideal!
2829  {
2830 #ifndef SING_NDEBUG
2831  WarnS("error in nc_rComplete");
2832 #endif
2833  // cleanup?
2834 
2835 // rDelete(res);
2836 // return r;
2837 
2838  // just go on..
2839  }
2840 
2841  if( rIsSCA(r) )
2842  {
2844  WarnS("error in sca_Force!");
2845  }
2846  }
2847 #endif
2848 
2849  return res;
2850 }
2851 
2852 // construct Wp,C ring
2853 ring rModifyRing_Wp(ring r, int* weights)
2854 {
2855  ring res=(ring)omAlloc0Bin(sip_sring_bin);
2856  *res = *r;
2857 #ifdef HAVE_PLURAL
2858  res->GetNC() = NULL;
2859 #endif
2860 
2861  /*weights: entries for 3 blocks: NULL*/
2862  res->wvhdl = (int **)omAlloc0(3 * sizeof(int *));
2863  /*order: Wp,C,0*/
2864  res->order = (rRingOrder_t *) omAlloc(3 * sizeof(rRingOrder_t *));
2865  res->block0 = (int *)omAlloc0(3 * sizeof(int *));
2866  res->block1 = (int *)omAlloc0(3 * sizeof(int *));
2867  /* ringorder Wp for the first block: var 1..r->N */
2868  res->order[0] = ringorder_Wp;
2869  res->block0[0] = 1;
2870  res->block1[0] = r->N;
2871  res->wvhdl[0] = weights;
2872  /* ringorder C for the second block: no vars */
2873  res->order[1] = ringorder_C;
2874  /* the last block: everything is 0 */
2875  res->order[2] = (rRingOrder_t)0;
2876 
2877  //int tmpref=r->cf->ref;
2878  rComplete(res, 1);
2879  //r->cf->ref=tmpref;
2880 #ifdef HAVE_PLURAL
2881  if (rIsPluralRing(r))
2882  {
2883  if ( nc_rComplete(r, res, false) ) // no qideal!
2884  {
2885 #ifndef SING_NDEBUG
2886  WarnS("error in nc_rComplete");
2887 #endif
2888  // cleanup?
2889 
2890 // rDelete(res);
2891 // return r;
2892 
2893  // just go on..
2894  }
2895  }
2896 #endif
2897  return res;
2898 }
2899 
2900 // construct lp, C ring with r->N variables, r->names vars....
2901 ring rModifyRing_Simple(ring r, BOOLEAN ommit_degree, BOOLEAN ommit_comp, unsigned long exp_limit, BOOLEAN &simple)
2902 {
2903  simple=TRUE;
2904  if (!rHasSimpleOrder(r))
2905  {
2906  simple=FALSE; // sorting needed
2907  assume (r != NULL );
2908  assume (exp_limit > 1);
2909  int bits;
2910 
2911  exp_limit=rGetExpSize(exp_limit, bits, r->N);
2912 
2913  int nblocks=1+(ommit_comp!=0);
2914  rRingOrder_t *order=(rRingOrder_t*)omAlloc0((nblocks+1)*sizeof(rRingOrder_t));
2915  int *block0=(int*)omAlloc0((nblocks+1)*sizeof(int));
2916  int *block1=(int*)omAlloc0((nblocks+1)*sizeof(int));
2917  int **wvhdl=(int**)omAlloc0((nblocks+1)*sizeof(int *));
2918 
2919  order[0]=ringorder_lp;
2920  block0[0]=1;
2921  block1[0]=r->N;
2922  if (!ommit_comp)
2923  {
2924  order[1]=ringorder_C;
2925  }
2926  ring res=(ring)omAlloc0Bin(sip_sring_bin);
2927  *res = *r;
2928 #ifdef HAVE_PLURAL
2929  res->GetNC() = NULL;
2930 #endif
2931  // res->qideal, res->idroot ???
2932  res->wvhdl=wvhdl;
2933  res->order=order;
2934  res->block0=block0;
2935  res->block1=block1;
2936  res->bitmask=exp_limit;
2937  //int tmpref=r->cf->ref;
2938  rComplete(res, 1);
2939  //r->cf->ref=tmpref;
2940 
2941 #ifdef HAVE_PLURAL
2942  if (rIsPluralRing(r))
2943  {
2944  if ( nc_rComplete(r, res, false) ) // no qideal!
2945  {
2946 #ifndef SING_NDEBUG
2947  WarnS("error in nc_rComplete");
2948 #endif
2949  // cleanup?
2950 
2951 // rDelete(res);
2952 // return r;
2953 
2954  // just go on..
2955  }
2956  }
2957 #endif
2958 
2959  rOptimizeLDeg(res);
2960 
2961  return res;
2962  }
2963  return rModifyRing(r, ommit_degree, ommit_comp, exp_limit);
2964 }
2965 
2967 {
2969 }
2970 
2971 
2973 {
2974  rUnComplete(r);
2975  omFree(r->order);
2976  omFree(r->block0);
2977  omFree(r->block1);
2978  omFree(r->wvhdl);
2980 }
2981 
2983 {
2984  rUnComplete(r);
2985  omFree(r->order);
2986  omFree(r->block0);
2987  omFree(r->block1);
2988  omFree(r->wvhdl[0]);
2989  omFree(r->wvhdl);
2991 }
2992 
2993 static void rSetOutParams(ring r)
2994 {
2995  r->VectorOut = (r->order[0] == ringorder_c);
2996  r->CanShortOut = TRUE;
2997  {
2998  int i;
2999  if (rParameter(r)!=NULL)
3000  {
3001  for (i=0;i<rPar(r);i++)
3002  {
3003  if(strlen(rParameter(r)[i])>1)
3004  {
3005  r->CanShortOut=FALSE;
3006  break;
3007  }
3008  }
3009  }
3010  if (r->CanShortOut)
3011  {
3012  // Hmm... sometimes (e.g., from maGetPreimage) new variables
3013  // are introduced, but their names are never set
3014  // hence, we do the following awkward trick
3015  int N = omSizeOfAddr(r->names)/sizeof(char*);
3016  if (r->N < N) N = r->N;
3017 
3018  for (i=(N-1);i>=0;i--)
3019  {
3020  if(r->names[i] != NULL && strlen(r->names[i])>1)
3021  {
3022  r->CanShortOut=FALSE;
3023  break;
3024  }
3025  }
3026  }
3027  }
3028  r->ShortOut = r->CanShortOut;
3029 
3030  assume( !( !r->CanShortOut && r->ShortOut ) );
3031 }
3032 
3033 static void rSetFirstWv(ring r, int i, rRingOrder_t* order, int* block1, int** wvhdl)
3034 {
3035  // cheat for ringorder_aa
3036  if (order[i] == ringorder_aa)
3037  i++;
3038  if(block1[i]!=r->N) r->LexOrder=TRUE;
3039  r->firstBlockEnds=block1[i];
3040  r->firstwv = wvhdl[i];
3041  if ((order[i]== ringorder_ws)
3042  || (order[i]==ringorder_Ws)
3043  || (order[i]== ringorder_wp)
3044  || (order[i]==ringorder_Wp)
3045  || (order[i]== ringorder_a)
3046  /*|| (order[i]==ringorder_A)*/)
3047  {
3048  int j;
3049  for(j=block1[i]-r->block0[i];j>=0;j--)
3050  {
3051  if (r->firstwv[j]==0) r->LexOrder=TRUE;
3052  }
3053  }
3054  else if (order[i]==ringorder_a64)
3055  {
3056  int j;
3057  int64 *w=rGetWeightVec(r);
3058  for(j=block1[i]-r->block0[i];j>=0;j--)
3059  {
3060  if (w[j]==0) r->LexOrder=TRUE;
3061  }
3062  }
3063 }
3064 
3065 static void rOptimizeLDeg(ring r)
3066 {
3067  if (r->pFDeg == p_Deg)
3068  {
3069  if (r->pLDeg == pLDeg1)
3070  r->pLDeg = pLDeg1_Deg;
3071  if (r->pLDeg == pLDeg1c)
3072  r->pLDeg = pLDeg1c_Deg;
3073  }
3074  else if (r->pFDeg == p_Totaldegree)
3075  {
3076  if (r->pLDeg == pLDeg1)
3077  r->pLDeg = pLDeg1_Totaldegree;
3078  if (r->pLDeg == pLDeg1c)
3079  r->pLDeg = pLDeg1c_Totaldegree;
3080  }
3081  else if (r->pFDeg == p_WFirstTotalDegree)
3082  {
3083  if (r->pLDeg == pLDeg1)
3084  r->pLDeg = pLDeg1_WFirstTotalDegree;
3085  if (r->pLDeg == pLDeg1c)
3086  r->pLDeg = pLDeg1c_WFirstTotalDegree;
3087  }
3088  r->pLDegOrig = r->pLDeg;
3089 }
3090 
3091 // set pFDeg, pLDeg, requires OrdSgn already set
3092 static void rSetDegStuff(ring r)
3093 {
3094  rRingOrder_t* order = r->order;
3095  int* block0 = r->block0;
3096  int* block1 = r->block1;
3097  int** wvhdl = r->wvhdl;
3098 
3099  if (order[0]==ringorder_S ||order[0]==ringorder_s || order[0]==ringorder_IS)
3100  {
3101  order++;
3102  block0++;
3103  block1++;
3104  wvhdl++;
3105  }
3106  r->LexOrder = FALSE;
3107  r->pFDeg = p_Totaldegree;
3108  r->pLDeg = (r->OrdSgn == 1 ? pLDegb : pLDeg0);
3109 
3110  /*======== ordering type is (am,_) ==================*/
3111  if (order[0]==ringorder_am)
3112  {
3113  for(int ii=block0[0];ii<=block1[0];ii++)
3114  if (wvhdl[0][ii-1]<0) { r->MixedOrder=2;break;}
3115  r->LexOrder=FALSE;
3116  for(int ii=block0[0];ii<=block1[0];ii++)
3117  if (wvhdl[0][ii-1]==0) { r->LexOrder=TRUE;break;}
3118  if ((block0[0]==1)&&(block1[0]==r->N))
3119  {
3120  r->pFDeg = p_Deg;
3121  r->pLDeg = pLDeg1c_Deg;
3122  }
3123  else
3124  {
3125  r->pFDeg = p_WTotaldegree;
3126  r->LexOrder=TRUE;
3127  r->pLDeg = pLDeg1c_WFirstTotalDegree;
3128  }
3129  r->firstwv = wvhdl[0];
3130  }
3131  /*======== ordering type is (_,c) =========================*/
3132  else if ((order[0]==ringorder_unspec) || (order[1] == 0)
3133  ||(
3134  ((order[1]==ringorder_c)||(order[1]==ringorder_C)
3135  ||(order[1]==ringorder_S)
3136  ||(order[1]==ringorder_s))
3137  && (order[0]!=ringorder_M)
3138  && (order[2]==0))
3139  )
3140  {
3141  if (r->OrdSgn == -1) r->pLDeg = pLDeg0c;
3142  if ((order[0] == ringorder_lp)
3143  || (order[0] == ringorder_ls)
3144  || (order[0] == ringorder_rp)
3145  || (order[0] == ringorder_rs))
3146  {
3147  r->LexOrder=TRUE;
3148  r->pLDeg = pLDeg1c;
3149  r->pFDeg = p_Totaldegree;
3150  }
3151  else if ((order[0] == ringorder_a)
3152  || (order[0] == ringorder_wp)
3153  || (order[0] == ringorder_Wp))
3154  {
3155  r->pFDeg = p_WFirstTotalDegree;
3156  }
3157  else if ((order[0] == ringorder_ws)
3158  || (order[0] == ringorder_Ws))
3159  {
3160  for(int ii=block0[0];ii<=block1[0];ii++)
3161  {
3162  if (wvhdl[0][ii-1]<0) { r->MixedOrder=2;break;}
3163  }
3164  if (r->MixedOrder==0)
3165  {
3166  if ((block0[0]==1)&&(block1[0]==r->N))
3167  r->pFDeg = p_WTotaldegree;
3168  else
3169  r->pFDeg = p_WFirstTotalDegree;
3170  }
3171  else
3172  r->pFDeg = p_Totaldegree;
3173  }
3174  r->firstBlockEnds=block1[0];
3175  r->firstwv = wvhdl[0];
3176  }
3177  /*======== ordering type is (c,_) =========================*/
3178  else if (((order[0]==ringorder_c)
3179  ||(order[0]==ringorder_C)
3180  ||(order[0]==ringorder_S)
3181  ||(order[0]==ringorder_s))
3182  && (order[1]!=ringorder_M)
3183  && (order[2]==0))
3184  {
3185  if ((order[1] == ringorder_lp)
3186  || (order[1] == ringorder_ls)
3187  || (order[1] == ringorder_rp)
3188  || order[1] == ringorder_rs)
3189  {
3190  r->LexOrder=TRUE;
3191  r->pLDeg = pLDeg1c;
3192  r->pFDeg = p_Totaldegree;
3193  }
3194  r->firstBlockEnds=block1[1];
3195  if (wvhdl!=NULL) r->firstwv = wvhdl[1];
3196  if ((order[1] == ringorder_a)
3197  || (order[1] == ringorder_wp)
3198  || (order[1] == ringorder_Wp))
3199  r->pFDeg = p_WFirstTotalDegree;
3200  else if ((order[1] == ringorder_ws)
3201  || (order[1] == ringorder_Ws))
3202  {
3203  for(int ii=block0[1];ii<=block1[1];ii++)
3204  if (wvhdl[1][ii-1]<0) { r->MixedOrder=2;break;}
3205  if (r->MixedOrder==FALSE)
3206  r->pFDeg = p_WFirstTotalDegree;
3207  else
3208  r->pFDeg = p_Totaldegree;
3209  }
3210  }
3211  /*------- more than one block ----------------------*/
3212  else
3213  {
3214  if ((r->VectorOut)||(order[0]==ringorder_C)||(order[0]==ringorder_S)||(order[0]==ringorder_s))
3215  {
3216  rSetFirstWv(r, 1, order, block1, wvhdl);
3217  }
3218  else
3219  rSetFirstWv(r, 0, order, block1, wvhdl);
3220 
3221  if ((order[0]!=ringorder_c)
3222  && (order[0]!=ringorder_C)
3223  && (order[0]!=ringorder_S)
3224  && (order[0]!=ringorder_s))
3225  {
3226  r->pLDeg = pLDeg1c;
3227  }
3228  else
3229  {
3230  r->pLDeg = pLDeg1;
3231  }
3232  r->pFDeg = p_WTotaldegree; // may be improved: p_Totaldegree for lp/dp/ls/.. blocks
3233  }
3234 
3237  {
3238  if(r->MixedOrder==FALSE)
3239  r->pFDeg = p_Deg;
3240  else
3241  r->pFDeg = p_Totaldegree;
3242  }
3243 
3244  if( rGetISPos(0, r) != -1 ) // Are there Schreyer induced blocks?
3245  {
3246 #ifndef SING_NDEBUG
3247  assume( r->pFDeg == p_Deg || r->pFDeg == p_WTotaldegree || r->pFDeg == p_Totaldegree);
3248 #endif
3249 
3250  r->pLDeg = pLDeg1; // ?
3251  }
3252 
3253  r->pFDegOrig = r->pFDeg;
3254  // NOTE: this leads to wrong ecart during std
3255  // in Old/sre.tst
3256  rOptimizeLDeg(r); // also sets r->pLDegOrig
3257 }
3258 
3259 /*2
3260 * set NegWeightL_Size, NegWeightL_Offset
3261 */
3262 static void rSetNegWeight(ring r)
3263 {
3264  int i,l;
3265  if (r->typ!=NULL)
3266  {
3267  l=0;
3268  for(i=0;i<r->OrdSize;i++)
3269  {
3270  if((r->typ[i].ord_typ==ro_wp_neg)
3271  ||(r->typ[i].ord_typ==ro_am))
3272  l++;
3273  }
3274  if (l>0)
3275  {
3276  r->NegWeightL_Size=l;
3277  r->NegWeightL_Offset=(int *) omAlloc(l*sizeof(int));
3278  l=0;
3279  for(i=0;i<r->OrdSize;i++)
3280  {
3281  if(r->typ[i].ord_typ==ro_wp_neg)
3282  {
3283  r->NegWeightL_Offset[l]=r->typ[i].data.wp.place;
3284  l++;
3285  }
3286  else if(r->typ[i].ord_typ==ro_am)
3287  {
3288  r->NegWeightL_Offset[l]=r->typ[i].data.am.place;
3289  l++;
3290  }
3291  }
3292  return;
3293  }
3294  }
3295  r->NegWeightL_Size = 0;
3296  r->NegWeightL_Offset = NULL;
3297 }
3298 
3299 static void rSetOption(ring r)
3300 {
3301  // set redthrough
3302  if (!TEST_OPT_OLDSTD && r->OrdSgn == 1 && ! r->LexOrder)
3303  r->options |= Sy_bit(OPT_REDTHROUGH);
3304  else
3305  r->options &= ~Sy_bit(OPT_REDTHROUGH);
3306 
3307  // set intStrategy
3308  if ( (r->cf->extRing!=NULL)
3309  || rField_is_Q(r)
3310  || rField_is_Ring(r)
3311  )
3312  r->options |= Sy_bit(OPT_INTSTRATEGY);
3313  else
3314  r->options &= ~Sy_bit(OPT_INTSTRATEGY);
3315 
3316  // set redTail
3317  if (r->LexOrder || r->OrdSgn == -1 || (r->cf->extRing!=NULL))
3318  r->options &= ~Sy_bit(OPT_REDTAIL);
3319  else
3320  r->options |= Sy_bit(OPT_REDTAIL);
3321 }
3322 
3323 static void rCheckOrdSgn(ring r,int i/*last block*/);
3324 
3325 /* -------------------------------------------------------- */
3326 /*2
3327 * change all global variables to fit the description of the new ring
3328 */
3329 
3330 void p_SetGlobals(const ring r, BOOLEAN complete)
3331 {
3332 // // // if (r->ppNoether!=NULL) p_Delete(&r->ppNoether,r); // ???
3333 
3334  r->pLexOrder=r->LexOrder;
3335  if (complete)
3336  {
3338  si_opt_1 |= r->options;
3339  }
3340 }
3341 
3342 static inline int sign(int x) { return (x > 0) - (x < 0);}
3344 {
3345  int i;
3346  poly p=p_One(r);
3347  p_SetExp(p,1,1,r);
3348  p_Setm(p,r);
3349  int vz=sign(p_FDeg(p,r));
3350  for(i=2;i<=rVar(r);i++)
3351  {
3352  p_SetExp(p,i-1,0,r);
3353  p_SetExp(p,i,1,r);
3354  p_Setm(p,r);
3355  if (sign(p_FDeg(p,r))!=vz)
3356  {
3357  p_Delete(&p,r);
3358  return TRUE;
3359  }
3360  }
3361  p_Delete(&p,r);
3362  return FALSE;
3363 }
3364 
3365 BOOLEAN rComplete(ring r, int force)
3366 {
3367  if (r->VarOffset!=NULL && force == 0) return FALSE;
3368  rSetOutParams(r);
3369  int n=rBlocks(r)-1;
3370  int i;
3371  int bits;
3372  r->bitmask=rGetExpSize(r->bitmask,bits,r->N);
3373  r->BitsPerExp = bits;
3374  r->ExpPerLong = BIT_SIZEOF_LONG / bits;
3375  r->divmask=rGetDivMask(bits);
3376 
3377  // will be used for ordsgn:
3378  long *tmp_ordsgn=(long *)omAlloc0(3*(n+r->N)*sizeof(long));
3379  // will be used for VarOffset:
3380  int *v=(int *)omAlloc((r->N+1)*sizeof(int));
3381  for(i=r->N; i>=0 ; i--)
3382  {
3383  v[i]=-1;
3384  }
3385  sro_ord *tmp_typ=(sro_ord *)omAlloc0(3*(n+r->N)*sizeof(sro_ord));
3386  int typ_i=0;
3387  int prev_ordsgn=0;
3388 
3389  // fill in v, tmp_typ, tmp_ordsgn, determine typ_i (== ordSize)
3390  int j=0;
3391  int j_bits=BITS_PER_LONG;
3392 
3393  BOOLEAN need_to_add_comp=FALSE; // Only for ringorder_s and ringorder_S!
3394 
3395  for(i=0;i<n;i++)
3396  {
3397  tmp_typ[typ_i].order_index=i;
3398  switch (r->order[i])
3399  {
3400  case ringorder_a:
3401  case ringorder_aa:
3402  rO_WDegree(j,j_bits,r->block0[i],r->block1[i],tmp_ordsgn,tmp_typ[typ_i],
3403  r->wvhdl[i]);
3404  typ_i++;
3405  break;
3406 
3407  case ringorder_am:
3408  rO_WMDegree(j,j_bits,r->block0[i],r->block1[i],tmp_ordsgn,tmp_typ[typ_i],
3409  r->wvhdl[i]);
3410  typ_i++;
3411  break;
3412 
3413  case ringorder_a64:
3414  rO_WDegree64(j,j_bits,r->block0[i],r->block1[i],tmp_ordsgn,
3415  tmp_typ[typ_i], (int64 *)(r->wvhdl[i]));
3416  typ_i++;
3417  break;
3418 
3419  case ringorder_c:
3420  rO_Align(j, j_bits);
3421  rO_LexVars_neg(j, j_bits, 0,0, prev_ordsgn,tmp_ordsgn,v,BITS_PER_LONG, -1);
3422  r->ComponentOrder=1;
3423  break;
3424 
3425  case ringorder_C:
3426  rO_Align(j, j_bits);
3427  rO_LexVars(j, j_bits, 0,0, prev_ordsgn,tmp_ordsgn,v,BITS_PER_LONG, -1);
3428  r->ComponentOrder=-1;
3429  break;
3430 
3431  case ringorder_M:
3432  {
3433  int k,l;
3434  k=r->block1[i]-r->block0[i]+1; // number of vars
3435  for(l=0;l<k;l++)
3436  {
3437  rO_WDegree(j,j_bits,r->block0[i],r->block1[i],tmp_ordsgn,
3438  tmp_typ[typ_i],
3439  r->wvhdl[i]+(r->block1[i]-r->block0[i]+1)*l);
3440  typ_i++;
3441  }
3442  break;
3443  }
3444 
3445  case ringorder_lp:
3446  rO_LexVars(j, j_bits, r->block0[i],r->block1[i], prev_ordsgn,
3447  tmp_ordsgn,v,bits, -1);
3448  break;
3449 
3450  case ringorder_ls:
3451  rO_LexVars_neg(j, j_bits, r->block0[i],r->block1[i], prev_ordsgn,
3452  tmp_ordsgn,v, bits, -1);
3453  break;
3454 
3455  case ringorder_rs:
3456  rO_LexVars_neg(j, j_bits, r->block1[i],r->block0[i], prev_ordsgn,
3457  tmp_ordsgn,v, bits, -1);
3458  break;
3459 
3460  case ringorder_rp:
3461  rO_LexVars(j, j_bits, r->block1[i],r->block0[i], prev_ordsgn,
3462  tmp_ordsgn,v, bits, -1);
3463  break;
3464 
3465  case ringorder_dp:
3466  if (r->block0[i]==r->block1[i])
3467  {
3468  rO_LexVars(j, j_bits, r->block0[i],r->block0[i], prev_ordsgn,
3469  tmp_ordsgn,v, bits, -1);
3470  }
3471  else
3472  {
3473  rO_TDegree(j,j_bits,r->block0[i],r->block1[i],tmp_ordsgn,
3474  tmp_typ[typ_i]);
3475  typ_i++;
3476  rO_LexVars_neg(j, j_bits, r->block1[i],r->block0[i]+1,
3477  prev_ordsgn,tmp_ordsgn,v,bits, r->block0[i]);
3478  }
3479  break;
3480 
3481  case ringorder_Dp:
3482  if (r->block0[i]==r->block1[i])
3483  {
3484  rO_LexVars(j, j_bits, r->block0[i],r->block0[i], prev_ordsgn,
3485  tmp_ordsgn,v, bits, -1);
3486  }
3487  else
3488  {
3489  rO_TDegree(j,j_bits,r->block0[i],r->block1[i],tmp_ordsgn,
3490  tmp_typ[typ_i]);
3491  typ_i++;
3492  rO_LexVars(j, j_bits, r->block0[i],r->block1[i]-1, prev_ordsgn,
3493  tmp_ordsgn,v, bits, r->block1[i]);
3494  }
3495  break;
3496 
3497  case ringorder_ds:
3498  if (r->block0[i]==r->block1[i])
3499  {
3500  rO_LexVars_neg(j, j_bits,r->block0[i],r->block1[i],prev_ordsgn,
3501  tmp_ordsgn,v,bits, -1);
3502  }
3503  else
3504  {
3505  rO_TDegree_neg(j,j_bits,r->block0[i],r->block1[i],tmp_ordsgn,
3506  tmp_typ[typ_i]);
3507  typ_i++;
3508  rO_LexVars_neg(j, j_bits, r->block1[i],r->block0[i]+1,
3509  prev_ordsgn,tmp_ordsgn,v,bits, r->block0[i]);
3510  }
3511  break;
3512 
3513  case ringorder_Ds:
3514  if (r->block0[i]==r->block1[i])
3515  {
3516  rO_LexVars_neg(j, j_bits, r->block0[i],r->block0[i],prev_ordsgn,
3517  tmp_ordsgn,v, bits, -1);
3518  }
3519  else
3520  {
3521  rO_TDegree_neg(j,j_bits,r->block0[i],r->block1[i],tmp_ordsgn,
3522  tmp_typ[typ_i]);
3523  typ_i++;
3524  rO_LexVars(j, j_bits, r->block0[i],r->block1[i]-1, prev_ordsgn,
3525  tmp_ordsgn,v, bits, r->block1[i]);
3526  }
3527  break;
3528 
3529  case ringorder_wp:
3530  rO_WDegree(j,j_bits,r->block0[i],r->block1[i],tmp_ordsgn,
3531  tmp_typ[typ_i], r->wvhdl[i]);
3532  typ_i++;
3533  { // check for weights <=0
3534  int jj;
3535  BOOLEAN have_bad_weights=FALSE;
3536  for(jj=r->block1[i]-r->block0[i];jj>=0; jj--)
3537  {
3538  if (r->wvhdl[i][jj]<=0) have_bad_weights=TRUE;
3539  }
3540  if (have_bad_weights)
3541  {
3542  rO_TDegree(j,j_bits,r->block0[i],r->block1[i],tmp_ordsgn,
3543  tmp_typ[typ_i]);
3544  typ_i++;
3545  }
3546  }
3547  if (r->block1[i]!=r->block0[i])
3548  {
3549  rO_LexVars_neg(j, j_bits,r->block1[i],r->block0[i]+1, prev_ordsgn,
3550  tmp_ordsgn, v,bits, r->block0[i]);
3551  }
3552  break;
3553 
3554  case ringorder_Wp:
3555  rO_WDegree(j,j_bits,r->block0[i],r->block1[i],tmp_ordsgn,
3556  tmp_typ[typ_i], r->wvhdl[i]);
3557  typ_i++;
3558  { // check for weights <=0
3559  int jj;
3560  BOOLEAN have_bad_weights=FALSE;
3561  for(jj=r->block1[i]-r->block0[i];jj>=0; jj--)
3562  {
3563  if (r->wvhdl[i][jj]<=0) have_bad_weights=TRUE;
3564  }
3565  if (have_bad_weights)
3566  {
3567  rO_TDegree(j,j_bits,r->block0[i],r->block1[i],tmp_ordsgn,
3568  tmp_typ[typ_i]);
3569  typ_i++;
3570  }
3571  }
3572  if (r->block1[i]!=r->block0[i])
3573  {
3574  rO_LexVars(j, j_bits,r->block0[i],r->block1[i]-1, prev_ordsgn,
3575  tmp_ordsgn,v, bits, r->block1[i]);
3576  }
3577  break;
3578 
3579  case ringorder_ws:
3580  rO_WDegree_neg(j,j_bits,r->block0[i],r->block1[i],tmp_ordsgn,
3581  tmp_typ[typ_i], r->wvhdl[i]);
3582  typ_i++;
3583  if (r->block1[i]!=r->block0[i])
3584  {
3585  rO_LexVars_neg(j, j_bits,r->block1[i],r->block0[i]+1, prev_ordsgn,
3586  tmp_ordsgn, v,bits, r->block0[i]);
3587  }
3588  break;
3589 
3590  case ringorder_Ws:
3591  rO_WDegree_neg(j,j_bits,r->block0[i],r->block1[i],tmp_ordsgn,
3592  tmp_typ[typ_i], r->wvhdl[i]);
3593  typ_i++;
3594  if (r->block1[i]!=r->block0[i])
3595  {
3596  rO_LexVars(j, j_bits,r->block0[i],r->block1[i]-1, prev_ordsgn,
3597  tmp_ordsgn,v, bits, r->block1[i]);
3598  }
3599  break;
3600 
3601  case ringorder_S:
3602  assume(typ_i == 1); // For LaScala3 only: on the 2nd place ([1])!
3603  // TODO: for K[x]: it is 0...?!
3604  rO_Syzcomp(j, j_bits,prev_ordsgn, tmp_ordsgn,tmp_typ[typ_i]);
3605  need_to_add_comp=TRUE;
3606  r->ComponentOrder=-1;
3607  typ_i++;
3608  break;
3609 
3610  case ringorder_s:
3611  assume(typ_i == 0 && j == 0);
3612  rO_Syz(j, j_bits, prev_ordsgn, r->block0[i], tmp_ordsgn, tmp_typ[typ_i]); // set syz-limit?
3613  need_to_add_comp=TRUE;
3614  r->ComponentOrder=-1;
3615  typ_i++;
3616  break;
3617 
3618  case ringorder_IS:
3619  {
3620 
3621  assume( r->block0[i] == r->block1[i] );
3622  const int s = r->block0[i];
3623  assume( -2 < s && s < 2);
3624 
3625  if(s == 0) // Prefix IS
3626  rO_ISPrefix(j, j_bits, prev_ordsgn, tmp_ordsgn, r->N, v, tmp_typ[typ_i++]); // What about prev_ordsgn?
3627  else // s = +1 or -1 // Note: typ_i might be incrimented here inside!
3628  {
3629  rO_ISSuffix(j, j_bits, prev_ordsgn, tmp_ordsgn, r->N, v, tmp_typ, typ_i, s); // Suffix.
3630  need_to_add_comp=FALSE;
3631  }
3632 
3633  break;
3634  }
3635  case ringorder_unspec:
3636  case ringorder_no:
3637  default:
3638  dReportError("undef. ringorder used\n");
3639  break;
3640  }
3641  }
3642  rCheckOrdSgn(r,n-1);
3643 
3644  int j0=j; // save j
3645  int j_bits0=j_bits; // save jbits
3646  rO_Align(j,j_bits);
3647  r->CmpL_Size = j;
3648 
3649  j_bits=j_bits0; j=j0;
3650 
3651  // fill in some empty slots with variables not already covered
3652  // v0 is special, is therefore normally already covered
3653  // now we do have rings without comp...
3654  if((need_to_add_comp) && (v[0]== -1))
3655  {
3656  if (prev_ordsgn==1)
3657  {
3658  rO_Align(j, j_bits);
3659  rO_LexVars(j, j_bits, 0,0, prev_ordsgn,tmp_ordsgn,v,BITS_PER_LONG, -1);
3660  }
3661  else
3662  {
3663  rO_Align(j, j_bits);
3664  rO_LexVars_neg(j, j_bits, 0,0, prev_ordsgn,tmp_ordsgn,v,BITS_PER_LONG, -1);
3665  }
3666  }
3667  // the variables
3668  for(i=1 ; i<=r->N ; i++)
3669  {
3670  if(v[i]==(-1))
3671  {
3672  if (prev_ordsgn==1)
3673  {
3674  rO_LexVars(j, j_bits, i,i, prev_ordsgn,tmp_ordsgn,v,bits, -1);
3675  }
3676  else
3677  {
3678  rO_LexVars_neg(j,j_bits,i,i, prev_ordsgn,tmp_ordsgn,v,bits, -1);
3679  }
3680  }
3681  }
3682 
3683  rO_Align(j,j_bits);
3684  // ----------------------------
3685  // finished with constructing the monomial, computing sizes:
3686 
3687  r->ExpL_Size=j;
3688  r->PolyBin = omGetSpecBin(POLYSIZE + (r->ExpL_Size)*sizeof(long));
3689  assume(r->PolyBin != NULL);
3690 
3691  // ----------------------------
3692  // indices and ordsgn vector for comparison
3693  //
3694  // r->pCompHighIndex already set
3695  r->ordsgn=(long *)omAlloc0(r->ExpL_Size*sizeof(long));
3696 
3697  for(j=0;j<r->CmpL_Size;j++)
3698  {
3699  r->ordsgn[j] = tmp_ordsgn[j];
3700  }
3701 
3702  omFreeSize((ADDRESS)tmp_ordsgn,(3*(n+r->N)*sizeof(long)));
3703 
3704  // ----------------------------
3705  // description of orderings for setm:
3706  //
3707  r->OrdSize=typ_i;
3708  if (typ_i==0) r->typ=NULL;
3709  else
3710  {
3711  r->typ=(sro_ord*)omAlloc(typ_i*sizeof(sro_ord));
3712  memcpy(r->typ,tmp_typ,typ_i*sizeof(sro_ord));
3713  }
3714  omFreeSize((ADDRESS)tmp_typ,(3*(n+r->N)*sizeof(sro_ord)));
3715 
3716  // ----------------------------
3717  // indices for (first copy of ) variable entries in exp.e vector (VarOffset):
3718  r->VarOffset=v;
3719 
3720  // ----------------------------
3721  // other indicies
3722  r->pCompIndex=(r->VarOffset[0] & 0xffff); //r->VarOffset[0];
3723  i=0; // position
3724  j=0; // index in r->typ
3725  if (i==r->pCompIndex) i++; // IS???
3726  while ((j < r->OrdSize)
3727  && ((r->typ[j].ord_typ==ro_syzcomp) ||
3728  (r->typ[j].ord_typ==ro_syz) || (r->typ[j].ord_typ==ro_isTemp) || (r->typ[j].ord_typ==ro_is) ||
3729  (r->order[r->typ[j].order_index] == ringorder_aa)))
3730  {
3731  i++; j++;
3732  }
3733 
3734  if (i==r->pCompIndex) i++;
3735  r->pOrdIndex=i;
3736 
3737  // ----------------------------
3738  rSetDegStuff(r); // OrdSgn etc already set
3739  rSetOption(r);
3740  // ----------------------------
3741  // r->p_Setm
3742  r->p_Setm = p_GetSetmProc(r);
3743 
3744  // ----------------------------
3745  // set VarL_*
3746  rSetVarL(r);
3747 
3748  // ----------------------------
3749  // right-adjust VarOffset
3751 
3752  // ----------------------------
3753  // set NegWeightL*
3754  rSetNegWeight(r);
3755 
3756  // ----------------------------
3757  // p_Procs: call AFTER NegWeightL
3758  r->p_Procs = (p_Procs_s*)omAlloc(sizeof(p_Procs_s));
3759  p_ProcsSet(r, r->p_Procs);
3760 
3761  // use totaldegree on crazy oderings:
3762  if ((r->pFDeg==p_WTotaldegree) && rOrd_is_MixedDegree_Ordering(r))
3763  r->pFDeg = p_Totaldegree;
3764  return FALSE;
3765 }
3766 
3767 static void rCheckOrdSgn(ring r,int b/*last block*/)
3768 { // set r->OrdSgn, r->MixedOrder
3769  // for each variable:
3770  int nonpos=0;
3771  int nonneg=0;
3772  for(int i=1;i<=r->N;i++)
3773  {
3774  int found=0;
3775  // for all blocks:
3776  for(int j=0;(j<=b) && (found==0);j++)
3777  {
3778  // search the first block containing var(i)
3779  if ((r->block0[j]<=i)&&(r->block1[j]>=i))
3780  {
3781  // what kind if block is it?
3782  if ((r->order[j]==ringorder_ls)
3783  || (r->order[j]==ringorder_ds)
3784  || (r->order[j]==ringorder_Ds)
3785  || (r->order[j]==ringorder_ws)
3786  || (r->order[j]==ringorder_Ws)
3787  || (r->order[j]==ringorder_rs))
3788  {
3789  r->OrdSgn=-1;
3790  nonpos++;
3791  found=1;
3792  }
3793  else if((r->order[j]==ringorder_a)
3794  ||(r->order[j]==ringorder_aa))
3795  {
3796  // <0: local/mixed ordering
3797  // >0: var(i) is okay, look at other vars
3798  // ==0: look at other blocks for var(i)
3799  if(r->wvhdl[j][i-r->block0[j]]<0)
3800  {
3801  r->OrdSgn=-1;
3802  nonpos++;
3803  found=1;
3804  }
3805  else if(r->wvhdl[j][i-r->block0[j]]>0)
3806  {
3807  nonneg++;
3808  found=1;
3809  }
3810  }
3811  else if(r->order[j]==ringorder_M)
3812  {
3813  // <0: local/mixed ordering
3814  // >0: var(i) is okay, look at other vars
3815  // ==0: look at other blocks for var(i)
3816  if(r->wvhdl[j][i-r->block0[j]]<0)
3817  {
3818  r->OrdSgn=-1;
3819  nonpos++;
3820  found=1;
3821  }
3822  else if(r->wvhdl[j][i-r->block0[j]]>0)
3823  {
3824  nonneg++;
3825  found=1;
3826  }
3827  else
3828  {
3829  // very bad:
3830  nonpos++;
3831  nonneg++;
3832  found=1;
3833  }
3834  }
3835  else if ((r->order[j]==ringorder_lp)
3836  || (r->order[j]==ringorder_dp)
3837  || (r->order[j]==ringorder_Dp)
3838  || (r->order[j]==ringorder_wp)
3839  || (r->order[j]==ringorder_Wp)
3840  || (r->order[j]==ringorder_rp))
3841  {
3842  found=1;
3843  nonneg++;
3844  }
3845  }
3846  }
3847  }
3848  if (nonpos>0)
3849  {
3850  r->OrdSgn=-1;
3851  if (nonneg>0) r->MixedOrder=1;
3852  }
3853  else
3854  {
3855  r->OrdSgn=1;
3856  r->MixedOrder=0;
3857  }
3858 }
3859 
3860 void rUnComplete(ring r)
3861 {
3862  if (r == NULL) return;
3863  if (r->VarOffset != NULL)
3864  {
3865  if (r->OrdSize!=0 && r->typ != NULL)
3866  {
3867  for(int i = 0; i < r->OrdSize; i++)
3868  if( r->typ[i].ord_typ == ro_is) // Search for suffixes! (prefix have the same VarOffset)
3869  {
3870  id_Delete(&r->typ[i].data.is.F, r);
3871  r->typ[i].data.is.F = NULL; // ?
3872 
3873  if( r->typ[i].data.is.pVarOffset != NULL )
3874  {
3875  omFreeSize((ADDRESS)r->typ[i].data.is.pVarOffset, (r->N +1)*sizeof(int));
3876  r->typ[i].data.is.pVarOffset = NULL; // ?
3877  }
3878  }
3879  else if (r->typ[i].ord_typ == ro_syz)
3880  {
3881  if(r->typ[i].data.syz.limit > 0)
3882  omFreeSize(r->typ[i].data.syz.syz_index, ((r->typ[i].data.syz.limit) +1)*sizeof(int));
3883  r->typ[i].data.syz.syz_index = NULL;
3884  }
3885  else if (r->typ[i].ord_typ == ro_syzcomp)
3886  {
3887  assume( r->typ[i].data.syzcomp.ShiftedComponents == NULL );
3888  assume( r->typ[i].data.syzcomp.Components == NULL );
3889 // WarnS( "rUnComplete : ord_typ == ro_syzcomp was unhandled!!! Possibly memory leak!!!" );
3890 #ifndef SING_NDEBUG
3891 // assume(0);
3892 #endif
3893  }
3894 
3895  omFreeSize((ADDRESS)r->typ,r->OrdSize*sizeof(sro_ord)); r->typ = NULL;
3896  }
3897 
3898  if (r->PolyBin != NULL)
3899  omUnGetSpecBin(&(r->PolyBin));
3900 
3901  omFreeSize((ADDRESS)r->VarOffset, (r->N +1)*sizeof(int));
3902 
3903  if (r->ordsgn != NULL && r->CmpL_Size != 0)
3904  omFreeSize((ADDRESS)r->ordsgn,r->ExpL_Size*sizeof(long));
3905  if (r->p_Procs != NULL)
3906  omFreeSize(r->p_Procs, sizeof(p_Procs_s));
3907  omfreeSize(r->VarL_Offset, r->VarL_Size*sizeof(int));
3908  }
3909  if (r->NegWeightL_Offset!=NULL)
3910  {
3911  omFreeSize(r->NegWeightL_Offset, r->NegWeightL_Size*sizeof(int));
3912  r->NegWeightL_Offset=NULL;
3913  }
3914 }
3915 
3916 // set r->VarL_Size, r->VarL_Offset, r->VarL_LowIndex
3917 static void rSetVarL(ring r)
3918 {
3919  int min = MAX_INT_VAL, min_j = -1;
3920  int* VarL_Number = (int*) omAlloc0(r->ExpL_Size*sizeof(int));
3921 
3922  int i,j;
3923 
3924  // count how often a var long is occupied by an exponent
3925  for (i=1; i<=r->N; i++)
3926  {
3927  VarL_Number[r->VarOffset[i] & 0xffffff]++;
3928  }
3929 
3930  // determine how many and min
3931  for (i=0, j=0; i<r->ExpL_Size; i++)
3932  {
3933  if (VarL_Number[i] != 0)
3934  {
3935  if (min > VarL_Number[i])
3936  {
3937  min = VarL_Number[i];
3938  min_j = j;
3939  }
3940  j++;
3941  }
3942  }
3943 
3944  r->VarL_Size = j; // number of long with exp. entries in
3945  // in p->exp
3946  r->VarL_Offset = (int*) omAlloc(r->VarL_Size*sizeof(int));
3947  r->VarL_LowIndex = 0;
3948 
3949  // set VarL_Offset
3950  for (i=0, j=0; i<r->ExpL_Size; i++)
3951  {
3952  if (VarL_Number[i] != 0)
3953  {
3954  r->VarL_Offset[j] = i;
3955  if (j > 0 && r->VarL_Offset[j-1] != r->VarL_Offset[j] - 1)
3956  r->VarL_LowIndex = -1;
3957  j++;
3958  }
3959  }
3960  if (r->VarL_LowIndex >= 0)
3961  r->VarL_LowIndex = r->VarL_Offset[0];
3962 
3963  if (min_j != 0)
3964  {
3965  j = r->VarL_Offset[min_j];
3966  r->VarL_Offset[min_j] = r->VarL_Offset[0];
3967  r->VarL_Offset[0] = j;
3968  }
3969  omFree(VarL_Number);
3970 }
3971 
3972 static void rRightAdjustVarOffset(ring r)
3973 {
3974  int* shifts = (int*) omAlloc(r->ExpL_Size*sizeof(int));
3975  int i;
3976  // initialize shifts
3977  for (i=0;i<r->ExpL_Size;i++)
3978  shifts[i] = BIT_SIZEOF_LONG;
3979 
3980  // find minimal bit shift in each long exp entry
3981  for (i=1;i<=r->N;i++)
3982  {
3983  if (shifts[r->VarOffset[i] & 0xffffff] > r->VarOffset[i] >> 24)
3984  shifts[r->VarOffset[i] & 0xffffff] = r->VarOffset[i] >> 24;
3985  }
3986  // reset r->VarOffset: set the minimal shift to 0
3987  for (i=1;i<=r->N;i++)
3988  {
3989  if (shifts[r->VarOffset[i] & 0xffffff] != 0)
3990  r->VarOffset[i]
3991  = (r->VarOffset[i] & 0xffffff) |
3992  (((r->VarOffset[i] >> 24) - shifts[r->VarOffset[i] & 0xffffff]) << 24);
3993  }
3994  omFree(shifts);
3995 }
3996 
3997 // get r->divmask depending on bits per exponent
3998 static unsigned long rGetDivMask(int bits)
3999 {
4000  unsigned long divmask = 1;
4001  int i = bits;
4002 
4003  while (i < BIT_SIZEOF_LONG)
4004  {
4005  divmask |= (((unsigned long) 1) << (unsigned long) i);
4006  i += bits;
4007  }
4008  return divmask;
4009 }
4010 
4011 #ifdef RDEBUG
4012 void rDebugPrint(const ring r)
4013 {
4014  if (r==NULL)
4015  {
4016  PrintS("NULL ?\n");
4017  return;
4018  }
4019  // corresponds to ro_typ from ring.h:
4020  const char *TYP[]={"ro_dp","ro_wp","ro_am","ro_wp64","ro_wp_neg","ro_cp",
4021  "ro_syzcomp", "ro_syz", "ro_isTemp", "ro_is", "ro_none"};
4022  int i,j;
4023 
4024  Print("ExpL_Size:%d ",r->ExpL_Size);
4025  Print("CmpL_Size:%d ",r->CmpL_Size);
4026  Print("VarL_Size:%d\n",r->VarL_Size);
4027  Print("bitmask=0x%lx (expbound=%ld) \n",r->bitmask, r->bitmask);
4028  Print("divmask=%lx\n", r->divmask);
4029  Print("BitsPerExp=%d ExpPerLong=%d at L[%d]\n", r->BitsPerExp, r->ExpPerLong, r->VarL_Offset[0]);
4030 
4031  Print("VarL_LowIndex: %d\n", r->VarL_LowIndex);
4032  PrintS("VarL_Offset:\n");
4033  if (r->VarL_Offset==NULL) PrintS(" NULL");
4034  else
4035  for(j = 0; j < r->VarL_Size; j++)
4036  Print(" VarL_Offset[%d]: %d ", j, r->VarL_Offset[j]);
4037  PrintLn();
4038 
4039 
4040  PrintS("VarOffset:\n");
4041  if (r->VarOffset==NULL) PrintS(" NULL\n");
4042  else
4043  for(j=0;j<=r->N;j++)
4044  Print(" v%d at e-pos %d, bit %d\n",
4045  j,r->VarOffset[j] & 0xffffff, r->VarOffset[j] >>24);
4046  PrintS("ordsgn:\n");
4047  for(j=0;j<r->CmpL_Size;j++)
4048  Print(" ordsgn %ld at pos %d\n",r->ordsgn[j],j);
4049  Print("OrdSgn:%d\n",r->OrdSgn);
4050  PrintS("ordrec:\n");
4051  for(j=0;j<r->OrdSize;j++)
4052  {
4053  Print(" typ %s", TYP[r->typ[j].ord_typ]);
4054  if (r->typ[j].ord_typ==ro_syz)
4055  {
4056  const short place = r->typ[j].data.syz.place;
4057  const int limit = r->typ[j].data.syz.limit;
4058  const int curr_index = r->typ[j].data.syz.curr_index;
4059  const int* syz_index = r->typ[j].data.syz.syz_index;
4060 
4061  Print(" limit %d (place: %d, curr_index: %d), syz_index: ", limit, place, curr_index);
4062 
4063  if( syz_index == NULL )
4064  PrintS("(NULL)");
4065  else
4066  {
4067  PrintS("{");
4068  for( i=0; i <= limit; i++ )
4069  Print("%d ", syz_index[i]);
4070  PrintS("}");
4071  }
4072 
4073  }
4074  else if (r->typ[j].ord_typ==ro_isTemp)
4075  {
4076  Print(" start (level) %d, suffixpos: %d, VO: ",r->typ[j].data.isTemp.start, r->typ[j].data.isTemp.suffixpos);
4077 
4078  }
4079  else if (r->typ[j].ord_typ==ro_is)
4080  {
4081  Print(" start %d, end: %d: ",r->typ[j].data.is.start, r->typ[j].data.is.end);
4082 
4083 // for( int k = 0; k <= r->N; k++) if (r->typ[j].data.is.pVarOffset[k] != -1) Print("[%2d]: %04x; ", k, r->typ[j].data.is.pVarOffset[k]);
4084 
4085  Print(" limit %d",r->typ[j].data.is.limit);
4086 #ifndef SING_NDEBUG
4087  //PrintS(" F: ");idShow(r->typ[j].data.is.F, r, r, 1);
4088 #endif
4089 
4090  PrintLn();
4091  }
4092  else if (r->typ[j].ord_typ==ro_am)
4093  {
4094  Print(" place %d",r->typ[j].data.am.place);
4095  Print(" start %d",r->typ[j].data.am.start);
4096  Print(" end %d",r->typ[j].data.am.end);
4097  Print(" len_gen %d",r->typ[j].data.am.len_gen);
4098  PrintS(" w:");
4099  int l=0;
4100  for(l=r->typ[j].data.am.start;l<=r->typ[j].data.am.end;l++)
4101  Print(" %d",r->typ[j].data.am.weights[l-r->typ[j].data.am.start]);
4102  l=r->typ[j].data.am.end+1;
4103  int ll=r->typ[j].data.am.weights[l-r->typ[j].data.am.start];
4104  PrintS(" m:");
4105  for(int lll=l+1;lll<l+ll+1;lll++)
4106  Print(" %d",r->typ[j].data.am.weights[lll-r->typ[j].data.am.start]);
4107  }
4108  else
4109  {
4110  Print(" place %d",r->typ[j].data.dp.place);
4111 
4112  if (r->typ[j].ord_typ!=ro_syzcomp && r->typ[j].ord_typ!=ro_syz)
4113  {
4114  Print(" start %d",r->typ[j].data.dp.start);
4115  Print(" end %d",r->typ[j].data.dp.end);
4116  if ((r->typ[j].ord_typ==ro_wp)
4117  || (r->typ[j].ord_typ==ro_wp_neg))
4118  {
4119  PrintS(" w:");
4120  for(int l=r->typ[j].data.wp.start;l<=r->typ[j].data.wp.end;l++)
4121  Print(" %d",r->typ[j].data.wp.weights[l-r->typ[j].data.wp.start]);
4122  }
4123  else if (r->typ[j].ord_typ==ro_wp64)
4124  {
4125  PrintS(" w64:");
4126  int l;
4127  for(l=r->typ[j].data.wp64.start;l<=r->typ[j].data.wp64.end;l++)
4128  Print(" %ld",(long)(((int64*)r->typ[j].data.wp64.weights64)+l-r->typ[j].data.wp64.start));
4129  }
4130  }
4131  }
4132  PrintLn();
4133  }
4134  Print("pOrdIndex:%d pCompIndex:%d\n", r->pOrdIndex, r->pCompIndex);
4135  Print("OrdSize:%d\n",r->OrdSize);
4136  PrintS("--------------------\n");
4137  for(j=0;j<r->ExpL_Size;j++)
4138  {
4139  Print("L[%d]: ",j);
4140  if (j< r->CmpL_Size)
4141  Print("ordsgn %ld ", r->ordsgn[j]);
4142  else
4143  PrintS("no comp ");
4144  i=1;
4145  for(;i<=r->N;i++)
4146  {
4147  if( (r->VarOffset[i] & 0xffffff) == j )
4148  { Print("v%d at e[%d], bit %d; ", i,r->VarOffset[i] & 0xffffff,
4149  r->VarOffset[i] >>24 ); }
4150  }
4151  if( r->pCompIndex==j ) PrintS("v0; ");
4152  for(i=0;i<r->OrdSize;i++)
4153  {
4154  if (r->typ[i].data.dp.place == j)
4155  {
4156  Print("ordrec:%s (start:%d, end:%d) ",TYP[r->typ[i].ord_typ],
4157  r->typ[i].data.dp.start, r->typ[i].data.dp.end);
4158  }
4159  }
4160 
4161  if (j==r->pOrdIndex)
4162  PrintS("pOrdIndex\n");
4163  else
4164  PrintLn();
4165  }
4166  Print("LexOrder:%d, MixedOrder:%d\n",r->LexOrder, r->MixedOrder);
4167 
4168  Print("NegWeightL_Size: %d, NegWeightL_Offset: ", r->NegWeightL_Size);
4169  if (r->NegWeightL_Offset==NULL) PrintS(" NULL");
4170  else
4171  for(j = 0; j < r->NegWeightL_Size; j++)
4172  Print(" [%d]: %d ", j, r->NegWeightL_Offset[j]);
4173  PrintLn();
4174 
4175  // p_Procs stuff
4176  p_Procs_s proc_names;
4177  const char* field;
4178  const char* length;
4179  const char* ord;
4180  p_Debug_GetProcNames(r, &proc_names); // changes p_Procs!!!
4181  p_Debug_GetSpecNames(r, field, length, ord);
4182 
4183  Print("p_Spec : %s, %s, %s\n", field, length, ord);
4184  PrintS("p_Procs :\n");
4185  for (i=0; i<(int) (sizeof(p_Procs_s)/sizeof(void*)); i++)
4186  {
4187  Print(" %s,\n", ((char**) &proc_names)[i]);
4188  }
4189 
4190  {
4191  PrintLn();
4192  PrintS("pFDeg : ");
4193 #define pFDeg_CASE(A) if(r->pFDeg == A) PrintS( "" #A "" )
4194  pFDeg_CASE(p_Totaldegree); else
4196  pFDeg_CASE(p_WTotaldegree); else
4197  pFDeg_CASE(p_Deg); else
4198 #undef pFDeg_CASE
4199  Print("(%p)", r->pFDeg); // default case
4200 
4201  PrintLn();
4202  Print("pLDeg : (%p)", r->pLDeg);
4203  PrintLn();
4204  }
4205  PrintS("pSetm:");
4206  void p_Setm_Dummy(poly p, const ring r);
4207  void p_Setm_TotalDegree(poly p, const ring r);
4208  void p_Setm_WFirstTotalDegree(poly p, const ring r);
4209  void p_Setm_General(poly p, const ring r);
4210  if (r->p_Setm==p_Setm_General) PrintS("p_Setm_General\n");
4211  else if (r->p_Setm==p_Setm_Dummy) PrintS("p_Setm_Dummy\n");
4212  else if (r->p_Setm==p_Setm_TotalDegree) PrintS("p_Setm_Totaldegree\n");
4213  else if (r->p_Setm==p_Setm_WFirstTotalDegree) PrintS("p_Setm_WFirstTotalDegree\n");
4214  else Print("%p\n",r->p_Setm);
4215 }
4216 
4217 void p_DebugPrint(poly p, const ring r)
4218 {
4219  int i,j;
4220  p_Write(p,r);
4221  j=2;
4222  while(p!=NULL)
4223  {
4224  Print("\nexp[0..%d]\n",r->ExpL_Size-1);
4225  for(i=0;i<r->ExpL_Size;i++)
4226  Print("%ld ",p->exp[i]);
4227  PrintLn();
4228  Print("v0:%ld ",p_GetComp(p, r));
4229  for(i=1;i<=r->N;i++) Print(" v%d:%ld",i,p_GetExp(p,i, r));
4230  PrintLn();
4231  pIter(p);
4232  j--;
4233  if (j==0) { PrintS("...\n"); break; }
4234  }
4235 }
4236 
4237 #endif // RDEBUG
4238 
4239 /// debug-print monomial poly/vector p, assuming that it lives in the ring R
4240 static inline void m_DebugPrint(const poly p, const ring R)
4241 {
4242  Print("\nexp[0..%d]\n", R->ExpL_Size - 1);
4243  for(int i = 0; i < R->ExpL_Size; i++)
4244  Print("%09lx ", p->exp[i]);
4245  PrintLn();
4246  Print("v0:%9ld ", p_GetComp(p, R));
4247  for(int i = 1; i <= R->N; i++) Print(" v%d:%5ld",i, p_GetExp(p, i, R));
4248  PrintLn();
4249 }
4250 
4251 
4252 // F = system("ISUpdateComponents", F, V, MIN );
4253 // // replace gen(i) -> gen(MIN + V[i-MIN]) for all i > MIN in all terms from F!
4254 void pISUpdateComponents(ideal F, const intvec *const V, const int MIN, const ring r )
4255 {
4256  assume( V != NULL );
4257  assume( MIN >= 0 );
4258 
4259  if( F == NULL )
4260  return;
4261 
4262  for( int j = (F->ncols*F->nrows) - 1; j >= 0; j-- )
4263  {
4264 #ifdef PDEBUG
4265  Print("F[%d]:", j);
4266  p_wrp(F->m[j], r);
4267 #endif
4268 
4269  for( poly p = F->m[j]; p != NULL; pIter(p) )
4270  {
4271  int c = p_GetComp(p, r);
4272 
4273  if( c > MIN )
4274  {
4275 #ifdef PDEBUG
4276  Print("gen[%d] -> gen(%d)\n", c, MIN + (*V)[ c - MIN - 1 ]);
4277 #endif
4278 
4279  p_SetComp( p, MIN + (*V)[ c - MIN - 1 ], r );
4280  }
4281  }
4282 #ifdef PDEBUG
4283  Print("new F[%d]:", j);
4284  p_Test(F->m[j], r);
4285  p_wrp(F->m[j], r);
4286 #endif
4287  }
4288 }
4289 
4290 /*2
4291 * asssume that rComplete was called with r
4292 * assume that the first block ist ringorder_S
4293 * change the block to reflect the sequence given by appending v
4294 */
4295 static inline void rNChangeSComps(int* currComponents, long* currShiftedComponents, ring r)
4296 {
4297  assume(r->typ[1].ord_typ == ro_syzcomp);
4298 
4299  r->typ[1].data.syzcomp.ShiftedComponents = currShiftedComponents;
4300  r->typ[1].data.syzcomp.Components = currComponents;
4301 }
4302 
4303 static inline void rNGetSComps(int** currComponents, long** currShiftedComponents, ring r)
4304 {
4305  assume(r->typ[1].ord_typ == ro_syzcomp);
4306 
4307  *currShiftedComponents = r->typ[1].data.syzcomp.ShiftedComponents;
4308  *currComponents = r->typ[1].data.syzcomp.Components;
4309 }
4310 #ifdef PDEBUG
4311 static inline void rDBChangeSComps(int* currComponents,
4312  long* currShiftedComponents,
4313  int length,
4314  ring r)
4315 {
4316  assume(r->typ[1].ord_typ == ro_syzcomp);
4317 
4318  r->typ[1].data.syzcomp.length = length;
4319  rNChangeSComps( currComponents, currShiftedComponents, r);
4320 }
4321 static inline void rDBGetSComps(int** currComponents,
4322  long** currShiftedComponents,
4323  int *length,
4324  ring r)
4325 {
4326  assume(r->typ[1].ord_typ == ro_syzcomp);
4327 
4328  *length = r->typ[1].data.syzcomp.length;
4329  rNGetSComps( currComponents, currShiftedComponents, r);
4330 }
4331 #endif
4332 
4333 void rChangeSComps(int* currComponents, long* currShiftedComponents, int length, ring r)
4334 {
4335 #ifdef PDEBUG
4336  rDBChangeSComps(currComponents, currShiftedComponents, length, r);
4337 #else
4338  rNChangeSComps(currComponents, currShiftedComponents, r);
4339 #endif
4340 }
4341 
4342 void rGetSComps(int** currComponents, long** currShiftedComponents, int *length, ring r)
4343 {
4344 #ifdef PDEBUG
4345  rDBGetSComps(currComponents, currShiftedComponents, length, r);
4346 #else
4347  rNGetSComps(currComponents, currShiftedComponents, r);
4348 #endif
4349 }
4350 
4351 
4352 /////////////////////////////////////////////////////////////////////////////
4353 //
4354 // The following routines all take as input a ring r, and return R
4355 // where R has a certain property. R might be equal r in which case r
4356 // had already this property
4357 //
4358 ring rAssure_SyzOrder(const ring r, BOOLEAN complete)
4359 {
4360  if ( r->order[0] == ringorder_c ) return r;
4361  return rAssure_SyzComp(r,complete);
4362 }
4363 ring rAssure_SyzComp(const ring r, BOOLEAN complete)
4364 {
4365  if ( r->order[0] == ringorder_s ) return r;
4366 
4367  if ( r->order[0] == ringorder_IS )
4368  {
4369 #ifndef SING_NDEBUG
4370  WarnS("rAssure_SyzComp: input ring has an IS-ordering!");
4371 #endif
4372 // return r;
4373  }
4374  ring res=rCopy0(r, FALSE, FALSE);
4375  int i=rBlocks(r);
4376  int j;
4377 
4378  res->order=(rRingOrder_t *)omAlloc((i+1)*sizeof(rRingOrder_t));
4379  res->block0=(int *)omAlloc0((i+1)*sizeof(int));
4380  res->block1=(int *)omAlloc0((i+1)*sizeof(int));
4381  int ** wvhdl =(int **)omAlloc0((i+1)*sizeof(int**));
4382  for(j=i;j>0;j--)
4383  {
4384  res->order[j]=r->order[j-1];
4385  res->block0[j]=r->block0[j-1];
4386  res->block1[j]=r->block1[j-1];
4387  if (r->wvhdl[j-1] != NULL)
4388  {
4389  wvhdl[j] = (int*) omMemDup(r->wvhdl[j-1]);
4390  }
4391  }
4392  res->order[0]=ringorder_s;
4393 
4394  res->wvhdl = wvhdl;
4395 
4396  if (complete)
4397  {
4398  rComplete(res, 1);
4399 
4400 #ifdef HAVE_PLURAL
4401  if (rIsPluralRing(r))
4402  {
4403  if ( nc_rComplete(r, res, false) ) // no qideal!
4404  {
4405 #ifndef SING_NDEBUG
4406  WarnS("error in nc_rComplete"); // cleanup?// rDelete(res);// return r; // just go on..
4407 #endif
4408  }
4409  }
4411 #endif
4412 
4413 #ifdef HAVE_PLURAL
4414  ring old_ring = r;
4415 #endif
4416 
4417  if (r->qideal!=NULL)
4418  {
4419  res->qideal= idrCopyR_NoSort(r->qideal, r, res);
4420 
4421  assume(id_RankFreeModule(res->qideal, res) == 0);
4422 
4423 #ifdef HAVE_PLURAL
4424  if( rIsPluralRing(res) )
4425  if( nc_SetupQuotient(res, r, true) )
4426  {
4427 // WarnS("error in nc_SetupQuotient"); // cleanup? rDelete(res); return r; // just go on...?
4428  }
4429 
4430 #endif
4431  assume(id_RankFreeModule(res->qideal, res) == 0);
4432  }
4433 
4434 #ifdef HAVE_PLURAL
4435  assume((res->qideal==NULL) == (old_ring->qideal==NULL));
4436  assume(rIsPluralRing(res) == rIsPluralRing(old_ring));
4437  assume(rIsSCA(res) == rIsSCA(old_ring));
4438  assume(ncRingType(res) == ncRingType(old_ring));
4439 #endif
4440  }
4441  return res;
4442 }
4443 
4445 {
4446  int i;
4447  if (r->typ!=NULL)
4448  {
4449  for(i=r->OrdSize-1;i>=0;i--)
4450  {
4451  if ((r->typ[i].ord_typ==ro_dp)
4452  && (r->typ[i].data.dp.start==1)
4453  && (r->typ[i].data.dp.end==r->N))
4454  {
4455  return TRUE;
4456  }
4457  }
4458  }
4459  return FALSE;
4460 }
4461 
4462 ring rAssure_TDeg(ring r, int &pos)
4463 {
4464  int i;
4465  if (r->typ!=NULL)
4466  {
4467  for(i=r->OrdSize-1;i>=0;i--)
4468  {
4469  if ((r->typ[i].ord_typ==ro_dp)
4470  && (r->typ[i].data.dp.start==1)
4471  && (r->typ[i].data.dp.end==r->N))
4472  {
4473  pos=r->typ[i].data.dp.place;
4474  //printf("no change, pos=%d\n",pos);
4475  return r;
4476  }
4477  }
4478  }
4479 
4480 #ifdef HAVE_PLURAL
4481  nc_struct* save=r->GetNC();
4482  r->GetNC()=NULL;
4483 #endif
4484  ring res=rCopy(r);
4485  if (res->qideal!=NULL)
4486  {
4487  id_Delete(&res->qideal,r);
4488  }
4489 
4490  i=rBlocks(r);
4491  int j;
4492 
4493  res->ExpL_Size=r->ExpL_Size+1; // one word more in each monom
4494  res->PolyBin=omGetSpecBin(POLYSIZE + (res->ExpL_Size)*sizeof(long));
4495  omFree((ADDRESS)res->ordsgn);
4496  res->ordsgn=(long *)omAlloc0(res->ExpL_Size*sizeof(long));
4497  for(j=0;j<r->CmpL_Size;j++)
4498  {
4499  res->ordsgn[j] = r->ordsgn[j];
4500  }
4501  res->OrdSize=r->OrdSize+1; // one block more for pSetm
4502  if (r->typ!=NULL)
4503  omFree((ADDRESS)res->typ);
4504  res->typ=(sro_ord*)omAlloc0(res->OrdSize*sizeof(sro_ord));
4505  if (r->typ!=NULL)
4506  memcpy(res->typ,r->typ,r->OrdSize*sizeof(sro_ord));
4507  // the additional block for pSetm: total degree at the last word
4508  // but not included in the compare part
4509  res->typ[res->OrdSize-1].ord_typ=ro_dp;
4510  res->typ[res->OrdSize-1].data.dp.start=1;
4511  res->typ[res->OrdSize-1].data.dp.end=res->N;
4512  res->typ[res->OrdSize-1].data.dp.place=res->ExpL_Size-1;
4513  pos=res->ExpL_Size-1;
4514  //res->pOrdIndex=pos; //NO: think of a(1,0),dp !
4515  extern void p_Setm_General(poly p, ring r);
4516  res->p_Setm=p_Setm_General;
4517  // ----------------------------
4518  omFree((ADDRESS)res->p_Procs);
4519  res->p_Procs = (p_Procs_s*)omAlloc(sizeof(p_Procs_s));
4520 
4521  p_ProcsSet(res, res->p_Procs);
4522 #ifdef HAVE_PLURAL
4523  r->GetNC()=save;
4524  if (rIsPluralRing(r))
4525  {
4526  if ( nc_rComplete(r, res, false) ) // no qideal!
4527  {
4528 #ifndef SING_NDEBUG
4529  WarnS("error in nc_rComplete");
4530 #endif
4531  // just go on..
4532  }
4533  }
4534 #endif
4535  if (r->qideal!=NULL)
4536  {
4537  res->qideal=idrCopyR_NoSort(r->qideal,r, res);
4538 #ifdef HAVE_PLURAL
4539  if (rIsPluralRing(res))
4540  {
4541 // nc_SetupQuotient(res, currRing);
4542  nc_SetupQuotient(res, r); // ?
4543  }
4544  assume((res->qideal==NULL) == (r->qideal==NULL));
4545 #endif
4546  }
4547 
4548 #ifdef HAVE_PLURAL
4550  assume(rIsSCA(res) == rIsSCA(r));
4552 #endif
4553 
4554  return res;
4555 }
4556 
4557 ring rAssure_HasComp(const ring r)
4558 {
4559  int last_block;
4560  int i=0;
4561  do
4562  {
4563  if (r->order[i] == ringorder_c ||
4564  r->order[i] == ringorder_C) return r;
4565  if (r->order[i] == 0)
4566  break;
4567  i++;
4568  } while (1);
4569  //WarnS("re-creating ring with comps");
4570  last_block=i-1;
4571 
4572  ring new_r = rCopy0(r, FALSE, FALSE);
4573  i+=2;
4574  new_r->wvhdl=(int **)omAlloc0(i * sizeof(int *));
4575  new_r->order = (rRingOrder_t *) omAlloc0(i * sizeof(rRingOrder_t));
4576  new_r->block0 = (int *) omAlloc0(i * sizeof(int));
4577  new_r->block1 = (int *) omAlloc0(i * sizeof(int));
4578  memcpy(new_r->order,r->order,(i-1) * sizeof(rRingOrder_t));
4579  memcpy(new_r->block0,r->block0,(i-1) * sizeof(int));
4580  memcpy(new_r->block1,r->block1,(i-1) * sizeof(int));
4581  for (int j=0; j<=last_block; j++)
4582  {
4583  if (r->wvhdl[j]!=NULL)
4584  {
4585  new_r->wvhdl[j] = (int*) omMemDup(r->wvhdl[j]);
4586  }
4587  }
4588  last_block++;
4589  new_r->order[last_block]=ringorder_C;
4590  //new_r->block0[last_block]=0;
4591  //new_r->block1[last_block]=0;
4592  //new_r->wvhdl[last_block]=NULL;
4593 
4594  rComplete(new_r, 1);
4595 
4596 #ifdef HAVE_PLURAL
4597  if (rIsPluralRing(r))
4598  {
4599  if ( nc_rComplete(r, new_r, false) ) // no qideal!
4600  {
4601 #ifndef SING_NDEBUG
4602  WarnS("error in nc_rComplete"); // cleanup?// rDelete(res);// return r; // just go on..
4603 #endif
4604  }
4605  }
4606  assume(rIsPluralRing(r) == rIsPluralRing(new_r));
4607 #endif
4608 
4609  return new_r;
4610 }
4611 
4612 ring rAssure_CompLastBlock(ring r, BOOLEAN complete)
4613 {
4614  int last_block = rBlocks(r) - 2;
4615  if (r->order[last_block] != ringorder_c &&
4616  r->order[last_block] != ringorder_C)
4617  {
4618  int c_pos = 0;
4619  int i;
4620 
4621  for (i=0; i< last_block; i++)
4622  {
4623  if (r->order[i] == ringorder_c || r->order[i] == ringorder_C)
4624  {
4625  c_pos = i;
4626  break;
4627  }
4628  }
4629  if (c_pos != -1)
4630  {
4631  ring new_r = rCopy0(r, FALSE, TRUE);
4632  for (i=c_pos+1; i<=last_block; i++)
4633  {
4634  new_r->order[i-1] = new_r->order[i];
4635  new_r->block0[i-1] = new_r->block0[i];
4636  new_r->block1[i-1] = new_r->block1[i];
4637  new_r->wvhdl[i-1] = new_r->wvhdl[i];
4638  }
4639  new_r->order[last_block] = r->order[c_pos];
4640  new_r->block0[last_block] = r->block0[c_pos];
4641  new_r->block1[last_block] = r->block1[c_pos];
4642  new_r->wvhdl[last_block] = r->wvhdl[c_pos];
4643  if (complete)
4644  {
4645  rComplete(new_r, 1);
4646 
4647 #ifdef HAVE_PLURAL
4648  if (rIsPluralRing(r))
4649  {
4650  if ( nc_rComplete(r, new_r, false) ) // no qideal!
4651  {
4652 #ifndef SING_NDEBUG
4653  WarnS("error in nc_rComplete"); // cleanup?// rDelete(res);// return r; // just go on..
4654 #endif
4655  }
4656  }
4657  assume(rIsPluralRing(r) == rIsPluralRing(new_r));
4658 #endif
4659  }
4660  return new_r;
4661  }
4662  }
4663  return r;
4664 }
4665 
4666 // Moves _c or _C ordering to the last place AND adds _s on the 1st place
4668 {
4669  rTest(r);
4670 
4671  ring new_r_1 = rAssure_CompLastBlock(r, FALSE); // due to this FALSE - no completion!
4672  ring new_r = rAssure_SyzComp(new_r_1, FALSE); // new_r_1 is used only here!!!
4673 
4674  if (new_r == r)
4675  return r;
4676 
4677  ring old_r = r;
4678  if (new_r_1 != new_r && new_r_1 != old_r) rDelete(new_r_1);
4679 
4680  rComplete(new_r, TRUE);
4681 #ifdef HAVE_PLURAL
4682  if (rIsPluralRing(old_r))
4683  {
4684  if ( nc_rComplete(old_r, new_r, false) ) // no qideal!
4685  {
4686 # ifndef SING_NDEBUG
4687  WarnS("error in nc_rComplete"); // cleanup? rDelete(res); return r; // just go on...?
4688 # endif
4689  }
4690  }
4691 #endif
4692 
4693 ///? rChangeCurrRing(new_r);
4694  if (old_r->qideal != NULL)
4695  {
4696  new_r->qideal = idrCopyR(old_r->qideal, old_r, new_r);
4697  }
4698 
4699 #ifdef HAVE_PLURAL
4700  if( rIsPluralRing(old_r) )
4701  if( nc_SetupQuotient(new_r, old_r, true) )
4702  {
4703 #ifndef SING_NDEBUG
4704  WarnS("error in nc_SetupQuotient"); // cleanup? rDelete(res); return r; // just go on...?
4705 #endif
4706  }
4707 #endif
4708 
4709 #ifdef HAVE_PLURAL
4710  assume((new_r->qideal==NULL) == (old_r->qideal==NULL));
4711  assume(rIsPluralRing(new_r) == rIsPluralRing(old_r));
4712  assume(rIsSCA(new_r) == rIsSCA(old_r));
4713  assume(ncRingType(new_r) == ncRingType(old_r));
4714 #endif
4715 
4716  rTest(new_r);
4717  rTest(old_r);
4718  return new_r;
4719 }
4720 
4721 // use this for global orderings consisting of two blocks
4722 static ring rAssure_Global(rRingOrder_t b1, rRingOrder_t b2, const ring r)
4723 {
4724  int r_blocks = rBlocks(r);
4725 
4726  assume(b1 == ringorder_c || b1 == ringorder_C ||
4727  b2 == ringorder_c || b2 == ringorder_C ||
4728  b2 == ringorder_S);
4729  if ((r_blocks == 3) &&
4730  (r->order[0] == b1) &&
4731  (r->order[1] == b2) &&
4732  (r->order[2] == 0))
4733  return r;
4734  ring res = rCopy0(r, TRUE, FALSE);
4735  res->order = (rRingOrder_t*)omAlloc0(3*sizeof(rRingOrder_t));
4736  res->block0 = (int*)omAlloc0(3*sizeof(int));
4737  res->block1 = (int*)omAlloc0(3*sizeof(int));
4738  res->wvhdl = (int**)omAlloc0(3*sizeof(int*));
4739  res->order[0] = b1;
4740  res->order[1] = b2;
4741  if (b1 == ringorder_c || b1 == ringorder_C)
4742  {
4743  res->block0[1] = 1;
4744  res->block1[1] = r->N;
4745  }
4746  else
4747  {
4748  res->block0[0] = 1;
4749  res->block1[0] = r->N;
4750  }
4751  rComplete(res, 1);
4752 #ifdef HAVE_PLURAL
4753  if (rIsPluralRing(r))
4754  {
4755  if ( nc_rComplete(r, res, false) ) // no qideal!
4756  {
4757 #ifndef SING_NDEBUG
4758  WarnS("error in nc_rComplete");
4759 #endif
4760  }
4761  }
4762 #endif
4763 // rChangeCurrRing(res);
4764  return res;
4765 }
4766 
4767 ring rAssure_InducedSchreyerOrdering(const ring r, BOOLEAN complete/* = TRUE*/, int sgn/* = 1*/)
4768 { // TODO: ???? Add leading Syz-comp ordering here...????
4769 
4770 #if MYTEST
4771  Print("rAssure_InducedSchreyerOrdering(r, complete = %d, sgn = %d): r: \n", complete, sgn);
4772  rWrite(r);
4773 #ifdef RDEBUG
4774  rDebugPrint(r);
4775 #endif
4776  PrintLn();
4777 #endif
4778  assume((sgn == 1) || (sgn == -1));
4779 
4780  ring res=rCopy0(r, FALSE, FALSE); // No qideal & ordering copy.
4781 
4782  int n = rBlocks(r); // Including trailing zero!
4783 
4784  // Create 2 more blocks for prefix/suffix:
4785  res->order=(rRingOrder_t *)omAlloc0((n+2)*sizeof(rRingOrder_t)); // 0 .. n+1
4786  res->block0=(int *)omAlloc0((n+2)*sizeof(int));
4787  res->block1=(int *)omAlloc0((n+2)*sizeof(int));
4788  int ** wvhdl =(int **)omAlloc0((n+2)*sizeof(int**));
4789 
4790  // Encapsulate all existing blocks between induced Schreyer ordering markers: prefix and suffix!
4791  // Note that prefix and suffix have the same ringorder marker and only differ in block[] parameters!
4792 
4793  // new 1st block
4794  int j = 0;
4795  res->order[j] = ringorder_IS; // Prefix
4796  res->block0[j] = res->block1[j] = 0;
4797  // wvhdl[j] = NULL;
4798  j++;
4799 
4800  for(int i = 0; (i <= n) && (r->order[i] != 0); i++, j++) // i = [0 .. n-1] <- non-zero old blocks
4801  {
4802  res->order [j] = r->order [i];
4803  res->block0[j] = r->block0[i];
4804  res->block1[j] = r->block1[i];
4805 
4806  if (r->wvhdl[i] != NULL)
4807  {
4808  wvhdl[j] = (int*) omMemDup(r->wvhdl[i]);
4809  } // else wvhdl[j] = NULL;
4810  }
4811 
4812  // new last block
4813  res->order [j] = ringorder_IS; // Suffix
4814  res->block0[j] = res->block1[j] = sgn; // Sign of v[o]: 1 for C, -1 for c
4815  // wvhdl[j] = NULL;
4816  j++;
4817 
4818  // res->order [j] = 0; // The End!
4819  res->wvhdl = wvhdl;
4820 
4821  // j == the last zero block now!
4822  assume(j == (n+1));
4823  assume(res->order[0]==ringorder_IS);
4824  assume(res->order[j-1]==ringorder_IS);
4825  assume(res->order[j]==0);
4826 
4827 
4828  if (complete)
4829  {
4830  rComplete(res, 1);
4831 
4832 #ifdef HAVE_PLURAL
4833  if (rIsPluralRing(r))
4834  {
4835  if ( nc_rComplete(r, res, false) ) // no qideal!
4836  {
4837 #ifndef SING_NDEBUG
4838  WarnS("error in nc_rComplete"); // cleanup?// rDelete(res);// return r; // just go on..
4839 #endif
4840  }
4841  }
4843 #endif
4844 
4845 
4846 #ifdef HAVE_PLURAL
4847  ring old_ring = r;
4848 #endif
4849 
4850  if (r->qideal!=NULL)
4851  {
4852  res->qideal= idrCopyR_NoSort(r->qideal, r, res);
4853 
4854  assume(id_RankFreeModule(res->qideal, res) == 0);
4855 
4856 #ifdef HAVE_PLURAL
4857  if( rIsPluralRing(res) )
4858  if( nc_SetupQuotient(res, r, true) )
4859  {
4860 // WarnS("error in nc_SetupQuotient"); // cleanup? rDelete(res); return r; // just go on...?
4861  }
4862 
4863 #endif
4864  assume(id_RankFreeModule(res->qideal, res) == 0);
4865  }
4866 
4867 #ifdef HAVE_PLURAL
4868  assume((res->qideal==NULL) == (old_ring->qideal==NULL));
4869  assume(rIsPluralRing(res) == rIsPluralRing(old_ring));
4870  assume(rIsSCA(res) == rIsSCA(old_ring));
4871  assume(ncRingType(res) == ncRingType(old_ring));
4872 #endif
4873  }
4874 
4875  return res;
4876 }
4877 
4878 ring rAssure_dp_S(const ring r)
4879 {
4881 }
4882 
4883 ring rAssure_dp_C(const ring r)
4884 {
4886 }
4887 
4888 ring rAssure_C_dp(const ring r)
4889 {
4891 }
4892 
4893 ring rAssure_c_dp(const ring r)
4894 {
4896 }
4897 
4898 
4899 
4900 /// Finds p^th IS ordering, and returns its position in r->typ[]
4901 /// returns -1 if something went wrong!
4902 /// p - starts with 0!
4903 int rGetISPos(const int p, const ring r)
4904 {
4905  // Put the reference set F into the ring -ordering -recor
4906 #if MYTEST
4907  Print("rIsIS(p: %d)\nF:", p);
4908  PrintLn();
4909 #endif
4910 
4911  if (r->typ==NULL)
4912  {
4913 // dReportError("'rIsIS:' Error: wrong ring! (typ == NULL)");
4914  return -1;
4915  }
4916 
4917  int j = p; // Which IS record to use...
4918  for( int pos = 0; pos < r->OrdSize; pos++ )
4919  if( r->typ[pos].ord_typ == ro_is)
4920  if( j-- == 0 )
4921  return pos;
4922 
4923  return -1;
4924 }
4925 
4926 
4927 
4928 
4929 
4930 
4931 /// Changes r by setting induced ordering parameters: limit and reference leading terms
4932 /// F belong to r, we will DO a copy!
4933 /// We will use it AS IS!
4934 /// returns true is everything was allright!
4935 BOOLEAN rSetISReference(const ring r, const ideal F, const int i, const int p)
4936 {
4937  // Put the reference set F into the ring -ordering -recor
4938 
4939  if (r->typ==NULL)
4940  {
4941  dReportError("Error: WRONG USE of rSetISReference: wrong ring! (typ == NULL)");
4942  return FALSE;
4943  }
4944 
4945 
4946  int pos = rGetISPos(p, r);
4947 
4948  if( pos == -1 )
4949  {
4950  dReportError("Error: WRONG USE of rSetISReference: specified ordering block was not found!!!" );
4951  return FALSE;
4952  }
4953 
4954 #if MYTEST
4955  if( i != r->typ[pos].data.is.limit )
4956  Print("Changing record on pos: %d\nOld limit: %d --->> New Limit: %d\n", pos, r->typ[pos].data.is.limit, i);
4957 #endif
4958 
4959  const ideal FF = idrHeadR(F, r, r); // id_Copy(F, r); // ???
4960 
4961 
4962  if( r->typ[pos].data.is.F != NULL)
4963  {
4964 #if MYTEST
4965  PrintS("Deleting old reference set F... \n"); // idShow(r->typ[pos].data.is.F, r); PrintLn();
4966 #endif
4967  id_Delete(&r->typ[pos].data.is.F, r);
4968  r->typ[pos].data.is.F = NULL;
4969  }
4970 
4971  assume(r->typ[pos].data.is.F == NULL);
4972 
4973  r->typ[pos].data.is.F = FF; // F is owened by ring now! TODO: delete at the end!
4974 
4975  r->typ[pos].data.is.limit = i; // First induced component
4976 
4977 #if MYTEST
4978  PrintS("New reference set FF : \n"); idShow(FF, r, r, 1); PrintLn();
4979 #endif
4980 
4981  return TRUE;
4982 }
4983 
4984 #ifdef PDEBUG
4986 #endif
4987 
4988 
4989 void rSetSyzComp(int k, const ring r)
4990 {
4991  if(k < 0)
4992  {
4993  dReportError("rSetSyzComp with negative limit!");
4994  return;
4995  }
4996 
4997  assume( k >= 0 );
4998  if (TEST_OPT_PROT) Print("{%d}", k);
4999  if ((r->typ!=NULL) && (r->typ[0].ord_typ==ro_syz))
5000  {
5001  r->block0[0]=r->block1[0] = k;
5002  if( k == r->typ[0].data.syz.limit )
5003  return; // nothing to do
5004 
5005  int i;
5006  if (r->typ[0].data.syz.limit == 0)
5007  {
5008  r->typ[0].data.syz.syz_index = (int*) omAlloc0((k+1)*sizeof(int));
5009  r->typ[0].data.syz.syz_index[0] = 0;
5010  r->typ[0].data.syz.curr_index = 1;
5011  }
5012  else
5013  {
5014  r->typ[0].data.syz.syz_index = (int*)
5015  omReallocSize(r->typ[0].data.syz.syz_index,
5016  (r->typ[0].data.syz.limit+1)*sizeof(int),
5017  (k+1)*sizeof(int));
5018  }
5019  for (i=r->typ[0].data.syz.limit + 1; i<= k; i++)
5020  {
5021  r->typ[0].data.syz.syz_index[i] =
5022  r->typ[0].data.syz.curr_index;
5023  }
5024  if(k < r->typ[0].data.syz.limit) // ?
5025  {
5026 #ifndef SING_NDEBUG
5027  Warn("rSetSyzComp called with smaller limit (%d) as before (%d)", k, r->typ[0].data.syz.limit);
5028 #endif
5029  r->typ[0].data.syz.curr_index = 1 + r->typ[0].data.syz.syz_index[k];
5030  }
5031 
5032 
5033  r->typ[0].data.syz.limit = k;
5034  r->typ[0].data.syz.curr_index++;
5035  }
5036  else if(
5037  (r->typ!=NULL) &&
5038  (r->typ[0].ord_typ==ro_isTemp)
5039  )
5040  {
5041 // (r->typ[currRing->typ[0].data.isTemp.suffixpos].data.is.limit == k)
5042 #ifndef SING_NDEBUG
5043  Warn("rSetSyzComp(%d) in an IS ring! Be careful!", k);
5044 #endif
5045  }
5046  else if (r->order[0]==ringorder_s)
5047  {
5048  r->block0[0] = r->block1[0] = k;
5049  }
5050  else if (r->order[0]!=ringorder_c)
5051  {
5052  dReportError("syzcomp in incompatible ring");
5053  }
5054 #ifdef PDEBUG
5055  extern int pDBsyzComp;
5056  pDBsyzComp=k;
5057 #endif
5058 }
5059 
5060 // return the max-comonent wchich has syzIndex i
5061 int rGetMaxSyzComp(int i, const ring r)
5062 {
5063  if ((r->typ!=NULL) && (r->typ[0].ord_typ==ro_syz) &&
5064  r->typ[0].data.syz.limit > 0 && i > 0)
5065  {
5066  assume(i <= r->typ[0].data.syz.limit);
5067  int j;
5068  for (j=0; j<r->typ[0].data.syz.limit; j++)
5069  {
5070  if (r->typ[0].data.syz.syz_index[j] == i &&
5071  r->typ[0].data.syz.syz_index[j+1] != i)
5072  {
5073  assume(r->typ[0].data.syz.syz_index[j+1] == i+1);
5074  return j;
5075  }
5076  }
5077  return r->typ[0].data.syz.limit;
5078  }
5079  else
5080  {
5081  return 0;
5082  }
5083 }
5084 
5086 {
5087  if (r == NULL) return FALSE;
5088  int i, j, nb = rBlocks(r);
5089  for (i=0; i<nb; i++)
5090  {
5091  if (r->wvhdl[i] != NULL)
5092  {
5093  int length = r->block1[i] - r->block0[i];
5094  int* wvhdl = r->wvhdl[i];
5095  if (r->order[i] == ringorder_M) length *= length;
5096  assume(omSizeOfAddr(wvhdl) >= length*sizeof(int));
5097 
5098  for (j=0; j< length; j++)
5099  {
5100  if (wvhdl[j] != 0 && wvhdl[j] != 1) return FALSE;
5101  }
5102  }
5103  }
5104  return TRUE;
5105 }
5106 
5108 {
5109  assume(r != NULL);
5110  int lb = rBlocks(r) - 2;
5111  return (r->order[lb] == ringorder_c || r->order[lb] == ringorder_C);
5112 }
5113 
5115 {
5116  return (r->cf->type);
5117  if (rField_is_Zp(r)) return n_Zp;
5118  if (rField_is_Q(r)) return n_Q;
5119  if (rField_is_R(r)) return n_R;
5120  if (rField_is_GF(r)) return n_GF;
5121  if (rField_is_long_R(r)) return n_long_R;
5122  if (rField_is_Zp_a(r)) return getCoeffType(r->cf);
5123  if (rField_is_Q_a(r)) return getCoeffType(r->cf);
5124  if (rField_is_long_C(r)) return n_long_C;
5125  if (rField_is_Ring_Z(r)) return n_Z;
5126  if (rField_is_Ring_ModN(r)) return n_Zn;
5127  if (rField_is_Ring_PtoM(r)) return n_Znm;
5128  if (rField_is_Ring_2toM(r)) return n_Z2m;
5129 
5130  return n_unknown;
5131 }
5132 
5133 int64 * rGetWeightVec(const ring r)
5134 {
5135  assume(r!=NULL);
5136  assume(r->OrdSize>0);
5137  int i=0;
5138  while((r->typ[i].ord_typ!=ro_wp64) && (r->typ[i].ord_typ>0)) i++;
5139  assume(r->typ[i].ord_typ==ro_wp64);
5140  return (int64*)(r->typ[i].data.wp64.weights64);
5141 }
5142 
5143 void rSetWeightVec(ring r, int64 *wv)
5144 {
5145  assume(r!=NULL);
5146  assume(r->OrdSize>0);
5147  assume(r->typ[0].ord_typ==ro_wp64);
5148  memcpy(r->typ[0].data.wp64.weights64,wv,r->N*sizeof(int64));
5149 }
5150 
5151 #include <ctype.h>
5152 
5153 static int rRealloc1(ring r, int size, int pos)
5154 {
5155  r->order=(rRingOrder_t*)omReallocSize(r->order, size*sizeof(rRingOrder_t), (size+1)*sizeof(rRingOrder_t));
5156  r->block0=(int*)omReallocSize(r->block0, size*sizeof(int), (size+1)*sizeof(int));
5157  r->block1=(int*)omReallocSize(r->block1, size*sizeof(int), (size+1)*sizeof(int));
5158  r->wvhdl=(int **)omReallocSize(r->wvhdl,size*sizeof(int *), (size+1)*sizeof(int *));
5159  for(int k=size; k>pos; k--) r->wvhdl[k]=r->wvhdl[k-1];
5160  r->order[size]=(rRingOrder_t)0;
5161  size++;
5162  return size;
5163 }
5164 #if 0 // currently unused
5165 static int rReallocM1(ring r, int size, int pos)
5166 {
5167  r->order=(int*)omReallocSize(r->order, size*sizeof(int), (size-1)*sizeof(int));
5168  r->block0=(int*)omReallocSize(r->block0, size*sizeof(int), (size-1)*sizeof(int));
5169  r->block1=(int*)omReallocSize(r->block1, size*sizeof(int), (size-1)*sizeof(int));
5170  r->wvhdl=(int **)omReallocSize(r->wvhdl,size*sizeof(int *), (size-1)*sizeof(int *));
5171  for(int k=pos+1; k<size; k++) r->wvhdl[k]=r->wvhdl[k+1];
5172  size--;
5173  return size;
5174 }
5175 #endif
5176 static void rOppWeight(int *w, int l)
5177 {
5178  int i2=(l+1)/2;
5179  for(int j=0; j<=i2; j++)
5180  {
5181  int t=w[j];
5182  w[j]=w[l-j];
5183  w[l-j]=t;
5184  }
5185 }
5186 
5187 #define rOppVar(R,I) (rVar(R)+1-I)
5188 
5189 ring rOpposite(ring src)
5190  /* creates an opposite algebra of R */
5191  /* that is R^opp, where f (*^opp) g = g*f */
5192  /* treats the case of qring */
5193 {
5194  if (src == NULL) return(NULL);
5195 
5196 #ifdef RDEBUG
5197  rTest(src);
5198 #endif
5199 
5200  //rChangeCurrRing(src);
5201 
5202 #ifdef RDEBUG
5203  rTest(src);
5204 // rWrite(src);
5205 // rDebugPrint(src);
5206 #endif
5207 
5208 
5209  ring r = rCopy0(src,FALSE); /* qideal will be deleted later on!!! */
5210 
5211  // change vars v1..vN -> vN..v1
5212  int i;
5213  int i2 = (rVar(r)-1)/2;
5214  for(i=i2; i>=0; i--)
5215  {
5216  // index: 0..N-1
5217  //Print("ex var names: %d <-> %d\n",i,rOppVar(r,i));
5218  // exchange names
5219  char *p;
5220  p = r->names[rVar(r)-1-i];
5221  r->names[rVar(r)-1-i] = r->names[i];
5222  r->names[i] = p;
5223  }
5224 // i2=(rVar(r)+1)/2;
5225 // for(int i=i2; i>0; i--)
5226 // {
5227 // // index: 1..N
5228 // //Print("ex var places: %d <-> %d\n",i,rVar(r)+1-i);
5229 // // exchange VarOffset
5230 // int t;
5231 // t=r->VarOffset[i];
5232 // r->VarOffset[i]=r->VarOffset[rOppVar(r,i)];
5233 // r->VarOffset[rOppVar(r,i)]=t;
5234 // }
5235  // change names:
5236  for (i=rVar(r)-1; i>=0; i--)
5237  {
5238  char *p=r->names[i];
5239  if(isupper(*p)) *p = tolower(*p);
5240  else *p = toupper(*p);
5241  }
5242  // change ordering: listing
5243  // change ordering: compare
5244 // for(i=0; i<r->OrdSize; i++)
5245 // {
5246 // int t,tt;
5247 // switch(r->typ[i].ord_typ)
5248 // {
5249 // case ro_dp:
5250 // //
5251 // t=r->typ[i].data.dp.start;
5252 // r->typ[i].data.dp.start=rOppVar(r,r->typ[i].data.dp.end);
5253 // r->typ[i].data.dp.end=rOppVar(r,t);
5254 // break;
5255 // case ro_wp:
5256 // case ro_wp_neg:
5257 // {
5258 // t=r->typ[i].data.wp.start;
5259 // r->typ[i].data.wp.start=rOppVar(r,r->typ[i].data.wp.end);
5260 // r->typ[i].data.wp.end=rOppVar(r,t);
5261 // // invert r->typ[i].data.wp.weights
5262 // rOppWeight(r->typ[i].data.wp.weights,
5263 // r->typ[i].data.wp.end-r->typ[i].data.wp.start);
5264 // break;
5265 // }
5266 // //case ro_wp64:
5267 // case ro_syzcomp:
5268 // case ro_syz:
5269 // WerrorS("not implemented in rOpposite");
5270 // // should not happen
5271 // break;
5272 //
5273 // case ro_cp:
5274 // t=r->typ[i].data.cp.start;
5275 // r->typ[i].data.cp.start=rOppVar(r,r->typ[i].data.cp.end);
5276 // r->typ[i].data.cp.end=rOppVar(r,t);
5277 // break;
5278 // case ro_none:
5279 // default:
5280 // Werror("unknown type in rOpposite(%d)",r->typ[i].ord_typ);
5281 // break;
5282 // }
5283 // }
5284  // Change order/block structures (needed for rPrint, rAdd etc.)
5285  int j=0;
5286  int l=rBlocks(src);
5287  for(i=0; src->order[i]!=0; i++)
5288  {
5289  switch (src->order[i])
5290  {
5291  case ringorder_c: /* c-> c */
5292  case ringorder_C: /* C-> C */
5293  case ringorder_no /*=0*/: /* end-of-block */
5294  r->order[j]=src->order[i];
5295  j++; break;
5296  case ringorder_lp: /* lp -> rp */
5297  r->order[j]=ringorder_rp;
5298  r->block0[j]=rOppVar(r, src->block1[i]);
5299  r->block1[j]=rOppVar(r, src->block0[i]);
5300  break;
5301  case ringorder_rp: /* rp -> lp */
5302  r->order[j]=ringorder_lp;
5303  r->block0[j]=rOppVar(r, src->block1[i]);
5304  r->block1[j]=rOppVar(r, src->block0[i]);
5305  break;
5306  case ringorder_dp: /* dp -> a(1..1),ls */
5307  {
5308  l=rRealloc1(r,l,j);
5309  r->order[j]=ringorder_a;
5310  r->block0[j]=rOppVar(r, src->block1[i]);
5311  r->block1[j]=rOppVar(r, src->block0[i]);
5312  r->wvhdl[j]=(int*)omAlloc((r->block1[j]-r->block0[j]+1)*sizeof(int));
5313  for(int k=r->block0[j]; k<=r->block1[j]; k++)
5314  r->wvhdl[j][k-r->block0[j]]=1;
5315  j++;
5316  r->order[j]=ringorder_ls;
5317  r->block0[j]=rOppVar(r, src->block1[i]);
5318  r->block1[j]=rOppVar(r, src->block0[i]);
5319  j++;
5320  break;
5321  }
5322  case ringorder_Dp: /* Dp -> a(1..1),rp */
5323  {
5324  l=rRealloc1(r,l,j);
5325  r->order[j]=ringorder_a;
5326  r->block0[j]=rOppVar(r, src->block1[i]);
5327  r->block1[j]=rOppVar(r, src->block0[i]);
5328  r->wvhdl[j]=(int*)omAlloc((r->block1[j]-r->block0[j]+1)*sizeof(int));
5329  for(int k=r->block0[j]; k<=r->block1[j]; k++)
5330  r->wvhdl[j][k-r->block0[j]]=1;
5331  j++;
5332  r->order[j]=ringorder_rp;
5333  r->block0[j]=rOppVar(r, src->block1[i]);
5334  r->block1[j]=rOppVar(r, src->block0[i]);
5335  j++;
5336  break;
5337  }
5338  case ringorder_wp: /* wp -> a(...),ls */
5339  {
5340  l=rRealloc1(r,l,j);
5341  r->order[j]=ringorder_a;
5342  r->block0[j]=rOppVar(r, src->block1[i]);
5343  r->block1[j]=rOppVar(r, src->block0[i]);
5344  r->wvhdl[j]=r->wvhdl[j+1]; r->wvhdl[j+1]=NULL;
5345  rOppWeight(r->wvhdl[j], r->block1[j]-r->block0[j]);
5346  j++;
5347  r->order[j]=ringorder_ls;
5348  r->block0[j]=rOppVar(r, src->block1[i]);
5349  r->block1[j]=rOppVar(r, src->block0[i]);
5350  j++;
5351  break;
5352  }
5353  case ringorder_Wp: /* Wp -> a(...),rp */
5354  {
5355  l=rRealloc1(r,l,j);
5356  r->order[j]=ringorder_a;
5357  r->block0[j]=rOppVar(r, src->block1[i]);
5358  r->block1[j]=rOppVar(r, src->block0[i]);
5359  r->wvhdl[j]=r->wvhdl[j+1]; r->wvhdl[j+1]=NULL;
5360  rOppWeight(r->wvhdl[j], r->block1[j]-r->block0[j]);
5361  j++;
5362  r->order[j]=ringorder_rp;
5363  r->block0[j]=rOppVar(r, src->block1[i]);
5364  r->block1[j]=rOppVar(r, src->block0[i]);
5365  j++;
5366  break;
5367  }
5368  case ringorder_M: /* M -> M */
5369  {
5370  r->order[j]=ringorder_M;
5371  r->block0[j]=rOppVar(r, src->block1[i]);
5372  r->block1[j]=rOppVar(r, src->block0[i]);
5373  int n=r->block1[j]-r->block0[j];
5374  /* M is a (n+1)x(n+1) matrix */
5375  for (int nn=0; nn<=n; nn++)
5376  {
5377  rOppWeight(&(r->wvhdl[j][nn*(n+1)]), n /*r->block1[j]-r->block0[j]*/);
5378  }
5379  j++;
5380  break;
5381  }
5382  case ringorder_a: /* a(...),ls -> wp/dp */
5383  {
5384  r->block0[j]=rOppVar(r, src->block1[i]);
5385  r->block1[j]=rOppVar(r, src->block0[i]);
5386  rOppWeight(r->wvhdl[j], r->block1[j]-r->block0[j]);
5387  if (src->order[i+1]==ringorder_ls)
5388  {
5389  r->order[j]=ringorder_wp;
5390  i++;
5391  //l=rReallocM1(r,l,j);
5392  }
5393  else
5394  {
5395  r->order[j]=ringorder_a;
5396  }
5397  j++;
5398  break;
5399  }
5400  // not yet done:
5401  case ringorder_ls:
5402  case ringorder_rs:
5403  case ringorder_ds:
5404  case ringorder_Ds:
5405  case ringorder_ws:
5406  case ringorder_Ws:
5407  case ringorder_am:
5408  case ringorder_a64:
5409  // should not occur:
5410  case ringorder_S:
5411  case ringorder_IS:
5412  case ringorder_s:
5413  case ringorder_aa:
5414  case ringorder_L:
5415  case ringorder_unspec:
5416  Werror("order %s not (yet) supported", rSimpleOrdStr(src->order[i]));
5417  break;
5418  }
5419  }
5420  rComplete(r);
5421 
5422 
5423 #ifdef RDEBUG
5424  rTest(r);
5425 #endif
5426 
5427  //rChangeCurrRing(r);
5428 
5429 #ifdef RDEBUG
5430  rTest(r);
5431 // rWrite(r);
5432 // rDebugPrint(r);
5433 #endif
5434 
5435 
5436 #ifdef HAVE_PLURAL
5437  // now, we initialize a non-comm structure on r
5438  if (rIsPluralRing(src))
5439  {
5440 // assume( currRing == r);
5441 
5442  int *perm = (int *)omAlloc0((rVar(r)+1)*sizeof(int));
5443  int *par_perm = NULL;
5444  nMapFunc nMap = n_SetMap(src->cf,r->cf);
5445  int ni,nj;
5446  for(i=1; i<=r->N; i++)
5447  {
5448  perm[i] = rOppVar(r,i);
5449  }
5450 
5451  matrix C = mpNew(rVar(r),rVar(r));
5452  matrix D = mpNew(rVar(r),rVar(r));
5453 
5454  for (i=1; i< rVar(r); i++)
5455  {
5456  for (j=i+1; j<=rVar(r); j++)
5457  {
5458  ni = r->N +1 - i;
5459  nj = r->N +1 - j; /* i<j ==> nj < ni */
5460 
5461  assume(MATELEM(src->GetNC()->C,i,j) != NULL);
5462  MATELEM(C,nj,ni) = p_PermPoly(MATELEM(src->GetNC()->C,i,j),perm,src,r, nMap,par_perm,rPar(src));
5463 
5464  if(MATELEM(src->GetNC()->D,i,j) != NULL)
5465  MATELEM(D,nj,ni) = p_PermPoly(MATELEM(src->GetNC()->D,i,j),perm,src,r, nMap,par_perm,rPar(src));
5466  }
5467  }
5468 
5469  id_Test((ideal)C, r);
5470  id_Test((ideal)D, r);
5471 
5472  if (nc_CallPlural(C, D, NULL, NULL, r, false, false, true, r)) // no qring setup!
5473  WarnS("Error initializing non-commutative multiplication!");
5474 
5475 #ifdef RDEBUG
5476  rTest(r);
5477 // rWrite(r);
5478 // rDebugPrint(r);
5479 #endif
5480 
5481  assume( r->GetNC()->IsSkewConstant == src->GetNC()->IsSkewConstant);
5482 
5483  omFreeSize((ADDRESS)perm,(rVar(r)+1)*sizeof(int));
5484  }
5485 #endif /* HAVE_PLURAL */
5486 
5487  /* now oppose the qideal for qrings */
5488  if (src->qideal != NULL)
5489  {
5490  id_Delete(&(r->qideal), r);
5491 
5492 #ifdef HAVE_PLURAL
5493  r->qideal = idOppose(src, src->qideal, r); // into the currRing: r
5494 #else
5495  r->qideal = id_Copy(src->qideal, r); // ?
5496 #endif
5497 
5498 #ifdef HAVE_PLURAL
5499  if( rIsPluralRing(r) )
5500  {
5502 #ifdef RDEBUG
5503  rTest(r);
5504 // rWrite(r);
5505 // rDebugPrint(r);
5506 #endif
5507  }
5508 #endif
5509  }
5510 #ifdef HAVE_PLURAL
5511  if( rIsPluralRing(r) )
5512  assume( ncRingType(r) == ncRingType(src) );
5513 #endif
5514  rTest(r);
5515 
5516  return r;
5517 }
5518 
5519 ring rEnvelope(ring R)
5520  /* creates an enveloping algebra of R */
5521  /* that is R^e = R \tensor_K R^opp */
5522 {
5523  ring Ropp = rOpposite(R);
5524  ring Renv = NULL;
5525  int stat = rSum(R, Ropp, Renv); /* takes care of qideals */
5526  if ( stat <=0 )
5527  WarnS("Error in rEnvelope at rSum");
5528  rTest(Renv);
5529  return Renv;
5530 }
5531 
5532 #ifdef HAVE_PLURAL
5533 BOOLEAN nc_rComplete(const ring src, ring dest, bool bSetupQuotient)
5534 /* returns TRUE is there were errors */
5535 /* dest is actualy equals src with the different ordering */
5536 /* we map src->nc correctly to dest->src */
5537 /* to be executed after rComplete, before rChangeCurrRing */
5538 {
5539 // NOTE: Originally used only by idElimination to transfer NC structure to dest
5540 // ring created by dirty hack (without nc_CallPlural)
5541  rTest(src);
5542 
5543  assume(!rIsPluralRing(dest)); // destination must be a newly constructed commutative ring
5544 
5545  if (!rIsPluralRing(src))
5546  {
5547  return FALSE;
5548  }
5549 
5550  const int N = dest->N;
5551 
5552  assume(src->N == N);
5553 
5554 // ring save = currRing;
5555 
5556 // if (dest != save)
5557 // rChangeCurrRing(dest);
5558 
5559  const ring srcBase = src;
5560 
5561  assume( n_SetMap(srcBase->cf,dest->cf) == n_SetMap(dest->cf,dest->cf) ); // currRing is important here!
5562 
5563  matrix C = mpNew(N,N); // ring independent
5564  matrix D = mpNew(N,N);
5565 
5566  matrix C0 = src->GetNC()->C;
5567  matrix D0 = src->GetNC()->D;
5568 
5569  // map C and D into dest
5570  for (int i = 1; i < N; i++)
5571  {
5572  for (int j = i + 1; j <= N; j++)
5573  {
5574  const number n = n_Copy(p_GetCoeff(MATELEM(C0,i,j), srcBase), srcBase->cf); // src, mapping for coeffs into currRing = dest!
5575  const poly p = p_NSet(n, dest);
5576  MATELEM(C,i,j) = p;
5577  if (MATELEM(D0,i,j) != NULL)
5578  MATELEM(D,i,j) = prCopyR(MATELEM(D0,i,j), srcBase, dest); // ?
5579  }
5580  }
5581  /* One must test C and D _only_ in r->GetNC()->basering!!! not in r!!! */
5582 
5583  id_Test((ideal)C, dest);
5584  id_Test((ideal)D, dest);
5585 
5586  if (nc_CallPlural(C, D, NULL, NULL, dest, bSetupQuotient, false, true, dest)) // also takes care about quotient ideal
5587  {
5588  //WarnS("Error transferring non-commutative structure");
5589  // error message should be in the interpreter interface
5590 
5591  mp_Delete(&C, dest);
5592  mp_Delete(&D, dest);
5593 
5594 // if (currRing != save)
5595 // rChangeCurrRing(save);
5596 
5597  return TRUE;
5598  }
5599 
5600 // mp_Delete(&C, dest); // used by nc_CallPlural!
5601 // mp_Delete(&D, dest);
5602 
5603 // if (dest != save)
5604 // rChangeCurrRing(save);
5605 
5606  assume(rIsPluralRing(dest));
5607  return FALSE;
5608 }
5609 #endif
5610 
5611 void rModify_a_to_A(ring r)
5612 // to be called BEFORE rComplete:
5613 // changes every Block with a(...) to A(...)
5614 {
5615  int i=0;
5616  int j;
5617  while(r->order[i]!=0)
5618  {
5619  if (r->order[i]==ringorder_a)
5620  {
5621  r->order[i]=ringorder_a64;
5622  int *w=r->wvhdl[i];
5623  int64 *w64=(int64 *)omAlloc((r->block1[i]-r->block0[i]+1)*sizeof(int64));
5624  for(j=r->block1[i]-r->block0[i];j>=0;j--)
5625  w64[j]=(int64)w[j];
5626  r->wvhdl[i]=(int*)w64;
5627  omFreeSize(w,(r->block1[i]-r->block0[i]+1)*sizeof(int));
5628  }
5629  i++;
5630  }
5631 }
5632 
5633 
5634 poly rGetVar(const int varIndex, const ring r)
5635 {
5636  poly p = p_ISet(1, r);
5637  p_SetExp(p, varIndex, 1, r);
5638  p_Setm(p, r);
5639  return p;
5640 }
5641 
5642 
5643 /// TODO: rewrite somehow...
5644 int n_IsParam(const number m, const ring r)
5645 {
5646  assume(r != NULL);
5647  const coeffs C = r->cf;
5648  assume(C != NULL);
5649 
5651 
5652  const n_coeffType _filed_type = getCoeffType(C);
5653 
5654  if(( _filed_type == n_algExt )||( _filed_type == n_polyExt ))
5655  return naIsParam(m, C);
5656 
5657  if( _filed_type == n_transExt )
5658  return ntIsParam(m, C);
5659 
5660  Werror("n_IsParam: IsParam is not to be used for (coeff_type = %d)",getCoeffType(C));
5661 
5662  return 0;
5663 }
short N
Definition: ring.h:311
#define omAllocBin(bin)
Definition: omAllocDecl.h:205
for idElimination, like a, except pFDeg, pWeigths ignore it
Definition: ring.h:99
n_coeffType rFieldType(ring r)
Definition: ring.cc:5114
ideal SCAQuotient(const ring r)
Definition: sca.h:10
int pDBsyzComp
Definition: ring.cc:4985
void p_Setm_General(poly p, const ring r)
Definition: p_polys.cc:163
const CanonicalForm int s
Definition: facAbsFact.cc:55
unsigned si_opt_1
Definition: options.c:5
ring rEnvelope(ring R)
Definition: ring.cc:5519
void p_DebugPrint(poly p, const ring r)
Definition: ring.cc:4217
#define omCheckAddrSize(addr, size)
Definition: omAllocDecl.h:327
#define D(A)
Definition: gentable.cc:123
for int64 weights
Definition: ring.h:79
#define omMemDup(s)
Definition: omAllocDecl.h:264
char * rVarStr(ring r)
Definition: ring.cc:598
n_Procs_s * cf
Definition: ring.h:373
static void rOptimizeLDeg(ring r)
Definition: ring.cc:3065
Definition: ring.h:68
omBin_t * omBin
Definition: omStructs.h:12
void PrintLn()
Definition: reporter.cc:310
#define Print
Definition: emacs.cc:83
long pLDeg1(poly p, int *l, const ring r)
Definition: p_polys.cc:842
only used if HAVE_RINGS is defined
Definition: coeffs.h:44
#define omcheckAddrSize(addr, size)
Definition: omAllocDecl.h:329
poly rGetVar(const int varIndex, const ring r)
Definition: ring.cc:5634
static void rO_LexVars(int &place, int &bitplace, int start, int end, int &prev_ord, long *o, int *v, int bits, int opt_var)
Definition: ring.cc:2247
omBin char_ptr_bin
Definition: ring.cc:55
int rSumInternal(ring r1, ring r2, ring &sum, BOOLEAN vartest, BOOLEAN dp_dp)
returns -1 for not compatible, 1 for compatible (and sum) dp_dp:0: block ordering, 1: dp,dp, 2: aa(...),dp vartest: check for name conflicts
Definition: ring.cc:726
Definition: ring.h:61
non-simple ordering as specified by currRing
Definition: ring.h:107
int order_index
Definition: ring.h:229
simple ordering, exponent vector has priority component is compatible with exp-vector order ...
Definition: ring.h:111
static void rSetNegWeight(ring r)
Definition: ring.cc:3262
poly prCopyR(poly p, ring src_r, ring dest_r)
Definition: prCopy.cc:36
static BOOLEAN rField_is_Zp_a(const ring r)
Definition: ring.h:521
long pLDeg1c_Totaldegree(poly p, int *l, const ring r)
Definition: p_polys.cc:1006
p_SetmProc p_GetSetmProc(const ring r)
Definition: p_polys.cc:561
rOrderType_t rGetOrderType(ring r)
Definition: ring.cc:1718
#define TEST_OPT_PROT
Definition: options.h:98
only used if HAVE_RINGS is defined
Definition: coeffs.h:46
used for all transcendental extensions, i.e., the top-most extension in an extension tower is transce...
Definition: coeffs.h:39
loop
Definition: myNF.cc:98
static int min(int a, int b)
Definition: fast_mult.cc:268
BOOLEAN rRing_is_Homog(ring r)
Definition: ring.cc:5085
if(0 > strat->sl)
Definition: myNF.cc:73
static BOOLEAN rField_is_Ring_PtoM(const ring r)
Definition: ring.h:471
int sgn(const Rational &a)
Definition: GMPrat.cc:437
long pLDeg1c(poly p, int *l, const ring r)
Definition: p_polys.cc:878
#define FALSE
Definition: auxiliary.h:94
static void rO_ISSuffix(int &place, int &bitplace, int &prev_ord, long *o, int N, int *v, sro_ord *tmp_typ, int &typ_i, int sgn)
Definition: ring.cc:2382
size_t omSizeOfAddr(const void *addr)
return P p
Definition: myNF.cc:203
opposite of ls
Definition: ring.h:100
ideal id_Copy(ideal h1, const ring r)
copy an ideal
static FORCE_INLINE BOOLEAN n_IsOne(number n, const coeffs r)
TRUE iff &#39;n&#39; represents the one element.
Definition: coeffs.h:472
BOOLEAN nc_rComplete(const ring src, ring dest, bool bSetupQuotient)
Definition: ring.cc:5533
static int rPar(const ring r)
(r->cf->P)
Definition: ring.h:590
poly p_NSet(number n, const ring r)
returns the poly representing the number n, destroys n
Definition: p_polys.cc:1444
BOOLEAN rOrd_is_WeightedDegree_Ordering(const ring r)
Definition: ring.cc:1904
void p_Setm_WFirstTotalDegree(poly p, const ring r)
Definition: p_polys.cc:555
static BOOLEAN rField_is_Ring_ModN(const ring r)
Definition: ring.h:468
#define id_Test(A, lR)
Definition: simpleideals.h:80
char * rString(ring r)
Definition: ring.cc:648
static unsigned long p_SetComp(poly p, unsigned long c, ring r)
Definition: p_polys.h:242
char * rParStr(ring r)
Definition: ring.cc:624
struct p_Procs_s p_Procs_s
Definition: ring.h:29
static BOOLEAN rField_is_R(const ring r)
Definition: ring.h:510
#define p_GetComp(p, r)
Definition: monomials.h:72
static int rRealloc1(ring r, int size, int pos)
Definition: ring.cc:5153
BOOLEAN rOrd_is_MixedDegree_Ordering(ring r)
Definition: ring.cc:3343
bool nc_SetupQuotient(ring rGR, const ring rG=NULL, bool bCopy=false)
Definition: old.gring.cc:3434
ring rCopy0AndAddA(const ring r, int64vec *wv64, BOOLEAN copy_qideal, BOOLEAN copy_ordering)
Definition: ring.cc:1462
rational (GMP) numbers
Definition: coeffs.h:31
ring rModifyRing_Wp(ring r, int *weights)
construct Wp, C ring
Definition: ring.cc:2853
BOOLEAN rIsPolyVar(int v, const ring r)
returns TRUE if var(i) belongs to p-block
Definition: ring.cc:1913
void rUnComplete(ring r)
Definition: ring.cc:3860
#define omFreeSize(addr, size)
Definition: omAllocDecl.h:260
{p < 2^31}
Definition: coeffs.h:30
int rChar(ring r)
Definition: ring.cc:688
static BOOLEAN rShortOut(const ring r)
Definition: ring.h:572
ring rOpposite(ring src)
Definition: ring.cc:5189
static short rVar(const ring r)
#define rVar(r) (r->N)
Definition: ring.h:583
void id_Delete(ideal *h, ring r)
deletes an ideal/module/matrix
#define omfreeSize(addr, size)
Definition: omAllocDecl.h:236
static void m_DebugPrint(const poly p, const ring R)
debug-print monomial poly/vector p, assuming that it lives in the ring R
Definition: ring.cc:4240
long pLDeg0c(poly p, int *l, const ring r)
Definition: p_polys.cc:771
void nc_rKill(ring r)
complete destructor
Definition: old.gring.cc:2486
static void rNGetSComps(int **currComponents, long **currShiftedComponents, ring r)
Definition: ring.cc:4303
static void rOppWeight(int *w, int l)
Definition: ring.cc:5176
ring rModifyRing(ring r, BOOLEAN omit_degree, BOOLEAN try_omit_comp, unsigned long exp_limit)
Definition: ring.cc:2606
long int64
Definition: auxiliary.h:66
void p_Debug_GetSpecNames(const ring r, const char *&field, const char *&length, const char *&ord)
Definition: p_Procs_Set.h:200
BOOLEAN rOrder_is_WeightedOrdering(rRingOrder_t order)
Definition: ring.cc:1825
#define omUnGetSpecBin(bin_ptr)
Definition: omBin.h:14
static BOOLEAN rField_is_Q_a(const ring r)
Definition: ring.h:531
Definition: ring.h:255
#define TRUE
Definition: auxiliary.h:98
ring rAssure_SyzOrder(const ring r, BOOLEAN complete)
Definition: ring.cc:4358
static long p_Totaldegree(poly p, const ring r)
Definition: p_polys.h:1430
static void rO_ISPrefix(int &place, int &bitplace, int &prev_ord, long *o, int, int *v, sro_ord &ord_struct)
Definition: ring.cc:2364
#define MIN(a, b)
Definition: omDebug.c:102
void * ADDRESS
Definition: auxiliary.h:115
BOOLEAN rOrder_is_DegOrdering(const rRingOrder_t order)
Definition: ring.cc:1806
simple ordering, component has priority
Definition: ring.h:108
#define POLYSIZE
Definition: monomials.h:241
static void rO_Syz(int &place, int &bitplace, int &prev_ord, int syz_comp, long *o, sro_ord &ord_struct)
Definition: ring.cc:2338
void WerrorS(const char *s)
Definition: feFopen.cc:24
int k
Definition: cfEzgcd.cc:93
void p_Setm_TotalDegree(poly p, const ring r)
Definition: p_polys.cc:548
static BOOLEAN rField_is_GF(const ring r)
Definition: ring.h:513
static char const ** rParameter(const ring r)
(r->cf->parameter)
Definition: ring.h:616
char * StringEndS()
Definition: reporter.cc:151
long * currShiftedComponents
Definition: syz1.cc:40
int rGetISPos(const int p, const ring r)
Finds p^th IS ordering, and returns its position in r->typ[] returns -1 if something went wrong! p - ...
Definition: ring.cc:4903
#define Q
Definition: sirandom.c:25
#define rOppVar(R, I)
Definition: ring.cc:5187
BOOLEAN rDBTest(ring r, const char *fn, const int l)
Definition: ring.cc:1952
ring rAssure_HasComp(const ring r)
Definition: ring.cc:4557
long pLDeg1_Deg(poly p, int *l, const ring r)
Definition: p_polys.cc:911
#define WarnS
Definition: emacs.cc:81
Definition: ring.h:66
Definition: nc.h:83
ring rAssure_c_dp(const ring r)
Definition: ring.cc:4893
#define omAlloc(size)
Definition: omAllocDecl.h:210
#define Sy_bit(x)
Definition: options.h:30
ring rAssure_SyzComp_CompLastBlock(const ring r)
makes sure that c/C ordering is last ordering and SyzIndex is first
Definition: ring.cc:4667
static BOOLEAN rCanShortOut(const ring r)
Definition: ring.h:577
Definition: ring.h:64
BOOLEAN rHasSimpleOrder(const ring r)
Definition: ring.cc:1765
union sro_ord::@0 data
BOOLEAN rHas_c_Ordering(const ring r)
Definition: ring.cc:1761
ideal idrHeadR(ideal id, ring r, ring dest_r)
Copy leading terms of id[i] via prHeeadR into dest_r.
Definition: prCopy.cc:157
BOOLEAN rHasSimpleOrderAA(ring r)
Definition: ring.cc:1840
ideal idOppose(ring Rop_src, ideal I, const ring Rop_dst)
opposes a module I from Rop to currRing(dst)
Definition: old.gring.cc:3412
static void rSetOption(ring r)
Definition: ring.cc:3299
real floating point (GMP) numbers
Definition: coeffs.h:34
void iiWriteMatrix(matrix im, const char *n, int dim, const ring r, int spaces)
set spaces to zero by default
Definition: matpol.cc:743
void idShow(const ideal id, const ring lmRing, const ring tailRing, const int debugPrint)
Definition: simpleideals.cc:60
bool found
Definition: facFactorize.cc:56
static void rDBGetSComps(int **currComponents, long **currShiftedComponents, int *length, ring r)
Definition: ring.cc:4321
simple ordering, exponent vector has priority component not compatible with exp-vector order ...
Definition: ring.h:109
long pLDeg1c_Deg(poly p, int *l, const ring r)
Definition: p_polys.cc:942
int * block0
Definition: ring.h:262
ring rAssure_InducedSchreyerOrdering(const ring r, BOOLEAN complete, int sgn)
Definition: ring.cc:4767
#define pIter(p)
Definition: monomials.h:44
int rSum(ring r1, ring r2, ring &sum)
Definition: ring.cc:1306
poly res
Definition: myNF.cc:322
static void rSetDegStuff(ring r)
Definition: ring.cc:3092
#define omReallocSize(addr, o_size, size)
Definition: omAllocDecl.h:220
bool sca_Force(ring rGR, int b, int e)
Definition: sca.cc:1174
static void rO_LexVars_neg(int &place, int &bitplace, int start, int end, int &prev_ord, long *o, int *v, int bits, int opt_var)
Definition: ring.cc:2284
static void rO_Align(int &place, int &bitplace)
Definition: ring.cc:2102
single prescision (6,6) real numbers
Definition: coeffs.h:32
void rGetSComps(int **currComponents, long **currShiftedComponents, int *length, ring r)
Definition: ring.cc:4342
ro_typ ord_typ
Definition: ring.h:228
static void rDBChangeSComps(int *currComponents, long *currShiftedComponents, int length, ring r)
Definition: ring.cc:4311
static int rBlocks(ring r)
Definition: ring.h:559
int r_IsRingVar(const char *n, char **names, int N)
Definition: ring.cc:222
long p_Deg(poly a, const ring r)
Definition: p_polys.cc:588
const ring r
Definition: syzextra.cc:208
poly p_PermPoly(poly p, const int *perm, const ring oldRing, const ring dst, nMapFunc nMap, const int *par_perm, int OldPar, BOOLEAN use_mult)
Definition: p_polys.cc:3985
static void rO_WMDegree(int &place, int &bitplace, int start, int end, long *o, sro_ord &ord_struct, int *weights)
Definition: ring.cc:2181
Coefficient rings, fields and other domains suitable for Singular polynomials.
static FORCE_INLINE BOOLEAN nCoeff_is_algExt(const coeffs r)
TRUE iff r represents an algebraic extension field.
Definition: coeffs.h:927
int naIsParam(number m, const coeffs cf)
if m == var(i)/1 => return i,
Definition: algext.cc:1106
BOOLEAN rHasTDeg(ring r)
Definition: ring.cc:4444
Definition: intvec.h:14
long id_RankFreeModule(ideal s, ring lmRing, ring tailRing)
return the maximal component number found in any polynomial in s
const CanonicalForm CFMap CFMap & N
Definition: cfEzgcd.cc:49
poly p_One(const ring r)
Definition: p_polys.cc:1314
BOOLEAN rComplete(ring r, int force)
this needs to be called whenever a new ring is created: new fields in ring are created (like VarOffse...
Definition: ring.cc:3365
static void rO_WDegree_neg(int &place, int &bitplace, int start, int end, long *o, sro_ord &ord_struct, int *weights)
Definition: ring.cc:2221
for(int i=0;i< R->ExpL_Size;i++) Print("%09lx "
Definition: cfEzgcd.cc:66
static long p_GetExp(const poly p, const unsigned long iBitmask, const int VarOffset)
get a single variable exponent : the integer VarOffset encodes:
Definition: p_polys.h:464
#define OPT_REDTAIL
Definition: options.h:86
int j
Definition: myNF.cc:70
only used if HAVE_RINGS is defined
Definition: coeffs.h:45
#define omFree(addr)
Definition: omAllocDecl.h:261
#define TEST_OPT_OLDSTD
Definition: options.h:117
#define assume(x)
Definition: mod2.h:394
static BOOLEAN rIsPluralRing(const ring r)
we must always have this test!
Definition: ring.h:404
The main handler for Singular numbers which are suitable for Singular polynomials.
long p_WFirstTotalDegree(poly p, const ring r)
Definition: p_polys.cc:597
void StringSetS(const char *st)
Definition: reporter.cc:128
int rGetMaxSyzComp(int i, const ring r)
return the max-comonent wchich has syzIndex i Assume: i<= syzIndex_limit
Definition: ring.cc:5061
static void rO_TDegree_neg(int &place, int &bitplace, int start, int end, long *o, sro_ord &ord_struct)
Definition: ring.cc:2127
int rows() const
Definition: int64vec.h:57
ring rCopy0(const ring r, BOOLEAN copy_qideal, BOOLEAN copy_ordering)
Definition: ring.cc:1325
void StringAppendS(const char *st)
Definition: reporter.cc:107
#define A
Definition: sirandom.c:23
number(* nMapFunc)(number a, const coeffs src, const coeffs dst)
maps "a", which lives in src, into dst
Definition: coeffs.h:73
long pLDeg0(poly p, int *l, const ring r)
Definition: p_polys.cc:740
ring rAssure_SyzComp(const ring r, BOOLEAN complete)
Definition: ring.cc:4363
const ring R
Definition: DebugPrint.cc:36
ring rAssure_dp_C(const ring r)
Definition: ring.cc:4883
complex floating point (GMP) numbers
Definition: coeffs.h:42
const char * rSimpleOrdStr(int ord)
Definition: ring.cc:88
const int MAX_INT_VAL
Definition: mylimits.h:12
rRingOrder_t
order stuff
Definition: ring.h:75
gmp_float sqrt(const gmp_float &a)
Definition: mpr_complex.cc:329
static ring rAssure_Global(rRingOrder_t b1, rRingOrder_t b2, const ring r)
Definition: ring.cc:4722
#define rTest(r)
Definition: ring.h:777
BOOLEAN rOrd_is_Totaldegree_Ordering(const ring r)
Definition: ring.cc:1891
void p_Setm_Dummy(poly p, const ring r)
Definition: p_polys.cc:542
static long p_FDeg(const poly p, const ring r)
Definition: p_polys.h:375
BOOLEAN rCheckIV(const intvec *iv)
Definition: ring.cc:185
Definition: ring.h:226
All the auxiliary stuff.
omBin sip_sring_bin
Definition: ring.cc:54
int m
Definition: cfEzgcd.cc:119
BOOLEAN rSamePolyRep(ring r1, ring r2)
returns TRUE, if r1 and r2 represents the monomials in the same way FALSE, otherwise this is an analo...
Definition: ring.cc:1677
only used if HAVE_RINGS is defined
Definition: coeffs.h:43
#define pFDeg_CASE(A)
static int si_max(const int a, const int b)
Definition: auxiliary.h:120
void rDebugPrint(const ring r)
Definition: ring.cc:4012
#define StringAppend
Definition: emacs.cc:82
static void rO_WDegree64(int &place, int &bitplace, int start, int end, long *o, sro_ord &ord_struct, int64 *weights)
Definition: ring.cc:2203
int i
Definition: cfEzgcd.cc:123
Induced (Schreyer) ordering.
Definition: ring.h:101
void PrintS(const char *s)
Definition: reporter.cc:284
ring rAssure_TDeg(ring r, int &pos)
Definition: ring.cc:4462
static BOOLEAN rField_is_Q(const ring r)
Definition: ring.h:501
ring rAssure_CompLastBlock(ring r, BOOLEAN complete)
makes sure that c/C ordering is last ordering
Definition: ring.cc:4612
rRingOrder_t * order
Definition: ring.h:261
static void rO_Syzcomp(int &place, int &bitplace, int &prev_ord, long *o, sro_ord &ord_struct)
Definition: ring.cc:2323
void p_Debug_GetProcNames(const ring r, p_Procs_s *p_Procs)
Definition: p_Procs_Set.h:211
S?
Definition: ring.h:83
BOOLEAN rOrd_SetCompRequiresSetm(const ring r)
return TRUE if p_SetComp requires p_Setm
Definition: ring.cc:1871
static void rSetVarL(ring r)
set r->VarL_Size, r->VarL_Offset, r->VarL_LowIndex
Definition: ring.cc:3917
static void rSetFirstWv(ring r, int i, rRingOrder_t *order, int *block1, int **wvhdl)
Definition: ring.cc:3033
void rWrite(ring r, BOOLEAN details)
Definition: ring.cc:236
ring rDefault(const coeffs cf, int N, char **n, int ord_size, rRingOrder_t *ord, int *block0, int *block1, int **wvhdl)
Definition: ring.cc:113
void rKillModified_Wp_Ring(ring r)
Definition: ring.cc:2982
static void rSetOutParams(ring r)
Definition: ring.cc:2993
static unsigned long rGetExpSize(unsigned long bitmask, int &bits)
Definition: ring.cc:2473
#define IDELEMS(i)
Definition: simpleideals.h:24
BOOLEAN rEqual(ring r1, ring r2, BOOLEAN qr)
returns TRUE, if r1 equals r2 FALSE, otherwise Equality is determined componentwise, if qr == 1, then qrideal equality is tested, as well
Definition: ring.cc:1629
void mp_Delete(matrix *a, const ring r)
Definition: matpol.cc:789
static FORCE_INLINE nMapFunc n_SetMap(const coeffs src, const coeffs dst)
set the mapping function pointers for translating numbers from src to dst
Definition: coeffs.h:725
short OrdSgn
Definition: ring.h:313
static short scaFirstAltVar(ring r)
Definition: sca.h:18
static FORCE_INLINE n_coeffType getCoeffType(const coeffs r)
Returns the type of coeffs domain.
Definition: coeffs.h:425
Definition: ring.h:69
BOOLEAN p_EqualPolys(poly p1, poly p2, const ring r)
Definition: p_polys.cc:4367
#define p_Test(p, r)
Definition: p_polys.h:160
static BOOLEAN rField_is_long_C(const ring r)
Definition: ring.h:537
void rSetSyzComp(int k, const ring r)
Definition: ring.cc:4989
Definition: ring.h:69
int size(const CanonicalForm &f, const Variable &v)
int size ( const CanonicalForm & f, const Variable & v )
Definition: cf_ops.cc:600
static BOOLEAN rField_is_Zp(const ring r)
Definition: ring.h:495
#define OPT_INTSTRATEGY
Definition: options.h:87
rOrderType_t
Definition: ring.h:105
void pISUpdateComponents(ideal F, const intvec *const V, const int MIN, const ring r)
Definition: ring.cc:4254
matrix mpNew(int r, int c)
create a r x c zero-matrix
Definition: matpol.cc:44
static FORCE_INLINE coeffs nCopyCoeff(const coeffs r)
"copy" coeffs, i.e. increment ref
Definition: coeffs.h:433
void p_Write0(poly p, ring lmRing, ring tailRing)
Definition: polys0.cc:196
static void p_Delete(poly *p, const ring r)
Definition: p_polys.h:843
#define omAlloc0Bin(bin)
Definition: omAllocDecl.h:206
#define omGetSpecBin(size)
Definition: omBin.h:11
ideal idInit(int idsize, int rank)
initialise an ideal / module
Definition: simpleideals.cc:38
void rSetWeightVec(ring r, int64 *wv)
Definition: ring.cc:5143
BOOLEAN nc_CallPlural(matrix cc, matrix dd, poly cn, poly dn, ring r, bool bSetupQuotient, bool bCopyInput, bool bBeQuiet, ring curr, bool dummy_ring=false)
returns TRUE if there were errors analyze inputs, check them for consistency detects nc_type...
Definition: old.gring.cc:2693
const Variable & v
< [in] a sqrfree bivariate poly
Definition: facBivar.h:37
bool nc_rCopy(ring res, const ring r, bool bSetupQuotient)
Definition: old.gring.cc:3034
ring rCopy(ring r)
Definition: ring.cc:1614
static unsigned long rGetDivMask(int bits)
get r->divmask depending on bits per exponent
Definition: ring.cc:3998
static unsigned long p_SetExp(poly p, const unsigned long e, const unsigned long iBitmask, const int VarOffset)
set a single variable exponent : VarOffset encodes the position in p->exp
Definition: p_polys.h:483
BOOLEAN rHasSimpleLexOrder(const ring r)
returns TRUE, if simple lp or ls ordering
Definition: ring.cc:1797
n_coeffType
Definition: coeffs.h:27
static void rO_TDegree(int &place, int &bitplace, int start, int end, long *o, sro_ord &ord_struct)
Definition: ring.cc:2113
void maFindPerm(char const *const *const preim_names, int preim_n, char const *const *const preim_par, int preim_p, char const *const *const names, int n, char const *const *const par, int nop, int *perm, int *par_perm, n_coeffType ch)
Definition: maps.cc:169
CanonicalForm cf
Definition: cfModGcd.cc:4024
long pLDegb(poly p, int *l, const ring r)
Definition: p_polys.cc:812
static FORCE_INLINE void n_CoeffWrite(const coeffs r, BOOLEAN details=TRUE)
output the coeff description
Definition: coeffs.h:745
static BOOLEAN rField_is_Ring_2toM(const ring r)
Definition: ring.h:465
static BOOLEAN rField_is_Ring(const ring r)
Definition: ring.h:477
#define NULL
Definition: omList.c:10
ring rAssure_dp_S(const ring r)
Definition: ring.cc:4878
static const char *const ringorder_name[]
Definition: ring.cc:58
long pLDeg1_Totaldegree(poly p, int *l, const ring r)
Definition: p_polys.cc:976
int length() const
Definition: intvec.h:86
{p^n < 2^16}
Definition: coeffs.h:33
static FORCE_INLINE number n_Copy(number n, const coeffs r)
return a copy of &#39;n&#39;
Definition: coeffs.h:455
int * block1
Definition: ring.h:263
void rDelete(ring r)
unconditionally deletes fields in r
Definition: ring.cc:448
ring rAssure_C_dp(const ring r)
Definition: ring.cc:4888
used for all algebraic extensions, i.e., the top-most extension in an extension tower is algebraic ...
Definition: coeffs.h:36
char ** names
Definition: ring.h:266
static BOOLEAN rField_is_Ring_Z(const ring r)
Definition: ring.h:474
ring nc_rCreateNCcomm_rCopy(ring r)
Definition: ring.cc:696
void p_ProcsSet(ring r, p_Procs_s *p_Procs)
Definition: p_Procs_Set.h:138
static BOOLEAN rField_is_long_R(const ring r)
Definition: ring.h:534
int rTypeOfMatrixOrder(const intvec *order)
Definition: ring.cc:195
const CanonicalForm & w
Definition: facAbsFact.cc:55
static short scaLastAltVar(ring r)
Definition: sca.h:25
static void rO_WDegree(int &place, int &bitplace, int start, int end, long *o, sro_ord &ord_struct, int *weights)
Definition: ring.cc:2141
BOOLEAN rSetISReference(const ring r, const ideal F, const int i, const int p)
Changes r by setting induced ordering parameters: limit and reference leading terms F belong to r...
Definition: ring.cc:4935
Variable x
Definition: cfModGcd.cc:4023
Definition: ring.h:63
void rModify_a_to_A(ring r)
Definition: ring.cc:5611
static bool rIsSCA(const ring r)
Definition: nc.h:206
static void rRightAdjustVarOffset(ring r)
right-adjust r->VarOffset
Definition: ring.cc:3972
Definition: ring.h:60
#define BITS_PER_LONG
Definition: ring.cc:52
void rKillModifiedRing(ring r)
Definition: ring.cc:2972
#define OPT_REDTHROUGH
Definition: options.h:77
ideal idrCopyR(ideal id, ring src_r, ring dest_r)
Definition: prCopy.cc:193
static void p_Setm(poly p, const ring r)
Definition: p_polys.h:228
#define p_GetCoeff(p, r)
Definition: monomials.h:57
long pLDeg1_WFirstTotalDegree(poly p, int *l, const ring r)
Definition: p_polys.cc:1039
rRingOrder_t rOrderName(char *ordername)
Definition: ring.cc:508
static nc_type & ncRingType(nc_struct *p)
Definition: nc.h:175
long pLDeg1c_WFirstTotalDegree(poly p, int *l, const ring r)
Definition: p_polys.cc:1069
Definition: ring.h:62
int dReportError(const char *fmt,...)
Definition: dError.cc:45
static FORCE_INLINE BOOLEAN nCoeff_is_Extension(const coeffs r)
Definition: coeffs.h:863
int ntIsParam(number m, const coeffs cf)
if m == var(i)/1 => return i,
Definition: transext.cc:2199
int n_IsParam(const number m, const ring r)
TODO: rewrite somehow...
Definition: ring.cc:5644
#define BIT_SIZEOF_LONG
Definition: auxiliary.h:78
#define TEST_RINGDEP_OPTS
Definition: options.h:95
long p_WTotaldegree(poly p, const ring r)
Definition: p_polys.cc:614
#define omCheckAddr(addr)
Definition: omAllocDecl.h:328
void p_wrp(poly p, ring lmRing, ring tailRing)
Definition: polys0.cc:237
char * rCharStr(const ring r)
TODO: make it a virtual method of coeffs, together with: Decompose & Compose, rParameter & rPar...
Definition: ring.cc:622
void p_Write(poly p, ring lmRing, ring tailRing)
Definition: polys0.cc:206
static FORCE_INLINE char * nCoeffString(const coeffs cf)
TODO: make it a virtual method of coeffs, together with: Decompose & Compose, rParameter & rPar...
Definition: coeffs.h:976
polyrec * poly
Definition: hilb.h:10
static void rCheckOrdSgn(ring r, int i)
Definition: ring.cc:3767
int ** wvhdl
Definition: ring.h:265
#define omFreeBin(addr, bin)
Definition: omAllocDecl.h:259
ring rModifyRing_Simple(ring r, BOOLEAN ommit_degree, BOOLEAN ommit_comp, unsigned long exp_limit, BOOLEAN &simple)
Definition: ring.cc:2901
void p_SetGlobals(const ring r, BOOLEAN complete)
set all properties of a new ring - also called by rComplete
Definition: ring.cc:3330
s?
Definition: ring.h:84
int BOOLEAN
Definition: auxiliary.h:85
const poly b
Definition: syzextra.cc:213
BOOLEAN rRing_has_CompLastBlock(ring r)
Definition: ring.cc:5107
void rKillModifiedRing_Simple(ring r)
Definition: ring.cc:2966
ideal idrCopyR_NoSort(ideal id, ring src_r, ring dest_r)
Definition: prCopy.cc:206
void rChangeSComps(int *currComponents, long *currShiftedComponents, int length, ring r)
Definition: ring.cc:4333
void nKillChar(coeffs r)
undo all initialisations
Definition: numbers.cc:504
ideal id_SimpleAdd(ideal h1, ideal h2, const ring R)
concat the lists h1 and h2 without zeros
poly p_ISet(long i, const ring r)
returns the poly representing the integer i
Definition: p_polys.cc:1298
static int sign(int x)
Definition: ring.cc:3342
char * rOrdStr(ring r)
Definition: ring.cc:522
void Werror(const char *fmt,...)
Definition: reporter.cc:189
int64 * rGetWeightVec(const ring r)
Definition: ring.cc:5133
#define omAlloc0(size)
Definition: omAllocDecl.h:211
int l
Definition: cfEzgcd.cc:94
static void rNChangeSComps(int *currComponents, long *currShiftedComponents, ring r)
Definition: ring.cc:4295
used to represent polys as coeffcients
Definition: coeffs.h:35
#define UPMATELEM(i, j, nVar)
Definition: nc.h:44
#define MATELEM(mat, i, j)
Definition: matpol.h:29
coeffs nInitChar(n_coeffType t, void *parameter)
one-time initialisations for new coeffs in case of an error return NULL
Definition: numbers.cc:341
unsigned long bitmask
Definition: ring.h:357
#define Warn
Definition: emacs.cc:80
#define omStrDup(s)
Definition: omAllocDecl.h:263