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