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, const rRingOrder_t o)
149 {
150  assume( cf != NULL);
151  /*order: o=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 o=lp for the first block: var 1..N */
156  order[0] = o;
157  block0[0] = 1;
158  block1[0] = N;
159  /* the last block: everything is 0 */
160  order[1] = 0;
161 
162  return rDefault(cf,N,n,2,order,block0,block1);
163 }
164 
165 ring rDefault(int ch, int N, char **n)
166 {
167  coeffs cf;
168  if (ch==0) cf=nInitChar(n_Q,NULL);
169  else cf=nInitChar(n_Zp,(void*)(long)ch);
170  assume( cf != NULL);
171  return rDefault(cf,N,n);
172 }
173 
174 ///////////////////////////////////////////////////////////////////////////
175 //
176 // rInit: define a new ring from sleftv's
177 //
178 //-> ipshell.cc
179 
180 /////////////////////////////
181 // Auxillary functions
182 //
183 
184 // check intvec, describing the ordering
186 {
187  if ((iv->length()!=2)&&(iv->length()!=3))
188  {
189  WerrorS("weights only for orderings wp,ws,Wp,Ws,a,M");
190  return TRUE;
191  }
192  return FALSE;
193 }
194 
195 int rTypeOfMatrixOrder(const intvec* order)
196 {
197  int i=0,j,typ=1;
198  int sz = (int)sqrt((double)(order->length()-2));
199  if ((sz*sz)!=(order->length()-2))
200  {
201  WerrorS("Matrix order is not a square matrix");
202  typ=0;
203  }
204  while ((i<sz) && (typ==1))
205  {
206  j=0;
207  while ((j<sz) && ((*order)[j*sz+i+2]==0)) j++;
208  if (j>=sz)
209  {
210  typ = 0;
211  WerrorS("Matrix order not complete");
212  }
213  else if ((*order)[j*sz+i+2]<0)
214  typ = -1;
215  else
216  i++;
217  }
218  return typ;
219 }
220 
221 
222 int r_IsRingVar(const char *n, char**names,int N)
223 {
224  if (names!=NULL)
225  {
226  for (int i=0; i<N; i++)
227  {
228  if (names[i]==NULL) return -1;
229  if (strcmp(n,names[i]) == 0) return (int)i;
230  }
231  }
232  return -1;
233 }
234 
235 
236 void rWrite(ring r, BOOLEAN details)
237 {
238  if ((r==NULL)||(r->order==NULL))
239  return; /*to avoid printing after errors....*/
240 
241  assume(r != NULL);
242  const coeffs C = r->cf;
243  assume(C != NULL);
244 
245  int nblocks=rBlocks(r);
246 
247  // omCheckAddrSize(r,sizeof(ip_sring));
248  omCheckAddrSize(r->order,nblocks*sizeof(int));
249  omCheckAddrSize(r->block0,nblocks*sizeof(int));
250  omCheckAddrSize(r->block1,nblocks*sizeof(int));
251  omCheckAddrSize(r->wvhdl,nblocks*sizeof(int *));
252  omCheckAddrSize(r->names,r->N*sizeof(char *));
253 
254  nblocks--;
255 
256 
257  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)&&(r->cf!=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("undefined");
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=0;
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==NULL)||(r2==NULL)
1305  ||(r1->cf==NULL)||(r2->cf==NULL))
1306  return -1;
1307  if (r1==r2)
1308  {
1309  sum=r1;
1310  r1->ref++;
1311  return 0;
1312  }
1313  return rSumInternal(r1,r2,sum,TRUE,FALSE);
1314 }
1315 
1316 /*2
1317  * create a copy of the ring r
1318  * used for qring definition,..
1319  * DOES NOT CALL rComplete
1320  */
1321 ring rCopy0(const ring r, BOOLEAN copy_qideal, BOOLEAN copy_ordering)
1322 {
1323  if (r == NULL) return NULL;
1324  int i,j;
1325  ring res=(ring)omAllocBin(sip_sring_bin);
1326  memset(res,0,sizeof(ip_sring));
1327  //memcpy(res,r,sizeof(ip_sring));
1328  //memset: res->idroot=NULL; /* local objects */
1329  //ideal minideal;
1330  res->options=r->options; /* ring dependent options */
1331 
1332  //memset: res->ordsgn=NULL;
1333  //memset: res->typ=NULL;
1334  //memset: res->VarOffset=NULL;
1335  //memset: res->firstwv=NULL;
1336 
1337  //struct omBin PolyBin; /* Bin from where monoms are allocated */
1338  //memset: res->PolyBin=NULL; // rComplete
1339  res->cf=nCopyCoeff(r->cf); /* coeffs */
1340 
1341  //memset: res->ref=0; /* reference counter to the ring */
1342 
1343  res->N=rVar(r); /* number of vars */
1344 
1345  res->firstBlockEnds=r->firstBlockEnds;
1346 #ifdef HAVE_PLURAL
1347  res->real_var_start=r->real_var_start;
1348  res->real_var_end=r->real_var_end;
1349 #endif
1350 
1351 #ifdef HAVE_SHIFTBBA
1352  res->isLPring=r->isLPring; /* 0 for non-letterplace rings, otherwise the number of LP blocks, at least 1, known also as lV */
1353 #endif
1354 
1355  res->VectorOut=r->VectorOut;
1356  res->ShortOut=r->ShortOut;
1357  res->CanShortOut=r->CanShortOut;
1358 
1359  //memset: res->ExpL_Size=0;
1360  //memset: res->CmpL_Size=0;
1361  //memset: res->VarL_Size=0;
1362  //memset: res->pCompIndex=0;
1363  //memset: res->pOrdIndex=0;
1364  //memset: res->OrdSize=0;
1365  //memset: res->VarL_LowIndex=0;
1366  //memset: res->NegWeightL_Size=0;
1367  //memset: res->NegWeightL_Offset=NULL;
1368  //memset: res->VarL_Offset=NULL;
1369 
1370  // the following are set by rComplete unless predefined
1371  // therefore, we copy these values: maybe they are non-standard
1372  /* mask for getting single exponents */
1373  res->bitmask=r->bitmask;
1374  res->divmask=r->divmask;
1375  res->BitsPerExp = r->BitsPerExp;
1376  res->ExpPerLong = r->ExpPerLong;
1377 
1378  //memset: res->p_Procs=NULL;
1379  //memset: res->pFDeg=NULL;
1380  //memset: res->pLDeg=NULL;
1381  //memset: res->pFDegOrig=NULL;
1382  //memset: res->pLDegOrig=NULL;
1383  //memset: res->p_Setm=NULL;
1384  //memset: res->cf=NULL;
1385 
1386 /*
1387  if (r->extRing!=NULL)
1388  r->extRing->ref++;
1389 
1390  res->extRing=r->extRing;
1391  //memset: res->qideal=NULL;
1392 */
1393 
1394 
1395  if (copy_ordering == TRUE)
1396  {
1397  res->LexOrder=r->LexOrder; // TRUE if the monomial ordering has polynomial and power series blocks
1398  res->MixedOrder=r->MixedOrder; // TRUE for mixed (global/local) ordering, FALSE otherwise,
1399  i=rBlocks(r);
1400  res->wvhdl = (int **)omAlloc(i * sizeof(int *));
1401  res->order = (int *) omAlloc(i * sizeof(int));
1402  res->block0 = (int *) omAlloc(i * sizeof(int));
1403  res->block1 = (int *) omAlloc(i * sizeof(int));
1404  for (j=0; j<i; j++)
1405  {
1406  if (r->wvhdl[j]!=NULL)
1407  {
1408  res->wvhdl[j] = (int*) omMemDup(r->wvhdl[j]);
1409  }
1410  else
1411  res->wvhdl[j]=NULL;
1412  }
1413  memcpy(res->order,r->order,i * sizeof(int));
1414  memcpy(res->block0,r->block0,i * sizeof(int));
1415  memcpy(res->block1,r->block1,i * sizeof(int));
1416  }
1417  //memset: else
1418  //memset: {
1419  //memset: res->wvhdl = NULL;
1420  //memset: res->order = NULL;
1421  //memset: res->block0 = NULL;
1422  //memset: res->block1 = NULL;
1423  //memset: }
1424 
1425  res->names = (char **)omAlloc0(rVar(r) * sizeof(char *));
1426  for (i=0; i<rVar(res); i++)
1427  {
1428  res->names[i] = omStrDup(r->names[i]);
1429  }
1430  if (r->qideal!=NULL)
1431  {
1432  if (copy_qideal)
1433  {
1434  #ifndef SING_NDEBUG
1435  if (!copy_ordering)
1436  WerrorS("internal error: rCopy0(Q,TRUE,FALSE)");
1437  else
1438  #endif
1439  {
1440  #ifndef SING_NDEBUG
1441  WarnS("internal bad stuff: rCopy0(Q,TRUE,TRUE)");
1442  #endif
1443  rComplete(res);
1444  res->qideal= idrCopyR_NoSort(r->qideal, r, res);
1445  rUnComplete(res);
1446  }
1447  }
1448  //memset: else res->qideal = NULL;
1449  }
1450  //memset: else res->qideal = NULL;
1451  //memset: res->GetNC() = NULL; // copy is purely commutative!!!
1452  return res;
1453 }
1454 
1455 /*2
1456  * create a copy of the ring r
1457  * used for qring definition,..
1458  * DOES NOT CALL rComplete
1459  */
1460 ring rCopy0AndAddA(const ring r, int64vec *wv64, BOOLEAN copy_qideal, BOOLEAN copy_ordering)
1461 {
1462  if (r == NULL) return NULL;
1463  int i,j;
1464  ring res=(ring)omAlloc0Bin(sip_sring_bin);
1465  //memcpy(res,r,sizeof(ip_sring));
1466  //memset: res->idroot=NULL; /* local objects */
1467  //ideal minideal;
1468  res->options=r->options; /* ring dependent options */
1469 
1470  //memset: res->ordsgn=NULL;
1471  //memset: res->typ=NULL;
1472  //memset: res->VarOffset=NULL;
1473  //memset: res->firstwv=NULL;
1474 
1475  //struct omBin PolyBin; /* Bin from where monoms are allocated */
1476  //memset: res->PolyBin=NULL; // rComplete
1477  res->cf=nCopyCoeff(r->cf); /* coeffs */
1478 
1479  //memset: res->ref=0; /* reference counter to the ring */
1480 
1481  res->N=rVar(r); /* number of vars */
1482 
1483  res->firstBlockEnds=r->firstBlockEnds;
1484 #ifdef HAVE_PLURAL
1485  res->real_var_start=r->real_var_start;
1486  res->real_var_end=r->real_var_end;
1487 #endif
1488 
1489 #ifdef HAVE_SHIFTBBA
1490  res->isLPring=r->isLPring; /* 0 for non-letterplace rings, otherwise the number of LP blocks, at least 1, known also as lV */
1491 #endif
1492 
1493  res->VectorOut=r->VectorOut;
1494  res->ShortOut=r->ShortOut;
1495  res->CanShortOut=r->CanShortOut;
1496  res->LexOrder=r->LexOrder; // TRUE if the monomial ordering has polynomial and power series blocks
1497  res->MixedOrder=r->MixedOrder; // TRUE for mixed (global/local) ordering, FALSE otherwise,
1498 
1499  //memset: res->ExpL_Size=0;
1500  //memset: res->CmpL_Size=0;
1501  //memset: res->VarL_Size=0;
1502  //memset: res->pCompIndex=0;
1503  //memset: res->pOrdIndex=0;
1504  //memset: res->OrdSize=0;
1505  //memset: res->VarL_LowIndex=0;
1506  //memset: res->NegWeightL_Size=0;
1507  //memset: res->NegWeightL_Offset=NULL;
1508  //memset: res->VarL_Offset=NULL;
1509 
1510  // the following are set by rComplete unless predefined
1511  // therefore, we copy these values: maybe they are non-standard
1512  /* mask for getting single exponents */
1513  res->bitmask=r->bitmask;
1514  res->divmask=r->divmask;
1515  res->BitsPerExp = r->BitsPerExp;
1516  res->ExpPerLong = r->ExpPerLong;
1517 
1518  //memset: res->p_Procs=NULL;
1519  //memset: res->pFDeg=NULL;
1520  //memset: res->pLDeg=NULL;
1521  //memset: res->pFDegOrig=NULL;
1522  //memset: res->pLDegOrig=NULL;
1523  //memset: res->p_Setm=NULL;
1524  //memset: res->cf=NULL;
1525 
1526 /*
1527  if (r->extRing!=NULL)
1528  r->extRing->ref++;
1529 
1530  res->extRing=r->extRing;
1531  //memset: res->qideal=NULL;
1532 */
1533 
1534 
1535  if (copy_ordering == TRUE)
1536  {
1537  i=rBlocks(r)+1; // DIFF to rCopy0
1538  res->wvhdl = (int **)omAlloc(i * sizeof(int *));
1539  res->order = (int *) omAlloc(i * sizeof(int));
1540  res->block0 = (int *) omAlloc(i * sizeof(int));
1541  res->block1 = (int *) omAlloc(i * sizeof(int));
1542  for (j=0; j<i-1; j++)
1543  {
1544  if (r->wvhdl[j]!=NULL)
1545  {
1546  res->wvhdl[j+1] = (int*) omMemDup(r->wvhdl[j]); //DIFF
1547  }
1548  else
1549  res->wvhdl[j+1]=NULL; //DIFF
1550  }
1551  memcpy(&(res->order[1]),r->order,(i-1) * sizeof(int)); //DIFF
1552  memcpy(&(res->block0[1]),r->block0,(i-1) * sizeof(int)); //DIFF
1553  memcpy(&(res->block1[1]),r->block1,(i-1) * sizeof(int)); //DIFF
1554  }
1555  //memset: else
1556  //memset: {
1557  //memset: res->wvhdl = NULL;
1558  //memset: res->order = NULL;
1559  //memset: res->block0 = NULL;
1560  //memset: res->block1 = NULL;
1561  //memset: }
1562 
1563  //the added A
1564  res->order[0]=ringorder_a64;
1565  int length=wv64->rows();
1566  int64 *A=(int64 *)omAlloc(length*sizeof(int64));
1567  for(j=length-1;j>=0;j--)
1568  {
1569  A[j]=(*wv64)[j];
1570  }
1571  res->wvhdl[0]=(int *)A;
1572  res->block0[0]=1;
1573  res->block1[0]=length;
1574  //
1575 
1576  res->names = (char **)omAlloc0(rVar(r) * sizeof(char *));
1577  for (i=0; i<rVar(res); i++)
1578  {
1579  res->names[i] = omStrDup(r->names[i]);
1580  }
1581  if (r->qideal!=NULL)
1582  {
1583  if (copy_qideal)
1584  {
1585  #ifndef SING_NDEBUG
1586  if (!copy_ordering)
1587  WerrorS("internal error: rCopy0(Q,TRUE,FALSE)");
1588  else
1589  #endif
1590  {
1591  #ifndef SING_NDEBUG
1592  WarnS("internal bad stuff: rCopy0(Q,TRUE,TRUE)");
1593  #endif
1594  rComplete(res);
1595  res->qideal= idrCopyR_NoSort(r->qideal, r, res);
1596  rUnComplete(res);
1597  }
1598  }
1599  //memset: else res->qideal = NULL;
1600  }
1601  //memset: else res->qideal = NULL;
1602  //memset: res->GetNC() = NULL; // copy is purely commutative!!!
1603  return res;
1604 }
1605 
1606 /*2
1607  * create a copy of the ring r, which must be equivalent to currRing
1608  * used for qring definition,..
1609  * (i.e.: normal rings: same nCopy as currRing;
1610  * qring: same nCopy, same idCopy as currRing)
1611  */
1612 ring rCopy(ring r)
1613 {
1614  if (r == NULL) return NULL;
1615  ring res=rCopy0(r,FALSE,TRUE);
1616  rComplete(res, 1); // res is purely commutative so far
1617  if (r->qideal!=NULL) res->qideal=idrCopyR_NoSort(r->qideal, r, res);
1618 
1619 #ifdef HAVE_PLURAL
1620  if (rIsPluralRing(r))
1621  if( nc_rCopy(res, r, true) ) {}
1622 #endif
1623 
1624  return res;
1625 }
1626 
1627 BOOLEAN rEqual(ring r1, ring r2, BOOLEAN qr)
1628 {
1629  if (r1 == r2) return TRUE;
1630  if (r1 == NULL || r2 == NULL) return FALSE;
1631  if (r1->cf!=r2->cf) return FALSE;
1632  if (rVar(r1)!=rVar(r2)) return FALSE;
1633 
1634  if( !rSamePolyRep(r1, r2) )
1635  return FALSE;
1636 
1637  int i/*, j*/;
1638 
1639  for (i=0; i<rVar(r1); i++)
1640  {
1641  if ((r1->names[i] != NULL) && (r2->names[i] != NULL))
1642  {
1643  if (strcmp(r1->names[i], r2->names[i])) return FALSE;
1644  }
1645  else if ((r1->names[i] != NULL) ^ (r2->names[i] != NULL))
1646  {
1647  return FALSE;
1648  }
1649  }
1650 
1651  if (qr)
1652  {
1653  if (r1->qideal != NULL)
1654  {
1655  ideal id1 = r1->qideal, id2 = r2->qideal;
1656  int i, n;
1657  poly *m1, *m2;
1658 
1659  if (id2 == NULL) return FALSE;
1660  if ((n = IDELEMS(id1)) != IDELEMS(id2)) return FALSE;
1661 
1662  {
1663  m1 = id1->m;
1664  m2 = id2->m;
1665  for (i=0; i<n; i++)
1666  if (! p_EqualPolys(m1[i],m2[i], r1, r2)) return FALSE;
1667  }
1668  }
1669  else if (r2->qideal != NULL) return FALSE;
1670  }
1671 
1672  return TRUE;
1673 }
1674 
1675 BOOLEAN rSamePolyRep(ring r1, ring r2)
1676 {
1677  int i, j;
1678 
1679  if (r1 == r2) return TRUE;
1680 
1681  if (r1 == NULL || r2 == NULL) return FALSE;
1682 
1683  if ((r1->cf != r2->cf)
1684  || (rVar(r1) != rVar(r2))
1685  || (r1->OrdSgn != r2->OrdSgn))
1686  return FALSE;
1687 
1688  i=0;
1689  while (r1->order[i] != 0)
1690  {
1691  if (r2->order[i] == 0) return FALSE;
1692  if ((r1->order[i] != r2->order[i])
1693  || (r1->block0[i] != r2->block0[i])
1694  || (r1->block1[i] != r2->block1[i]))
1695  return FALSE;
1696  if (r1->wvhdl[i] != NULL)
1697  {
1698  if (r2->wvhdl[i] == NULL)
1699  return FALSE;
1700  for (j=0; j<r1->block1[i]-r1->block0[i]+1; j++)
1701  if (r2->wvhdl[i][j] != r1->wvhdl[i][j])
1702  return FALSE;
1703  }
1704  else if (r2->wvhdl[i] != NULL) return FALSE;
1705  i++;
1706  }
1707  if (r2->order[i] != 0) return FALSE;
1708 
1709  // we do not check variable names
1710  // we do not check minpoly/minideal
1711  // we do not check qideal
1712 
1713  return TRUE;
1714 }
1715 
1717 {
1718  // check for simple ordering
1719  if (rHasSimpleOrder(r))
1720  {
1721  if ((r->order[1] == ringorder_c)
1722  || (r->order[1] == ringorder_C))
1723  {
1724  switch(r->order[0])
1725  {
1726  case ringorder_dp:
1727  case ringorder_wp:
1728  case ringorder_ds:
1729  case ringorder_ws:
1730  case ringorder_ls:
1731  case ringorder_unspec:
1732  if (r->order[1] == ringorder_C
1733  || r->order[0] == ringorder_unspec)
1734  return rOrderType_ExpComp;
1735  return rOrderType_Exp;
1736 
1737  default:
1738  assume(r->order[0] == ringorder_lp ||
1739  r->order[0] == ringorder_rs ||
1740  r->order[0] == ringorder_Dp ||
1741  r->order[0] == ringorder_Wp ||
1742  r->order[0] == ringorder_Ds ||
1743  r->order[0] == ringorder_Ws);
1744 
1745  if (r->order[1] == ringorder_c) return rOrderType_ExpComp;
1746  return rOrderType_Exp;
1747  }
1748  }
1749  else
1750  {
1751  assume((r->order[0]==ringorder_c)||(r->order[0]==ringorder_C));
1752  return rOrderType_CompExp;
1753  }
1754  }
1755  else
1756  return rOrderType_General;
1757 }
1758 
1760 {
1761  return (r->order[0] == ringorder_c);
1762 }
1764 {
1765  if (r->order[0] == ringorder_unspec) return TRUE;
1766  int blocks = rBlocks(r) - 1;
1767  assume(blocks >= 1);
1768  if (blocks == 1) return TRUE;
1769 
1770  int s = 0;
1771  while( (s < blocks) && (r->order[s] == ringorder_IS) && (r->order[blocks-1] == ringorder_IS) )
1772  {
1773  s++;
1774  blocks--;
1775  }
1776 
1777  if ((blocks - s) > 2) return FALSE;
1778 
1779  assume( blocks == s + 2 );
1780 
1781  if (
1782  (r->order[s] != ringorder_c)
1783  && (r->order[s] != ringorder_C)
1784  && (r->order[s+1] != ringorder_c)
1785  && (r->order[s+1] != ringorder_C)
1786  )
1787  return FALSE;
1788  if ((r->order[s+1] == ringorder_M)
1789  || (r->order[s] == ringorder_M))
1790  return FALSE;
1791  return TRUE;
1792 }
1793 
1794 // returns TRUE, if simple lp or ls ordering
1796 {
1797  return rHasSimpleOrder(r) &&
1798  (r->order[0] == ringorder_ls ||
1799  r->order[0] == ringorder_lp ||
1800  r->order[1] == ringorder_ls ||
1801  r->order[1] == ringorder_lp);
1802 }
1803 
1805 {
1806  switch(order)
1807  {
1808  case ringorder_dp:
1809  case ringorder_Dp:
1810  case ringorder_ds:
1811  case ringorder_Ds:
1812  case ringorder_Ws:
1813  case ringorder_Wp:
1814  case ringorder_ws:
1815  case ringorder_wp:
1816  return TRUE;
1817 
1818  default:
1819  return FALSE;
1820  }
1821 }
1822 
1824 {
1825  switch(order)
1826  {
1827  case ringorder_Ws:
1828  case ringorder_Wp:
1829  case ringorder_ws:
1830  case ringorder_wp:
1831  return TRUE;
1832 
1833  default:
1834  return FALSE;
1835  }
1836 }
1837 
1839 {
1840  if (r->order[0] == ringorder_unspec) return TRUE;
1841  int blocks = rBlocks(r) - 1;
1842  assume(blocks >= 1);
1843  if (blocks == 1) return TRUE;
1844 
1845  int s = 0;
1846  while( (s < blocks) && (r->order[s] == ringorder_IS) && (r->order[blocks-1] == ringorder_IS) )
1847  {
1848  s++;
1849  blocks--;
1850  }
1851 
1852  if ((blocks - s) > 3) return FALSE;
1853 
1854 // if ((blocks > 3) || (blocks < 2)) return FALSE;
1855  if ((blocks - s) == 3)
1856  {
1857  return (((r->order[s] == ringorder_aa) && (r->order[s+1] != ringorder_M) &&
1858  ((r->order[s+2] == ringorder_c) || (r->order[s+2] == ringorder_C))) ||
1859  (((r->order[s] == ringorder_c) || (r->order[s] == ringorder_C)) &&
1860  (r->order[s+1] == ringorder_aa) && (r->order[s+2] != ringorder_M)));
1861  }
1862  else
1863  {
1864  return ((r->order[s] == ringorder_aa) && (r->order[s+1] != ringorder_M));
1865  }
1866 }
1867 
1868 // return TRUE if p_SetComp requires p_Setm
1870 {
1871  if (r->typ != NULL)
1872  {
1873  int pos;
1874  for (pos=0;pos<r->OrdSize;pos++)
1875  {
1876  sro_ord* o=&(r->typ[pos]);
1877  if ( (o->ord_typ == ro_syzcomp)
1878  || (o->ord_typ == ro_syz)
1879  || (o->ord_typ == ro_is)
1880  || (o->ord_typ == ro_am)
1881  || (o->ord_typ == ro_isTemp))
1882  return TRUE;
1883  }
1884  }
1885  return FALSE;
1886 }
1887 
1888 // return TRUE if p->exp[r->pOrdIndex] holds total degree of p */
1890 {
1891  // Hmm.... what about Syz orderings?
1892  return (rVar(r) > 1 &&
1893  ((rHasSimpleOrder(r) &&
1894  (rOrder_is_DegOrdering((rRingOrder_t)r->order[0]) ||
1895  rOrder_is_DegOrdering(( rRingOrder_t)r->order[1]))) ||
1896  (rHasSimpleOrderAA(r) &&
1897  (rOrder_is_DegOrdering((rRingOrder_t)r->order[1]) ||
1898  rOrder_is_DegOrdering((rRingOrder_t)r->order[2])))));
1899 }
1900 
1901 // return TRUE if p->exp[r->pOrdIndex] holds a weighted degree of p */
1903 {
1904  // Hmm.... what about Syz orderings?
1905  return ((rVar(r) > 1) &&
1906  rHasSimpleOrder(r) &&
1907  (rOrder_is_WeightedOrdering((rRingOrder_t)r->order[0]) ||
1908  rOrder_is_WeightedOrdering(( rRingOrder_t)r->order[1])));
1909 }
1910 
1911 BOOLEAN rIsPolyVar(int v,const ring r)
1912 {
1913  int i=0;
1914  while(r->order[i]!=0)
1915  {
1916  if((r->block0[i]<=v)
1917  && (r->block1[i]>=v))
1918  {
1919  switch(r->order[i])
1920  {
1921  case ringorder_a:
1922  return (r->wvhdl[i][v-r->block0[i]]>0);
1923  case ringorder_M:
1924  return 2; /*don't know*/
1925  case ringorder_a64: /* assume: all weight are non-negative!*/
1926  case ringorder_lp:
1927  case ringorder_rs:
1928  case ringorder_dp:
1929  case ringorder_Dp:
1930  case ringorder_wp:
1931  case ringorder_Wp:
1932  return TRUE;
1933  case ringorder_ls:
1934  case ringorder_ds:
1935  case ringorder_Ds:
1936  case ringorder_ws:
1937  case ringorder_Ws:
1938  return FALSE;
1939  default:
1940  break;
1941  }
1942  }
1943  i++;
1944  }
1945  return 3; /* could not find var v*/
1946 }
1947 
1948 #ifdef RDEBUG
1949 // This should eventually become a full-fledge ring check, like pTest
1950 BOOLEAN rDBTest(ring r, const char* fn, const int l)
1951 {
1952  int i,j;
1953 
1954  if (r == NULL)
1955  {
1956  dReportError("Null ring in %s:%d", fn, l);
1957  return FALSE;
1958  }
1959 
1960 
1961  if (r->N == 0) return TRUE;
1962 
1963  if ((r->OrdSgn!=1) && (r->OrdSgn!= -1))
1964  {
1965  dReportError("missing OrdSgn in %s:%d", fn, l);
1966  return FALSE;
1967  }
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 
2962 void rKillModifiedRing(ring r)
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 static void rSetFirstWv(ring r, int i, int* order, int* block1, int** wvhdl)
3024 {
3025  // cheat for ringorder_aa
3026  if (order[i] == ringorder_aa)
3027  i++;
3028  if(block1[i]!=r->N) r->LexOrder=TRUE;
3029  r->firstBlockEnds=block1[i];
3030  r->firstwv = wvhdl[i];
3031  if ((order[i]== ringorder_ws)
3032  || (order[i]==ringorder_Ws)
3033  || (order[i]== ringorder_wp)
3034  || (order[i]==ringorder_Wp)
3035  || (order[i]== ringorder_a)
3036  /*|| (order[i]==ringorder_A)*/)
3037  {
3038  int j;
3039  for(j=block1[i]-r->block0[i];j>=0;j--)
3040  {
3041  if (r->firstwv[j]<0) r->MixedOrder=TRUE;
3042  if (r->firstwv[j]==0) r->LexOrder=TRUE;
3043  }
3044  }
3045  else if (order[i]==ringorder_a64)
3046  {
3047  int j;
3048  int64 *w=rGetWeightVec(r);
3049  for(j=block1[i]-r->block0[i];j>=0;j--)
3050  {
3051  if (w[j]==0) r->LexOrder=TRUE;
3052  }
3053  }
3054 }
3055 
3056 static void rOptimizeLDeg(ring r)
3057 {
3058  if (r->pFDeg == p_Deg)
3059  {
3060  if (r->pLDeg == pLDeg1)
3061  r->pLDeg = pLDeg1_Deg;
3062  if (r->pLDeg == pLDeg1c)
3063  r->pLDeg = pLDeg1c_Deg;
3064  }
3065  else if (r->pFDeg == p_Totaldegree)
3066  {
3067  if (r->pLDeg == pLDeg1)
3068  r->pLDeg = pLDeg1_Totaldegree;
3069  if (r->pLDeg == pLDeg1c)
3070  r->pLDeg = pLDeg1c_Totaldegree;
3071  }
3072  else if (r->pFDeg == p_WFirstTotalDegree)
3073  {
3074  if (r->pLDeg == pLDeg1)
3075  r->pLDeg = pLDeg1_WFirstTotalDegree;
3076  if (r->pLDeg == pLDeg1c)
3077  r->pLDeg = pLDeg1c_WFirstTotalDegree;
3078  }
3079  r->pLDegOrig = r->pLDeg;
3080 }
3081 
3082 // set pFDeg, pLDeg, requires OrdSgn already set
3083 static void rSetDegStuff(ring r)
3084 {
3085  int* order = r->order;
3086  int* block0 = r->block0;
3087  int* block1 = r->block1;
3088  int** wvhdl = r->wvhdl;
3089 
3090  if (order[0]==ringorder_S ||order[0]==ringorder_s || order[0]==ringorder_IS)
3091  {
3092  order++;
3093  block0++;
3094  block1++;
3095  wvhdl++;
3096  }
3097  r->LexOrder = FALSE;
3098  r->pFDeg = p_Totaldegree;
3099  r->pLDeg = (r->OrdSgn == 1 ? pLDegb : pLDeg0);
3100 
3101  /*======== ordering type is (am,_) ==================*/
3102  if (order[0]==ringorder_am)
3103  {
3104  r->MixedOrder = FALSE;
3105  for(int ii=block0[0];ii<=block1[0];ii++)
3106  if (wvhdl[0][ii-1]<0) { r->MixedOrder=2;break;}
3107  r->LexOrder=FALSE;
3108  for(int ii=block0[0];ii<=block1[0];ii++)
3109  if (wvhdl[0][ii-1]==0) { r->LexOrder=TRUE;break;}
3110  if ((block0[0]==1)&&(block1[0]==r->N))
3111  {
3112  r->pFDeg = p_Deg;
3113  r->pLDeg = pLDeg1c_Deg;
3114  }
3115  else
3116  {
3117  r->pFDeg = p_WTotaldegree;
3118  r->LexOrder=TRUE;
3119  r->pLDeg = pLDeg1c_WFirstTotalDegree;
3120  }
3121  r->firstwv = wvhdl[0];
3122  }
3123  /*======== ordering type is (_,c) =========================*/
3124  else if ((order[0]==ringorder_unspec) || (order[1] == 0)
3125  ||(
3126  ((order[1]==ringorder_c)||(order[1]==ringorder_C)
3127  ||(order[1]==ringorder_S)
3128  ||(order[1]==ringorder_s))
3129  && (order[0]!=ringorder_M)
3130  && (order[2]==0))
3131  )
3132  {
3133  if (r->OrdSgn == -1) r->pLDeg = pLDeg0c;
3134  if ((order[0] == ringorder_lp)
3135  || (order[0] == ringorder_ls)
3136  || (order[0] == ringorder_rp)
3137  || (order[0] == ringorder_rs))
3138  {
3139  r->LexOrder=TRUE;
3140  r->pLDeg = pLDeg1c;
3141  r->pFDeg = p_Totaldegree;
3142  }
3143  else if ((order[0] == ringorder_a)
3144  || (order[0] == ringorder_wp)
3145  || (order[0] == ringorder_Wp))
3146  {
3147  r->pFDeg = p_WFirstTotalDegree;
3148  }
3149  else if ((order[0] == ringorder_ws)
3150  || (order[0] == ringorder_Ws))
3151  {
3152  for(int ii=block0[0];ii<=block1[0];ii++)
3153  {
3154  if (wvhdl[0][ii-1]<0) { r->MixedOrder=2;break;}
3155  }
3156  if (r->MixedOrder==0)
3157  r->pFDeg = p_WFirstTotalDegree;
3158  else
3159  r->pFDeg = p_Totaldegree;
3160  }
3161  r->firstBlockEnds=block1[0];
3162  r->firstwv = wvhdl[0];
3163  }
3164  /*======== ordering type is (c,_) =========================*/
3165  else if (((order[0]==ringorder_c)
3166  ||(order[0]==ringorder_C)
3167  ||(order[0]==ringorder_S)
3168  ||(order[0]==ringorder_s))
3169  && (order[1]!=ringorder_M)
3170  && (order[2]==0))
3171  {
3172  if ((order[1] == ringorder_lp)
3173  || (order[1] == ringorder_ls)
3174  || (order[1] == ringorder_rp)
3175  || order[1] == ringorder_rs)
3176  {
3177  r->LexOrder=TRUE;
3178  r->pLDeg = pLDeg1c;
3179  r->pFDeg = p_Totaldegree;
3180  }
3181  r->firstBlockEnds=block1[1];
3182  if (wvhdl!=NULL) r->firstwv = wvhdl[1];
3183  if ((order[1] == ringorder_a)
3184  || (order[1] == ringorder_wp)
3185  || (order[1] == ringorder_Wp))
3186  r->pFDeg = p_WFirstTotalDegree;
3187  else if ((order[1] == ringorder_ws)
3188  || (order[1] == ringorder_Ws))
3189  {
3190  for(int ii=block0[1];ii<=block1[1];ii++)
3191  if (wvhdl[1][ii-1]<0) { r->MixedOrder=2;break;}
3192  if (r->MixedOrder==FALSE)
3193  r->pFDeg = p_WFirstTotalDegree;
3194  else
3195  r->pFDeg = p_Totaldegree;
3196  }
3197  }
3198  /*------- more than one block ----------------------*/
3199  else
3200  {
3201  if ((r->VectorOut)||(order[0]==ringorder_C)||(order[0]==ringorder_S)||(order[0]==ringorder_s))
3202  {
3203  rSetFirstWv(r, 1, order, block1, wvhdl);
3204  }
3205  else
3206  rSetFirstWv(r, 0, order, block1, wvhdl);
3207 
3208  if ((order[0]!=ringorder_c)
3209  && (order[0]!=ringorder_C)
3210  && (order[0]!=ringorder_S)
3211  && (order[0]!=ringorder_s))
3212  {
3213  r->pLDeg = pLDeg1c;
3214  }
3215  else
3216  {
3217  r->pLDeg = pLDeg1;
3218  }
3219  r->pFDeg = p_WTotaldegree; // may be improved: p_Totaldegree for lp/dp/ls/.. blocks
3220  }
3221 
3223  {
3224  if(r->MixedOrder==FALSE)
3225  r->pFDeg = p_Deg;
3226  else
3227  r->pFDeg = p_Totaldegree;
3228  }
3229 
3230  if( rGetISPos(0, r) != -1 ) // Are there Schreyer induced blocks?
3231  {
3232 #ifndef SING_NDEBUG
3233  assume( r->pFDeg == p_Deg || r->pFDeg == p_WTotaldegree || r->pFDeg == p_Totaldegree);
3234 #endif
3235 
3236  r->pLDeg = pLDeg1; // ?
3237  }
3238 
3239  r->pFDegOrig = r->pFDeg;
3240  // NOTE: this leads to wrong ecart during std
3241  // in Old/sre.tst
3242  rOptimizeLDeg(r); // also sets r->pLDegOrig
3243 }
3244 
3245 /*2
3246 * set NegWeightL_Size, NegWeightL_Offset
3247 */
3248 static void rSetNegWeight(ring r)
3249 {
3250  int i,l;
3251  if (r->typ!=NULL)
3252  {
3253  l=0;
3254  for(i=0;i<r->OrdSize;i++)
3255  {
3256  if((r->typ[i].ord_typ==ro_wp_neg)
3257  ||(r->typ[i].ord_typ==ro_am))
3258  l++;
3259  }
3260  if (l>0)
3261  {
3262  r->NegWeightL_Size=l;
3263  r->NegWeightL_Offset=(int *) omAlloc(l*sizeof(int));
3264  l=0;
3265  for(i=0;i<r->OrdSize;i++)
3266  {
3267  if(r->typ[i].ord_typ==ro_wp_neg)
3268  {
3269  r->NegWeightL_Offset[l]=r->typ[i].data.wp.place;
3270  l++;
3271  }
3272  else if(r->typ[i].ord_typ==ro_am)
3273  {
3274  r->NegWeightL_Offset[l]=r->typ[i].data.am.place;
3275  l++;
3276  }
3277  }
3278  return;
3279  }
3280  }
3281  r->NegWeightL_Size = 0;
3282  r->NegWeightL_Offset = NULL;
3283 }
3284 
3285 static void rSetOption(ring r)
3286 {
3287  // set redthrough
3288  if (!TEST_OPT_OLDSTD && r->OrdSgn == 1 && ! r->LexOrder)
3289  r->options |= Sy_bit(OPT_REDTHROUGH);
3290  else
3291  r->options &= ~Sy_bit(OPT_REDTHROUGH);
3292 
3293  // set intStrategy
3294  if ( (r->cf->extRing!=NULL)
3295  || rField_is_Q(r)
3296  || rField_is_Ring(r)
3297  )
3298  r->options |= Sy_bit(OPT_INTSTRATEGY);
3299  else
3300  r->options &= ~Sy_bit(OPT_INTSTRATEGY);
3301 
3302  // set redTail
3303  if (r->LexOrder || r->OrdSgn == -1 || (r->cf->extRing!=NULL))
3304  r->options &= ~Sy_bit(OPT_REDTAIL);
3305  else
3306  r->options |= Sy_bit(OPT_REDTAIL);
3307 }
3308 
3309 static void rCheckOrdSgn(ring r,int i/*last block*/);
3310 
3311 /* -------------------------------------------------------- */
3312 /*2
3313 * change all global variables to fit the description of the new ring
3314 */
3315 
3316 void p_SetGlobals(const ring r, BOOLEAN complete)
3317 {
3318 // // // if (r->ppNoether!=NULL) p_Delete(&r->ppNoether,r); // ???
3319 
3320  r->pLexOrder=r->LexOrder;
3321  if (complete)
3322  {
3324  si_opt_1 |= r->options;
3325  }
3326 }
3327 
3328 static inline int sign(int x) { return (x > 0) - (x < 0);}
3330 {
3331  int i;
3332  poly p=p_One(r);
3333  p_SetExp(p,1,1,r);
3334  p_Setm(p,r);
3335  int vz=sign(p_FDeg(p,r));
3336  for(i=2;i<=rVar(r);i++)
3337  {
3338  p_SetExp(p,i-1,0,r);
3339  p_SetExp(p,i,1,r);
3340  p_Setm(p,r);
3341  if (sign(p_FDeg(p,r))!=vz)
3342  {
3343  p_Delete(&p,r);
3344  return TRUE;
3345  }
3346  }
3347  p_Delete(&p,r);
3348  return FALSE;
3349 }
3350 
3351 BOOLEAN rComplete(ring r, int force)
3352 {
3353  if (r->VarOffset!=NULL && force == 0) return FALSE;
3354  rSetOutParams(r);
3355  int n=rBlocks(r)-1;
3356  int i;
3357  int bits;
3358  r->bitmask=rGetExpSize(r->bitmask,bits,r->N);
3359  r->BitsPerExp = bits;
3360  r->ExpPerLong = BIT_SIZEOF_LONG / bits;
3361  r->divmask=rGetDivMask(bits);
3362 
3363  // will be used for ordsgn:
3364  long *tmp_ordsgn=(long *)omAlloc0(3*(n+r->N)*sizeof(long));
3365  // will be used for VarOffset:
3366  int *v=(int *)omAlloc((r->N+1)*sizeof(int));
3367  for(i=r->N; i>=0 ; i--)
3368  {
3369  v[i]=-1;
3370  }
3371  sro_ord *tmp_typ=(sro_ord *)omAlloc0(3*(n+r->N)*sizeof(sro_ord));
3372  int typ_i=0;
3373  int prev_ordsgn=0;
3374 
3375  // fill in v, tmp_typ, tmp_ordsgn, determine typ_i (== ordSize)
3376  int j=0;
3377  int j_bits=BITS_PER_LONG;
3378 
3379  BOOLEAN need_to_add_comp=FALSE; // Only for ringorder_s and ringorder_S!
3380 
3381  for(i=0;i<n;i++)
3382  {
3383  tmp_typ[typ_i].order_index=i;
3384  switch (r->order[i])
3385  {
3386  case ringorder_a:
3387  case ringorder_aa:
3388  rO_WDegree(j,j_bits,r->block0[i],r->block1[i],tmp_ordsgn,tmp_typ[typ_i],
3389  r->wvhdl[i]);
3390  typ_i++;
3391  break;
3392 
3393  case ringorder_am:
3394  rO_WMDegree(j,j_bits,r->block0[i],r->block1[i],tmp_ordsgn,tmp_typ[typ_i],
3395  r->wvhdl[i]);
3396  typ_i++;
3397  break;
3398 
3399  case ringorder_a64:
3400  rO_WDegree64(j,j_bits,r->block0[i],r->block1[i],tmp_ordsgn,
3401  tmp_typ[typ_i], (int64 *)(r->wvhdl[i]));
3402  typ_i++;
3403  break;
3404 
3405  case ringorder_c:
3406  rO_Align(j, j_bits);
3407  rO_LexVars_neg(j, j_bits, 0,0, prev_ordsgn,tmp_ordsgn,v,BITS_PER_LONG, -1);
3408  r->ComponentOrder=1;
3409  break;
3410 
3411  case ringorder_C:
3412  rO_Align(j, j_bits);
3413  rO_LexVars(j, j_bits, 0,0, prev_ordsgn,tmp_ordsgn,v,BITS_PER_LONG, -1);
3414  r->ComponentOrder=-1;
3415  break;
3416 
3417  case ringorder_M:
3418  {
3419  int k,l;
3420  k=r->block1[i]-r->block0[i]+1; // number of vars
3421  for(l=0;l<k;l++)
3422  {
3423  rO_WDegree(j,j_bits,r->block0[i],r->block1[i],tmp_ordsgn,
3424  tmp_typ[typ_i],
3425  r->wvhdl[i]+(r->block1[i]-r->block0[i]+1)*l);
3426  typ_i++;
3427  }
3428  break;
3429  }
3430 
3431  case ringorder_lp:
3432  rO_LexVars(j, j_bits, r->block0[i],r->block1[i], prev_ordsgn,
3433  tmp_ordsgn,v,bits, -1);
3434  break;
3435 
3436  case ringorder_ls:
3437  rO_LexVars_neg(j, j_bits, r->block0[i],r->block1[i], prev_ordsgn,
3438  tmp_ordsgn,v, bits, -1);
3439  break;
3440 
3441  case ringorder_rs:
3442  rO_LexVars_neg(j, j_bits, r->block1[i],r->block0[i], prev_ordsgn,
3443  tmp_ordsgn,v, bits, -1);
3444  break;
3445 
3446  case ringorder_rp:
3447  rO_LexVars(j, j_bits, r->block1[i],r->block0[i], prev_ordsgn,
3448  tmp_ordsgn,v, bits, -1);
3449  break;
3450 
3451  case ringorder_dp:
3452  if (r->block0[i]==r->block1[i])
3453  {
3454  rO_LexVars(j, j_bits, r->block0[i],r->block0[i], prev_ordsgn,
3455  tmp_ordsgn,v, bits, -1);
3456  }
3457  else
3458  {
3459  rO_TDegree(j,j_bits,r->block0[i],r->block1[i],tmp_ordsgn,
3460  tmp_typ[typ_i]);
3461  typ_i++;
3462  rO_LexVars_neg(j, j_bits, r->block1[i],r->block0[i]+1,
3463  prev_ordsgn,tmp_ordsgn,v,bits, r->block0[i]);
3464  }
3465  break;
3466 
3467  case ringorder_Dp:
3468  if (r->block0[i]==r->block1[i])
3469  {
3470  rO_LexVars(j, j_bits, r->block0[i],r->block0[i], prev_ordsgn,
3471  tmp_ordsgn,v, bits, -1);
3472  }
3473  else
3474  {
3475  rO_TDegree(j,j_bits,r->block0[i],r->block1[i],tmp_ordsgn,
3476  tmp_typ[typ_i]);
3477  typ_i++;
3478  rO_LexVars(j, j_bits, r->block0[i],r->block1[i]-1, prev_ordsgn,
3479  tmp_ordsgn,v, bits, r->block1[i]);
3480  }
3481  break;
3482 
3483  case ringorder_ds:
3484  if (r->block0[i]==r->block1[i])
3485  {
3486  rO_LexVars_neg(j, j_bits,r->block0[i],r->block1[i],prev_ordsgn,
3487  tmp_ordsgn,v,bits, -1);
3488  }
3489  else
3490  {
3491  rO_TDegree_neg(j,j_bits,r->block0[i],r->block1[i],tmp_ordsgn,
3492  tmp_typ[typ_i]);
3493  typ_i++;
3494  rO_LexVars_neg(j, j_bits, r->block1[i],r->block0[i]+1,
3495  prev_ordsgn,tmp_ordsgn,v,bits, r->block0[i]);
3496  }
3497  break;
3498 
3499  case ringorder_Ds:
3500  if (r->block0[i]==r->block1[i])
3501  {
3502  rO_LexVars_neg(j, j_bits, r->block0[i],r->block0[i],prev_ordsgn,
3503  tmp_ordsgn,v, bits, -1);
3504  }
3505  else
3506  {
3507  rO_TDegree_neg(j,j_bits,r->block0[i],r->block1[i],tmp_ordsgn,
3508  tmp_typ[typ_i]);
3509  typ_i++;
3510  rO_LexVars(j, j_bits, r->block0[i],r->block1[i]-1, prev_ordsgn,
3511  tmp_ordsgn,v, bits, r->block1[i]);
3512  }
3513  break;
3514 
3515  case ringorder_wp:
3516  rO_WDegree(j,j_bits,r->block0[i],r->block1[i],tmp_ordsgn,
3517  tmp_typ[typ_i], r->wvhdl[i]);
3518  typ_i++;
3519  { // check for weights <=0
3520  int jj;
3521  BOOLEAN have_bad_weights=FALSE;
3522  for(jj=r->block1[i]-r->block0[i];jj>=0; jj--)
3523  {
3524  if (r->wvhdl[i][jj]<=0) have_bad_weights=TRUE;
3525  }
3526  if (have_bad_weights)
3527  {
3528  rO_TDegree(j,j_bits,r->block0[i],r->block1[i],tmp_ordsgn,
3529  tmp_typ[typ_i]);
3530  typ_i++;
3531  }
3532  }
3533  if (r->block1[i]!=r->block0[i])
3534  {
3535  rO_LexVars_neg(j, j_bits,r->block1[i],r->block0[i]+1, prev_ordsgn,
3536  tmp_ordsgn, v,bits, r->block0[i]);
3537  }
3538  break;
3539 
3540  case ringorder_Wp:
3541  rO_WDegree(j,j_bits,r->block0[i],r->block1[i],tmp_ordsgn,
3542  tmp_typ[typ_i], r->wvhdl[i]);
3543  typ_i++;
3544  { // check for weights <=0
3545  int jj;
3546  BOOLEAN have_bad_weights=FALSE;
3547  for(jj=r->block1[i]-r->block0[i];jj>=0; jj--)
3548  {
3549  if (r->wvhdl[i][jj]<=0) have_bad_weights=TRUE;
3550  }
3551  if (have_bad_weights)
3552  {
3553  rO_TDegree(j,j_bits,r->block0[i],r->block1[i],tmp_ordsgn,
3554  tmp_typ[typ_i]);
3555  typ_i++;
3556  }
3557  }
3558  if (r->block1[i]!=r->block0[i])
3559  {
3560  rO_LexVars(j, j_bits,r->block0[i],r->block1[i]-1, prev_ordsgn,
3561  tmp_ordsgn,v, bits, r->block1[i]);
3562  }
3563  break;
3564 
3565  case ringorder_ws:
3566  rO_WDegree_neg(j,j_bits,r->block0[i],r->block1[i],tmp_ordsgn,
3567  tmp_typ[typ_i], r->wvhdl[i]);
3568  typ_i++;
3569  if (r->block1[i]!=r->block0[i])
3570  {
3571  rO_LexVars_neg(j, j_bits,r->block1[i],r->block0[i]+1, prev_ordsgn,
3572  tmp_ordsgn, v,bits, r->block0[i]);
3573  }
3574  break;
3575 
3576  case ringorder_Ws:
3577  rO_WDegree_neg(j,j_bits,r->block0[i],r->block1[i],tmp_ordsgn,
3578  tmp_typ[typ_i], r->wvhdl[i]);
3579  typ_i++;
3580  if (r->block1[i]!=r->block0[i])
3581  {
3582  rO_LexVars(j, j_bits,r->block0[i],r->block1[i]-1, prev_ordsgn,
3583  tmp_ordsgn,v, bits, r->block1[i]);
3584  }
3585  break;
3586 
3587  case ringorder_S:
3588  assume(typ_i == 1); // For LaScala3 only: on the 2nd place ([1])!
3589  // TODO: for K[x]: it is 0...?!
3590  rO_Syzcomp(j, j_bits,prev_ordsgn, tmp_ordsgn,tmp_typ[typ_i]);
3591  need_to_add_comp=TRUE;
3592  r->ComponentOrder=-1;
3593  typ_i++;
3594  break;
3595 
3596  case ringorder_s:
3597  assume(typ_i == 0 && j == 0);
3598  rO_Syz(j, j_bits, prev_ordsgn, tmp_ordsgn, tmp_typ[typ_i]); // set syz-limit?
3599  need_to_add_comp=TRUE;
3600  r->ComponentOrder=-1;
3601  typ_i++;
3602  break;
3603 
3604  case ringorder_IS:
3605  {
3606 
3607  assume( r->block0[i] == r->block1[i] );
3608  const int s = r->block0[i];
3609  assume( -2 < s && s < 2);
3610 
3611  if(s == 0) // Prefix IS
3612  rO_ISPrefix(j, j_bits, prev_ordsgn, tmp_ordsgn, r->N, v, tmp_typ[typ_i++]); // What about prev_ordsgn?
3613  else // s = +1 or -1 // Note: typ_i might be incrimented here inside!
3614  {
3615  rO_ISSuffix(j, j_bits, prev_ordsgn, tmp_ordsgn, r->N, v, tmp_typ, typ_i, s); // Suffix.
3616  need_to_add_comp=FALSE;
3617  }
3618 
3619  break;
3620  }
3621  case ringorder_unspec:
3622  case ringorder_no:
3623  default:
3624  dReportError("undef. ringorder used\n");
3625  break;
3626  }
3627  }
3628  rCheckOrdSgn(r,n-1);
3629 
3630  int j0=j; // save j
3631  int j_bits0=j_bits; // save jbits
3632  rO_Align(j,j_bits);
3633  r->CmpL_Size = j;
3634 
3635  j_bits=j_bits0; j=j0;
3636 
3637  // fill in some empty slots with variables not already covered
3638  // v0 is special, is therefore normally already covered
3639  // now we do have rings without comp...
3640  if((need_to_add_comp) && (v[0]== -1))
3641  {
3642  if (prev_ordsgn==1)
3643  {
3644  rO_Align(j, j_bits);
3645  rO_LexVars(j, j_bits, 0,0, prev_ordsgn,tmp_ordsgn,v,BITS_PER_LONG, -1);
3646  }
3647  else
3648  {
3649  rO_Align(j, j_bits);
3650  rO_LexVars_neg(j, j_bits, 0,0, prev_ordsgn,tmp_ordsgn,v,BITS_PER_LONG, -1);
3651  }
3652  }
3653  // the variables
3654  for(i=1 ; i<=r->N ; i++)
3655  {
3656  if(v[i]==(-1))
3657  {
3658  if (prev_ordsgn==1)
3659  {
3660  rO_LexVars(j, j_bits, i,i, prev_ordsgn,tmp_ordsgn,v,bits, -1);
3661  }
3662  else
3663  {
3664  rO_LexVars_neg(j,j_bits,i,i, prev_ordsgn,tmp_ordsgn,v,bits, -1);
3665  }
3666  }
3667  }
3668 
3669  rO_Align(j,j_bits);
3670  // ----------------------------
3671  // finished with constructing the monomial, computing sizes:
3672 
3673  r->ExpL_Size=j;
3674  r->PolyBin = omGetSpecBin(POLYSIZE + (r->ExpL_Size)*sizeof(long));
3675  assume(r->PolyBin != NULL);
3676 
3677  // ----------------------------
3678  // indices and ordsgn vector for comparison
3679  //
3680  // r->pCompHighIndex already set
3681  r->ordsgn=(long *)omAlloc0(r->ExpL_Size*sizeof(long));
3682 
3683  for(j=0;j<r->CmpL_Size;j++)
3684  {
3685  r->ordsgn[j] = tmp_ordsgn[j];
3686  }
3687 
3688  omFreeSize((ADDRESS)tmp_ordsgn,(3*(n+r->N)*sizeof(long)));
3689 
3690  // ----------------------------
3691  // description of orderings for setm:
3692  //
3693  r->OrdSize=typ_i;
3694  if (typ_i==0) r->typ=NULL;
3695  else
3696  {
3697  r->typ=(sro_ord*)omAlloc(typ_i*sizeof(sro_ord));
3698  memcpy(r->typ,tmp_typ,typ_i*sizeof(sro_ord));
3699  }
3700  omFreeSize((ADDRESS)tmp_typ,(3*(n+r->N)*sizeof(sro_ord)));
3701 
3702  // ----------------------------
3703  // indices for (first copy of ) variable entries in exp.e vector (VarOffset):
3704  r->VarOffset=v;
3705 
3706  // ----------------------------
3707  // other indicies
3708  r->pCompIndex=(r->VarOffset[0] & 0xffff); //r->VarOffset[0];
3709  i=0; // position
3710  j=0; // index in r->typ
3711  if (i==r->pCompIndex) i++; // IS???
3712  while ((j < r->OrdSize)
3713  && ((r->typ[j].ord_typ==ro_syzcomp) ||
3714  (r->typ[j].ord_typ==ro_syz) || (r->typ[j].ord_typ==ro_isTemp) || (r->typ[j].ord_typ==ro_is) ||
3715  (r->order[r->typ[j].order_index] == ringorder_aa)))
3716  {
3717  i++; j++;
3718  }
3719 
3720  if (i==r->pCompIndex) i++;
3721  r->pOrdIndex=i;
3722 
3723  // ----------------------------
3724  rSetDegStuff(r); // OrdSgn etc already set
3725  rSetOption(r);
3726  // ----------------------------
3727  // r->p_Setm
3728  r->p_Setm = p_GetSetmProc(r);
3729 
3730  // ----------------------------
3731  // set VarL_*
3732  rSetVarL(r);
3733 
3734  // ----------------------------
3735  // right-adjust VarOffset
3737 
3738  // ----------------------------
3739  // set NegWeightL*
3740  rSetNegWeight(r);
3741 
3742  // ----------------------------
3743  // p_Procs: call AFTER NegWeightL
3744  r->p_Procs = (p_Procs_s*)omAlloc(sizeof(p_Procs_s));
3745  p_ProcsSet(r, r->p_Procs);
3746 
3747  // use totaldegree on crazy oderings:
3748  if ((r->pFDeg==p_WTotaldegree) && rOrd_is_MixedDegree_Ordering(r))
3749  r->pFDeg = p_Totaldegree;
3750  return FALSE;
3751 }
3752 
3753 static void rCheckOrdSgn(ring r,int b/*last block*/)
3754 { // set r->OrdSgn, r->MixedOrder
3755  // for each variable:
3756  int nonpos=0;
3757  int nonneg=0;
3758  for(int i=1;i<=r->N;i++)
3759  {
3760  int found=0;
3761  // for all blocks:
3762  for(int j=0;(j<=b) && (found==0);j++)
3763  {
3764  // search the first block containing var(i)
3765  if ((r->block0[j]<=i)&&(r->block1[j]>=i))
3766  {
3767  // what kind if block is it?
3768  if ((r->order[j]==ringorder_ls)
3769  || (r->order[j]==ringorder_ds)
3770  || (r->order[j]==ringorder_Ds)
3771  || (r->order[j]==ringorder_ws)
3772  || (r->order[j]==ringorder_Ws)
3773  || (r->order[j]==ringorder_rs))
3774  {
3775  r->OrdSgn=-1;
3776  nonpos++;
3777  found=1;
3778  }
3779  else if((r->order[j]==ringorder_a)
3780  ||(r->order[j]==ringorder_aa))
3781  {
3782  // <0: local/mixed ordering
3783  // >0: var(i) is okay, look at other vars
3784  // ==0: look at other blocks for var(i)
3785  if(r->wvhdl[j][i-r->block0[j]]<0)
3786  {
3787  r->OrdSgn=-1;
3788  nonpos++;
3789  found=1;
3790  }
3791  else if(r->wvhdl[j][i-r->block0[j]]>0)
3792  {
3793  nonneg++;
3794  found=1;
3795  }
3796  }
3797  else if(r->order[j]==ringorder_M)
3798  {
3799  // <0: local/mixed ordering
3800  // >0: var(i) is okay, look at other vars
3801  // ==0: look at other blocks for var(i)
3802  if(r->wvhdl[j][i-r->block0[j]]<0)
3803  {
3804  r->OrdSgn=-1;
3805  nonpos++;
3806  found=1;
3807  }
3808  else if(r->wvhdl[j][i-r->block0[j]]>0)
3809  {
3810  nonneg++;
3811  found=1;
3812  }
3813  else
3814  {
3815  // very bad:
3816  nonpos++;
3817  nonneg++;
3818  found=1;
3819  }
3820  }
3821  else if ((r->order[j]==ringorder_lp)
3822  || (r->order[j]==ringorder_dp)
3823  || (r->order[j]==ringorder_Dp)
3824  || (r->order[j]==ringorder_wp)
3825  || (r->order[j]==ringorder_Wp)
3826  || (r->order[j]==ringorder_rp))
3827  {
3828  found=1;
3829  nonneg++;
3830  }
3831  }
3832  }
3833  }
3834  if (nonpos>0)
3835  {
3836  r->OrdSgn=-1;
3837  if (nonneg>0) r->MixedOrder=1;
3838  }
3839  else
3840  {
3841  r->OrdSgn=1;
3842  r->MixedOrder=0;
3843  }
3844 }
3845 
3846 void rUnComplete(ring r)
3847 {
3848  if (r == NULL) return;
3849  if (r->VarOffset != NULL)
3850  {
3851  if (r->OrdSize!=0 && r->typ != NULL)
3852  {
3853  for(int i = 0; i < r->OrdSize; i++)
3854  if( r->typ[i].ord_typ == ro_is) // Search for suffixes! (prefix have the same VarOffset)
3855  {
3856  id_Delete(&r->typ[i].data.is.F, r);
3857  r->typ[i].data.is.F = NULL; // ?
3858 
3859  if( r->typ[i].data.is.pVarOffset != NULL )
3860  {
3861  omFreeSize((ADDRESS)r->typ[i].data.is.pVarOffset, (r->N +1)*sizeof(int));
3862  r->typ[i].data.is.pVarOffset = NULL; // ?
3863  }
3864  }
3865  else if (r->typ[i].ord_typ == ro_syz)
3866  {
3867  if(r->typ[i].data.syz.limit > 0)
3868  omFreeSize(r->typ[i].data.syz.syz_index, ((r->typ[i].data.syz.limit) +1)*sizeof(int));
3869  r->typ[i].data.syz.syz_index = NULL;
3870  }
3871  else if (r->typ[i].ord_typ == ro_syzcomp)
3872  {
3873  assume( r->typ[i].data.syzcomp.ShiftedComponents == NULL );
3874  assume( r->typ[i].data.syzcomp.Components == NULL );
3875 // WarnS( "rUnComplete : ord_typ == ro_syzcomp was unhandled!!! Possibly memory leak!!!" );
3876 #ifndef SING_NDEBUG
3877 // assume(0);
3878 #endif
3879  }
3880 
3881  omFreeSize((ADDRESS)r->typ,r->OrdSize*sizeof(sro_ord)); r->typ = NULL;
3882  }
3883 
3884  if (r->PolyBin != NULL)
3885  omUnGetSpecBin(&(r->PolyBin));
3886 
3887  omFreeSize((ADDRESS)r->VarOffset, (r->N +1)*sizeof(int));
3888 
3889  if (r->ordsgn != NULL && r->CmpL_Size != 0)
3890  omFreeSize((ADDRESS)r->ordsgn,r->ExpL_Size*sizeof(long));
3891  if (r->p_Procs != NULL)
3892  omFreeSize(r->p_Procs, sizeof(p_Procs_s));
3893  omfreeSize(r->VarL_Offset, r->VarL_Size*sizeof(int));
3894  }
3895  if (r->NegWeightL_Offset!=NULL)
3896  {
3897  omFreeSize(r->NegWeightL_Offset, r->NegWeightL_Size*sizeof(int));
3898  r->NegWeightL_Offset=NULL;
3899  }
3900 }
3901 
3902 // set r->VarL_Size, r->VarL_Offset, r->VarL_LowIndex
3903 static void rSetVarL(ring r)
3904 {
3905  int min = MAX_INT_VAL, min_j = -1;
3906  int* VarL_Number = (int*) omAlloc0(r->ExpL_Size*sizeof(int));
3907 
3908  int i,j;
3909 
3910  // count how often a var long is occupied by an exponent
3911  for (i=1; i<=r->N; i++)
3912  {
3913  VarL_Number[r->VarOffset[i] & 0xffffff]++;
3914  }
3915 
3916  // determine how many and min
3917  for (i=0, j=0; i<r->ExpL_Size; i++)
3918  {
3919  if (VarL_Number[i] != 0)
3920  {
3921  if (min > VarL_Number[i])
3922  {
3923  min = VarL_Number[i];
3924  min_j = j;
3925  }
3926  j++;
3927  }
3928  }
3929 
3930  r->VarL_Size = j; // number of long with exp. entries in
3931  // in p->exp
3932  r->VarL_Offset = (int*) omAlloc(r->VarL_Size*sizeof(int));
3933  r->VarL_LowIndex = 0;
3934 
3935  // set VarL_Offset
3936  for (i=0, j=0; i<r->ExpL_Size; i++)
3937  {
3938  if (VarL_Number[i] != 0)
3939  {
3940  r->VarL_Offset[j] = i;
3941  if (j > 0 && r->VarL_Offset[j-1] != r->VarL_Offset[j] - 1)
3942  r->VarL_LowIndex = -1;
3943  j++;
3944  }
3945  }
3946  if (r->VarL_LowIndex >= 0)
3947  r->VarL_LowIndex = r->VarL_Offset[0];
3948 
3949  if (min_j != 0)
3950  {
3951  j = r->VarL_Offset[min_j];
3952  r->VarL_Offset[min_j] = r->VarL_Offset[0];
3953  r->VarL_Offset[0] = j;
3954  }
3955  omFree(VarL_Number);
3956 }
3957 
3958 static void rRightAdjustVarOffset(ring r)
3959 {
3960  int* shifts = (int*) omAlloc(r->ExpL_Size*sizeof(int));
3961  int i;
3962  // initialize shifts
3963  for (i=0;i<r->ExpL_Size;i++)
3964  shifts[i] = BIT_SIZEOF_LONG;
3965 
3966  // find minimal bit shift in each long exp entry
3967  for (i=1;i<=r->N;i++)
3968  {
3969  if (shifts[r->VarOffset[i] & 0xffffff] > r->VarOffset[i] >> 24)
3970  shifts[r->VarOffset[i] & 0xffffff] = r->VarOffset[i] >> 24;
3971  }
3972  // reset r->VarOffset: set the minimal shift to 0
3973  for (i=1;i<=r->N;i++)
3974  {
3975  if (shifts[r->VarOffset[i] & 0xffffff] != 0)
3976  r->VarOffset[i]
3977  = (r->VarOffset[i] & 0xffffff) |
3978  (((r->VarOffset[i] >> 24) - shifts[r->VarOffset[i] & 0xffffff]) << 24);
3979  }
3980  omFree(shifts);
3981 }
3982 
3983 // get r->divmask depending on bits per exponent
3984 static unsigned long rGetDivMask(int bits)
3985 {
3986  unsigned long divmask = 1;
3987  int i = bits;
3988 
3989  while (i < BIT_SIZEOF_LONG)
3990  {
3991  divmask |= (((unsigned long) 1) << (unsigned long) i);
3992  i += bits;
3993  }
3994  return divmask;
3995 }
3996 
3997 #ifdef RDEBUG
3998 void rDebugPrint(const ring r)
3999 {
4000  if (r==NULL)
4001  {
4002  PrintS("NULL ?\n");
4003  return;
4004  }
4005  // corresponds to ro_typ from ring.h:
4006  const char *TYP[]={"ro_dp","ro_wp","ro_am","ro_wp64","ro_wp_neg","ro_cp",
4007  "ro_syzcomp", "ro_syz", "ro_isTemp", "ro_is", "ro_none"};
4008  int i,j;
4009 
4010  Print("ExpL_Size:%d ",r->ExpL_Size);
4011  Print("CmpL_Size:%d ",r->CmpL_Size);
4012  Print("VarL_Size:%d\n",r->VarL_Size);
4013  Print("bitmask=0x%lx (expbound=%ld) \n",r->bitmask, r->bitmask);
4014  Print("divmask=%lx\n", r->divmask);
4015  Print("BitsPerExp=%d ExpPerLong=%d at L[%d]\n", r->BitsPerExp, r->ExpPerLong, r->VarL_Offset[0]);
4016 
4017  Print("VarL_LowIndex: %d\n", r->VarL_LowIndex);
4018  PrintS("VarL_Offset:\n");
4019  if (r->VarL_Offset==NULL) PrintS(" NULL");
4020  else
4021  for(j = 0; j < r->VarL_Size; j++)
4022  Print(" VarL_Offset[%d]: %d ", j, r->VarL_Offset[j]);
4023  PrintLn();
4024 
4025 
4026  PrintS("VarOffset:\n");
4027  if (r->VarOffset==NULL) PrintS(" NULL\n");
4028  else
4029  for(j=0;j<=r->N;j++)
4030  Print(" v%d at e-pos %d, bit %d\n",
4031  j,r->VarOffset[j] & 0xffffff, r->VarOffset[j] >>24);
4032  PrintS("ordsgn:\n");
4033  for(j=0;j<r->CmpL_Size;j++)
4034  Print(" ordsgn %ld at pos %d\n",r->ordsgn[j],j);
4035  Print("OrdSgn:%d\n",r->OrdSgn);
4036  PrintS("ordrec:\n");
4037  for(j=0;j<r->OrdSize;j++)
4038  {
4039  Print(" typ %s", TYP[r->typ[j].ord_typ]);
4040  if (r->typ[j].ord_typ==ro_syz)
4041  {
4042  const short place = r->typ[j].data.syz.place;
4043  const int limit = r->typ[j].data.syz.limit;
4044  const int curr_index = r->typ[j].data.syz.curr_index;
4045  const int* syz_index = r->typ[j].data.syz.syz_index;
4046 
4047  Print(" limit %d (place: %d, curr_index: %d), syz_index: ", limit, place, curr_index);
4048 
4049  if( syz_index == NULL )
4050  PrintS("(NULL)");
4051  else
4052  {
4053  PrintS("{");
4054  for( i=0; i <= limit; i++ )
4055  Print("%d ", syz_index[i]);
4056  PrintS("}");
4057  }
4058 
4059  }
4060  else if (r->typ[j].ord_typ==ro_isTemp)
4061  {
4062  Print(" start (level) %d, suffixpos: %d, VO: ",r->typ[j].data.isTemp.start, r->typ[j].data.isTemp.suffixpos);
4063 
4064  }
4065  else if (r->typ[j].ord_typ==ro_is)
4066  {
4067  Print(" start %d, end: %d: ",r->typ[j].data.is.start, r->typ[j].data.is.end);
4068 
4069 // 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]);
4070 
4071  Print(" limit %d",r->typ[j].data.is.limit);
4072 #ifndef SING_NDEBUG
4073  //PrintS(" F: ");idShow(r->typ[j].data.is.F, r, r, 1);
4074 #endif
4075 
4076  PrintLn();
4077  }
4078  else if (r->typ[j].ord_typ==ro_am)
4079  {
4080  Print(" place %d",r->typ[j].data.am.place);
4081  Print(" start %d",r->typ[j].data.am.start);
4082  Print(" end %d",r->typ[j].data.am.end);
4083  Print(" len_gen %d",r->typ[j].data.am.len_gen);
4084  PrintS(" w:");
4085  int l=0;
4086  for(l=r->typ[j].data.am.start;l<=r->typ[j].data.am.end;l++)
4087  Print(" %d",r->typ[j].data.am.weights[l-r->typ[j].data.am.start]);
4088  l=r->typ[j].data.am.end+1;
4089  int ll=r->typ[j].data.am.weights[l-r->typ[j].data.am.start];
4090  PrintS(" m:");
4091  for(int lll=l+1;lll<l+ll+1;lll++)
4092  Print(" %d",r->typ[j].data.am.weights[lll-r->typ[j].data.am.start]);
4093  }
4094  else
4095  {
4096  Print(" place %d",r->typ[j].data.dp.place);
4097 
4098  if (r->typ[j].ord_typ!=ro_syzcomp && r->typ[j].ord_typ!=ro_syz)
4099  {
4100  Print(" start %d",r->typ[j].data.dp.start);
4101  Print(" end %d",r->typ[j].data.dp.end);
4102  if ((r->typ[j].ord_typ==ro_wp)
4103  || (r->typ[j].ord_typ==ro_wp_neg))
4104  {
4105  PrintS(" w:");
4106  for(int l=r->typ[j].data.wp.start;l<=r->typ[j].data.wp.end;l++)
4107  Print(" %d",r->typ[j].data.wp.weights[l-r->typ[j].data.wp.start]);
4108  }
4109  else if (r->typ[j].ord_typ==ro_wp64)
4110  {
4111  PrintS(" w64:");
4112  int l;
4113  for(l=r->typ[j].data.wp64.start;l<=r->typ[j].data.wp64.end;l++)
4114  Print(" %ld",(long)(((int64*)r->typ[j].data.wp64.weights64)+l-r->typ[j].data.wp64.start));
4115  }
4116  }
4117  }
4118  PrintLn();
4119  }
4120  Print("pOrdIndex:%d pCompIndex:%d\n", r->pOrdIndex, r->pCompIndex);
4121  Print("OrdSize:%d\n",r->OrdSize);
4122  PrintS("--------------------\n");
4123  for(j=0;j<r->ExpL_Size;j++)
4124  {
4125  Print("L[%d]: ",j);
4126  if (j< r->CmpL_Size)
4127  Print("ordsgn %ld ", r->ordsgn[j]);
4128  else
4129  PrintS("no comp ");
4130  i=1;
4131  for(;i<=r->N;i++)
4132  {
4133  if( (r->VarOffset[i] & 0xffffff) == j )
4134  { Print("v%d at e[%d], bit %d; ", i,r->VarOffset[i] & 0xffffff,
4135  r->VarOffset[i] >>24 ); }
4136  }
4137  if( r->pCompIndex==j ) PrintS("v0; ");
4138  for(i=0;i<r->OrdSize;i++)
4139  {
4140  if (r->typ[i].data.dp.place == j)
4141  {
4142  Print("ordrec:%s (start:%d, end:%d) ",TYP[r->typ[i].ord_typ],
4143  r->typ[i].data.dp.start, r->typ[i].data.dp.end);
4144  }
4145  }
4146 
4147  if (j==r->pOrdIndex)
4148  PrintS("pOrdIndex\n");
4149  else
4150  PrintLn();
4151  }
4152  Print("LexOrder:%d, MixedOrder:%d\n",r->LexOrder, r->MixedOrder);
4153 
4154  Print("NegWeightL_Size: %d, NegWeightL_Offset: ", r->NegWeightL_Size);
4155  if (r->NegWeightL_Offset==NULL) PrintS(" NULL");
4156  else
4157  for(j = 0; j < r->NegWeightL_Size; j++)
4158  Print(" [%d]: %d ", j, r->NegWeightL_Offset[j]);
4159  PrintLn();
4160 
4161  // p_Procs stuff
4162  p_Procs_s proc_names;
4163  const char* field;
4164  const char* length;
4165  const char* ord;
4166  p_Debug_GetProcNames(r, &proc_names); // changes p_Procs!!!
4167  p_Debug_GetSpecNames(r, field, length, ord);
4168 
4169  Print("p_Spec : %s, %s, %s\n", field, length, ord);
4170  PrintS("p_Procs :\n");
4171  for (i=0; i<(int) (sizeof(p_Procs_s)/sizeof(void*)); i++)
4172  {
4173  Print(" %s,\n", ((char**) &proc_names)[i]);
4174  }
4175 
4176  {
4177  PrintLn();
4178  PrintS("pFDeg : ");
4179 #define pFDeg_CASE(A) if(r->pFDeg == A) PrintS( "" #A "" )
4180  pFDeg_CASE(p_Totaldegree); else
4182  pFDeg_CASE(p_WTotaldegree); else
4183  pFDeg_CASE(p_Deg); else
4184 #undef pFDeg_CASE
4185  Print("(%p)", r->pFDeg); // default case
4186 
4187  PrintLn();
4188  Print("pLDeg : (%p)", r->pLDeg);
4189  PrintLn();
4190  }
4191  PrintS("pSetm:");
4192  void p_Setm_Dummy(poly p, const ring r);
4193  void p_Setm_TotalDegree(poly p, const ring r);
4194  void p_Setm_WFirstTotalDegree(poly p, const ring r);
4195  void p_Setm_General(poly p, const ring r);
4196  if (r->p_Setm==p_Setm_General) PrintS("p_Setm_General\n");
4197  else if (r->p_Setm==p_Setm_Dummy) PrintS("p_Setm_Dummy\n");
4198  else if (r->p_Setm==p_Setm_TotalDegree) PrintS("p_Setm_Totaldegree\n");
4199  else if (r->p_Setm==p_Setm_WFirstTotalDegree) PrintS("p_Setm_WFirstTotalDegree\n");
4200  else Print("%p\n",r->p_Setm);
4201 }
4202 
4203 void p_DebugPrint(poly p, const ring r)
4204 {
4205  int i,j;
4206  p_Write(p,r);
4207  j=2;
4208  while(p!=NULL)
4209  {
4210  Print("\nexp[0..%d]\n",r->ExpL_Size-1);
4211  for(i=0;i<r->ExpL_Size;i++)
4212  Print("%ld ",p->exp[i]);
4213  PrintLn();
4214  Print("v0:%ld ",p_GetComp(p, r));
4215  for(i=1;i<=r->N;i++) Print(" v%d:%ld",i,p_GetExp(p,i, r));
4216  PrintLn();
4217  pIter(p);
4218  j--;
4219  if (j==0) { PrintS("...\n"); break; }
4220  }
4221 }
4222 
4223 #endif // RDEBUG
4224 
4225 /// debug-print monomial poly/vector p, assuming that it lives in the ring R
4226 static inline void m_DebugPrint(const poly p, const ring R)
4227 {
4228  Print("\nexp[0..%d]\n", R->ExpL_Size - 1);
4229  for(int i = 0; i < R->ExpL_Size; i++)
4230  Print("%09lx ", p->exp[i]);
4231  PrintLn();
4232  Print("v0:%9ld ", p_GetComp(p, R));
4233  for(int i = 1; i <= R->N; i++) Print(" v%d:%5ld",i, p_GetExp(p, i, R));
4234  PrintLn();
4235 }
4236 
4237 
4238 // F = system("ISUpdateComponents", F, V, MIN );
4239 // // replace gen(i) -> gen(MIN + V[i-MIN]) for all i > MIN in all terms from F!
4240 void pISUpdateComponents(ideal F, const intvec *const V, const int MIN, const ring r )
4241 {
4242  assume( V != NULL );
4243  assume( MIN >= 0 );
4244 
4245  if( F == NULL )
4246  return;
4247 
4248  for( int j = (F->ncols*F->nrows) - 1; j >= 0; j-- )
4249  {
4250 #ifdef PDEBUG
4251  Print("F[%d]:", j);
4252  p_wrp(F->m[j], r);
4253 #endif
4254 
4255  for( poly p = F->m[j]; p != NULL; pIter(p) )
4256  {
4257  int c = p_GetComp(p, r);
4258 
4259  if( c > MIN )
4260  {
4261 #ifdef PDEBUG
4262  Print("gen[%d] -> gen(%d)\n", c, MIN + (*V)[ c - MIN - 1 ]);
4263 #endif
4264 
4265  p_SetComp( p, MIN + (*V)[ c - MIN - 1 ], r );
4266  }
4267  }
4268 #ifdef PDEBUG
4269  Print("new F[%d]:", j);
4270  p_Test(F->m[j], r);
4271  p_wrp(F->m[j], r);
4272 #endif
4273  }
4274 }
4275 
4276 /*2
4277 * asssume that rComplete was called with r
4278 * assume that the first block ist ringorder_S
4279 * change the block to reflect the sequence given by appending v
4280 */
4281 static inline void rNChangeSComps(int* currComponents, long* currShiftedComponents, ring r)
4282 {
4283  assume(r->typ[1].ord_typ == ro_syzcomp);
4284 
4285  r->typ[1].data.syzcomp.ShiftedComponents = currShiftedComponents;
4286  r->typ[1].data.syzcomp.Components = currComponents;
4287 }
4288 
4289 static inline void rNGetSComps(int** currComponents, long** currShiftedComponents, ring r)
4290 {
4291  assume(r->typ[1].ord_typ == ro_syzcomp);
4292 
4293  *currShiftedComponents = r->typ[1].data.syzcomp.ShiftedComponents;
4294  *currComponents = r->typ[1].data.syzcomp.Components;
4295 }
4296 #ifdef PDEBUG
4297 static inline void rDBChangeSComps(int* currComponents,
4298  long* currShiftedComponents,
4299  int length,
4300  ring r)
4301 {
4302  assume(r->typ[1].ord_typ == ro_syzcomp);
4303 
4304  r->typ[1].data.syzcomp.length = length;
4305  rNChangeSComps( currComponents, currShiftedComponents, r);
4306 }
4307 static inline void rDBGetSComps(int** currComponents,
4308  long** currShiftedComponents,
4309  int *length,
4310  ring r)
4311 {
4312  assume(r->typ[1].ord_typ == ro_syzcomp);
4313 
4314  *length = r->typ[1].data.syzcomp.length;
4315  rNGetSComps( currComponents, currShiftedComponents, r);
4316 }
4317 #endif
4318 
4319 void rChangeSComps(int* currComponents, long* currShiftedComponents, int length, ring r)
4320 {
4321 #ifdef PDEBUG
4322  rDBChangeSComps(currComponents, currShiftedComponents, length, r);
4323 #else
4324  rNChangeSComps(currComponents, currShiftedComponents, r);
4325 #endif
4326 }
4327 
4328 void rGetSComps(int** currComponents, long** currShiftedComponents, int *length, ring r)
4329 {
4330 #ifdef PDEBUG
4331  rDBGetSComps(currComponents, currShiftedComponents, length, r);
4332 #else
4333  rNGetSComps(currComponents, currShiftedComponents, r);
4334 #endif
4335 }
4336 
4337 
4338 /////////////////////////////////////////////////////////////////////////////
4339 //
4340 // The following routines all take as input a ring r, and return R
4341 // where R has a certain property. R might be equal r in which case r
4342 // had already this property
4343 //
4344 ring rAssure_SyzOrder(const ring r, BOOLEAN complete)
4345 {
4346  if ( r->order[0] == ringorder_c ) return r;
4347  return rAssure_SyzComp(r,complete);
4348 }
4349 ring rAssure_SyzComp(const ring r, BOOLEAN complete)
4350 {
4351  if ( r->order[0] == ringorder_s ) return r;
4352 
4353  if ( r->order[0] == ringorder_IS )
4354  {
4355 #ifndef SING_NDEBUG
4356  WarnS("rAssure_SyzComp: input ring has an IS-ordering!");
4357 #endif
4358 // return r;
4359  }
4360  ring res=rCopy0(r, FALSE, FALSE);
4361  int i=rBlocks(r);
4362  int j;
4363 
4364  res->order=(int *)omAlloc((i+1)*sizeof(int));
4365  res->block0=(int *)omAlloc0((i+1)*sizeof(int));
4366  res->block1=(int *)omAlloc0((i+1)*sizeof(int));
4367  int ** wvhdl =(int **)omAlloc0((i+1)*sizeof(int**));
4368  for(j=i;j>0;j--)
4369  {
4370  res->order[j]=r->order[j-1];
4371  res->block0[j]=r->block0[j-1];
4372  res->block1[j]=r->block1[j-1];
4373  if (r->wvhdl[j-1] != NULL)
4374  {
4375  wvhdl[j] = (int*) omMemDup(r->wvhdl[j-1]);
4376  }
4377  }
4378  res->order[0]=ringorder_s;
4379 
4380  res->wvhdl = wvhdl;
4381 
4382  if (complete)
4383  {
4384  rComplete(res, 1);
4385 
4386 #ifdef HAVE_PLURAL
4387  if (rIsPluralRing(r))
4388  {
4389  if ( nc_rComplete(r, res, false) ) // no qideal!
4390  {
4391 #ifndef SING_NDEBUG
4392  WarnS("error in nc_rComplete"); // cleanup?// rDelete(res);// return r; // just go on..
4393 #endif
4394  }
4395  }
4396  assume(rIsPluralRing(r) == rIsPluralRing(res));
4397 #endif
4398 
4399 #ifdef HAVE_PLURAL
4400  ring old_ring = r;
4401 #endif
4402 
4403  if (r->qideal!=NULL)
4404  {
4405  res->qideal= idrCopyR_NoSort(r->qideal, r, res);
4406 
4407  assume(id_RankFreeModule(res->qideal, res) == 0);
4408 
4409 #ifdef HAVE_PLURAL
4410  if( rIsPluralRing(res) )
4411  if( nc_SetupQuotient(res, r, true) )
4412  {
4413 // WarnS("error in nc_SetupQuotient"); // cleanup? rDelete(res); return r; // just go on...?
4414  }
4415 
4416 #endif
4417  assume(id_RankFreeModule(res->qideal, res) == 0);
4418  }
4419 
4420 #ifdef HAVE_PLURAL
4421  assume((res->qideal==NULL) == (old_ring->qideal==NULL));
4422  assume(rIsPluralRing(res) == rIsPluralRing(old_ring));
4423  assume(rIsSCA(res) == rIsSCA(old_ring));
4424  assume(ncRingType(res) == ncRingType(old_ring));
4425 #endif
4426  }
4427  return res;
4428 }
4429 
4430 ring rAssure_TDeg(ring r, int start_var, int end_var, int &pos)
4431 {
4432  int i;
4433  if (r->typ!=NULL)
4434  {
4435  for(i=r->OrdSize-1;i>=0;i--)
4436  {
4437  if ((r->typ[i].ord_typ==ro_dp)
4438  && (r->typ[i].data.dp.start==start_var)
4439  && (r->typ[i].data.dp.end==end_var))
4440  {
4441  pos=r->typ[i].data.dp.place;
4442  //printf("no change, pos=%d\n",pos);
4443  return r;
4444  }
4445  }
4446  }
4447 
4448 #ifdef HAVE_PLURAL
4449  nc_struct* save=r->GetNC();
4450  r->GetNC()=NULL;
4451 #endif
4452  ring res=rCopy(r);
4453 
4454  i=rBlocks(r);
4455  int j;
4456 
4457  res->ExpL_Size=r->ExpL_Size+1; // one word more in each monom
4458  res->PolyBin=omGetSpecBin(POLYSIZE + (res->ExpL_Size)*sizeof(long));
4459  omFree((ADDRESS)res->ordsgn);
4460  res->ordsgn=(long *)omAlloc0(res->ExpL_Size*sizeof(long));
4461  for(j=0;j<r->CmpL_Size;j++)
4462  {
4463  res->ordsgn[j] = r->ordsgn[j];
4464  }
4465  res->OrdSize=r->OrdSize+1; // one block more for pSetm
4466  if (r->typ!=NULL)
4467  omFree((ADDRESS)res->typ);
4468  res->typ=(sro_ord*)omAlloc0(res->OrdSize*sizeof(sro_ord));
4469  if (r->typ!=NULL)
4470  memcpy(res->typ,r->typ,r->OrdSize*sizeof(sro_ord));
4471  // the additional block for pSetm: total degree at the last word
4472  // but not included in the compare part
4473  res->typ[res->OrdSize-1].ord_typ=ro_dp;
4474  res->typ[res->OrdSize-1].data.dp.start=start_var;
4475  res->typ[res->OrdSize-1].data.dp.end=end_var;
4476  res->typ[res->OrdSize-1].data.dp.place=res->ExpL_Size-1;
4477  pos=res->ExpL_Size-1;
4478  //if ((start_var==1) && (end_var==res->N)) res->pOrdIndex=pos;
4479  extern void p_Setm_General(poly p, ring r);
4480  res->p_Setm=p_Setm_General;
4481  // ----------------------------
4482  omFree((ADDRESS)res->p_Procs);
4483  res->p_Procs = (p_Procs_s*)omAlloc(sizeof(p_Procs_s));
4484 
4485  p_ProcsSet(res, res->p_Procs);
4486  if (res->qideal!=NULL) id_Delete(&res->qideal,res);
4487 #ifdef HAVE_PLURAL
4488  r->GetNC()=save;
4489  if (rIsPluralRing(r))
4490  {
4491  if ( nc_rComplete(r, res, false) ) // no qideal!
4492  {
4493 #ifndef SING_NDEBUG
4494  WarnS("error in nc_rComplete");
4495 #endif
4496  // just go on..
4497  }
4498  }
4499 #endif
4500  if (r->qideal!=NULL)
4501  {
4502  res->qideal=idrCopyR_NoSort(r->qideal,r, res);
4503 #ifdef HAVE_PLURAL
4504  if (rIsPluralRing(res))
4505  {
4506 // nc_SetupQuotient(res, currRing);
4507  nc_SetupQuotient(res, r); // ?
4508  }
4509  assume((res->qideal==NULL) == (r->qideal==NULL));
4510 #endif
4511  }
4512 
4513 #ifdef HAVE_PLURAL
4514  assume(rIsPluralRing(res) == rIsPluralRing(r));
4515  assume(rIsSCA(res) == rIsSCA(r));
4516  assume(ncRingType(res) == ncRingType(r));
4517 #endif
4518 
4519  return res;
4520 }
4521 
4522 ring rAssure_HasComp(const ring r)
4523 {
4524  int last_block;
4525  int i=0;
4526  do
4527  {
4528  if (r->order[i] == ringorder_c ||
4529  r->order[i] == ringorder_C) return r;
4530  if (r->order[i] == 0)
4531  break;
4532  i++;
4533  } while (1);
4534  //WarnS("re-creating ring with comps");
4535  last_block=i-1;
4536 
4537  ring new_r = rCopy0(r, FALSE, FALSE);
4538  i+=2;
4539  new_r->wvhdl=(int **)omAlloc0(i * sizeof(int *));
4540  new_r->order = (int *) omAlloc0(i * sizeof(int));
4541  new_r->block0 = (int *) omAlloc0(i * sizeof(int));
4542  new_r->block1 = (int *) omAlloc0(i * sizeof(int));
4543  memcpy(new_r->order,r->order,(i-1) * sizeof(int));
4544  memcpy(new_r->block0,r->block0,(i-1) * sizeof(int));
4545  memcpy(new_r->block1,r->block1,(i-1) * sizeof(int));
4546  for (int j=0; j<=last_block; j++)
4547  {
4548  if (r->wvhdl[j]!=NULL)
4549  {
4550  new_r->wvhdl[j] = (int*) omMemDup(r->wvhdl[j]);
4551  }
4552  }
4553  last_block++;
4554  new_r->order[last_block]=ringorder_C;
4555  //new_r->block0[last_block]=0;
4556  //new_r->block1[last_block]=0;
4557  //new_r->wvhdl[last_block]=NULL;
4558 
4559  rComplete(new_r, 1);
4560 
4561 #ifdef HAVE_PLURAL
4562  if (rIsPluralRing(r))
4563  {
4564  if ( nc_rComplete(r, new_r, false) ) // no qideal!
4565  {
4566 #ifndef SING_NDEBUG
4567  WarnS("error in nc_rComplete"); // cleanup?// rDelete(res);// return r; // just go on..
4568 #endif
4569  }
4570  }
4571  assume(rIsPluralRing(r) == rIsPluralRing(new_r));
4572 #endif
4573 
4574  return new_r;
4575 }
4576 
4577 ring rAssure_CompLastBlock(ring r, BOOLEAN complete)
4578 {
4579  int last_block = rBlocks(r) - 2;
4580  if (r->order[last_block] != ringorder_c &&
4581  r->order[last_block] != ringorder_C)
4582  {
4583  int c_pos = 0;
4584  int i;
4585 
4586  for (i=0; i< last_block; i++)
4587  {
4588  if (r->order[i] == ringorder_c || r->order[i] == ringorder_C)
4589  {
4590  c_pos = i;
4591  break;
4592  }
4593  }
4594  if (c_pos != -1)
4595  {
4596  ring new_r = rCopy0(r, FALSE, TRUE);
4597  for (i=c_pos+1; i<=last_block; i++)
4598  {
4599  new_r->order[i-1] = new_r->order[i];
4600  new_r->block0[i-1] = new_r->block0[i];
4601  new_r->block1[i-1] = new_r->block1[i];
4602  new_r->wvhdl[i-1] = new_r->wvhdl[i];
4603  }
4604  new_r->order[last_block] = r->order[c_pos];
4605  new_r->block0[last_block] = r->block0[c_pos];
4606  new_r->block1[last_block] = r->block1[c_pos];
4607  new_r->wvhdl[last_block] = r->wvhdl[c_pos];
4608  if (complete)
4609  {
4610  rComplete(new_r, 1);
4611 
4612 #ifdef HAVE_PLURAL
4613  if (rIsPluralRing(r))
4614  {
4615  if ( nc_rComplete(r, new_r, false) ) // no qideal!
4616  {
4617 #ifndef SING_NDEBUG
4618  WarnS("error in nc_rComplete"); // cleanup?// rDelete(res);// return r; // just go on..
4619 #endif
4620  }
4621  }
4622  assume(rIsPluralRing(r) == rIsPluralRing(new_r));
4623 #endif
4624  }
4625  return new_r;
4626  }
4627  }
4628  return r;
4629 }
4630 
4631 // Moves _c or _C ordering to the last place AND adds _s on the 1st place
4633 {
4634  rTest(r);
4635 
4636  ring new_r_1 = rAssure_CompLastBlock(r, FALSE); // due to this FALSE - no completion!
4637  ring new_r = rAssure_SyzComp(new_r_1, FALSE); // new_r_1 is used only here!!!
4638 
4639  if (new_r == r)
4640  return r;
4641 
4642  ring old_r = r;
4643  if (new_r_1 != new_r && new_r_1 != old_r) rDelete(new_r_1);
4644 
4645  rComplete(new_r, TRUE);
4646 #ifdef HAVE_PLURAL
4647  if (rIsPluralRing(old_r))
4648  {
4649  if ( nc_rComplete(old_r, new_r, false) ) // no qideal!
4650  {
4651 # ifndef SING_NDEBUG
4652  WarnS("error in nc_rComplete"); // cleanup? rDelete(res); return r; // just go on...?
4653 # endif
4654  }
4655  }
4656 #endif
4657 
4658 ///? rChangeCurrRing(new_r);
4659  if (old_r->qideal != NULL)
4660  {
4661  new_r->qideal = idrCopyR(old_r->qideal, old_r, new_r);
4662  }
4663 
4664 #ifdef HAVE_PLURAL
4665  if( rIsPluralRing(old_r) )
4666  if( nc_SetupQuotient(new_r, old_r, true) )
4667  {
4668 #ifndef SING_NDEBUG
4669  WarnS("error in nc_SetupQuotient"); // cleanup? rDelete(res); return r; // just go on...?
4670 #endif
4671  }
4672 #endif
4673 
4674 #ifdef HAVE_PLURAL
4675  assume((new_r->qideal==NULL) == (old_r->qideal==NULL));
4676  assume(rIsPluralRing(new_r) == rIsPluralRing(old_r));
4677  assume(rIsSCA(new_r) == rIsSCA(old_r));
4678  assume(ncRingType(new_r) == ncRingType(old_r));
4679 #endif
4680 
4681  rTest(new_r);
4682  rTest(old_r);
4683  return new_r;
4684 }
4685 
4686 // use this for global orderings consisting of two blocks
4687 static ring rAssure_Global(rRingOrder_t b1, rRingOrder_t b2, const ring r)
4688 {
4689  int r_blocks = rBlocks(r);
4690 
4691  assume(b1 == ringorder_c || b1 == ringorder_C ||
4692  b2 == ringorder_c || b2 == ringorder_C ||
4693  b2 == ringorder_S);
4694  if ((r_blocks == 3) &&
4695  (r->order[0] == b1) &&
4696  (r->order[1] == b2) &&
4697  (r->order[2] == 0))
4698  return r;
4699  ring res = rCopy0(r, TRUE, FALSE);
4700  res->order = (int*)omAlloc0(3*sizeof(int));
4701  res->block0 = (int*)omAlloc0(3*sizeof(int));
4702  res->block1 = (int*)omAlloc0(3*sizeof(int));
4703  res->wvhdl = (int**)omAlloc0(3*sizeof(int*));
4704  res->order[0] = b1;
4705  res->order[1] = b2;
4706  if (b1 == ringorder_c || b1 == ringorder_C)
4707  {
4708  res->block0[1] = 1;
4709  res->block1[1] = r->N;
4710  }
4711  else
4712  {
4713  res->block0[0] = 1;
4714  res->block1[0] = r->N;
4715  }
4716  rComplete(res, 1);
4717 #ifdef HAVE_PLURAL
4718  if (rIsPluralRing(r))
4719  {
4720  if ( nc_rComplete(r, res, false) ) // no qideal!
4721  {
4722 #ifndef SING_NDEBUG
4723  WarnS("error in nc_rComplete");
4724 #endif
4725  }
4726  }
4727 #endif
4728 // rChangeCurrRing(res);
4729  return res;
4730 }
4731 
4732 ring rAssure_InducedSchreyerOrdering(const ring r, BOOLEAN complete = TRUE, int sgn = 1)
4733 { // TODO: ???? Add leading Syz-comp ordering here...????
4734 
4735 #if MYTEST
4736  Print("rAssure_InducedSchreyerOrdering(r, complete = %d, sgn = %d): r: \n", complete, sgn);
4737  rWrite(r);
4738 #ifdef RDEBUG
4739  rDebugPrint(r);
4740 #endif
4741  PrintLn();
4742 #endif
4743  assume((sgn == 1) || (sgn == -1));
4744 
4745  ring res=rCopy0(r, FALSE, FALSE); // No qideal & ordering copy.
4746 
4747  int n = rBlocks(r); // Including trailing zero!
4748 
4749  // Create 2 more blocks for prefix/suffix:
4750  res->order=(int *)omAlloc0((n+2)*sizeof(int)); // 0 .. n+1
4751  res->block0=(int *)omAlloc0((n+2)*sizeof(int));
4752  res->block1=(int *)omAlloc0((n+2)*sizeof(int));
4753  int ** wvhdl =(int **)omAlloc0((n+2)*sizeof(int**));
4754 
4755  // Encapsulate all existing blocks between induced Schreyer ordering markers: prefix and suffix!
4756  // Note that prefix and suffix have the same ringorder marker and only differ in block[] parameters!
4757 
4758  // new 1st block
4759  int j = 0;
4760  res->order[j] = ringorder_IS; // Prefix
4761  res->block0[j] = res->block1[j] = 0;
4762  // wvhdl[j] = NULL;
4763  j++;
4764 
4765  for(int i = 0; (i <= n) && (r->order[i] != 0); i++, j++) // i = [0 .. n-1] <- non-zero old blocks
4766  {
4767  res->order [j] = r->order [i];
4768  res->block0[j] = r->block0[i];
4769  res->block1[j] = r->block1[i];
4770 
4771  if (r->wvhdl[i] != NULL)
4772  {
4773  wvhdl[j] = (int*) omMemDup(r->wvhdl[i]);
4774  } // else wvhdl[j] = NULL;
4775  }
4776 
4777  // new last block
4778  res->order [j] = ringorder_IS; // Suffix
4779  res->block0[j] = res->block1[j] = sgn; // Sign of v[o]: 1 for C, -1 for c
4780  // wvhdl[j] = NULL;
4781  j++;
4782 
4783  // res->order [j] = 0; // The End!
4784  res->wvhdl = wvhdl;
4785 
4786  // j == the last zero block now!
4787  assume(j == (n+1));
4788  assume(res->order[0]==ringorder_IS);
4789  assume(res->order[j-1]==ringorder_IS);
4790  assume(res->order[j]==0);
4791 
4792 
4793  if (complete)
4794  {
4795  rComplete(res, 1);
4796 
4797 #ifdef HAVE_PLURAL
4798  if (rIsPluralRing(r))
4799  {
4800  if ( nc_rComplete(r, res, false) ) // no qideal!
4801  {
4802 #ifndef SING_NDEBUG
4803  WarnS("error in nc_rComplete"); // cleanup?// rDelete(res);// return r; // just go on..
4804 #endif
4805  }
4806  }
4807  assume(rIsPluralRing(r) == rIsPluralRing(res));
4808 #endif
4809 
4810 
4811 #ifdef HAVE_PLURAL
4812  ring old_ring = r;
4813 #endif
4814 
4815  if (r->qideal!=NULL)
4816  {
4817  res->qideal= idrCopyR_NoSort(r->qideal, r, res);
4818 
4819  assume(id_RankFreeModule(res->qideal, res) == 0);
4820 
4821 #ifdef HAVE_PLURAL
4822  if( rIsPluralRing(res) )
4823  if( nc_SetupQuotient(res, r, true) )
4824  {
4825 // WarnS("error in nc_SetupQuotient"); // cleanup? rDelete(res); return r; // just go on...?
4826  }
4827 
4828 #endif
4829  assume(id_RankFreeModule(res->qideal, res) == 0);
4830  }
4831 
4832 #ifdef HAVE_PLURAL
4833  assume((res->qideal==NULL) == (old_ring->qideal==NULL));
4834  assume(rIsPluralRing(res) == rIsPluralRing(old_ring));
4835  assume(rIsSCA(res) == rIsSCA(old_ring));
4836  assume(ncRingType(res) == ncRingType(old_ring));
4837 #endif
4838  }
4839 
4840  return res;
4841 }
4842 
4843 ring rAssure_dp_S(const ring r)
4844 {
4846 }
4847 
4848 ring rAssure_dp_C(const ring r)
4849 {
4851 }
4852 
4853 ring rAssure_C_dp(const ring r)
4854 {
4856 }
4857 
4858 ring rAssure_c_dp(const ring r)
4859 {
4861 }
4862 
4863 
4864 
4865 /// Finds p^th IS ordering, and returns its position in r->typ[]
4866 /// returns -1 if something went wrong!
4867 /// p - starts with 0!
4868 int rGetISPos(const int p, const ring r)
4869 {
4870  // Put the reference set F into the ring -ordering -recor
4871 #if MYTEST
4872  Print("rIsIS(p: %d)\nF:", p);
4873  PrintLn();
4874 #endif
4875 
4876  if (r->typ==NULL)
4877  {
4878 // dReportError("'rIsIS:' Error: wrong ring! (typ == NULL)");
4879  return -1;
4880  }
4881 
4882  int j = p; // Which IS record to use...
4883  for( int pos = 0; pos < r->OrdSize; pos++ )
4884  if( r->typ[pos].ord_typ == ro_is)
4885  if( j-- == 0 )
4886  return pos;
4887 
4888  return -1;
4889 }
4890 
4891 
4892 
4893 
4894 
4895 
4896 /// Changes r by setting induced ordering parameters: limit and reference leading terms
4897 /// F belong to r, we will DO a copy!
4898 /// We will use it AS IS!
4899 /// returns true is everything was allright!
4900 BOOLEAN rSetISReference(const ring r, const ideal F, const int i, const int p)
4901 {
4902  // Put the reference set F into the ring -ordering -recor
4903 
4904  if (r->typ==NULL)
4905  {
4906  dReportError("Error: WRONG USE of rSetISReference: wrong ring! (typ == NULL)");
4907  return FALSE;
4908  }
4909 
4910 
4911  int pos = rGetISPos(p, r);
4912 
4913  if( pos == -1 )
4914  {
4915  dReportError("Error: WRONG USE of rSetISReference: specified ordering block was not found!!!" );
4916  return FALSE;
4917  }
4918 
4919 #if MYTEST
4920  if( i != r->typ[pos].data.is.limit )
4921  Print("Changing record on pos: %d\nOld limit: %d --->> New Limit: %d\n", pos, r->typ[pos].data.is.limit, i);
4922 #endif
4923 
4924  const ideal FF = idrHeadR(F, r, r); // id_Copy(F, r); // ???
4925 
4926 
4927  if( r->typ[pos].data.is.F != NULL)
4928  {
4929 #if MYTEST
4930  PrintS("Deleting old reference set F... \n"); // idShow(r->typ[pos].data.is.F, r); PrintLn();
4931 #endif
4932  id_Delete(&r->typ[pos].data.is.F, r);
4933  r->typ[pos].data.is.F = NULL;
4934  }
4935 
4936  assume(r->typ[pos].data.is.F == NULL);
4937 
4938  r->typ[pos].data.is.F = FF; // F is owened by ring now! TODO: delete at the end!
4939 
4940  r->typ[pos].data.is.limit = i; // First induced component
4941 
4942 #if MYTEST
4943  PrintS("New reference set FF : \n"); idShow(FF, r, r, 1); PrintLn();
4944 #endif
4945 
4946  return TRUE;
4947 }
4948 
4949 #ifdef PDEBUG
4951 #endif
4952 
4953 
4954 void rSetSyzComp(int k, const ring r)
4955 {
4956  if(k < 0)
4957  {
4958  dReportError("rSetSyzComp with negative limit!");
4959  return;
4960  }
4961 
4962  assume( k >= 0 );
4963  if (TEST_OPT_PROT) Print("{%d}", k);
4964  if ((r->typ!=NULL) && (r->typ[0].ord_typ==ro_syz))
4965  {
4966  if( k == r->typ[0].data.syz.limit )
4967  return; // nothing to do
4968 
4969  int i;
4970  if (r->typ[0].data.syz.limit == 0)
4971  {
4972  r->typ[0].data.syz.syz_index = (int*) omAlloc0((k+1)*sizeof(int));
4973  r->typ[0].data.syz.syz_index[0] = 0;
4974  r->typ[0].data.syz.curr_index = 1;
4975  }
4976  else
4977  {
4978  r->typ[0].data.syz.syz_index = (int*)
4979  omReallocSize(r->typ[0].data.syz.syz_index,
4980  (r->typ[0].data.syz.limit+1)*sizeof(int),
4981  (k+1)*sizeof(int));
4982  }
4983  for (i=r->typ[0].data.syz.limit + 1; i<= k; i++)
4984  {
4985  r->typ[0].data.syz.syz_index[i] =
4986  r->typ[0].data.syz.curr_index;
4987  }
4988  if(k < r->typ[0].data.syz.limit) // ?
4989  {
4990 #ifndef SING_NDEBUG
4991  Warn("rSetSyzComp called with smaller limit (%d) as before (%d)", k, r->typ[0].data.syz.limit);
4992 #endif
4993  r->typ[0].data.syz.curr_index = 1 + r->typ[0].data.syz.syz_index[k];
4994  }
4995 
4996 
4997  r->typ[0].data.syz.limit = k;
4998  r->typ[0].data.syz.curr_index++;
4999  }
5000  else if(
5001  (r->typ!=NULL) &&
5002  (r->typ[0].ord_typ==ro_isTemp)
5003  )
5004  {
5005 // (r->typ[currRing->typ[0].data.isTemp.suffixpos].data.is.limit == k)
5006 #ifndef SING_NDEBUG
5007  Warn("rSetSyzComp(%d) in an IS ring! Be careful!", k);
5008 #endif
5009  }
5010  else
5011  if ((r->order[0]!=ringorder_c) && (k!=0)) // ???
5012  {
5013  dReportError("syzcomp in incompatible ring");
5014  }
5015 #ifdef PDEBUG
5016  extern int pDBsyzComp;
5017  pDBsyzComp=k;
5018 #endif
5019 }
5020 
5021 // return the max-comonent wchich has syzIndex i
5022 int rGetMaxSyzComp(int i, const ring r)
5023 {
5024  if ((r->typ!=NULL) && (r->typ[0].ord_typ==ro_syz) &&
5025  r->typ[0].data.syz.limit > 0 && i > 0)
5026  {
5027  assume(i <= r->typ[0].data.syz.limit);
5028  int j;
5029  for (j=0; j<r->typ[0].data.syz.limit; j++)
5030  {
5031  if (r->typ[0].data.syz.syz_index[j] == i &&
5032  r->typ[0].data.syz.syz_index[j+1] != i)
5033  {
5034  assume(r->typ[0].data.syz.syz_index[j+1] == i+1);
5035  return j;
5036  }
5037  }
5038  return r->typ[0].data.syz.limit;
5039  }
5040  else
5041  {
5042  return 0;
5043  }
5044 }
5045 
5047 {
5048  if (r == NULL) return FALSE;
5049  int i, j, nb = rBlocks(r);
5050  for (i=0; i<nb; i++)
5051  {
5052  if (r->wvhdl[i] != NULL)
5053  {
5054  int length = r->block1[i] - r->block0[i];
5055  int* wvhdl = r->wvhdl[i];
5056  if (r->order[i] == ringorder_M) length *= length;
5057  assume(omSizeOfAddr(wvhdl) >= length*sizeof(int));
5058 
5059  for (j=0; j< length; j++)
5060  {
5061  if (wvhdl[j] != 0 && wvhdl[j] != 1) return FALSE;
5062  }
5063  }
5064  }
5065  return TRUE;
5066 }
5067 
5069 {
5070  assume(r != NULL);
5071  int lb = rBlocks(r) - 2;
5072  return (r->order[lb] == ringorder_c || r->order[lb] == ringorder_C);
5073 }
5074 
5076 {
5077  return (r->cf->type);
5078  if (rField_is_Zp(r)) return n_Zp;
5079  if (rField_is_Q(r)) return n_Q;
5080  if (rField_is_R(r)) return n_R;
5081  if (rField_is_GF(r)) return n_GF;
5082  if (rField_is_long_R(r)) return n_long_R;
5083  if (rField_is_Zp_a(r)) return getCoeffType(r->cf);
5084  if (rField_is_Q_a(r)) return getCoeffType(r->cf);
5085  if (rField_is_long_C(r)) return n_long_C;
5086  if (rField_is_Ring_Z(r)) return n_Z;
5087  if (rField_is_Ring_ModN(r)) return n_Zn;
5088  if (rField_is_Ring_PtoM(r)) return n_Znm;
5089  if (rField_is_Ring_2toM(r)) return n_Z2m;
5090 
5091  return n_unknown;
5092 }
5093 
5094 int64 * rGetWeightVec(const ring r)
5095 {
5096  assume(r!=NULL);
5097  assume(r->OrdSize>0);
5098  int i=0;
5099  while((r->typ[i].ord_typ!=ro_wp64) && (r->typ[i].ord_typ>0)) i++;
5100  assume(r->typ[i].ord_typ==ro_wp64);
5101  return (int64*)(r->typ[i].data.wp64.weights64);
5102 }
5103 
5104 void rSetWeightVec(ring r, int64 *wv)
5105 {
5106  assume(r!=NULL);
5107  assume(r->OrdSize>0);
5108  assume(r->typ[0].ord_typ==ro_wp64);
5109  memcpy(r->typ[0].data.wp64.weights64,wv,r->N*sizeof(int64));
5110 }
5111 
5112 #include <ctype.h>
5113 
5114 static int rRealloc1(ring r, int size, int pos)
5115 {
5116  r->order=(int*)omReallocSize(r->order, size*sizeof(int), (size+1)*sizeof(int));
5117  r->block0=(int*)omReallocSize(r->block0, size*sizeof(int), (size+1)*sizeof(int));
5118  r->block1=(int*)omReallocSize(r->block1, size*sizeof(int), (size+1)*sizeof(int));
5119  r->wvhdl=(int **)omReallocSize(r->wvhdl,size*sizeof(int *), (size+1)*sizeof(int *));
5120  for(int k=size; k>pos; k--) r->wvhdl[k]=r->wvhdl[k-1];
5121  r->order[size]=0;
5122  size++;
5123  return size;
5124 }
5125 #if 0 // currently unused
5126 static int rReallocM1(ring r, int size, int pos)
5127 {
5128  r->order=(int*)omReallocSize(r->order, size*sizeof(int), (size-1)*sizeof(int));
5129  r->block0=(int*)omReallocSize(r->block0, size*sizeof(int), (size-1)*sizeof(int));
5130  r->block1=(int*)omReallocSize(r->block1, size*sizeof(int), (size-1)*sizeof(int));
5131  r->wvhdl=(int **)omReallocSize(r->wvhdl,size*sizeof(int *), (size-1)*sizeof(int *));
5132  for(int k=pos+1; k<size; k++) r->wvhdl[k]=r->wvhdl[k+1];
5133  size--;
5134  return size;
5135 }
5136 #endif
5137 static void rOppWeight(int *w, int l)
5138 {
5139  int i2=(l+1)/2;
5140  for(int j=0; j<=i2; j++)
5141  {
5142  int t=w[j];
5143  w[j]=w[l-j];
5144  w[l-j]=t;
5145  }
5146 }
5147 
5148 #define rOppVar(R,I) (rVar(R)+1-I)
5149 
5150 ring rOpposite(ring src)
5151  /* creates an opposite algebra of R */
5152  /* that is R^opp, where f (*^opp) g = g*f */
5153  /* treats the case of qring */
5154 {
5155  if (src == NULL) return(NULL);
5156 
5157 #ifdef RDEBUG
5158  rTest(src);
5159 #endif
5160 
5161  //rChangeCurrRing(src);
5162 
5163 #ifdef RDEBUG
5164  rTest(src);
5165 // rWrite(src);
5166 // rDebugPrint(src);
5167 #endif
5168 
5169 
5170  ring r = rCopy0(src,FALSE); /* qideal will be deleted later on!!! */
5171 
5172  // change vars v1..vN -> vN..v1
5173  int i;
5174  int i2 = (rVar(r)-1)/2;
5175  for(i=i2; i>=0; i--)
5176  {
5177  // index: 0..N-1
5178  //Print("ex var names: %d <-> %d\n",i,rOppVar(r,i));
5179  // exchange names
5180  char *p;
5181  p = r->names[rVar(r)-1-i];
5182  r->names[rVar(r)-1-i] = r->names[i];
5183  r->names[i] = p;
5184  }
5185 // i2=(rVar(r)+1)/2;
5186 // for(int i=i2; i>0; i--)
5187 // {
5188 // // index: 1..N
5189 // //Print("ex var places: %d <-> %d\n",i,rVar(r)+1-i);
5190 // // exchange VarOffset
5191 // int t;
5192 // t=r->VarOffset[i];
5193 // r->VarOffset[i]=r->VarOffset[rOppVar(r,i)];
5194 // r->VarOffset[rOppVar(r,i)]=t;
5195 // }
5196  // change names:
5197  for (i=rVar(r)-1; i>=0; i--)
5198  {
5199  char *p=r->names[i];
5200  if(isupper(*p)) *p = tolower(*p);
5201  else *p = toupper(*p);
5202  }
5203  // change ordering: listing
5204  // change ordering: compare
5205 // for(i=0; i<r->OrdSize; i++)
5206 // {
5207 // int t,tt;
5208 // switch(r->typ[i].ord_typ)
5209 // {
5210 // case ro_dp:
5211 // //
5212 // t=r->typ[i].data.dp.start;
5213 // r->typ[i].data.dp.start=rOppVar(r,r->typ[i].data.dp.end);
5214 // r->typ[i].data.dp.end=rOppVar(r,t);
5215 // break;
5216 // case ro_wp:
5217 // case ro_wp_neg:
5218 // {
5219 // t=r->typ[i].data.wp.start;
5220 // r->typ[i].data.wp.start=rOppVar(r,r->typ[i].data.wp.end);
5221 // r->typ[i].data.wp.end=rOppVar(r,t);
5222 // // invert r->typ[i].data.wp.weights
5223 // rOppWeight(r->typ[i].data.wp.weights,
5224 // r->typ[i].data.wp.end-r->typ[i].data.wp.start);
5225 // break;
5226 // }
5227 // //case ro_wp64:
5228 // case ro_syzcomp:
5229 // case ro_syz:
5230 // WerrorS("not implemented in rOpposite");
5231 // // should not happen
5232 // break;
5233 //
5234 // case ro_cp:
5235 // t=r->typ[i].data.cp.start;
5236 // r->typ[i].data.cp.start=rOppVar(r,r->typ[i].data.cp.end);
5237 // r->typ[i].data.cp.end=rOppVar(r,t);
5238 // break;
5239 // case ro_none:
5240 // default:
5241 // Werror("unknown type in rOpposite(%d)",r->typ[i].ord_typ);
5242 // break;
5243 // }
5244 // }
5245  // Change order/block structures (needed for rPrint, rAdd etc.)
5246  int j=0;
5247  int l=rBlocks(src);
5248  for(i=0; src->order[i]!=0; i++)
5249  {
5250  switch (src->order[i])
5251  {
5252  case ringorder_c: /* c-> c */
5253  case ringorder_C: /* C-> C */
5254  case ringorder_no /*=0*/: /* end-of-block */
5255  r->order[j]=src->order[i];
5256  j++; break;
5257  case ringorder_lp: /* lp -> rp */
5258  r->order[j]=ringorder_rp;
5259  r->block0[j]=rOppVar(r, src->block1[i]);
5260  r->block1[j]=rOppVar(r, src->block0[i]);
5261  break;
5262  case ringorder_rp: /* rp -> lp */
5263  r->order[j]=ringorder_lp;
5264  r->block0[j]=rOppVar(r, src->block1[i]);
5265  r->block1[j]=rOppVar(r, src->block0[i]);
5266  break;
5267  case ringorder_dp: /* dp -> a(1..1),ls */
5268  {
5269  l=rRealloc1(r,l,j);
5270  r->order[j]=ringorder_a;
5271  r->block0[j]=rOppVar(r, src->block1[i]);
5272  r->block1[j]=rOppVar(r, src->block0[i]);
5273  r->wvhdl[j]=(int*)omAlloc((r->block1[j]-r->block0[j]+1)*sizeof(int));
5274  for(int k=r->block0[j]; k<=r->block1[j]; k++)
5275  r->wvhdl[j][k-r->block0[j]]=1;
5276  j++;
5277  r->order[j]=ringorder_ls;
5278  r->block0[j]=rOppVar(r, src->block1[i]);
5279  r->block1[j]=rOppVar(r, src->block0[i]);
5280  j++;
5281  break;
5282  }
5283  case ringorder_Dp: /* Dp -> a(1..1),rp */
5284  {
5285  l=rRealloc1(r,l,j);
5286  r->order[j]=ringorder_a;
5287  r->block0[j]=rOppVar(r, src->block1[i]);
5288  r->block1[j]=rOppVar(r, src->block0[i]);
5289  r->wvhdl[j]=(int*)omAlloc((r->block1[j]-r->block0[j]+1)*sizeof(int));
5290  for(int k=r->block0[j]; k<=r->block1[j]; k++)
5291  r->wvhdl[j][k-r->block0[j]]=1;
5292  j++;
5293  r->order[j]=ringorder_rp;
5294  r->block0[j]=rOppVar(r, src->block1[i]);
5295  r->block1[j]=rOppVar(r, src->block0[i]);
5296  j++;
5297  break;
5298  }
5299  case ringorder_wp: /* wp -> a(...),ls */
5300  {
5301  l=rRealloc1(r,l,j);
5302  r->order[j]=ringorder_a;
5303  r->block0[j]=rOppVar(r, src->block1[i]);
5304  r->block1[j]=rOppVar(r, src->block0[i]);
5305  r->wvhdl[j]=r->wvhdl[j+1]; r->wvhdl[j+1]=NULL;
5306  rOppWeight(r->wvhdl[j], r->block1[j]-r->block0[j]);
5307  j++;
5308  r->order[j]=ringorder_ls;
5309  r->block0[j]=rOppVar(r, src->block1[i]);
5310  r->block1[j]=rOppVar(r, src->block0[i]);
5311  j++;
5312  break;
5313  }
5314  case ringorder_Wp: /* Wp -> a(...),rp */
5315  {
5316  l=rRealloc1(r,l,j);
5317  r->order[j]=ringorder_a;
5318  r->block0[j]=rOppVar(r, src->block1[i]);
5319  r->block1[j]=rOppVar(r, src->block0[i]);
5320  r->wvhdl[j]=r->wvhdl[j+1]; r->wvhdl[j+1]=NULL;
5321  rOppWeight(r->wvhdl[j], r->block1[j]-r->block0[j]);
5322  j++;
5323  r->order[j]=ringorder_rp;
5324  r->block0[j]=rOppVar(r, src->block1[i]);
5325  r->block1[j]=rOppVar(r, src->block0[i]);
5326  j++;
5327  break;
5328  }
5329  case ringorder_M: /* M -> M */
5330  {
5331  r->order[j]=ringorder_M;
5332  r->block0[j]=rOppVar(r, src->block1[i]);
5333  r->block1[j]=rOppVar(r, src->block0[i]);
5334  int n=r->block1[j]-r->block0[j];
5335  /* M is a (n+1)x(n+1) matrix */
5336  for (int nn=0; nn<=n; nn++)
5337  {
5338  rOppWeight(&(r->wvhdl[j][nn*(n+1)]), n /*r->block1[j]-r->block0[j]*/);
5339  }
5340  j++;
5341  break;
5342  }
5343  case ringorder_a: /* a(...),ls -> wp/dp */
5344  {
5345  r->block0[j]=rOppVar(r, src->block1[i]);
5346  r->block1[j]=rOppVar(r, src->block0[i]);
5347  rOppWeight(r->wvhdl[j], r->block1[j]-r->block0[j]);
5348  if (src->order[i+1]==ringorder_ls)
5349  {
5350  r->order[j]=ringorder_wp;
5351  i++;
5352  //l=rReallocM1(r,l,j);
5353  }
5354  else
5355  {
5356  r->order[j]=ringorder_a;
5357  }
5358  j++;
5359  break;
5360  }
5361  // not yet done:
5362  case ringorder_ls:
5363  case ringorder_rs:
5364  case ringorder_ds:
5365  case ringorder_Ds:
5366  case ringorder_ws:
5367  case ringorder_Ws:
5368  // should not occur:
5369  case ringorder_S:
5370  case ringorder_IS:
5371  case ringorder_s:
5372  case ringorder_aa:
5373  case ringorder_L:
5374  case ringorder_unspec:
5375  Werror("order %s not (yet) supported", rSimpleOrdStr(src->order[i]));
5376  break;
5377  }
5378  }
5379  rComplete(r);
5380 
5381 
5382 #ifdef RDEBUG
5383  rTest(r);
5384 #endif
5385 
5386  //rChangeCurrRing(r);
5387 
5388 #ifdef RDEBUG
5389  rTest(r);
5390 // rWrite(r);
5391 // rDebugPrint(r);
5392 #endif
5393 
5394 
5395 #ifdef HAVE_PLURAL
5396  // now, we initialize a non-comm structure on r
5397  if (rIsPluralRing(src))
5398  {
5399 // assume( currRing == r);
5400 
5401  int *perm = (int *)omAlloc0((rVar(r)+1)*sizeof(int));
5402  int *par_perm = NULL;
5403  nMapFunc nMap = n_SetMap(src->cf,r->cf);
5404  int ni,nj;
5405  for(i=1; i<=r->N; i++)
5406  {
5407  perm[i] = rOppVar(r,i);
5408  }
5409 
5410  matrix C = mpNew(rVar(r),rVar(r));
5411  matrix D = mpNew(rVar(r),rVar(r));
5412 
5413  for (i=1; i< rVar(r); i++)
5414  {
5415  for (j=i+1; j<=rVar(r); j++)
5416  {
5417  ni = r->N +1 - i;
5418  nj = r->N +1 - j; /* i<j ==> nj < ni */
5419 
5420  assume(MATELEM(src->GetNC()->C,i,j) != NULL);
5421  MATELEM(C,nj,ni) = p_PermPoly(MATELEM(src->GetNC()->C,i,j),perm,src,r, nMap,par_perm,rPar(src));
5422 
5423  if(MATELEM(src->GetNC()->D,i,j) != NULL)
5424  MATELEM(D,nj,ni) = p_PermPoly(MATELEM(src->GetNC()->D,i,j),perm,src,r, nMap,par_perm,rPar(src));
5425  }
5426  }
5427 
5428  id_Test((ideal)C, r);
5429  id_Test((ideal)D, r);
5430 
5431  if (nc_CallPlural(C, D, NULL, NULL, r, false, false, true, r)) // no qring setup!
5432  WarnS("Error initializing non-commutative multiplication!");
5433 
5434 #ifdef RDEBUG
5435  rTest(r);
5436 // rWrite(r);
5437 // rDebugPrint(r);
5438 #endif
5439 
5440  assume( r->GetNC()->IsSkewConstant == src->GetNC()->IsSkewConstant);
5441 
5442  omFreeSize((ADDRESS)perm,(rVar(r)+1)*sizeof(int));
5443  }
5444 #endif /* HAVE_PLURAL */
5445 
5446  /* now oppose the qideal for qrings */
5447  if (src->qideal != NULL)
5448  {
5449  id_Delete(&(r->qideal), r);
5450 
5451 #ifdef HAVE_PLURAL
5452  r->qideal = idOppose(src, src->qideal, r); // into the currRing: r
5453 #else
5454  r->qideal = id_Copy(src->qideal, r); // ?
5455 #endif
5456 
5457 #ifdef HAVE_PLURAL
5458  if( rIsPluralRing(r) )
5459  {
5460  nc_SetupQuotient(r);
5461 #ifdef RDEBUG
5462  rTest(r);
5463 // rWrite(r);
5464 // rDebugPrint(r);
5465 #endif
5466  }
5467 #endif
5468  }
5469 #ifdef HAVE_PLURAL
5470  if( rIsPluralRing(r) )
5471  assume( ncRingType(r) == ncRingType(src) );
5472 #endif
5473  rTest(r);
5474 
5475  return r;
5476 }
5477 
5478 ring rEnvelope(ring R)
5479  /* creates an enveloping algebra of R */
5480  /* that is R^e = R \tensor_K R^opp */
5481 {
5482  ring Ropp = rOpposite(R);
5483  ring Renv = NULL;
5484  int stat = rSum(R, Ropp, Renv); /* takes care of qideals */
5485  if ( stat <=0 )
5486  WarnS("Error in rEnvelope at rSum");
5487  rTest(Renv);
5488  return Renv;
5489 }
5490 
5491 #ifdef HAVE_PLURAL
5492 BOOLEAN nc_rComplete(const ring src, ring dest, bool bSetupQuotient)
5493 /* returns TRUE is there were errors */
5494 /* dest is actualy equals src with the different ordering */
5495 /* we map src->nc correctly to dest->src */
5496 /* to be executed after rComplete, before rChangeCurrRing */
5497 {
5498 // NOTE: Originally used only by idElimination to transfer NC structure to dest
5499 // ring created by dirty hack (without nc_CallPlural)
5500  rTest(src);
5501 
5502  assume(!rIsPluralRing(dest)); // destination must be a newly constructed commutative ring
5503 
5504  if (!rIsPluralRing(src))
5505  {
5506  return FALSE;
5507  }
5508 
5509  const int N = dest->N;
5510 
5511  assume(src->N == N);
5512 
5513 // ring save = currRing;
5514 
5515 // if (dest != save)
5516 // rChangeCurrRing(dest);
5517 
5518  const ring srcBase = src;
5519 
5520  assume( n_SetMap(srcBase->cf,dest->cf) == n_SetMap(dest->cf,dest->cf) ); // currRing is important here!
5521 
5522  matrix C = mpNew(N,N); // ring independent
5523  matrix D = mpNew(N,N);
5524 
5525  matrix C0 = src->GetNC()->C;
5526  matrix D0 = src->GetNC()->D;
5527 
5528  // map C and D into dest
5529  for (int i = 1; i < N; i++)
5530  {
5531  for (int j = i + 1; j <= N; j++)
5532  {
5533  const number n = n_Copy(p_GetCoeff(MATELEM(C0,i,j), srcBase), srcBase->cf); // src, mapping for coeffs into currRing = dest!
5534  const poly p = p_NSet(n, dest);
5535  MATELEM(C,i,j) = p;
5536  if (MATELEM(D0,i,j) != NULL)
5537  MATELEM(D,i,j) = prCopyR(MATELEM(D0,i,j), srcBase, dest); // ?
5538  }
5539  }
5540  /* One must test C and D _only_ in r->GetNC()->basering!!! not in r!!! */
5541 
5542  id_Test((ideal)C, dest);
5543  id_Test((ideal)D, dest);
5544 
5545  if (nc_CallPlural(C, D, NULL, NULL, dest, bSetupQuotient, false, true, dest)) // also takes care about quotient ideal
5546  {
5547  //WarnS("Error transferring non-commutative structure");
5548  // error message should be in the interpreter interface
5549 
5550  mp_Delete(&C, dest);
5551  mp_Delete(&D, dest);
5552 
5553 // if (currRing != save)
5554 // rChangeCurrRing(save);
5555 
5556  return TRUE;
5557  }
5558 
5559 // mp_Delete(&C, dest); // used by nc_CallPlural!
5560 // mp_Delete(&D, dest);
5561 
5562 // if (dest != save)
5563 // rChangeCurrRing(save);
5564 
5565  assume(rIsPluralRing(dest));
5566  return FALSE;
5567 }
5568 #endif
5569 
5570 void rModify_a_to_A(ring r)
5571 // to be called BEFORE rComplete:
5572 // changes every Block with a(...) to A(...)
5573 {
5574  int i=0;
5575  int j;
5576  while(r->order[i]!=0)
5577  {
5578  if (r->order[i]==ringorder_a)
5579  {
5580  r->order[i]=ringorder_a64;
5581  int *w=r->wvhdl[i];
5582  int64 *w64=(int64 *)omAlloc((r->block1[i]-r->block0[i]+1)*sizeof(int64));
5583  for(j=r->block1[i]-r->block0[i];j>=0;j--)
5584  w64[j]=(int64)w[j];
5585  r->wvhdl[i]=(int*)w64;
5586  omFreeSize(w,(r->block1[i]-r->block0[i]+1)*sizeof(int));
5587  }
5588  i++;
5589  }
5590 }
5591 
5592 
5593 poly rGetVar(const int varIndex, const ring r)
5594 {
5595  poly p = p_ISet(1, r);
5596  p_SetExp(p, varIndex, 1, r);
5597  p_Setm(p, r);
5598  return p;
5599 }
5600 
5601 
5602 /// TODO: rewrite somehow...
5603 int n_IsParam(const number m, const ring r)
5604 {
5605  assume(r != NULL);
5606  const coeffs C = r->cf;
5607  assume(C != NULL);
5608 
5610 
5611  const n_coeffType _filed_type = getCoeffType(C);
5612 
5613  if(( _filed_type == n_algExt )||( _filed_type == n_polyExt ))
5614  return naIsParam(m, C);
5615 
5616  if( _filed_type == n_transExt )
5617  return ntIsParam(m, C);
5618 
5619  Werror("n_IsParam: IsParam is not to be used for (coeff_type = %d)",getCoeffType(C));
5620 
5621  return 0;
5622 }
short N
Definition: ring.h:311
#define omAllocBin(bin)
Definition: omAllocDecl.h:205
for idElimination, like a, except pFDeg, pWeigths ignore it
Definition: ring.h:99
n_coeffType rFieldType(ring r)
Definition: ring.cc:5075
ideal SCAQuotient(const ring r)
Definition: sca.h:10
int pDBsyzComp
Definition: ring.cc:4950
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:5478
void p_DebugPrint(poly p, const ring r)
Definition: ring.cc:4203
#define omCheckAddrSize(addr, size)
Definition: omAllocDecl.h:327
#define D(A)
Definition: gentable.cc:123
for int64 weights
Definition: ring.h:79
#define omMemDup(s)
Definition: omAllocDecl.h:264
char * rVarStr(ring r)
Definition: ring.cc:594
n_Procs_s * cf
Definition: ring.h:373
static void rOptimizeLDeg(ring r)
Definition: ring.cc:3056
Definition: ring.h:68
omBin_t * omBin
Definition: omStructs.h:12
void PrintLn()
Definition: reporter.cc:310
#define Print
Definition: emacs.cc:83
long pLDeg1(poly p, int *l, const ring r)
Definition: p_polys.cc:840
only used if HAVE_RINGS is defined
Definition: coeffs.h:44
#define omcheckAddrSize(addr, size)
Definition: omAllocDecl.h:329
poly rGetVar(const int varIndex, const ring r)
Definition: ring.cc:5593
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:107
int order_index
Definition: ring.h:229
simple ordering, exponent vector has priority < component is compatible with exp-vector order ...
Definition: ring.h:111
static void rSetNegWeight(ring r)
Definition: ring.cc:3248
poly prCopyR(poly p, ring src_r, ring dest_r)
Definition: prCopy.cc:36
static BOOLEAN rField_is_Zp_a(const ring r)
Definition: ring.h:521
long pLDeg1c_Totaldegree(poly p, int *l, const ring r)
Definition: p_polys.cc:1004
p_SetmProc p_GetSetmProc(const ring r)
Definition: p_polys.cc:559
rOrderType_t rGetOrderType(ring r)
Definition: ring.cc:1716
#define TEST_OPT_PROT
Definition: options.h:98
only used if HAVE_RINGS is defined
Definition: coeffs.h:46
used for all transcendental extensions, i.e., the top-most extension in an extension tower is transce...
Definition: coeffs.h:39
loop
Definition: myNF.cc:98
static int min(int a, int b)
Definition: fast_mult.cc:268
BOOLEAN rRing_is_Homog(ring r)
Definition: ring.cc:5046
if(0 > strat->sl)
Definition: myNF.cc:73
static void rSetFirstWv(ring r, int i, int *order, int *block1, int **wvhdl)
Definition: ring.cc:3023
static BOOLEAN rField_is_Ring_PtoM(const ring r)
Definition: ring.h:471
int sgn(const Rational &a)
Definition: GMPrat.cc:437
long pLDeg1c(poly p, int *l, const ring r)
Definition: p_polys.cc:876
#define FALSE
Definition: auxiliary.h:94
static void rO_ISSuffix(int &place, int &bitplace, int &prev_ord, long *o, int N, int *v, sro_ord *tmp_typ, int &typ_i, int sgn)
Definition: ring.cc:2372
size_t omSizeOfAddr(const void *addr)
Definition: omAllocSystem.c:97
return P p
Definition: myNF.cc:203
opposite of ls
Definition: ring.h:100
ideal id_Copy(ideal h1, const ring r)
copy an ideal
static FORCE_INLINE BOOLEAN n_IsOne(number n, const coeffs r)
TRUE iff &#39;n&#39; represents the one element.
Definition: coeffs.h:472
BOOLEAN nc_rComplete(const ring src, ring dest, bool bSetupQuotient)
Definition: ring.cc:5492
static int rPar(const ring r)
(r->cf->P)
Definition: ring.h:590
poly p_NSet(number n, const ring r)
returns the poly representing the number n, destroys n
Definition: p_polys.cc:1442
BOOLEAN rOrd_is_WeightedDegree_Ordering(const ring r)
Definition: ring.cc:1902
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:468
#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:242
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:510
#define p_GetComp(p, r)
Definition: monomials.h:72
static int rRealloc1(ring r, int size, int pos)
Definition: ring.cc:5114
BOOLEAN rOrd_is_MixedDegree_Ordering(ring r)
Definition: ring.cc:3329
bool nc_SetupQuotient(ring rGR, const ring rG=NULL, bool bCopy=false)
Definition: old.gring.cc:3487
ring rCopy0AndAddA(const ring r, int64vec *wv64, BOOLEAN copy_qideal, BOOLEAN copy_ordering)
Definition: ring.cc:1460
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:1911
void rUnComplete(ring r)
Definition: ring.cc:3846
#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:572
ring rOpposite(ring src)
Definition: ring.cc:5150
static short rVar(const ring r)
#define rVar(r) (r->N)
Definition: ring.h:583
void id_Delete(ideal *h, ring r)
deletes an ideal/module/matrix
#define omfreeSize(addr, size)
Definition: omAllocDecl.h:236
static void m_DebugPrint(const poly p, const ring R)
debug-print monomial poly/vector p, assuming that it lives in the ring R
Definition: ring.cc:4226
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:2539
static void rNGetSComps(int **currComponents, long **currShiftedComponents, ring r)
Definition: ring.cc:4289
static void rOppWeight(int *w, int l)
Definition: ring.cc:5137
ring rModifyRing(ring r, BOOLEAN omit_degree, BOOLEAN try_omit_comp, unsigned long exp_limit)
Definition: ring.cc:2596
long int64
Definition: auxiliary.h:66
void p_Debug_GetSpecNames(const ring r, const char *&field, const char *&length, const char *&ord)
Definition: p_Procs_Set.h:200
BOOLEAN rOrder_is_WeightedOrdering(rRingOrder_t order)
Definition: ring.cc:1823
#define omUnGetSpecBin(bin_ptr)
Definition: omBin.h:14
static BOOLEAN rField_is_Q_a(const ring r)
Definition: ring.h:531
Definition: ring.h:255
#define TRUE
Definition: auxiliary.h:98
ring rAssure_SyzOrder(const ring r, BOOLEAN complete)
Definition: ring.cc:4344
static void rO_Syz(int &place, int &bitplace, int &prev_ord, long *o, sro_ord &ord_struct)
Definition: ring.cc:2331
static long p_Totaldegree(poly p, const ring r)
Definition: p_polys.h:1430
static void rO_ISPrefix(int &place, int &bitplace, int &prev_ord, long *o, int, int *v, sro_ord &ord_struct)
Definition: ring.cc:2354
ring rAssure_TDeg(ring r, int start_var, int end_var, int &pos)
Definition: ring.cc:4430
#define MIN(a, b)
Definition: omDebug.c:102
void * ADDRESS
Definition: auxiliary.h:115
BOOLEAN rOrder_is_DegOrdering(const rRingOrder_t order)
Definition: ring.cc:1804
simple ordering, component has priority
Definition: ring.h:108
#define POLYSIZE
Definition: monomials.h:241
void WerrorS(const char *s)
Definition: feFopen.cc:24
int k
Definition: cfEzgcd.cc:93
void p_Setm_TotalDegree(poly p, const ring r)
Definition: p_polys.cc:546
static BOOLEAN rField_is_GF(const ring r)
Definition: ring.h:513
static char const ** rParameter(const ring r)
(r->cf->parameter)
Definition: ring.h:616
char * StringEndS()
Definition: reporter.cc:151
long * currShiftedComponents
Definition: syz1.cc:40
int rGetISPos(const int p, const ring r)
Finds p^th IS ordering, and returns its position in r->typ[] returns -1 if something went wrong! p - ...
Definition: ring.cc:4868
#define Q
Definition: sirandom.c:25
#define rOppVar(R, I)
Definition: ring.cc:5148
BOOLEAN rDBTest(ring r, const char *fn, const int l)
Definition: ring.cc:1950
ring rAssure_HasComp(const ring r)
Definition: ring.cc:4522
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:4858
#define omAlloc(size)
Definition: omAllocDecl.h:210
#define Sy_bit(x)
Definition: options.h:30
static BOOLEAN rCanShortOut(const ring r)
Definition: ring.h:577
Definition: ring.h:64
BOOLEAN rHasSimpleOrder(const ring r)
Definition: ring.cc:1763
union sro_ord::@0 data
BOOLEAN rHas_c_Ordering(const ring r)
Definition: ring.cc:1759
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:1838
ideal idOppose(ring Rop_src, ideal I, const ring Rop_dst)
opposes a module I from Rop to currRing(dst)
Definition: old.gring.cc:3465
static void rSetOption(ring r)
Definition: ring.cc:3285
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:746
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:4307
simple ordering, exponent vector has priority < component not compatible with exp-vector order ...
Definition: ring.h:109
long pLDeg1c_Deg(poly p, int *l, const ring r)
Definition: p_polys.cc:940
int * block0
Definition: ring.h:262
ring rAssure_SyzComp_CompLastBlock(const ring r, BOOLEAN)
makes sure that c/C ordering is last ordering and SyzIndex is first
Definition: ring.cc:4632
#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
static void rSetDegStuff(ring r)
Definition: ring.cc:3083
#define omReallocSize(addr, o_size, size)
Definition: omAllocDecl.h:220
bool sca_Force(ring rGR, int b, int e)
Definition: sca.cc:1174
static void rO_LexVars_neg(int &place, int &bitplace, int start, int end, int &prev_ord, long *o, int *v, int bits, int opt_var)
Definition: ring.cc: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:4328
ro_typ ord_typ
Definition: ring.h:228
static void rDBChangeSComps(int *currComponents, long *currShiftedComponents, int length, ring r)
Definition: ring.cc:4297
static int rBlocks(ring r)
Definition: ring.h:559
int r_IsRingVar(const char *n, char **names, int N)
Definition: ring.cc:222
long p_Deg(poly a, const ring r)
Definition: p_polys.cc:586
const ring r
Definition: syzextra.cc:208
poly p_PermPoly(poly p, const int *perm, const ring oldRing, const ring dst, nMapFunc nMap, const int *par_perm, int OldPar, BOOLEAN use_mult)
Definition: p_polys.cc:3938
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:927
int naIsParam(number m, const coeffs cf)
if m == var(i)/1 => return i,
Definition: algext.cc:1106
Definition: intvec.h:14
long id_RankFreeModule(ideal s, ring lmRing, ring tailRing)
return the maximal component number found in any polynomial in s
const CanonicalForm CFMap CFMap & N
Definition: cfEzgcd.cc:49
poly p_One(const ring r)
Definition: p_polys.cc:1312
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:3351
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:261
static long p_GetExp(const poly p, const unsigned long iBitmask, const int VarOffset)
get a single variable exponent : the integer VarOffset encodes:
Definition: p_polys.h:464
#define OPT_REDTAIL
Definition: options.h:86
int j
Definition: myNF.cc:70
only used if HAVE_RINGS is defined
Definition: coeffs.h:45
#define omFree(addr)
Definition: omAllocDecl.h:261
#define TEST_OPT_OLDSTD
Definition: options.h:117
#define assume(x)
Definition: mod2.h:394
static BOOLEAN rIsPluralRing(const ring r)
we must always have this test!
Definition: ring.h:404
The main handler for Singular numbers which are suitable for Singular polynomials.
long p_WFirstTotalDegree(poly p, const ring r)
Definition: p_polys.cc: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:5022
static void rO_TDegree_neg(int &place, int &bitplace, int start, int end, long *o, sro_ord &ord_struct)
Definition: ring.cc:2120
int rows() const
Definition: int64vec.h:57
ring rCopy0(const ring r, BOOLEAN copy_qideal, BOOLEAN copy_ordering)
Definition: ring.cc:1321
void StringAppendS(const char *st)
Definition: reporter.cc:107
#define A
Definition: sirandom.c:23
number(* nMapFunc)(number a, const coeffs src, const coeffs dst)
maps "a", which lives in src, into dst
Definition: coeffs.h:73
long pLDeg0(poly p, int *l, const ring r)
Definition: p_polys.cc:738
ring rAssure_SyzComp(const ring r, BOOLEAN complete)
Definition: ring.cc:4349
const ring R
Definition: DebugPrint.cc:36
ring rAssure_dp_C(const ring r)
Definition: ring.cc:4848
complex floating point (GMP) numbers
Definition: coeffs.h:42
const char * rSimpleOrdStr(int ord)
Definition: ring.cc:88
const int MAX_INT_VAL
Definition: mylimits.h:12
rRingOrder_t
order stuff
Definition: ring.h:75
gmp_float sqrt(const gmp_float &a)
Definition: mpr_complex.cc:329
static ring rAssure_Global(rRingOrder_t b1, rRingOrder_t b2, const ring r)
Definition: ring.cc:4687
#define rTest(r)
Definition: ring.h:778
BOOLEAN rOrd_is_Totaldegree_Ordering(const ring r)
Definition: ring.cc:1889
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:375
BOOLEAN rCheckIV(const intvec *iv)
Definition: ring.cc:185
Definition: ring.h:226
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:1675
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:43
#define pFDeg_CASE(A)
static int si_max(const int a, const int b)
Definition: auxiliary.h:120
void rDebugPrint(const ring r)
Definition: ring.cc:3998
#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:101
void PrintS(const char *s)
Definition: reporter.cc:284
static BOOLEAN rField_is_Q(const ring r)
Definition: ring.h:501
ring rAssure_CompLastBlock(ring r, BOOLEAN complete)
makes sure that c/C ordering is last ordering
Definition: ring.cc:4577
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:211
S?
Definition: ring.h:83
BOOLEAN rOrd_SetCompRequiresSetm(const ring r)
return TRUE if p_SetComp requires p_Setm
Definition: ring.cc:1869
static void rSetVarL(ring r)
set r->VarL_Size, r->VarL_Offset, r->VarL_LowIndex
Definition: ring.cc:3903
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:1627
void mp_Delete(matrix *a, const ring r)
Definition: matpol.cc:792
static FORCE_INLINE nMapFunc n_SetMap(const coeffs src, const coeffs dst)
set the mapping function pointers for translating numbers from src to dst
Definition: coeffs.h:725
short OrdSgn
Definition: ring.h:313
static short scaFirstAltVar(ring r)
Definition: sca.h:18
static FORCE_INLINE n_coeffType getCoeffType(const coeffs r)
Returns the type of coeffs domain.
Definition: coeffs.h:425
Definition: ring.h:69
BOOLEAN p_EqualPolys(poly p1, poly p2, const ring r)
Definition: p_polys.cc:4320
#define p_Test(p, r)
Definition: p_polys.h:160
static BOOLEAN rField_is_long_C(const ring r)
Definition: ring.h:537
void rSetSyzComp(int k, const ring r)
Definition: ring.cc:4954
Definition: ring.h:69
int size(const CanonicalForm &f, const Variable &v)
int size ( const CanonicalForm & f, const Variable & v )
Definition: cf_ops.cc:600
static BOOLEAN rField_is_Zp(const ring r)
Definition: ring.h:495
#define OPT_INTSTRATEGY
Definition: options.h:87
rOrderType_t
Definition: ring.h:105
void pISUpdateComponents(ideal F, const intvec *const V, const int MIN, const ring r)
Definition: ring.cc:4240
matrix mpNew(int r, int c)
create a r x c zero-matrix
Definition: matpol.cc:47
static FORCE_INLINE coeffs nCopyCoeff(const coeffs r)
"copy" coeffs, i.e. increment ref
Definition: coeffs.h:433
void p_Write0(poly p, ring lmRing, ring tailRing)
Definition: polys0.cc:196
static void p_Delete(poly *p, const ring r)
Definition: p_polys.h:843
#define omAlloc0Bin(bin)
Definition: omAllocDecl.h:206
#define omGetSpecBin(size)
Definition: omBin.h:11
ideal idInit(int idsize, int rank)
initialise an ideal / module
Definition: simpleideals.cc:38
void rSetWeightVec(ring r, int64 *wv)
Definition: ring.cc:5104
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:2746
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:3087
ring rCopy(ring r)
Definition: ring.cc:1612
static unsigned long rGetDivMask(int bits)
get r->divmask depending on bits per exponent
Definition: ring.cc:3984
static unsigned long p_SetExp(poly p, const unsigned long e, const unsigned long iBitmask, const int VarOffset)
set a single variable exponent : VarOffset encodes the position in p->exp
Definition: p_polys.h:483
BOOLEAN rHasSimpleLexOrder(const ring r)
returns TRUE, if simple lp or ls ordering
Definition: ring.cc:1795
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:745
static BOOLEAN rField_is_Ring_2toM(const ring r)
Definition: ring.h:465
static BOOLEAN rField_is_Ring(const ring r)
Definition: ring.h:477
#define NULL
Definition: omList.c:10
ring rAssure_dp_S(const ring r)
Definition: ring.cc:4843
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
int length() const
Definition: intvec.h:86
{p^n < 2^16}
Definition: coeffs.h:33
static FORCE_INLINE number n_Copy(number n, const coeffs r)
return a copy of &#39;n&#39;
Definition: coeffs.h:455
int * block1
Definition: ring.h:263
void rDelete(ring r)
unconditionally deletes fields in r
Definition: ring.cc:448
ring rAssure_C_dp(const ring r)
Definition: ring.cc:4853
used for all algebraic extensions, i.e., the top-most extension in an extension tower is algebraic ...
Definition: coeffs.h:36
char ** names
Definition: ring.h:266
ring rAssure_InducedSchreyerOrdering(const ring r, BOOLEAN complete=TRUE, int sgn=1)
Definition: ring.cc:4732
static BOOLEAN rField_is_Ring_Z(const ring r)
Definition: ring.h:474
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:138
static BOOLEAN rField_is_long_R(const ring r)
Definition: ring.h:534
int rTypeOfMatrixOrder(const intvec *order)
Definition: ring.cc:195
const CanonicalForm & w
Definition: facAbsFact.cc:55
static short scaLastAltVar(ring r)
Definition: sca.h:25
static void rO_WDegree(int &place, int &bitplace, int start, int end, long *o, sro_ord &ord_struct, int *weights)
Definition: ring.cc: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:4900
Variable x
Definition: cfModGcd.cc:4023
Definition: ring.h:63
void rModify_a_to_A(ring r)
Definition: ring.cc:5570
static bool rIsSCA(const ring r)
Definition: nc.h:206
static void rRightAdjustVarOffset(ring r)
right-adjust r->VarOffset
Definition: ring.cc:3958
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:228
#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:863
int ntIsParam(number m, const coeffs cf)
if m == var(i)/1 => return i,
Definition: transext.cc:2237
int n_IsParam(const number m, const ring r)
TODO: rewrite somehow...
Definition: ring.cc:5603
#define BIT_SIZEOF_LONG
Definition: auxiliary.h:78
#define TEST_RINGDEP_OPTS
Definition: options.h:95
long p_WTotaldegree(poly p, const ring r)
Definition: p_polys.cc: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:976
polyrec * poly
Definition: hilb.h:10
static void rCheckOrdSgn(ring r, int i)
Definition: ring.cc:3753
int ** wvhdl
Definition: ring.h:265
#define omFreeBin(addr, bin)
Definition: omAllocDecl.h:259
ring rModifyRing_Simple(ring r, BOOLEAN ommit_degree, BOOLEAN ommit_comp, unsigned long exp_limit, BOOLEAN &simple)
Definition: ring.cc:2891
void p_SetGlobals(const ring r, BOOLEAN complete)
set all properties of a new ring - also called by rComplete
Definition: ring.cc:3316
s?
Definition: ring.h:84
int BOOLEAN
Definition: auxiliary.h:85
const poly b
Definition: syzextra.cc:213
BOOLEAN rRing_has_CompLastBlock(ring r)
Definition: ring.cc:5068
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:4319
void nKillChar(coeffs r)
undo all initialisations
Definition: numbers.cc:496
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:1296
static int sign(int x)
Definition: ring.cc:3328
char * rOrdStr(ring r)
Definition: ring.cc:522
void Werror(const char *fmt,...)
Definition: reporter.cc:189
int64 * rGetWeightVec(const ring r)
Definition: ring.cc:5094
#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:4281
used to represent polys as coeffcients
Definition: coeffs.h:35
#define UPMATELEM(i, j, nVar)
Definition: nc.h:44
#define MATELEM(mat, i, j)
Definition: matpol.h:29
coeffs nInitChar(n_coeffType t, void *parameter)
one-time initialisations for new coeffs in case of an error return NULL
Definition: numbers.cc:334
unsigned long bitmask
Definition: ring.h:357
#define Warn
Definition: emacs.cc:80
#define omStrDup(s)
Definition: omAllocDecl.h:263