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