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