source: git/kernel/ring.cc @ 8f42a46

spielwiese
Last change on this file since 8f42a46 was 8f42a46, checked in by Hans Schönemann <hannes@…>, 19 years ago
*hannes: rNameCheck git-svn-id: file:///usr/local/Singular/svn/trunk@8672 2c84dea3-7e68-4137-9b89-c4e89433aadc
  • Property mode set to 100644
File size: 100.7 KB
Line 
1/****************************************
2*  Computer Algebra System SINGULAR     *
3****************************************/
4/* $Id: ring.cc,v 1.42 2005-09-28 15:00:18 Singular Exp $ */
5
6/*
7* ABSTRACT - the interpreter related ring operations
8*/
9
10/* includes */
11#include <math.h>
12#include "mod2.h"
13#include "structs.h"
14#include "omalloc.h"
15#include "polys.h"
16#include "numbers.h"
17#include "febase.h"
18#include "ipconv.h"
19#include "intvec.h"
20#include "longalg.h"
21#include "ffields.h"
22#include "ideals.h"
23#include "ring.h"
24#include "prCopy.h"
25#include "../Singular/ipshell.h"
26#include "p_Procs.h"
27#ifdef HAVE_PLURAL
28#include "gring.h"
29#include "matpol.h"
30#include "maps.h"
31#endif
32
33#define BITS_PER_LONG 8*SIZEOF_LONG
34
35static const char * const ringorder_name[] =
36{
37  " ?", //ringorder_no = 0,
38  "a", //ringorder_a,
39  "A", //ringorder_a64,
40  "c", //ringorder_c,
41  "C", //ringorder_C,
42  "M", //ringorder_M,
43  "S", //ringorder_S,
44  "s", //ringorder_s,
45  "lp", //ringorder_lp,
46  "dp", //ringorder_dp,
47  "rp", //ringorder_rp,
48  "Dp", //ringorder_Dp,
49  "wp", //ringorder_wp,
50  "Wp", //ringorder_Wp,
51  "ls", //ringorder_ls,
52  "ds", //ringorder_ds,
53  "Ds", //ringorder_Ds,
54  "ws", //ringorder_ws,
55  "Ws", //ringorder_Ws,
56  "L", //ringorder_L,
57  "aa", //ringorder_aa
58  " _" //ringorder_unspec
59};
60
61const char * rSimpleOrdStr(int ord)
62{
63  return ringorder_name[ord];
64}
65
66// unconditionally deletes fields in r
67void rDelete(ring r);
68// set r->VarL_Size, r->VarL_Offset, r->VarL_LowIndex
69static void rSetVarL(ring r);
70// get r->divmask depending on bits per exponent
71static unsigned long rGetDivMask(int bits);
72// right-adjust r->VarOffset
73static void rRightAdjustVarOffset(ring r);
74static void rOptimizeLDeg(ring r);
75
76/*0 implementation*/
77//BOOLEAN rField_is_R(ring r=currRing)
78//{
79//  if (r->ch== -1)
80//  {
81//    if (r->float_len==(short)0) return TRUE;
82//  }
83//  return FALSE;
84//}
85
86// internally changes the gloabl ring and resets the relevant
87// global variables:
88void rChangeCurrRing(ring r)
89{
90  /*------------ set global ring vars --------------------------------*/
91  currRing = r;
92  currQuotient=NULL;
93  if (r != NULL)
94  {
95    rTest(r);
96    /*------------ set global ring vars --------------------------------*/
97    currQuotient=r->qideal;
98
99    /*------------ global variables related to coefficients ------------*/
100    nSetChar(r);
101
102    /*------------ global variables related to polys -------------------*/
103    pSetGlobals(r);
104  }
105}
106
107void rNameCheck(ring R)
108{
109  int i,j;
110  for(i=0;i<R->N-1;i++)
111  {
112    for(j=i+1;j<R->N;j++)
113    {
114      if (strcmp(R->names[i],R->names[j])==0)
115      {
116        Warn("name conflict var(d) and var(%d): `%s`",i+1,j+1,R->names[i]);
117        omFree(R->names[j]);
118        R->names[j]=(char *)omAlloc(10);
119        sprintf(R->names[j],"@(%d)",j+1);
120      }
121    }
122  }
123}
124
125ring rDefault(int ch, int N, char **n)
126{
127  ring r=(ring) omAlloc0Bin(sip_sring_bin);
128  r->ch    = ch;
129  r->N     = N;
130  /*r->P     = 0; Alloc0 */
131  /*names*/
132  r->names = (char **) omAlloc0(N * sizeof(char_ptr));
133  int i;
134  for(i=0;i<N;i++)
135  {
136    r->names[i]  = omStrDup(n[i]);
137  }
138  /*weights: entries for 2 blocks: NULL*/
139  r->wvhdl = (int **)omAlloc0(2 * sizeof(int_ptr));
140  /*order: lp,0*/
141  r->order = (int *) omAlloc(2* sizeof(int *));
142  r->block0 = (int *)omAlloc0(2 * sizeof(int *));
143  r->block1 = (int *)omAlloc0(2 * sizeof(int *));
144  /* ringorder dp for the first block: var 1..N */
145  r->order[0]  = ringorder_lp;
146  r->block0[0] = 1;
147  r->block1[0] = N;
148  /* the last block: everything is 0 */
149  r->order[1]  = 0;
150  /*polynomial ring*/
151  r->OrdSgn    = 1;
152
153  /* complete ring intializations */
154  rComplete(r);
155  return r;
156}
157
158///////////////////////////////////////////////////////////////////////////
159//
160// rInit: define a new ring from sleftv's
161//
162
163/////////////////////////////
164// Auxillary functions
165//
166
167// check intvec, describing the ordering
168BOOLEAN rCheckIV(intvec *iv)
169{
170  if ((iv->length()!=2)&&(iv->length()!=3))
171  {
172    WerrorS("weights only for orderings wp,ws,Wp,Ws,a,M");
173    return TRUE;
174  }
175  return FALSE;
176}
177
178int rTypeOfMatrixOrder(intvec * order)
179{
180  int i=0,j,typ=1;
181  int sz = (int)sqrt((double)(order->length()-2));
182
183  while ((i<sz) && (typ==1))
184  {
185    j=0;
186    while ((j<sz) && ((*order)[j*sz+i+2]==0)) j++;
187    if (j>=sz)
188    {
189      typ = 0;
190      WerrorS("Matrix order not complete");
191    }
192    else if ((*order)[j*sz+i+2]<0)
193      typ = -1;
194    else
195      i++;
196  }
197  return typ;
198}
199
200// set R->order, R->block, R->wvhdl, r->OrdSgn from sleftv
201BOOLEAN rSleftvOrdering2Ordering(sleftv *ord, ring R);
202
203// get array of strings from list of sleftv's
204BOOLEAN rSleftvList2StringArray(sleftv* sl, char** p);
205
206
207/*2
208 * set a new ring from the data:
209 s: name, chr: ch, varnames: rv, ordering: ord, typ: typ
210 */
211
212int r_IsRingVar(const char *n, ring r)
213{
214  if ((r!=NULL) && (r->names!=NULL))
215  {
216    for (int i=0; i<r->N; i++)
217    {
218      if (r->names[i]==NULL) return -1;
219      if (strcmp(n,r->names[i]) == 0) return (int)i;
220    }
221  }
222  return -1;
223}
224
225
226void rWrite(ring r)
227{
228  if ((r==NULL)||(r->order==NULL))
229    return; /*to avoid printing after errors....*/
230
231  int nblocks=rBlocks(r);
232
233  // omCheckAddrSize(r,sizeof(ip_sring));
234  omCheckAddrSize(r->order,nblocks*sizeof(int));
235  omCheckAddrSize(r->block0,nblocks*sizeof(int));
236  omCheckAddrSize(r->block1,nblocks*sizeof(int));
237  omCheckAddrSize(r->wvhdl,nblocks*sizeof(int_ptr));
238  omCheckAddrSize(r->names,r->N*sizeof(char_ptr));
239
240  nblocks--;
241
242
243  if (rField_is_GF(r))
244  {
245    Print("//   # ground field : %d\n",rInternalChar(r));
246    Print("//   primitive element : %s\n", r->parameter[0]);
247    if (r==currRing)
248    {
249      StringSetS("//   minpoly        : ");
250      nfShowMipo();PrintS(StringAppendS("\n"));
251    }
252  }
253  else
254  {
255    PrintS("//   characteristic : ");
256    if ( rField_is_R(r) )             PrintS("0 (real)\n");  /* R */
257    else if ( rField_is_long_R(r) )
258      Print("0 (real:%d digits, additional %d digits)\n",
259             r->float_len,r->float_len2);  /* long R */
260    else if ( rField_is_long_C(r) )
261      Print("0 (complex:%d digits, additional %d digits)\n",
262             r->float_len, r->float_len2);  /* long C */
263    else
264      Print ("%d\n",rChar(r)); /* Fp(a) */
265    if (r->parameter!=NULL)
266    {
267      Print ("//   %d parameter    : ",rPar(r));
268      char **sp=r->parameter;
269      int nop=0;
270      while (nop<rPar(r))
271      {
272        PrintS(*sp);
273        PrintS(" ");
274        sp++; nop++;
275      }
276      PrintS("\n//   minpoly        : ");
277      if ( rField_is_long_C(r) )
278      {
279        // i^2+1:
280        Print("(%s^2+1)\n",r->parameter[0]);
281      }
282      else if (r->minpoly==NULL)
283      {
284        PrintS("0\n");
285      }
286      else if (r==currRing)
287      {
288        StringSetS(""); nWrite(r->minpoly); PrintS(StringAppendS("\n"));
289      }
290      else
291      {
292        PrintS("...\n");
293      }
294      if (r->minideal!=NULL)
295      {
296        if (r==currRing) iiWriteMatrix((matrix)r->minideal,"//   minpolys",1,0);
297        else PrintS("//   minpolys=...");
298        PrintLn();
299      }
300    }
301  }
302  Print("//   number of vars : %d",r->N);
303
304  //for (nblocks=0; r->order[nblocks]; nblocks++);
305  nblocks=rBlocks(r)-1;
306
307  for (int l=0, nlen=0 ; l<nblocks; l++)
308  {
309    int i;
310    Print("\n//        block %3d : ",l+1);
311
312    Print("ordering %s", rSimpleOrdStr(r->order[l]));
313
314    if ((r->order[l] >= ringorder_lp)
315    ||(r->order[l] == ringorder_M)
316    ||(r->order[l] == ringorder_a)
317    ||(r->order[l] == ringorder_a64)
318    ||(r->order[l] == ringorder_aa))
319    {
320      PrintS("\n//                  : names    ");
321      for (i = r->block0[l]-1; i<r->block1[l]; i++)
322      {
323        nlen = strlen(r->names[i]);
324        Print("%s ",r->names[i]);
325      }
326    }
327#ifndef NDEBUG
328    else if (r->order[l] == ringorder_s)
329    {
330      Print("  syzcomp at %d",r->typ[l].data.syz.limit);
331    }
332#endif
333
334    if (r->wvhdl[l]!=NULL)
335    {
336      for (int j= 0;
337           j<(r->block1[l]-r->block0[l]+1)*(r->block1[l]-r->block0[l]+1);
338           j+=i)
339      {
340        PrintS("\n//                  : weights  ");
341        for (i = 0; i<=r->block1[l]-r->block0[l]; i++)
342        {
343          if (r->order[l] == ringorder_a64)
344          { int64 *w=(int64 *)r->wvhdl[l];
345            Print("%*lld " ,nlen,w[i+j],i+j);
346          }
347          else
348            Print("%*d " ,nlen,r->wvhdl[l][i+j],i+j);
349        }
350        if (r->order[l]!=ringorder_M) break;
351      }
352    }
353  }
354#ifdef HAVE_PLURAL
355  if (r->nc!=NULL)
356  {
357    PrintS("\n//   noncommutative relations:");
358    if (r==currRing)
359    {
360      poly pl=NULL;
361      int nl;
362      int i,j;
363      //    Print("\n//   noncommutative relations (type %d):",(int)r->nc->type);
364      for (i = 1; i<r->N; i++)
365      {
366        for (j = i+1; j<=r->N; j++)
367        {
368          nl = nIsOne(p_GetCoeff(MATELEM(r->nc->C,i,j),r));
369          if ( (MATELEM(r->nc->D,i,j)!=NULL) || (!nl) )
370          {
371            Print("\n//    %s%s=",r->names[j-1],r->names[i-1]);
372            pl = MATELEM(r->nc->MT[UPMATELEM(i,j,r->N)],1,1);
373            pWrite0(pl);
374          }
375        }
376      }
377    }
378    else PrintS(" ...");
379#ifdef PDEBUG
380    Print("\n//   noncommutative type:%d",r->nc->type);
381    Print("\n//   is skew constant:%d",r->nc->IsSkewConstant);
382    Print("\n//   ref:%d",r->nc->ref);
383#endif
384  }
385#endif
386  if (r->qideal!=NULL)
387  {
388    PrintS("\n// quotient ring from ideal");
389    if (r==currRing)
390    {
391      PrintLn();
392      iiWriteMatrix((matrix)r->qideal,"_",1);
393    }
394    else PrintS(" ...");
395  }
396}
397
398void rDelete(ring r)
399{
400  int i, j;
401
402  if (r == NULL) return;
403
404#ifdef HAVE_PLURAL
405  if (r->nc != NULL)
406  {
407    if (r->nc->ref>1) /* in use by somebody else */
408    {
409      r->nc->ref--;
410    }
411    else
412    {
413      ncKill(r);
414    }
415  }
416#endif
417  nKillChar(r);
418  rUnComplete(r);
419  // delete order stuff
420  if (r->order != NULL)
421  {
422    i=rBlocks(r);
423    assume(r->block0 != NULL && r->block1 != NULL && r->wvhdl != NULL);
424    // delete order
425    omFreeSize((ADDRESS)r->order,i*sizeof(int));
426    omFreeSize((ADDRESS)r->block0,i*sizeof(int));
427    omFreeSize((ADDRESS)r->block1,i*sizeof(int));
428    // delete weights
429    for (j=0; j<i; j++)
430    {
431      if (r->wvhdl[j]!=NULL)
432        omFree(r->wvhdl[j]);
433    }
434    omFreeSize((ADDRESS)r->wvhdl,i*sizeof(int *));
435  }
436  else
437  {
438    assume(r->block0 == NULL && r->block1 == NULL && r->wvhdl == NULL);
439  }
440
441  // delete varnames
442  if(r->names!=NULL)
443  {
444    for (i=0; i<r->N; i++)
445    {
446      if (r->names[i] != NULL) omFree((ADDRESS)r->names[i]);
447    }
448    omFreeSize((ADDRESS)r->names,r->N*sizeof(char_ptr));
449  }
450
451  // delete parameter
452  if (r->parameter!=NULL)
453  {
454    char **s=r->parameter;
455    j = 0;
456    while (j < rPar(r))
457    {
458      if (*s != NULL) omFree((ADDRESS)*s);
459      s++;
460      j++;
461    }
462    omFreeSize((ADDRESS)r->parameter,rPar(r)*sizeof(char_ptr));
463  }
464  omFreeBin(r, ip_sring_bin);
465}
466
467int rOrderName(char * ordername)
468{
469  int order=ringorder_unspec;
470  while (order!= 0)
471  {
472    if (strcmp(ordername,rSimpleOrdStr(order))==0)
473      break;
474    order--;
475  }
476  if (order==0) Werror("wrong ring order `%s`",ordername);
477  omFree((ADDRESS)ordername);
478  return order;
479}
480
481char * rOrdStr(ring r)
482{
483  int nblocks,l,i;
484
485  for (nblocks=0; r->order[nblocks]; nblocks++);
486  nblocks--;
487
488  StringSetS("");
489  for (l=0; ; l++)
490  {
491    StringAppend((char *)rSimpleOrdStr(r->order[l]));
492    if ((r->order[l] != ringorder_c) && (r->order[l] != ringorder_C))
493    {
494      if (r->wvhdl[l]!=NULL)
495      {
496        StringAppendS("(");
497        for (int j= 0;
498             j<(r->block1[l]-r->block0[l]+1)*(r->block1[l]-r->block0[l]+1);
499             j+=i+1)
500        {
501          char c=',';
502          if(r->order[l]==ringorder_a64)
503          {
504            int64 * w=(int64 *)r->wvhdl[l];
505            for (i = 0; i<r->block1[l]-r->block0[l]; i++)
506            {
507              StringAppend("%lld," ,w[i]);
508            }
509            StringAppend("%lld)" ,w[i]);
510            break;
511          }
512          else
513          {
514            for (i = 0; i<r->block1[l]-r->block0[l]; i++)
515            {
516              StringAppend("%d," ,r->wvhdl[l][i+j]);
517            }
518          }
519          if (r->order[l]!=ringorder_M)
520          {
521            StringAppend("%d)" ,r->wvhdl[l][i+j]);
522            break;
523          }
524          if (j+i+1==(r->block1[l]-r->block0[l]+1)*(r->block1[l]-r->block0[l]+1))
525            c=')';
526          StringAppend("%d%c" ,r->wvhdl[l][i+j],c);
527        }
528      }
529      else
530        StringAppend("(%d)",r->block1[l]-r->block0[l]+1);
531    }
532    if (l==nblocks) return omStrDup(StringAppendS(""));
533    StringAppendS(",");
534  }
535}
536
537char * rVarStr(ring r)
538{
539  int i;
540  int l=2;
541  char *s;
542
543  for (i=0; i<r->N; i++)
544  {
545    l+=strlen(r->names[i])+1;
546  }
547  s=(char *)omAlloc(l);
548  s[0]='\0';
549  for (i=0; i<r->N-1; i++)
550  {
551    strcat(s,r->names[i]);
552    strcat(s,",");
553  }
554  strcat(s,r->names[i]);
555  return s;
556}
557
558char * rCharStr(ring r)
559{
560  char *s;
561  int i;
562
563  if (r->parameter==NULL)
564  {
565    i=r->ch;
566    if(i==-1)
567      s=omStrDup("real");                    /* R */
568    else
569    {
570      s=(char *)omAlloc(6);
571      sprintf(s,"%d",i);                   /* Q, Z/p */
572    }
573    return s;
574  }
575  if (rField_is_long_C(r))
576  {
577    s=(char *)omAlloc(21+strlen(r->parameter[0]));
578    sprintf(s,"complex,%d,%s",r->float_len,r->parameter[0]);   /* C */
579    return s;
580  }
581  int l=0;
582  for(i=0; i<rPar(r);i++)
583  {
584    l+=(strlen(r->parameter[i])+1);
585  }
586  s=(char *)omAlloc(l+6);
587  s[0]='\0';
588  if (r->ch<0)       sprintf(s,"%d",-r->ch); /* Fp(a) */
589  else if (r->ch==1) sprintf(s,"0");         /* Q(a)  */
590  else
591  {
592    sprintf(s,"%d,%s",r->ch,r->parameter[0]); /* Fq  */
593    return s;
594  }
595  char tt[2];
596  tt[0]=',';
597  tt[1]='\0';
598  for(i=0; i<rPar(r);i++)
599  {
600    strcat(s,tt);
601    strcat(s,r->parameter[i]);
602  }
603  return s;
604}
605
606char * rParStr(ring r)
607{
608  if (r->parameter==NULL) return omStrDup("");
609
610  int i;
611  int l=2;
612
613  for (i=0; i<rPar(r); i++)
614  {
615    l+=strlen(r->parameter[i])+1;
616  }
617  char *s=(char *)omAlloc(l);
618  s[0]='\0';
619  for (i=0; i<rPar(r)-1; i++)
620  {
621    strcat(s,r->parameter[i]);
622    strcat(s,",");
623  }
624  strcat(s,r->parameter[i]);
625  return s;
626}
627
628char * rString(ring r)
629{
630  char *ch=rCharStr(r);
631  char *var=rVarStr(r);
632  char *ord=rOrdStr(r);
633  char *res=(char *)omAlloc(strlen(ch)+strlen(var)+strlen(ord)+9);
634  sprintf(res,"(%s),(%s),(%s)",ch,var,ord);
635  omFree((ADDRESS)ch);
636  omFree((ADDRESS)var);
637  omFree((ADDRESS)ord);
638  return res;
639}
640
641int  rIsExtension(ring r)
642{
643  return (r->parameter!=NULL); /* R, Q, Fp: FALSE */
644}
645
646int  rIsExtension()
647{
648  return rIsExtension( currRing );
649}
650
651int rChar(ring r)
652{
653  if (rField_is_numeric(r))
654    return 0;
655  if (!rIsExtension(r)) /* Q, Fp */
656    return r->ch;
657  if (rField_is_Zp_a(r))  /* Fp(a)  */
658    return -r->ch;
659  if (rField_is_Q_a(r))   /* Q(a)  */
660    return 0;
661  /*else*/               /* GF(p,n) */
662  {
663    if ((r->ch & 1)==0) return 2;
664    int i=3;
665    while ((r->ch % i)!=0) i+=2;
666    return i;
667  }
668}
669
670/*2
671 *returns -1 for not compatible, (sum is undefined)
672 *         0 for equal, (and sum)
673 *         1 for compatible (and sum)
674 */
675int rSum(ring r1, ring r2, ring &sum)
676{
677  if (r1==r2)
678  {
679    sum=r1;
680    r1->ref++;
681    return 0;
682  }
683  ring save=currRing;
684  ip_sring tmpR;
685  memset(&tmpR,0,sizeof(tmpR));
686  /* check coeff. field =====================================================*/
687  if (rInternalChar(r1)==rInternalChar(r2))
688  {
689    tmpR.ch=rInternalChar(r1);
690    if (rField_is_Q(r1)||rField_is_Zp(r1)||rField_is_GF(r1)) /*Q, Z/p, GF(p,n)*/
691    {
692      if (r1->parameter!=NULL)
693      {
694        if (strcmp(r1->parameter[0],r2->parameter[0])==0) /* 1 char */
695        {
696          tmpR.parameter=(char **)omAllocBin(char_ptr_bin);
697          tmpR.parameter[0]=omStrDup(r1->parameter[0]);
698          tmpR.P=1;
699        }
700        else
701        {
702          WerrorS("GF(p,n)+GF(p,n)");
703          return -1;
704        }
705      }
706    }
707    else if ((r1->ch==1)||(r1->ch<-1)) /* Q(a),Z/p(a) */
708    {
709      if (r1->minpoly!=NULL)
710      {
711        if (r2->minpoly!=NULL)
712        {
713          // HANNES: TODO: delete nSetChar
714          rChangeCurrRing(r1);
715          if ((strcmp(r1->parameter[0],r2->parameter[0])==0) /* 1 char */
716              && n_Equal(r1->minpoly,r2->minpoly, r1))
717          {
718            tmpR.parameter=(char **)omAllocBin(char_ptr_bin);
719            tmpR.parameter[0]=omStrDup(r1->parameter[0]);
720            tmpR.minpoly=n_Copy(r1->minpoly, r1);
721            tmpR.P=1;
722            // HANNES: TODO: delete nSetChar
723            rChangeCurrRing(save);
724          }
725          else
726          {
727            // HANNES: TODO: delete nSetChar
728            rChangeCurrRing(save);
729            WerrorS("different minpolys");
730            return -1;
731          }
732        }
733        else
734        {
735          if ((strcmp(r1->parameter[0],r2->parameter[0])==0) /* 1 char */
736              && (rPar(r2)==1))
737          {
738            tmpR.parameter=(char **)omAllocBin(char_ptr_bin);
739            tmpR.parameter[0]=omStrDup(r1->parameter[0]);
740            tmpR.P=1;
741            tmpR.minpoly=n_Copy(r1->minpoly, r1);
742          }
743          else
744          {
745            WerrorS("different parameters and minpoly!=0");
746            return -1;
747          }
748        }
749      }
750      else /* r1->minpoly==NULL */
751      {
752        if (r2->minpoly!=NULL)
753        {
754          if ((strcmp(r1->parameter[0],r2->parameter[0])==0) /* 1 char */
755              && (rPar(r1)==1))
756          {
757            tmpR.parameter=(char **)omAllocBin(char_ptr_bin);
758            tmpR.parameter[0]=omStrDup(r1->parameter[0]);
759            tmpR.P=1;
760            tmpR.minpoly=n_Copy(r2->minpoly, r2);
761          }
762          else
763          {
764            WerrorS("different parameters and minpoly!=0");
765            return -1;
766          }
767        }
768        else
769        {
770          int len=rPar(r1)+rPar(r2);
771          tmpR.parameter=(char **)omAlloc0(len*sizeof(char_ptr));
772          int i;
773          for (i=0;i<rPar(r1);i++)
774          {
775            tmpR.parameter[i]=omStrDup(r1->parameter[i]);
776          }
777          int j,l;
778          for(j=0;j<rPar(r2);j++)
779          {
780            for(l=0;l<i;l++)
781            {
782              if(strcmp(tmpR.parameter[l],r2->parameter[j])==0)
783                break;
784            }
785            if (l==i)
786            {
787              tmpR.parameter[i]=omStrDup(r2->parameter[j]);
788              i++;
789            }
790          }
791          if (i!=len)
792          {
793            tmpR.parameter=(char**)omReallocSize(tmpR.parameter,len*sizeof(char_ptr),i*sizeof(char_ptr));
794          }
795          tmpR.P=i;
796        }
797      }
798    }
799  }
800  else /* r1->ch!=r2->ch */
801  {
802    if (r1->ch<-1) /* Z/p(a) */
803    {
804      if ((r2->ch==0) /* Q */
805          || (r2->ch==-r1->ch)) /* Z/p */
806      {
807        tmpR.ch=rInternalChar(r1);
808        tmpR.P=rPar(r1);
809        tmpR.parameter=(char **)omAlloc(rPar(r1)*sizeof(char_ptr));
810        int i;
811        for (i=0;i<rPar(r1);i++)
812        {
813          tmpR.parameter[i]=omStrDup(r1->parameter[i]);
814        }
815        if (r1->minpoly!=NULL)
816        {
817          tmpR.minpoly=n_Copy(r1->minpoly, r1);
818        }
819      }
820      else  /* R, Q(a),Z/q,Z/p(a),GF(p,n) */
821      {
822        WerrorS("Z/p(a)+(R,Q(a),Z/q(a),GF(q,n))");
823        return -1;
824      }
825    }
826    else if (r1->ch==-1) /* R */
827    {
828      WerrorS("R+..");
829      return -1;
830    }
831    else if (r1->ch==0) /* Q */
832    {
833      if ((r2->ch<-1)||(r2->ch==1)) /* Z/p(a),Q(a) */
834      {
835        tmpR.ch=rInternalChar(r2);
836        tmpR.P=rPar(r2);
837        tmpR.parameter=(char **)omAlloc(rPar(r2)*sizeof(char_ptr));
838        int i;
839        for (i=0;i<rPar(r2);i++)
840        {
841          tmpR.parameter[i]=omStrDup(r2->parameter[i]);
842        }
843        if (r2->minpoly!=NULL)
844        {
845          tmpR.minpoly=n_Copy(r2->minpoly, r2);
846        }
847      }
848      else if (r2->ch>1) /* Z/p,GF(p,n) */
849      {
850        tmpR.ch=r2->ch;
851        if (r2->parameter!=NULL)
852        {
853          tmpR.parameter=(char **)omAllocBin(char_ptr_bin);
854          tmpR.P=1;
855          tmpR.parameter[0]=omStrDup(r2->parameter[0]);
856        }
857      }
858      else
859      {
860        WerrorS("Q+R");
861        return -1; /* R */
862      }
863    }
864    else if (r1->ch==1) /* Q(a) */
865    {
866      if (r2->ch==0) /* Q */
867      {
868        tmpR.ch=rInternalChar(r1);
869        tmpR.P=rPar(r1);
870        tmpR.parameter=(char **)omAlloc(rPar(r1)*sizeof(char_ptr));
871        int i;
872        for(i=0;i<rPar(r1);i++)
873        {
874          tmpR.parameter[i]=omStrDup(r1->parameter[i]);
875        }
876        if (r1->minpoly!=NULL)
877        {
878          tmpR.minpoly=n_Copy(r1->minpoly, r1);
879        }
880      }
881      else  /* R, Z/p,GF(p,n) */
882      {
883        WerrorS("Q(a)+(R,Z/p,GF(p,n))");
884        return -1;
885      }
886    }
887    else /* r1->ch >=2 , Z/p */
888    {
889      if (r2->ch==0) /* Q */
890      {
891        tmpR.ch=r1->ch;
892      }
893      else if (r2->ch==-r1->ch) /* Z/p(a) */
894      {
895        tmpR.ch=rInternalChar(r2);
896        tmpR.P=rPar(r2);
897        tmpR.parameter=(char **)omAlloc(rPar(r2)*sizeof(char_ptr));
898        int i;
899        for(i=0;i<rPar(r2);i++)
900        {
901          tmpR.parameter[i]=omStrDup(r2->parameter[i]);
902        }
903        if (r2->minpoly!=NULL)
904        {
905          tmpR.minpoly=n_Copy(r2->minpoly, r2);
906        }
907      }
908      else
909      {
910        WerrorS("Z/p+(GF(q,n),Z/q(a),R,Q(a))");
911        return -1; /* GF(p,n),Z/q(a),R,Q(a) */
912      }
913    }
914  }
915  /* variable names ========================================================*/
916  int i,j,k;
917  int l=r1->N+r2->N;
918  char **names=(char **)omAlloc0(l*sizeof(char_ptr));
919  k=0;
920
921  // collect all varnames from r1, except those which are parameters
922  // of r2, or those which are the empty string
923  for (i=0;i<r1->N;i++)
924  {
925    BOOLEAN b=TRUE;
926
927    if (*(r1->names[i]) == '\0')
928      b = FALSE;
929    else if ((r2->parameter!=NULL) && (strlen(r1->names[i])==1))
930    {
931      for(j=0;j<rPar(r2);j++)
932      {
933        if (strcmp(r1->names[i],r2->parameter[j])==0)
934        {
935          b=FALSE;
936          break;
937        }
938      }
939    }
940
941    if (b)
942    {
943      //Print("name : %d: %s\n",k,r1->names[i]);
944      names[k]=omStrDup(r1->names[i]);
945      k++;
946    }
947    //else
948    //  Print("no name (par1) %s\n",r1->names[i]);
949  }
950  // Add variables from r2, except those which are parameters of r1
951  // those which are empty strings, and those which equal a var of r1
952  for(i=0;i<r2->N;i++)
953  {
954    BOOLEAN b=TRUE;
955
956    if (*(r2->names[i]) == '\0')
957      b = FALSE;
958    else if ((r1->parameter!=NULL) && (strlen(r2->names[i])==1))
959    {
960      for(j=0;j<rPar(r1);j++)
961      {
962        if (strcmp(r2->names[i],r1->parameter[j])==0)
963        {
964          b=FALSE;
965          break;
966        }
967      }
968    }
969
970    if (b)
971    {
972      for(j=0;j<r1->N;j++)
973      {
974        if (strcmp(r1->names[j],r2->names[i])==0)
975        {
976          b=FALSE;
977          break;
978        }
979      }
980      if (b)
981      {
982        //Print("name : %d : %s\n",k,r2->names[i]);
983        names[k]=omStrDup(r2->names[i]);
984        k++;
985      }
986      //else
987      //  Print("no name (var): %s\n",r2->names[i]);
988    }
989    //else
990    //  Print("no name (par): %s\n",r2->names[i]);
991  }
992  // check whether we found any vars at all
993  if (k == 0)
994  {
995    names[k]=omStrDup("");
996    k=1;
997  }
998  tmpR.N=k;
999  tmpR.names=names;
1000  /* ordering *======================================================== */
1001  tmpR.OrdSgn=1;
1002  if ((r1->order[0]==ringorder_unspec)
1003      && (r2->order[0]==ringorder_unspec))
1004  {
1005    tmpR.order=(int*)omAlloc(3*sizeof(int));
1006    tmpR.block0=(int*)omAlloc(3*sizeof(int));
1007    tmpR.block1=(int*)omAlloc(3*sizeof(int));
1008    tmpR.wvhdl=(int**)omAlloc0(3*sizeof(int_ptr));
1009    tmpR.order[0]=ringorder_unspec;
1010    tmpR.order[1]=ringorder_C;
1011    tmpR.order[2]=0;
1012    tmpR.block0[0]=1;
1013    tmpR.block1[0]=tmpR.N;
1014  }
1015  else if (l==k) /* r3=r1+r2 */
1016  {
1017    int b;
1018    ring rb;
1019    if (r1->order[0]==ringorder_unspec)
1020    {
1021      /* extend order of r2 to r3 */
1022      b=rBlocks(r2);
1023      rb=r2;
1024      tmpR.OrdSgn=r2->OrdSgn;
1025    }
1026    else if (r2->order[0]==ringorder_unspec)
1027    {
1028      /* extend order of r1 to r3 */
1029      b=rBlocks(r1);
1030      rb=r1;
1031      tmpR.OrdSgn=r1->OrdSgn;
1032    }
1033    else
1034    {
1035      b=rBlocks(r1)+rBlocks(r2)-2; /* for only one order C, only one 0 */
1036      rb=NULL;
1037    }
1038    tmpR.order=(int*)omAlloc0(b*sizeof(int));
1039    tmpR.block0=(int*)omAlloc0(b*sizeof(int));
1040    tmpR.block1=(int*)omAlloc0(b*sizeof(int));
1041    tmpR.wvhdl=(int**)omAlloc0(b*sizeof(int_ptr));
1042    /* weights not implemented yet ...*/
1043    if (rb!=NULL)
1044    {
1045      for (i=0;i<b;i++)
1046      {
1047        tmpR.order[i]=rb->order[i];
1048        tmpR.block0[i]=rb->block0[i];
1049        tmpR.block1[i]=rb->block1[i];
1050        if (rb->wvhdl[i]!=NULL)
1051          WarnS("rSum: weights not implemented");
1052      }
1053      tmpR.block0[0]=1;
1054    }
1055    else /* ring sum for complete rings */
1056    {
1057      for (i=0;r1->order[i]!=0;i++)
1058      {
1059        tmpR.order[i]=r1->order[i];
1060        tmpR.block0[i]=r1->block0[i];
1061        tmpR.block1[i]=r1->block1[i];
1062        if (r1->wvhdl[i]!=NULL)
1063          tmpR.wvhdl[i] = (int*) omMemDup(r1->wvhdl[i]);
1064      }
1065      j=i;
1066      i--;
1067      if ((r1->order[i]==ringorder_c)
1068          ||(r1->order[i]==ringorder_C))
1069      {
1070        j--;
1071        tmpR.order[b-2]=r1->order[i];
1072      }
1073      for (i=0;r2->order[i]!=0;i++)
1074      {
1075        if ((r2->order[i]!=ringorder_c)
1076            &&(r2->order[i]!=ringorder_C))
1077        {
1078          tmpR.order[j]=r2->order[i];
1079          tmpR.block0[j]=r2->block0[i]+r1->N;
1080          tmpR.block1[j]=r2->block1[i]+r1->N;
1081          if (r2->wvhdl[i]!=NULL)
1082          {
1083            tmpR.wvhdl[j] = (int*) omMemDup(r2->wvhdl[i]);
1084          }
1085          j++;
1086        }
1087      }
1088      if((r1->OrdSgn==-1)||(r2->OrdSgn==-1))
1089        tmpR.OrdSgn=-1;
1090    }
1091  }
1092  else if ((k==r1->N) && (k==r2->N)) /* r1 and r2 are "quite" the same ring */
1093    /* copy r1, because we have the variables from r1 */
1094  {
1095    int b=rBlocks(r1);
1096
1097    tmpR.order=(int*)omAlloc0(b*sizeof(int));
1098    tmpR.block0=(int*)omAlloc0(b*sizeof(int));
1099    tmpR.block1=(int*)omAlloc0(b*sizeof(int));
1100    tmpR.wvhdl=(int**)omAlloc0(b*sizeof(int_ptr));
1101    /* weights not implemented yet ...*/
1102    for (i=0;i<b;i++)
1103    {
1104      tmpR.order[i]=r1->order[i];
1105      tmpR.block0[i]=r1->block0[i];
1106      tmpR.block1[i]=r1->block1[i];
1107      if (r1->wvhdl[i]!=NULL)
1108      {
1109        tmpR.wvhdl[i] = (int*) omMemDup(r1->wvhdl[i]);
1110      }
1111    }
1112    tmpR.OrdSgn=r1->OrdSgn;
1113  }
1114  else
1115  {
1116    for(i=0;i<k;i++) omFree((ADDRESS)tmpR.names[i]);
1117    omFreeSize((ADDRESS)names,tmpR.N*sizeof(char_ptr));
1118    Werror("difficulties with variables: %d,%d -> %d",rVar(r1),rVar(r2),k);
1119    return -1;
1120  }
1121  sum=(ring)omAllocBin(ip_sring_bin);
1122  memcpy(sum,&tmpR,sizeof(ip_sring));
1123  rComplete(sum);
1124//#ifdef RDEBUG
1125//  rDebugPrint(sum);
1126//#endif
1127#ifdef HAVE_PLURAL
1128  ring old_ring = currRing;
1129  BOOLEAN R1_is_nc = rIsPluralRing(r1);
1130  BOOLEAN R2_is_nc = rIsPluralRing(r2);
1131  if ( (R1_is_nc) || (R2_is_nc))
1132  {
1133    rChangeCurrRing(r1); /* since rCopy works well only in currRing */
1134    ring R1 = rCopy(r1);
1135    rChangeCurrRing(r2);
1136    ring R2 = rCopy(r2);
1137    rChangeCurrRing(sum);
1138    /* basic nc constructions  */
1139    sum->nc = (nc_struct *)omAlloc0(sizeof(nc_struct));
1140    sum->nc->ref = 1;
1141    sum->nc->basering = sum;
1142    if ( !R1_is_nc ) nc_rCreateNCcomm(R1);
1143    if ( !R2_is_nc ) nc_rCreateNCcomm(R2);
1144    /* nc->type's */
1145    sum->nc->type = nc_undef;
1146    nc_type t1 = R1->nc->type, t2 = R2->nc->type;
1147    if ( t1==t2) sum->nc->type = t1;
1148    else
1149    {
1150      if ( (t1==nc_general) || (t2==nc_general) ) sum->nc->type = nc_general;
1151    }
1152    if (sum->nc->type == nc_undef) /* not yet done */
1153    {
1154      switch (t1)
1155      {
1156        case nc_comm:
1157          sum->nc->type = t2;
1158          break;
1159        case nc_lie:
1160          switch(t2)
1161          {
1162            case nc_skew:
1163              sum->nc->type = nc_general;  break;
1164            case nc_comm:
1165              sum->nc->type = nc_lie;  break;
1166            default:
1167              /*sum->nc->type = nc_undef;*/  break;
1168          }
1169          break;
1170        case nc_skew:
1171          switch(t2)
1172          {
1173            case nc_lie:
1174              sum->nc->type = nc_lie;  break;
1175            case nc_comm:
1176              sum->nc->type = nc_skew;  break;
1177            default:
1178              /*sum->nc->type = nc_undef;*/  break;
1179          }
1180        default:
1181          /*sum->nc->type = nc_undef;*/
1182          break;
1183      }
1184    }
1185    if (sum->nc->type == nc_undef)
1186      WarnS("Error on recognizing nc types");
1187    /* multiplication matrices business: */
1188    /* find permutations of vars and pars */
1189    int *perm1 = (int *)omAlloc0((rVar(R1)+1)*sizeof(int));
1190    int *par_perm1 = NULL;
1191    if (rPar(R1)!=0) par_perm1=(int *)omAlloc0((rPar(R1)+1)*sizeof(int));
1192    int *perm2 = (int *)omAlloc0((rVar(R2)+1)*sizeof(int));
1193    int *par_perm2 = NULL;
1194    if (rPar(R2)!=0) par_perm2=(int *)omAlloc0((rPar(R2)+1)*sizeof(int));
1195    maFindPerm(R1->names,  rVar(R1),  R1->parameter,  rPar(R1),
1196               sum->names, rVar(sum), sum->parameter, rPar(sum),
1197               perm1, par_perm1, sum->ch);
1198    maFindPerm(R2->names,  rVar(R2),  R2->parameter,  rPar(R2),
1199               sum->names, rVar(sum), sum->parameter, rPar(sum),
1200               perm2, par_perm2, sum->ch);
1201    nMapFunc nMap1 = nSetMap(R1);
1202    nMapFunc nMap2 = nSetMap(R2);
1203    matrix C1 = R1->nc->C, C2 = R2->nc->C;
1204    matrix D1 = R1->nc->D, D2 = R2->nc->D;
1205    int l = rVar(R1) + rVar(R2);
1206    matrix C  = mpNew(l,l);
1207    matrix D  = mpNew(l,l);
1208    int param_shift = 0;
1209    for (i=1; i<= rVar(R1) + rVar(R2); i++)
1210    {
1211      for (j= i+1; j<= rVar(R1) + rVar(R2); j++)
1212      {
1213        MATELEM(C,i,j) = pOne();
1214      }
1215    }
1216    for (i=1; i< rVar(R1); i++)
1217    {
1218      for (j=i+1; j<=rVar(R1); j++)
1219      {
1220
1221        MATELEM(C,i,j) = pPermPoly(MATELEM(C1,i,j),perm1,R1,nMap1,par_perm1,rPar(R1));
1222        if (MATELEM(D1,i,j) != NULL)
1223        {
1224          MATELEM(D,i,j) = pPermPoly(MATELEM(D1,i,j),perm1,R1,nMap1,par_perm1,rPar(R1));
1225        }
1226      }
1227    }
1228    for (i=1; i< rVar(R2); i++)
1229    {
1230      for (j=i+1; j<=rVar(R2); j++)
1231      {
1232        MATELEM(C,rVar(R1)+i,rVar(R1)+j) = pPermPoly(MATELEM(C2,i,j),perm2,R2,nMap2,par_perm2,rPar(R2));
1233              if (MATELEM(D2,i,j) != NULL)
1234        {
1235          MATELEM(D,rVar(R1)+i,rVar(R1)+j) = pPermPoly(MATELEM(D2,i,j),perm2,R2,nMap2,par_perm2,rPar(R2));
1236        }
1237      }
1238    }
1239    idTest((ideal)C);
1240    idTest((ideal)D);
1241    sum->nc->C = C;
1242    sum->nc->D = D;
1243    if (nc_InitMultiplication(sum))
1244      WarnS("Error initializing multiplication!");
1245    sum->nc->IsSkewConstant =(int)((R1->nc->IsSkewConstant) && (R2->nc->IsSkewConstant));
1246    /* delete R1, R2*/
1247    rDelete(R1);
1248    rDelete(R2);
1249    /* delete perm arrays */
1250    if (perm1!=NULL) omFree((ADDRESS)perm1);
1251    if (perm2!=NULL) omFree((ADDRESS)perm2);
1252    if (par_perm1!=NULL) omFree((ADDRESS)par_perm1);
1253    if (par_perm2!=NULL) omFree((ADDRESS)par_perm2);
1254    rChangeCurrRing(old_ring);
1255  }
1256#endif
1257  ideal Q=NULL;
1258  ideal Q1=NULL, Q2=NULL;
1259  ring old_ring2 = currRing;
1260  if (r1->qideal!=NULL)
1261  {
1262    rChangeCurrRing(sum);
1263//     if (r2->qideal!=NULL)
1264//     {
1265//       WerrorS("todo: qring+qring");
1266//       return -1;
1267//     }
1268//     else
1269//     {}
1270    /* these were defined in the Plural Part above... */
1271    int *perm1 = (int *)omAlloc0((rVar(r1)+1)*sizeof(int));
1272    int *par_perm1 = NULL;
1273    if (rPar(r1)!=0) par_perm1=(int *)omAlloc0((rPar(r1)+1)*sizeof(int));
1274    maFindPerm(r1->names,  rVar(r1),  r1->parameter,  rPar(r1),
1275               sum->names, rVar(sum), sum->parameter, rPar(sum),
1276               perm1, par_perm1, sum->ch);
1277    nMapFunc nMap1 = nSetMap(r1);
1278    Q1 = idInit(IDELEMS(r1->qideal),1);
1279    for (int for_i=0;for_i<IDELEMS(r1->qideal);for_i++)
1280      Q1->m[for_i] = pPermPoly(r1->qideal->m[for_i],perm1,r1,nMap1,par_perm1,rPar(r1));
1281    omFree((ADDRESS)perm1);
1282  }
1283
1284  if (r2->qideal!=NULL)
1285  {
1286    if (currRing!=sum)
1287      rChangeCurrRing(sum);
1288    int *perm2 = (int *)omAlloc0((rVar(r2)+1)*sizeof(int));
1289    int *par_perm2 = NULL;
1290    if (rPar(r2)!=0) par_perm2=(int *)omAlloc0((rPar(r2)+1)*sizeof(int));
1291    maFindPerm(r2->names,  rVar(r2),  r2->parameter,  rPar(r2),
1292               sum->names, rVar(sum), sum->parameter, rPar(sum),
1293               perm2, par_perm2, sum->ch);
1294    nMapFunc nMap2 = nSetMap(r2);
1295    Q2 = idInit(IDELEMS(r2->qideal),1);
1296    for (int for_i=0;for_i<IDELEMS(r2->qideal);for_i++)
1297      Q2->m[for_i] = pPermPoly(r2->qideal->m[for_i],perm2,r2,nMap2,par_perm2,rPar(r2));
1298    omFree((ADDRESS)perm2);
1299  }
1300  if ( (Q1!=NULL) || ( Q2!=NULL))
1301  {
1302    Q = idSimpleAdd(Q1,Q2);
1303    rChangeCurrRing(old_ring2);
1304  }
1305  sum->qideal = Q;
1306  return 1;
1307}
1308
1309/*2
1310 * create a copy of the ring r, which must be equivalent to currRing
1311 * used for qring definition,..
1312 * (i.e.: normal rings: same nCopy as currRing;
1313 *        qring:        same nCopy, same idCopy as currRing)
1314 * DOES NOT CALL rComplete
1315 */
1316ring rCopy0(ring r, BOOLEAN copy_qideal, BOOLEAN copy_ordering)
1317{
1318  if (r == NULL) return NULL;
1319  int i,j;
1320  ring res=(ring)omAllocBin(ip_sring_bin);
1321
1322  memcpy4(res,r,sizeof(ip_sring));
1323  res->VarOffset = NULL;
1324  res->ref=0;
1325  if (r->algring!=NULL)
1326    r->algring->ref++;
1327  if (r->parameter!=NULL)
1328  {
1329    res->minpoly=nCopy(r->minpoly);
1330    int l=rPar(r);
1331    res->parameter=(char **)omAlloc(l*sizeof(char_ptr));
1332    int i;
1333    for(i=0;i<rPar(r);i++)
1334    {
1335      res->parameter[i]=omStrDup(r->parameter[i]);
1336    }
1337    if (r->minideal!=NULL)
1338    {
1339      res->minideal=id_Copy(r->minideal,r->algring);
1340    }
1341  }
1342  if (copy_ordering == TRUE)
1343  {
1344    i=rBlocks(r);
1345    res->wvhdl   = (int **)omAlloc(i * sizeof(int_ptr));
1346    res->order   = (int *) omAlloc(i * sizeof(int));
1347    res->block0  = (int *) omAlloc(i * sizeof(int));
1348    res->block1  = (int *) omAlloc(i * sizeof(int));
1349    for (j=0; j<i; j++)
1350    {
1351      if (r->wvhdl[j]!=NULL)
1352      {
1353        res->wvhdl[j] = (int*) omMemDup(r->wvhdl[j]);
1354      }
1355      else
1356        res->wvhdl[j]=NULL;
1357    }
1358    memcpy4(res->order,r->order,i * sizeof(int));
1359    memcpy4(res->block0,r->block0,i * sizeof(int));
1360    memcpy4(res->block1,r->block1,i * sizeof(int));
1361  }
1362  else
1363  {
1364    res->wvhdl = NULL;
1365    res->order = NULL;
1366    res->block0 = NULL;
1367    res->block1 = NULL;
1368  }
1369
1370  res->names   = (char **)omAlloc0(rVar(r) * sizeof(char_ptr));
1371  for (i=0; i<res->N; i++)
1372  {
1373    res->names[i] = omStrDup(r->names[i]);
1374  }
1375  res->idroot = NULL;
1376  if (r->qideal!=NULL)
1377  {
1378    if (copy_qideal) res->qideal= idrCopyR_NoSort(r->qideal, r);
1379    else res->qideal = NULL;
1380  }
1381#ifdef HAVE_PLURAL
1382  if (rIsPluralRing(r))
1383  {
1384    res->nc=r->nc;
1385    res->nc->ref++;
1386  }
1387#endif
1388  return res;
1389}
1390
1391/*2
1392 * create a copy of the ring r, which must be equivalent to currRing
1393 * used for qring definition,..
1394 * (i.e.: normal rings: same nCopy as currRing;
1395 *        qring:        same nCopy, same idCopy as currRing)
1396 */
1397ring rCopy(ring r)
1398{
1399  if (r == NULL) return NULL;
1400  ring res=rCopy0(r);
1401  rComplete(res, 1);
1402  return res;
1403}
1404
1405// returns TRUE, if r1 equals r2 FALSE, otherwise Equality is
1406// determined componentwise, if qr == 1, then qrideal equality is
1407// tested, as well
1408BOOLEAN rEqual(ring r1, ring r2, BOOLEAN qr)
1409{
1410  int i, j;
1411
1412  if (r1 == r2) return 1;
1413
1414  if (r1 == NULL || r2 == NULL) return 0;
1415
1416  if ((rInternalChar(r1) != rInternalChar(r2))
1417  || (r1->float_len != r2->float_len)
1418  || (r1->float_len2 != r2->float_len2)
1419  || (rVar(r1) != rVar(r2))
1420  || (r1->OrdSgn != r2->OrdSgn)
1421  || (rPar(r1) != rPar(r2)))
1422    return 0;
1423
1424  for (i=0; i<rVar(r1); i++)
1425  {
1426    if (r1->names[i] != NULL && r2->names[i] != NULL)
1427    {
1428      if (strcmp(r1->names[i], r2->names[i])) return 0;
1429    }
1430    else if ((r1->names[i] != NULL) ^ (r2->names[i] != NULL))
1431    {
1432      return 0;
1433    }
1434  }
1435
1436  i=0;
1437  while (r1->order[i] != 0)
1438  {
1439    if (r2->order[i] == 0) return 0;
1440    if ((r1->order[i] != r2->order[i]) ||
1441        (r1->block0[i] != r2->block0[i]) || (r2->block0[i] != r1->block0[i]))
1442      return 0;
1443    if (r1->wvhdl[i] != NULL)
1444    {
1445      if (r2->wvhdl[i] == NULL)
1446        return 0;
1447      for (j=0; j<r1->block1[i]-r1->block0[i]+1; j++)
1448        if (r2->wvhdl[i][j] != r1->wvhdl[i][j])
1449          return 0;
1450    }
1451    else if (r2->wvhdl[i] != NULL) return 0;
1452    i++;
1453  }
1454
1455  for (i=0; i<rPar(r1);i++)
1456  {
1457      if (strcmp(r1->parameter[i], r2->parameter[i])!=0)
1458        return 0;
1459  }
1460
1461  if (r1->minpoly != NULL)
1462  {
1463    if (r2->minpoly == NULL) return 0;
1464    if (currRing == r1 || currRing == r2)
1465    {
1466      if (! nEqual(r1->minpoly, r2->minpoly)) return 0;
1467    }
1468  }
1469  else if (r2->minpoly != NULL) return 0;
1470
1471  if (qr)
1472  {
1473    if (r1->qideal != NULL)
1474    {
1475      ideal id1 = r1->qideal, id2 = r2->qideal;
1476      int i, n;
1477      poly *m1, *m2;
1478
1479      if (id2 == NULL) return 0;
1480      if ((n = IDELEMS(id1)) != IDELEMS(id2)) return 0;
1481
1482      if (currRing == r1 || currRing == r2)
1483      {
1484        m1 = id1->m;
1485        m2 = id2->m;
1486        for (i=0; i<n; i++)
1487          if (! pEqualPolys(m1[i],m2[i])) return 0;
1488      }
1489    }
1490    else if (r2->qideal != NULL) return 0;
1491  }
1492
1493  return 1;
1494}
1495
1496rOrderType_t rGetOrderType(ring r)
1497{
1498  // check for simple ordering
1499  if (rHasSimpleOrder(r))
1500  {
1501    if ((r->order[1] == ringorder_c) || (r->order[1] == ringorder_C))
1502    {
1503      switch(r->order[0])
1504      {
1505          case ringorder_dp:
1506          case ringorder_wp:
1507          case ringorder_ds:
1508          case ringorder_ws:
1509          case ringorder_ls:
1510          case ringorder_unspec:
1511            if (r->order[1] == ringorder_C ||  r->order[0] == ringorder_unspec)
1512              return rOrderType_ExpComp;
1513            return rOrderType_Exp;
1514
1515          default:
1516            assume(r->order[0] == ringorder_lp ||
1517                   r->order[0] == ringorder_rp ||
1518                   r->order[0] == ringorder_Dp ||
1519                   r->order[0] == ringorder_Wp ||
1520                   r->order[0] == ringorder_Ds ||
1521                   r->order[0] == ringorder_Ws);
1522
1523            if (r->order[1] == ringorder_c) return rOrderType_ExpComp;
1524            return rOrderType_Exp;
1525      }
1526    }
1527    else
1528    {
1529      assume((r->order[0]==ringorder_c)||(r->order[0]==ringorder_C));
1530      return rOrderType_CompExp;
1531    }
1532  }
1533  else
1534    return rOrderType_General;
1535}
1536
1537BOOLEAN rHasSimpleOrder(ring r)
1538{
1539  if (r->order[0] == ringorder_unspec) return TRUE;
1540  int blocks = rBlocks(r) - 1;
1541  assume(blocks >= 1);
1542  if (blocks == 1) return TRUE;
1543  if (blocks > 2)  return FALSE;
1544  if (r->order[0] != ringorder_c && r->order[0] != ringorder_C &&
1545      r->order[1] != ringorder_c && r->order[1] != ringorder_C)
1546    return FALSE;
1547  if (r->order[1] == ringorder_M || r->order[0] == ringorder_M)
1548    return FALSE;
1549  return TRUE;
1550}
1551
1552// returns TRUE, if simple lp or ls ordering
1553BOOLEAN rHasSimpleLexOrder(ring r)
1554{
1555  return rHasSimpleOrder(r) &&
1556    (r->order[0] == ringorder_ls ||
1557     r->order[0] == ringorder_lp ||
1558     r->order[1] == ringorder_ls ||
1559     r->order[1] == ringorder_lp);
1560}
1561
1562BOOLEAN rOrder_is_DegOrdering(rRingOrder_t order)
1563{
1564  switch(order)
1565  {
1566      case ringorder_dp:
1567      case ringorder_Dp:
1568      case ringorder_ds:
1569      case ringorder_Ds:
1570      case ringorder_Ws:
1571      case ringorder_Wp:
1572      case ringorder_ws:
1573      case ringorder_wp:
1574        return TRUE;
1575
1576      default:
1577        return FALSE;
1578  }
1579}
1580
1581BOOLEAN rOrder_is_WeightedOrdering(rRingOrder_t order)
1582{
1583  switch(order)
1584  {
1585      case ringorder_Ws:
1586      case ringorder_Wp:
1587      case ringorder_ws:
1588      case ringorder_wp:
1589        return TRUE;
1590
1591      default:
1592        return FALSE;
1593  }
1594}
1595
1596BOOLEAN rHasSimpleOrderAA(ring r)
1597{
1598  int blocks = rBlocks(r) - 1;
1599  if (blocks > 3 || blocks < 2) return FALSE;
1600  if (blocks == 3)
1601  {
1602    return ((r->order[0] == ringorder_aa && r->order[1] != ringorder_M &&
1603             (r->order[2] == ringorder_c || r->order[2] == ringorder_C)) ||
1604            ((r->order[0] == ringorder_c || r->order[0] == ringorder_C) &&
1605             r->order[1] == ringorder_aa && r->order[2] != ringorder_M));
1606  }
1607  else
1608  {
1609    return (r->order[0] == ringorder_aa && r->order[1] != ringorder_M);
1610  }
1611}
1612
1613// return TRUE if p_SetComp requires p_Setm
1614BOOLEAN rOrd_SetCompRequiresSetm(ring r)
1615{
1616  if (r->typ != NULL)
1617  {
1618    int pos;
1619    for (pos=0;pos<r->OrdSize;pos++)
1620    {
1621      sro_ord* o=&(r->typ[pos]);
1622      if (o->ord_typ == ro_syzcomp || o->ord_typ == ro_syz) return TRUE;
1623    }
1624  }
1625  return FALSE;
1626}
1627
1628// return TRUE if p->exp[r->pOrdIndex] holds total degree of p */
1629BOOLEAN rOrd_is_Totaldegree_Ordering(ring r)
1630{
1631  // Hmm.... what about Syz orderings?
1632  return (rVar(r) > 1 &&
1633          ((rHasSimpleOrder(r) &&
1634           (rOrder_is_DegOrdering((rRingOrder_t)r->order[0]) ||
1635            rOrder_is_DegOrdering(( rRingOrder_t)r->order[1]))) ||
1636           (rHasSimpleOrderAA(r) &&
1637            (rOrder_is_DegOrdering((rRingOrder_t)r->order[1]) ||
1638             rOrder_is_DegOrdering((rRingOrder_t)r->order[2])))));
1639}
1640
1641// return TRUE if p->exp[r->pOrdIndex] holds a weighted degree of p */
1642BOOLEAN rOrd_is_WeightedDegree_Ordering(ring r =currRing)
1643{
1644  // Hmm.... what about Syz orderings?
1645  return ((rVar(r) > 1) &&
1646          rHasSimpleOrder(r) &&
1647          (rOrder_is_WeightedOrdering((rRingOrder_t)r->order[0]) ||
1648           rOrder_is_WeightedOrdering(( rRingOrder_t)r->order[1])));
1649}
1650
1651BOOLEAN rIsPolyVar(int v, ring r)
1652{
1653  int  i=0;
1654  while(r->order[i]!=0)
1655  {
1656    if((r->block0[i]<=v)
1657    && (r->block1[i]>=v))
1658    {
1659      switch(r->order[i])
1660      {
1661        case ringorder_a:
1662          return (r->wvhdl[i][v-r->block0[i]]>0);
1663        case ringorder_M:
1664          return 2; /*don't know*/
1665        case ringorder_a64: /* assume: all weight are non-negative!*/
1666        case ringorder_lp:
1667        case ringorder_rp:
1668        case ringorder_dp:
1669        case ringorder_Dp:
1670        case ringorder_wp:
1671        case ringorder_Wp:
1672          return TRUE;
1673        case ringorder_ls:
1674        case ringorder_ds:
1675        case ringorder_Ds:
1676        case ringorder_ws:
1677        case ringorder_Ws:
1678          return FALSE;
1679        default:
1680          break;
1681      }
1682    }
1683    i++;
1684  }
1685  return 3; /* could not find var v*/
1686}
1687
1688#ifdef RDEBUG
1689// This should eventually become a full-fledge ring check, like pTest
1690BOOLEAN rDBTest(ring r, char* fn, int l)
1691{
1692  int i,j;
1693
1694  if (r == NULL)
1695  {
1696    dReportError("Null ring in %s:%d", fn, l);
1697    return FALSE;
1698  }
1699
1700
1701  if (r->N == 0) return TRUE;
1702
1703//  omCheckAddrSize(r,sizeof(ip_sring));
1704#if OM_CHECK > 0
1705  i=rBlocks(r);
1706  omCheckAddrSize(r->order,i*sizeof(int));
1707  omCheckAddrSize(r->block0,i*sizeof(int));
1708  omCheckAddrSize(r->block1,i*sizeof(int));
1709  omCheckAddrSize(r->wvhdl,i*sizeof(int *));
1710  for (j=0;j<i; j++)
1711  {
1712    if (r->wvhdl[j] != NULL) omCheckAddr(r->wvhdl[j]);
1713  }
1714#endif
1715  if (r->VarOffset == NULL)
1716  {
1717    dReportError("Null ring VarOffset -- no rComplete (?) in n %s:%d", fn, l);
1718    return FALSE;
1719  }
1720  omCheckAddrSize(r->VarOffset,(r->N+1)*sizeof(int));
1721
1722  if ((r->OrdSize==0)!=(r->typ==NULL))
1723  {
1724    dReportError("mismatch OrdSize and typ-pointer in %s:%d");
1725    return FALSE;
1726  }
1727  omcheckAddrSize(r->typ,r->OrdSize*sizeof(*(r->typ)));
1728  omCheckAddrSize(r->VarOffset,(r->N+1)*sizeof(*(r->VarOffset)));
1729  // test assumptions:
1730  for(i=0;i<=r->N;i++)
1731  {
1732    if(r->typ!=NULL)
1733    {
1734      for(j=0;j<r->OrdSize;j++)
1735      {
1736        if (r->typ[j].ord_typ==ro_cp)
1737        {
1738          if(((short)r->VarOffset[i]) == r->typ[j].data.cp.place)
1739            dReportError("ordrec %d conflicts with var %d",j,i);
1740        }
1741        else
1742          if ((r->typ[j].ord_typ!=ro_syzcomp)
1743          && (r->VarOffset[i] == r->typ[j].data.dp.place))
1744            dReportError("ordrec %d conflicts with var %d",j,i);
1745      }
1746    }
1747    int tmp;
1748      tmp=r->VarOffset[i] & 0xffffff;
1749      #if SIZEOF_LONG == 8
1750        if ((r->VarOffset[i] >> 24) >63)
1751      #else
1752        if ((r->VarOffset[i] >> 24) >31)
1753      #endif
1754          dReportError("bit_start out of range:%d",r->VarOffset[i] >> 24);
1755      if (i > 0 && ((tmp<0) ||(tmp>r->ExpL_Size-1)))
1756      {
1757        dReportError("varoffset out of range for var %d: %d",i,tmp);
1758      }
1759  }
1760  if(r->typ!=NULL)
1761  {
1762    for(j=0;j<r->OrdSize;j++)
1763    {
1764      if ((r->typ[j].ord_typ==ro_dp)
1765      || (r->typ[j].ord_typ==ro_wp)
1766      || (r->typ[j].ord_typ==ro_wp_neg))
1767      {
1768        if (r->typ[j].data.dp.start > r->typ[j].data.dp.end)
1769          dReportError("in ordrec %d: start(%d) > end(%d)",j,
1770            r->typ[j].data.dp.start, r->typ[j].data.dp.end);
1771        if ((r->typ[j].data.dp.start < 1)
1772        || (r->typ[j].data.dp.end > r->N))
1773          dReportError("in ordrec %d: start(%d)<1 or end(%d)>vars(%d)",j,
1774            r->typ[j].data.dp.start, r->typ[j].data.dp.end,r->N);
1775      }
1776    }
1777  }
1778  //assume(r->cf!=NULL);
1779
1780  return TRUE;
1781}
1782#endif
1783
1784static void rO_Align(int &place, int &bitplace)
1785{
1786  // increment place to the next aligned one
1787  // (count as Exponent_t,align as longs)
1788  if (bitplace!=BITS_PER_LONG)
1789  {
1790    place++;
1791    bitplace=BITS_PER_LONG;
1792  }
1793}
1794
1795static void rO_TDegree(int &place, int &bitplace, int start, int end,
1796    long *o, sro_ord &ord_struct)
1797{
1798  // degree (aligned) of variables v_start..v_end, ordsgn 1
1799  rO_Align(place,bitplace);
1800  ord_struct.ord_typ=ro_dp;
1801  ord_struct.data.dp.start=start;
1802  ord_struct.data.dp.end=end;
1803  ord_struct.data.dp.place=place;
1804  o[place]=1;
1805  place++;
1806  rO_Align(place,bitplace);
1807}
1808
1809static void rO_TDegree_neg(int &place, int &bitplace, int start, int end,
1810    long *o, sro_ord &ord_struct)
1811{
1812  // degree (aligned) of variables v_start..v_end, ordsgn -1
1813  rO_Align(place,bitplace);
1814  ord_struct.ord_typ=ro_dp;
1815  ord_struct.data.dp.start=start;
1816  ord_struct.data.dp.end=end;
1817  ord_struct.data.dp.place=place;
1818  o[place]=-1;
1819  place++;
1820  rO_Align(place,bitplace);
1821}
1822
1823static void rO_WDegree(int &place, int &bitplace, int start, int end,
1824    long *o, sro_ord &ord_struct, int *weights)
1825{
1826  // weighted degree (aligned) of variables v_start..v_end, ordsgn 1
1827  while((start<end) && (weights[0]==0)) { start++; weights++; }
1828  while((start<end) && (weights[end-start]==0)) { end--; }
1829  int i;
1830  int pure_tdeg=1;
1831  for(i=start;i<=end;i++)
1832  {
1833    if(weights[i-start]!=1)
1834    {
1835      pure_tdeg=0;
1836      break;
1837    }
1838  }
1839  if (pure_tdeg)
1840  {
1841    rO_TDegree(place,bitplace,start,end,o,ord_struct);
1842    return;
1843  }
1844  rO_Align(place,bitplace);
1845  ord_struct.ord_typ=ro_wp;
1846  ord_struct.data.wp.start=start;
1847  ord_struct.data.wp.end=end;
1848  ord_struct.data.wp.place=place;
1849  ord_struct.data.wp.weights=weights;
1850  o[place]=1;
1851  place++;
1852  rO_Align(place,bitplace);
1853  for(i=start;i<=end;i++)
1854  {
1855    if(weights[i-start]<0)
1856    {
1857      ord_struct.ord_typ=ro_wp_neg;
1858      break;
1859    }
1860  }
1861}
1862
1863static void rO_WDegree64(int &place, int &bitplace, int start, int end,
1864    long *o, sro_ord &ord_struct, int64 *weights)
1865{
1866  // weighted degree (aligned) of variables v_start..v_end, ordsgn 1,
1867  // reserved 2 places
1868  rO_Align(place,bitplace);
1869  ord_struct.ord_typ=ro_wp64;
1870  ord_struct.data.wp64.start=start;
1871  ord_struct.data.wp64.end=end;
1872  ord_struct.data.wp64.place=place;
1873  ord_struct.data.wp64.weights64=weights;
1874  o[place]=1;
1875  place++;
1876  o[place]=1;
1877  place++;
1878  rO_Align(place,bitplace);
1879  int i;
1880}
1881
1882static void rO_WDegree_neg(int &place, int &bitplace, int start, int end,
1883    long *o, sro_ord &ord_struct, int *weights)
1884{
1885  // weighted degree (aligned) of variables v_start..v_end, ordsgn -1
1886  while((start<end) && (weights[0]==0)) { start++; weights++; }
1887  while((start<end) && (weights[end-start]==0)) { end--; }
1888  rO_Align(place,bitplace);
1889  ord_struct.ord_typ=ro_wp;
1890  ord_struct.data.wp.start=start;
1891  ord_struct.data.wp.end=end;
1892  ord_struct.data.wp.place=place;
1893  ord_struct.data.wp.weights=weights;
1894  o[place]=-1;
1895  place++;
1896  rO_Align(place,bitplace);
1897  int i;
1898  for(i=start;i<=end;i++)
1899  {
1900    if(weights[i-start]<0)
1901    {
1902      ord_struct.ord_typ=ro_wp_neg;
1903      break;
1904    }
1905  }
1906}
1907
1908static void rO_LexVars(int &place, int &bitplace, int start, int end,
1909  int &prev_ord, long *o,int *v, int bits, int opt_var)
1910{
1911  // a block of variables v_start..v_end with lex order, ordsgn 1
1912  int k;
1913  int incr=1;
1914  if(prev_ord==-1) rO_Align(place,bitplace);
1915
1916  if (start>end)
1917  {
1918    incr=-1;
1919  }
1920  for(k=start;;k+=incr)
1921  {
1922    bitplace-=bits;
1923    if (bitplace < 0) { bitplace=BITS_PER_LONG-bits; place++; }
1924    o[place]=1;
1925    v[k]= place | (bitplace << 24);
1926    if (k==end) break;
1927  }
1928  prev_ord=1;
1929  if (opt_var!= -1)
1930  {
1931    assume((opt_var == end+1) ||(opt_var == end-1));
1932    if((opt_var != end+1) &&(opt_var != end-1)) WarnS("hier-2");
1933    int save_bitplace=bitplace;
1934    bitplace-=bits;
1935    if (bitplace < 0)
1936    {
1937      bitplace=save_bitplace;
1938      return;
1939    }
1940    // there is enough space for the optional var
1941    v[opt_var]=place | (bitplace << 24);
1942  }
1943}
1944
1945static void rO_LexVars_neg(int &place, int &bitplace, int start, int end,
1946  int &prev_ord, long *o,int *v, int bits, int opt_var)
1947{
1948  // a block of variables v_start..v_end with lex order, ordsgn -1
1949  int k;
1950  int incr=1;
1951  if(prev_ord==1) rO_Align(place,bitplace);
1952
1953  if (start>end)
1954  {
1955    incr=-1;
1956  }
1957  for(k=start;;k+=incr)
1958  {
1959    bitplace-=bits;
1960    if (bitplace < 0) { bitplace=BITS_PER_LONG-bits; place++; }
1961    o[place]=-1;
1962    v[k]=place | (bitplace << 24);
1963    if (k==end) break;
1964  }
1965  prev_ord=-1;
1966//  #if 0
1967  if (opt_var!= -1)
1968  {
1969    assume((opt_var == end+1) ||(opt_var == end-1));
1970    if((opt_var != end+1) &&(opt_var != end-1)) WarnS("hier-1");
1971    int save_bitplace=bitplace;
1972    bitplace-=bits;
1973    if (bitplace < 0)
1974    {
1975      bitplace=save_bitplace;
1976      return;
1977    }
1978    // there is enough space for the optional var
1979    v[opt_var]=place | (bitplace << 24);
1980  }
1981//  #endif
1982}
1983
1984static void rO_Syzcomp(int &place, int &bitplace, int &prev_ord,
1985    long *o, sro_ord &ord_struct)
1986{
1987  // ordering is derived from component number
1988  rO_Align(place,bitplace);
1989  ord_struct.ord_typ=ro_syzcomp;
1990  ord_struct.data.syzcomp.place=place;
1991  ord_struct.data.syzcomp.Components=NULL;
1992  ord_struct.data.syzcomp.ShiftedComponents=NULL;
1993  o[place]=1;
1994  prev_ord=1;
1995  place++;
1996  rO_Align(place,bitplace);
1997}
1998
1999static void rO_Syz(int &place, int &bitplace, int &prev_ord,
2000    long *o, sro_ord &ord_struct)
2001{
2002  // ordering is derived from component number
2003  // let's reserve one Exponent_t for it
2004  if ((prev_ord== 1) || (bitplace!=BITS_PER_LONG))
2005    rO_Align(place,bitplace);
2006  ord_struct.ord_typ=ro_syz;
2007  ord_struct.data.syz.place=place;
2008  ord_struct.data.syz.limit=0;
2009  ord_struct.data.syz.syz_index = NULL;
2010  ord_struct.data.syz.curr_index = 1;
2011  o[place]= -1;
2012  prev_ord=-1;
2013  place++;
2014}
2015
2016static unsigned long rGetExpSize(unsigned long bitmask, int & bits)
2017{
2018  if (bitmask == 0)
2019  {
2020    bits=16; bitmask=0xffff;
2021  }
2022  else if (bitmask <= 1)
2023  {
2024    bits=1; bitmask = 1;
2025  }
2026  else if (bitmask <= 3)
2027  {
2028    bits=2; bitmask = 3;
2029  }
2030  else if (bitmask <= 7)
2031  {
2032    bits=3; bitmask=7;
2033  }
2034  else if (bitmask <= 0xf)
2035  {
2036    bits=4; bitmask=0xf;
2037  }
2038  else if (bitmask <= 0x1f)
2039  {
2040    bits=5; bitmask=0x1f;
2041  }
2042  else if (bitmask <= 0x3f)
2043  {
2044    bits=6; bitmask=0x3f;
2045  }
2046#if SIZEOF_LONG == 8
2047  else if (bitmask <= 0x7f)
2048  {
2049    bits=7; bitmask=0x7f; /* 64 bit longs only */
2050  }
2051#endif
2052  else if (bitmask <= 0xff)
2053  {
2054    bits=8; bitmask=0xff;
2055  }
2056#if SIZEOF_LONG == 8
2057  else if (bitmask <= 0x1ff)
2058  {
2059    bits=9; bitmask=0x1ff; /* 64 bit longs only */
2060  }
2061#endif
2062  else if (bitmask <= 0x3ff)
2063  {
2064    bits=10; bitmask=0x3ff;
2065  }
2066#if SIZEOF_LONG == 8
2067  else if (bitmask <= 0xfff)
2068  {
2069    bits=12; bitmask=0xfff; /* 64 bit longs only */
2070  }
2071#endif
2072  else if (bitmask <= 0xffff)
2073  {
2074    bits=16; bitmask=0xffff;
2075  }
2076#if SIZEOF_LONG == 8
2077  else if (bitmask <= 0xfffff)
2078  {
2079    bits=20; bitmask=0xfffff; /* 64 bit longs only */
2080  }
2081  else if (bitmask <= 0xffffffff)
2082  {
2083    bits=32; bitmask=0xffffffff;
2084  }
2085  else
2086  {
2087    bits=64; bitmask=0xffffffffffffffff;
2088  }
2089#else
2090  else
2091  {
2092    bits=32; bitmask=0xffffffff;
2093  }
2094#endif
2095  return bitmask;
2096}
2097
2098/*2
2099* optimize rGetExpSize for a block of N variables, exp <=bitmask
2100*/
2101static unsigned long rGetExpSize(unsigned long bitmask, int & bits, int N)
2102{
2103  bitmask =rGetExpSize(bitmask, bits);
2104  int vars_per_long=BIT_SIZEOF_LONG/bits;
2105  int bits1;
2106  loop
2107  {
2108    if (bits == BIT_SIZEOF_LONG)
2109    {
2110      bits =  BIT_SIZEOF_LONG - 1;
2111      return LONG_MAX;
2112    }
2113    unsigned long bitmask1 =rGetExpSize(bitmask+1, bits1);
2114    int vars_per_long1=BIT_SIZEOF_LONG/bits1;
2115    if ((((N+vars_per_long-1)/vars_per_long) ==
2116         ((N+vars_per_long1-1)/vars_per_long1)))
2117    {
2118      vars_per_long=vars_per_long1;
2119      bits=bits1;
2120      bitmask=bitmask1;
2121    }
2122    else
2123    {
2124      return bitmask; /* and bits */
2125    }
2126  }
2127}
2128
2129/*2
2130 * create a copy of the ring r, which must be equivalent to currRing
2131 * used for std computations
2132 * may share data structures with currRing
2133 * DOES CALL rComplete
2134 */
2135ring rModifyRing(ring r, BOOLEAN omit_degree,
2136                         BOOLEAN omit_comp,
2137                         unsigned long exp_limit)
2138{
2139  assume (r != NULL );
2140  assume (exp_limit > 1);
2141  BOOLEAN need_other_ring;
2142  BOOLEAN omitted_degree = FALSE;
2143  int bits;
2144
2145  exp_limit=rGetExpSize(exp_limit, bits, r->N);
2146  need_other_ring = (exp_limit != r->bitmask);
2147
2148  int nblocks=rBlocks(r);
2149  int *order=(int*)omAlloc0((nblocks+1)*sizeof(int));
2150  int *block0=(int*)omAlloc0((nblocks+1)*sizeof(int));
2151  int *block1=(int*)omAlloc0((nblocks+1)*sizeof(int));
2152  int **wvhdl=(int**)omAlloc0((nblocks+1)*sizeof(int_ptr));
2153
2154  int i=0;
2155  int j=0; /*  i index in r, j index in res */
2156  loop
2157  {
2158    BOOLEAN copy_block_index=TRUE;
2159    int r_ord=r->order[i];
2160    if (r->block0[i]==r->block1[i])
2161    {
2162      switch(r_ord)
2163      {
2164        case ringorder_wp:
2165        case ringorder_dp:
2166        case ringorder_Wp:
2167        case ringorder_Dp:
2168          r_ord=ringorder_lp;
2169          break;
2170        case ringorder_Ws:
2171        case ringorder_Ds:
2172        case ringorder_ws:
2173        case ringorder_ds:
2174          r_ord=ringorder_ls;
2175          break;
2176        default:
2177          break;
2178      }
2179    }
2180    switch(r_ord)
2181    {
2182      case ringorder_C:
2183      case ringorder_c:
2184        if (!omit_comp)
2185        {
2186          order[j]=r_ord; /*r->order[i]*/;
2187        }
2188        else
2189        {
2190          j--;
2191          need_other_ring=TRUE;
2192          omit_comp=FALSE;
2193          copy_block_index=FALSE;
2194        }
2195        break;
2196      case ringorder_wp:
2197      case ringorder_dp:
2198      case ringorder_ws:
2199      case ringorder_ds:
2200        if(!omit_degree)
2201        {
2202          order[j]=r_ord; /*r->order[i]*/;
2203        }
2204        else
2205        {
2206          order[j]=ringorder_rp;
2207          need_other_ring=TRUE;
2208          omit_degree=FALSE;
2209          omitted_degree = TRUE;
2210        }
2211        break;
2212      case ringorder_Wp:
2213      case ringorder_Dp:
2214      case ringorder_Ws:
2215      case ringorder_Ds:
2216        if(!omit_degree)
2217        {
2218          order[j]=r_ord; /*r->order[i];*/
2219        }
2220        else
2221        {
2222          order[j]=ringorder_lp;
2223          need_other_ring=TRUE;
2224          omit_degree=FALSE;
2225          omitted_degree = TRUE;
2226        }
2227        break;
2228      default:
2229        order[j]=r_ord; /*r->order[i];*/
2230        break;
2231    }
2232    if (copy_block_index)
2233    {
2234      block0[j]=r->block0[i];
2235      block1[j]=r->block1[i];
2236      wvhdl[j]=r->wvhdl[i];
2237    }
2238    i++;j++;
2239    // order[j]=ringorder_no; //  done by omAlloc0
2240    if (i==nblocks) break;
2241  }
2242  if(!need_other_ring)
2243  {
2244    omFreeSize(order,(nblocks+1)*sizeof(int));
2245    omFreeSize(block0,(nblocks+1)*sizeof(int));
2246    omFreeSize(block1,(nblocks+1)*sizeof(int));
2247    omFreeSize(wvhdl,(nblocks+1)*sizeof(int_ptr));
2248    return r;
2249  }
2250  ring res=(ring)omAlloc0Bin(ip_sring_bin);
2251  *res = *r;
2252  // res->qideal, res->idroot ???
2253  res->wvhdl=wvhdl;
2254  res->order=order;
2255  res->block0=block0;
2256  res->block1=block1;
2257  res->bitmask=exp_limit;
2258  int tmpref=r->cf->ref;
2259  rComplete(res, 1);
2260  r->cf->ref=tmpref;
2261
2262  // adjust res->pFDeg: if it was changed globally, then
2263  // it must also be changed for new ring
2264  if (r->pFDegOrig != res->pFDegOrig &&
2265           rOrd_is_WeightedDegree_Ordering(r))
2266  {
2267    // still might need adjustment for weighted orderings
2268    // and omit_degree
2269    res->firstwv = r->firstwv;
2270    res->firstBlockEnds = r->firstBlockEnds;
2271    res->pFDeg = res->pFDegOrig = pWFirstTotalDegree;
2272  }
2273  if (omitted_degree)
2274    res->pLDeg = res->pLDegOrig = r->pLDegOrig;
2275
2276  rOptimizeLDeg(res);
2277
2278  // set syzcomp
2279  if (res->typ != NULL && res->typ[0].ord_typ == ro_syz)
2280  {
2281    res->typ[0] = r->typ[0];
2282    if (r->typ[0].data.syz.limit > 0)
2283    {
2284      res->typ[0].data.syz.syz_index
2285        = (int*) omAlloc((r->typ[0].data.syz.limit +1)*sizeof(int));
2286      memcpy(res->typ[0].data.syz.syz_index, r->typ[0].data.syz.syz_index,
2287             (r->typ[0].data.syz.limit +1)*sizeof(int));
2288    }
2289  }
2290  return res;
2291}
2292
2293// construct Wp,C ring
2294ring rModifyRing_Wp(ring r, int* weights)
2295{
2296  ring res=(ring)omAlloc0Bin(ip_sring_bin);
2297  *res = *r;
2298  /*weights: entries for 3 blocks: NULL*/
2299  res->wvhdl = (int **)omAlloc0(3 * sizeof(int_ptr));
2300  /*order: Wp,C,0*/
2301  res->order = (int *) omAlloc(3 * sizeof(int *));
2302  res->block0 = (int *)omAlloc0(3 * sizeof(int *));
2303  res->block1 = (int *)omAlloc0(3 * sizeof(int *));
2304  /* ringorder Wp for the first block: var 1..r->N */
2305  res->order[0]  = ringorder_Wp;
2306  res->block0[0] = 1;
2307  res->block1[0] = r->N;
2308  res->wvhdl[0] = weights;
2309  /* ringorder C for the second block: no vars */
2310  res->order[1]  = ringorder_C;
2311  /* the last block: everything is 0 */
2312  res->order[2]  = 0;
2313  /*polynomial ring*/
2314  res->OrdSgn    = 1;
2315
2316  int tmpref=r->cf->ref;
2317  rComplete(res, 1);
2318  r->cf->ref=tmpref;
2319  return res;
2320}
2321
2322// construct lp ring with r->N variables, r->names vars....
2323ring rModifyRing_Simple(ring r, BOOLEAN ommit_degree, BOOLEAN ommit_comp, unsigned long exp_limit, BOOLEAN &simple)
2324{
2325  simple=TRUE;
2326  if (!rHasSimpleOrder(r))
2327  {
2328    simple=FALSE; // sorting needed
2329    assume (r != NULL );
2330    assume (exp_limit > 1);
2331    BOOLEAN omitted_degree = FALSE;
2332    int bits;
2333
2334    exp_limit=rGetExpSize(exp_limit, bits, r->N);
2335
2336    int nblocks=1+(ommit_comp!=0);
2337    int *order=(int*)omAlloc0((nblocks+1)*sizeof(int));
2338    int *block0=(int*)omAlloc0((nblocks+1)*sizeof(int));
2339    int *block1=(int*)omAlloc0((nblocks+1)*sizeof(int));
2340    int **wvhdl=(int**)omAlloc0((nblocks+1)*sizeof(int_ptr));
2341
2342    order[0]=ringorder_lp;
2343    block0[0]=1;
2344    block1[0]=r->N;
2345    if (!ommit_comp)
2346    {
2347      order[1]=ringorder_C;
2348    }
2349    ring res=(ring)omAlloc0Bin(ip_sring_bin);
2350    *res = *r;
2351    // res->qideal, res->idroot ???
2352    res->wvhdl=wvhdl;
2353    res->order=order;
2354    res->block0=block0;
2355    res->block1=block1;
2356    res->bitmask=exp_limit;
2357    int tmpref=r->cf->ref;
2358    rComplete(res, 1);
2359    r->cf->ref=tmpref;
2360
2361    rOptimizeLDeg(res);
2362
2363    return res;
2364  }
2365  return rModifyRing(r, ommit_degree, ommit_comp, exp_limit);
2366}
2367
2368void rKillModifiedRing_Simple(ring r)
2369{
2370  rKillModifiedRing(r);
2371}
2372
2373
2374void rKillModifiedRing(ring r)
2375{
2376  rUnComplete(r);
2377  omFree(r->order);
2378  omFree(r->block0);
2379  omFree(r->block1);
2380  omFree(r->wvhdl);
2381  omFreeBin(r,ip_sring_bin);
2382}
2383
2384void rKillModified_Wp_Ring(ring r)
2385{
2386  rUnComplete(r);
2387  omFree(r->order);
2388  omFree(r->block0);
2389  omFree(r->block1);
2390  omFree(r->wvhdl[0]);
2391  omFree(r->wvhdl);
2392  omFreeBin(r,ip_sring_bin);
2393}
2394
2395static void rSetOutParams(ring r)
2396{
2397  r->VectorOut = (r->order[0] == ringorder_c);
2398  r->ShortOut = TRUE;
2399#ifdef HAVE_TCL
2400  if (tcllmode)
2401  {
2402    r->ShortOut = FALSE;
2403  }
2404  else
2405#endif
2406  {
2407    int i;
2408    if ((r->parameter!=NULL) && (r->ch<2))
2409    {
2410      for (i=0;i<rPar(r);i++)
2411      {
2412        if(strlen(r->parameter[i])>1)
2413        {
2414          r->ShortOut=FALSE;
2415          break;
2416        }
2417      }
2418    }
2419    if (r->ShortOut)
2420    {
2421      // Hmm... sometimes (e.g., from maGetPreimage) new variables
2422      // are intorduced, but their names are never set
2423      // hence, we do the following awkward trick
2424      int N = omSizeWOfAddr(r->names);
2425      if (r->N < N) N = r->N;
2426
2427      for (i=(N-1);i>=0;i--)
2428      {
2429        if(r->names[i] != NULL && strlen(r->names[i])>1)
2430        {
2431          r->ShortOut=FALSE;
2432          break;
2433        }
2434      }
2435    }
2436  }
2437  r->CanShortOut = r->ShortOut;
2438}
2439
2440/*2
2441* sets pMixedOrder and pComponentOrder for orderings with more than one block
2442* block of variables (ip is the block number, o_r the number of the ordering)
2443* o is the position of the orderingering in r
2444*/
2445static void rHighSet(ring r, int o_r, int o)
2446{
2447  switch(o_r)
2448  {
2449    case ringorder_lp:
2450    case ringorder_dp:
2451    case ringorder_Dp:
2452    case ringorder_wp:
2453    case ringorder_Wp:
2454    case ringorder_rp:
2455    case ringorder_a:
2456    case ringorder_aa:
2457    case ringorder_a64:
2458      if (r->OrdSgn==-1) r->MixedOrder=TRUE;
2459      break;
2460    case ringorder_ls:
2461    case ringorder_ds:
2462    case ringorder_Ds:
2463    case ringorder_s:
2464      break;
2465    case ringorder_ws:
2466    case ringorder_Ws:
2467      if (r->wvhdl[o]!=NULL)
2468      {
2469        int i;
2470        for(i=r->block1[o]-r->block0[o];i>=0;i--)
2471          if (r->wvhdl[o][i]<0) { r->MixedOrder=TRUE; break; }
2472      }
2473      break;
2474    case ringorder_c:
2475      r->ComponentOrder=1;
2476      break;
2477    case ringorder_C:
2478    case ringorder_S:
2479      r->ComponentOrder=-1;
2480      break;
2481    case ringorder_M:
2482      r->MixedOrder=TRUE;
2483      break;
2484    default:
2485      dReportError("wrong internal ordering:%d at %s, l:%d\n",o_r,__FILE__,__LINE__);
2486  }
2487}
2488
2489static void rSetFirstWv(ring r, int i, int* order, int* block1, int** wvhdl)
2490{
2491  // cheat for ringorder_aa
2492  if (order[i] == ringorder_aa)
2493    i++;
2494  if(block1[i]!=r->N) r->LexOrder=TRUE;
2495  r->firstBlockEnds=block1[i];
2496  r->firstwv = wvhdl[i];
2497  if ((order[i]== ringorder_ws) || (order[i]==ringorder_Ws)
2498  || (order[i]== ringorder_wp) || (order[i]==ringorder_Wp)
2499  || (order[i]== ringorder_a) /*|| (order[i]==ringorder_A)*/)
2500  {
2501    int j;
2502    for(j=block1[i]-r->block0[i];j>=0;j--)
2503    {
2504      if (r->firstwv[j]<0) r->MixedOrder=TRUE;
2505      if (r->firstwv[j]==0) r->LexOrder=TRUE;
2506    }
2507  }
2508  else if (order[i]==ringorder_a64)
2509  {
2510    int j;
2511    int64 *w=rGetWeightVec(r);
2512    for(j=block1[i]-r->block0[i];j>=0;j--)
2513    {
2514      if (w[j]==0) r->LexOrder=TRUE;
2515    }
2516  }
2517}
2518
2519static void rOptimizeLDeg(ring r)
2520{
2521  if (r->pFDeg == pDeg)
2522  {
2523    if (r->pLDeg == pLDeg1)
2524      r->pLDeg = pLDeg1_Deg;
2525    if (r->pLDeg == pLDeg1c)
2526      r->pLDeg = pLDeg1c_Deg;
2527  }
2528  else if (r->pFDeg == pTotaldegree)
2529  {
2530    if (r->pLDeg == pLDeg1)
2531      r->pLDeg = pLDeg1_Totaldegree;
2532    if (r->pLDeg == pLDeg1c)
2533      r->pLDeg = pLDeg1c_Totaldegree;
2534  }
2535  else if (r->pFDeg == pWFirstTotalDegree)
2536  {
2537    if (r->pLDeg == pLDeg1)
2538      r->pLDeg = pLDeg1_WFirstTotalDegree;
2539    if (r->pLDeg == pLDeg1c)
2540      r->pLDeg = pLDeg1c_WFirstTotalDegree;
2541  }
2542}
2543
2544// set pFDeg, pLDeg, MixOrder, ComponentOrder, etc
2545static void rSetDegStuff(ring r)
2546{
2547  int* order = r->order;
2548  int* block0 = r->block0;
2549  int* block1 = r->block1;
2550  int** wvhdl = r->wvhdl;
2551
2552  if (order[0]==ringorder_S ||order[0]==ringorder_s)
2553  {
2554    order++;
2555    block0++;
2556    block1++;
2557    wvhdl++;
2558  }
2559  r->LexOrder = FALSE;
2560  r->MixedOrder = FALSE;
2561  r->ComponentOrder = 1;
2562  r->pFDeg = pTotaldegree;
2563  r->pLDeg = (r->OrdSgn == 1 ? pLDegb : pLDeg0);
2564
2565  /*======== ordering type is (_,c) =========================*/
2566  if ((order[0]==ringorder_unspec) || (order[1] == 0)
2567      ||(
2568    ((order[1]==ringorder_c)||(order[1]==ringorder_C)
2569     ||(order[1]==ringorder_S)
2570     ||(order[1]==ringorder_s))
2571    && (order[0]!=ringorder_M)
2572    && (order[2]==0))
2573    )
2574  {
2575    if ((order[0]!=ringorder_unspec)
2576    && ((order[1]==ringorder_C)||(order[1]==ringorder_S)||
2577        (order[1]==ringorder_s)))
2578      r->ComponentOrder=-1;
2579    if (r->OrdSgn == -1) r->pLDeg = pLDeg0c;
2580    if ((order[0] == ringorder_lp) || (order[0] == ringorder_ls) || order[0] == ringorder_rp)
2581    {
2582      r->LexOrder=TRUE;
2583      r->pLDeg = pLDeg1c;
2584    }
2585    if (order[0] == ringorder_wp || order[0] == ringorder_Wp ||
2586        order[0] == ringorder_ws || order[0] == ringorder_Ws)
2587      r->pFDeg = pWFirstTotalDegree;
2588    r->firstBlockEnds=block1[0];
2589    r->firstwv = wvhdl[0];
2590  }
2591  /*======== ordering type is (c,_) =========================*/
2592  else if (((order[0]==ringorder_c)
2593            ||(order[0]==ringorder_C)
2594            ||(order[0]==ringorder_S)
2595            ||(order[0]==ringorder_s))
2596  && (order[1]!=ringorder_M)
2597  &&  (order[2]==0))
2598  {
2599    if ((order[0]==ringorder_C)||(order[0]==ringorder_S)||
2600        order[0]==ringorder_s)
2601      r->ComponentOrder=-1;
2602    if ((order[1] == ringorder_lp) || (order[1] == ringorder_ls) || order[1] == ringorder_rp)
2603    {
2604      r->LexOrder=TRUE;
2605      r->pLDeg = pLDeg1c;
2606    }
2607    r->firstBlockEnds=block1[1];
2608    r->firstwv = wvhdl[1];
2609    if (order[1] == ringorder_wp || order[1] == ringorder_Wp ||
2610        order[1] == ringorder_ws || order[1] == ringorder_Ws)
2611      r->pFDeg = pWFirstTotalDegree;
2612  }
2613  /*------- more than one block ----------------------*/
2614  else
2615  {
2616    if ((r->VectorOut)||(order[0]==ringorder_C)||(order[0]==ringorder_S)||(order[0]==ringorder_s))
2617    {
2618      rSetFirstWv(r, 1, order, block1, wvhdl);
2619    }
2620    else
2621      rSetFirstWv(r, 0, order, block1, wvhdl);
2622
2623    /*the number of orderings:*/
2624    int i = 0;
2625    while (order[++i] != 0);
2626    do
2627    {
2628      i--;
2629      rHighSet(r, order[i],i);
2630    }
2631    while (i != 0);
2632
2633    if ((order[0]!=ringorder_c)
2634        && (order[0]!=ringorder_C)
2635        && (order[0]!=ringorder_S)
2636        && (order[0]!=ringorder_s))
2637    {
2638      r->pLDeg = pLDeg1c;
2639    }
2640    else
2641    {
2642      r->pLDeg = pLDeg1;
2643    }
2644    r->pFDeg = pWTotaldegree; // may be improved: pTotaldegree for lp/dp/ls/.. blocks
2645  }
2646  if (rOrd_is_Totaldegree_Ordering(r) || rOrd_is_WeightedDegree_Ordering(r))
2647    r->pFDeg = pDeg;
2648
2649  r->pFDegOrig = r->pFDeg;
2650  r->pLDegOrig = r->pLDeg;
2651  rOptimizeLDeg(r);
2652}
2653
2654/*2
2655* set NegWeightL_Size, NegWeightL_Offset
2656*/
2657static void rSetNegWeight(ring r)
2658{
2659  int i,l;
2660  if (r->typ!=NULL)
2661  {
2662    l=0;
2663    for(i=0;i<r->OrdSize;i++)
2664    {
2665      if(r->typ[i].ord_typ==ro_wp_neg) l++;
2666    }
2667    if (l>0)
2668    {
2669      r->NegWeightL_Size=l;
2670      r->NegWeightL_Offset=(int *) omAlloc(l*sizeof(int));
2671      l=0;
2672      for(i=0;i<r->OrdSize;i++)
2673      {
2674        if(r->typ[i].ord_typ==ro_wp_neg)
2675        {
2676          r->NegWeightL_Offset[l]=r->typ[i].data.wp.place;
2677          l++;
2678        }
2679      }
2680      return;
2681    }
2682  }
2683  r->NegWeightL_Size = 0;
2684  r->NegWeightL_Offset = NULL;
2685}
2686
2687static void rSetOption(ring r)
2688{
2689  // set redthrough
2690  if (!TEST_OPT_OLDSTD && r->OrdSgn == 1 && ! r->LexOrder)
2691    r->options |= Sy_bit(OPT_REDTHROUGH);
2692  else
2693    r->options &= ~Sy_bit(OPT_REDTHROUGH);
2694
2695  // set intStrategy
2696  if (rField_is_Extension(r) || rField_is_Q(r))
2697    r->options |= Sy_bit(OPT_INTSTRATEGY);
2698  else
2699    r->options &= ~Sy_bit(OPT_INTSTRATEGY);
2700
2701  // set redTail
2702  if (r->LexOrder || r->OrdSgn == -1 || rField_is_Extension(r))
2703    r->options &= ~Sy_bit(OPT_REDTAIL);
2704  else
2705    r->options |= Sy_bit(OPT_REDTAIL);
2706}
2707
2708BOOLEAN rComplete(ring r, int force)
2709{
2710  if (r->VarOffset!=NULL && force == 0) return FALSE;
2711  nInitChar(r);
2712  rSetOutParams(r);
2713  int n=rBlocks(r)-1;
2714  int i;
2715  int bits;
2716  r->bitmask=rGetExpSize(r->bitmask,bits,r->N);
2717  r->BitsPerExp = bits;
2718  r->ExpPerLong = BIT_SIZEOF_LONG / bits;
2719  r->divmask=rGetDivMask(bits);
2720
2721  // will be used for ordsgn:
2722  long *tmp_ordsgn=(long *)omAlloc0(2*(n+r->N)*sizeof(long));
2723  // will be used for VarOffset:
2724  int *v=(int *)omAlloc((r->N+1)*sizeof(int));
2725  for(i=r->N; i>=0 ; i--)
2726  {
2727    v[i]=-1;
2728  }
2729  sro_ord *tmp_typ=(sro_ord *)omAlloc0(2*(n+r->N)*sizeof(sro_ord));
2730  int typ_i=0;
2731  int prev_ordsgn=0;
2732
2733  // fill in v, tmp_typ, tmp_ordsgn, determine typ_i (== ordSize)
2734  int j=0;
2735  int j_bits=BITS_PER_LONG;
2736  BOOLEAN need_to_add_comp=FALSE;
2737  for(i=0;i<n;i++)
2738  {
2739    tmp_typ[typ_i].order_index=i;
2740    switch (r->order[i])
2741    {
2742      case ringorder_a:
2743      case ringorder_aa:
2744        rO_WDegree(j,j_bits,r->block0[i],r->block1[i],tmp_ordsgn,tmp_typ[typ_i],
2745                   r->wvhdl[i]);
2746        typ_i++;
2747        break;
2748
2749      case ringorder_a64:
2750        rO_WDegree64(j,j_bits,r->block0[i],r->block1[i],tmp_ordsgn,
2751                     tmp_typ[typ_i], (int64 *)(r->wvhdl[i]));
2752        typ_i++;
2753        break;
2754
2755      case ringorder_c:
2756        rO_Align(j, j_bits);
2757        rO_LexVars_neg(j, j_bits, 0,0, prev_ordsgn,tmp_ordsgn,v,BITS_PER_LONG, -1);
2758        break;
2759
2760      case ringorder_C:
2761        rO_Align(j, j_bits);
2762        rO_LexVars(j, j_bits, 0,0, prev_ordsgn,tmp_ordsgn,v,BITS_PER_LONG, -1);
2763        break;
2764
2765      case ringorder_M:
2766        {
2767          int k,l;
2768          k=r->block1[i]-r->block0[i]+1; // number of vars
2769          for(l=0;l<k;l++)
2770          {
2771            rO_WDegree(j,j_bits,r->block0[i],r->block1[i],tmp_ordsgn,
2772                       tmp_typ[typ_i],
2773                       r->wvhdl[i]+(r->block1[i]-r->block0[i]+1)*l);
2774            typ_i++;
2775          }
2776          break;
2777        }
2778
2779      case ringorder_lp:
2780        rO_LexVars(j, j_bits, r->block0[i],r->block1[i], prev_ordsgn,
2781                   tmp_ordsgn,v,bits, -1);
2782        break;
2783
2784      case ringorder_ls:
2785        rO_LexVars_neg(j, j_bits, r->block0[i],r->block1[i], prev_ordsgn,
2786                       tmp_ordsgn,v, bits, -1);
2787        break;
2788
2789      case ringorder_rp:
2790        rO_LexVars_neg(j, j_bits, r->block1[i],r->block0[i], prev_ordsgn,
2791                       tmp_ordsgn,v, bits, -1);
2792        break;
2793
2794      case ringorder_dp:
2795        if (r->block0[i]==r->block1[i])
2796        {
2797          rO_LexVars(j, j_bits, r->block0[i],r->block0[i], prev_ordsgn,
2798                     tmp_ordsgn,v, bits, -1);
2799        }
2800        else
2801        {
2802          rO_TDegree(j,j_bits,r->block0[i],r->block1[i],tmp_ordsgn,
2803                     tmp_typ[typ_i]);
2804          typ_i++;
2805          rO_LexVars_neg(j, j_bits, r->block1[i],r->block0[i]+1,
2806                         prev_ordsgn,tmp_ordsgn,v,bits, r->block0[i]);
2807        }
2808        break;
2809
2810      case ringorder_Dp:
2811        if (r->block0[i]==r->block1[i])
2812        {
2813          rO_LexVars(j, j_bits, r->block0[i],r->block0[i], prev_ordsgn,
2814                     tmp_ordsgn,v, bits, -1);
2815        }
2816        else
2817        {
2818          rO_TDegree(j,j_bits,r->block0[i],r->block1[i],tmp_ordsgn,
2819                     tmp_typ[typ_i]);
2820          typ_i++;
2821          rO_LexVars(j, j_bits, r->block0[i],r->block1[i]-1, prev_ordsgn,
2822                     tmp_ordsgn,v, bits, r->block1[i]);
2823        }
2824        break;
2825
2826      case ringorder_ds:
2827        if (r->block0[i]==r->block1[i])
2828        {
2829          rO_LexVars_neg(j, j_bits,r->block0[i],r->block1[i],prev_ordsgn,
2830                         tmp_ordsgn,v,bits, -1);
2831        }
2832        else
2833        {
2834          rO_TDegree_neg(j,j_bits,r->block0[i],r->block1[i],tmp_ordsgn,
2835                         tmp_typ[typ_i]);
2836          typ_i++;
2837          rO_LexVars_neg(j, j_bits, r->block1[i],r->block0[i]+1,
2838                         prev_ordsgn,tmp_ordsgn,v,bits, r->block0[i]);
2839        }
2840        break;
2841
2842      case ringorder_Ds:
2843        if (r->block0[i]==r->block1[i])
2844        {
2845          rO_LexVars_neg(j, j_bits, r->block0[i],r->block0[i],prev_ordsgn,
2846                         tmp_ordsgn,v, bits, -1);
2847        }
2848        else
2849        {
2850          rO_TDegree_neg(j,j_bits,r->block0[i],r->block1[i],tmp_ordsgn,
2851                         tmp_typ[typ_i]);
2852          typ_i++;
2853          rO_LexVars(j, j_bits, r->block0[i],r->block1[i]-1, prev_ordsgn,
2854                     tmp_ordsgn,v, bits, r->block1[i]);
2855        }
2856        break;
2857
2858      case ringorder_wp:
2859        rO_WDegree(j,j_bits,r->block0[i],r->block1[i],tmp_ordsgn,
2860                   tmp_typ[typ_i], r->wvhdl[i]);
2861        typ_i++;
2862        if (r->block1[i]!=r->block0[i])
2863        {
2864          rO_LexVars_neg(j, j_bits,r->block1[i],r->block0[i]+1, prev_ordsgn,
2865                         tmp_ordsgn, v,bits, r->block0[i]);
2866        }
2867        break;
2868
2869      case ringorder_Wp:
2870        rO_WDegree(j,j_bits,r->block0[i],r->block1[i],tmp_ordsgn,
2871                   tmp_typ[typ_i], r->wvhdl[i]);
2872        typ_i++;
2873        if (r->block1[i]!=r->block0[i])
2874        {
2875          rO_LexVars(j, j_bits,r->block0[i],r->block1[i]-1, prev_ordsgn,
2876                     tmp_ordsgn,v, bits, r->block1[i]);
2877        }
2878        break;
2879
2880      case ringorder_ws:
2881        rO_WDegree_neg(j,j_bits,r->block0[i],r->block1[i],tmp_ordsgn,
2882                       tmp_typ[typ_i], r->wvhdl[i]);
2883        typ_i++;
2884        if (r->block1[i]!=r->block0[i])
2885        {
2886          rO_LexVars_neg(j, j_bits,r->block1[i],r->block0[i]+1, prev_ordsgn,
2887                         tmp_ordsgn, v,bits, r->block0[i]);
2888        }
2889        break;
2890
2891      case ringorder_Ws:
2892        rO_WDegree_neg(j,j_bits,r->block0[i],r->block1[i],tmp_ordsgn,
2893                       tmp_typ[typ_i], r->wvhdl[i]);
2894        typ_i++;
2895        if (r->block1[i]!=r->block0[i])
2896        {
2897          rO_LexVars(j, j_bits,r->block0[i],r->block1[i]-1, prev_ordsgn,
2898                     tmp_ordsgn,v, bits, r->block1[i]);
2899        }
2900        break;
2901
2902      case ringorder_S:
2903        rO_Syzcomp(j, j_bits,prev_ordsgn, tmp_ordsgn,tmp_typ[typ_i]);
2904        need_to_add_comp=TRUE;
2905        typ_i++;
2906        break;
2907
2908      case ringorder_s:
2909        rO_Syz(j, j_bits,prev_ordsgn, tmp_ordsgn,tmp_typ[typ_i]);
2910        need_to_add_comp=TRUE;
2911        typ_i++;
2912        break;
2913
2914      case ringorder_unspec:
2915      case ringorder_no:
2916      default:
2917        dReportError("undef. ringorder used\n");
2918        break;
2919    }
2920  }
2921
2922  int j0=j; // save j
2923  int j_bits0=j_bits; // save jbits
2924  rO_Align(j,j_bits);
2925  r->CmpL_Size = j;
2926
2927  j_bits=j_bits0; j=j0;
2928
2929  // fill in some empty slots with variables not already covered
2930  // v0 is special, is therefore normally already covered
2931  // now we do have rings without comp...
2932  if((need_to_add_comp) && (v[0]== -1))
2933  {
2934    if (prev_ordsgn==1)
2935    {
2936      rO_Align(j, j_bits);
2937      rO_LexVars(j, j_bits, 0,0, prev_ordsgn,tmp_ordsgn,v,BITS_PER_LONG, -1);
2938    }
2939    else
2940    {
2941      rO_Align(j, j_bits);
2942      rO_LexVars_neg(j, j_bits, 0,0, prev_ordsgn,tmp_ordsgn,v,BITS_PER_LONG, -1);
2943    }
2944  }
2945  // the variables
2946  for(i=1 ; i<r->N+1 ; i++)
2947  {
2948    if(v[i]==(-1))
2949    {
2950      if (prev_ordsgn==1)
2951      {
2952        rO_LexVars(j, j_bits, i,i, prev_ordsgn,tmp_ordsgn,v,bits, -1);
2953      }
2954      else
2955      {
2956        rO_LexVars_neg(j,j_bits,i,i, prev_ordsgn,tmp_ordsgn,v,bits, -1);
2957      }
2958    }
2959  }
2960
2961  rO_Align(j,j_bits);
2962  // ----------------------------
2963  // finished with constructing the monomial, computing sizes:
2964
2965  r->ExpL_Size=j;
2966  r->PolyBin = omGetSpecBin(POLYSIZE + (r->ExpL_Size)*sizeof(long));
2967  assume(r->PolyBin != NULL);
2968
2969  // ----------------------------
2970  // indices and ordsgn vector for comparison
2971  //
2972  // r->pCompHighIndex already set
2973  r->ordsgn=(long *)omAlloc0(r->ExpL_Size*sizeof(long));
2974
2975  for(j=0;j<r->CmpL_Size;j++)
2976  {
2977    r->ordsgn[j] = tmp_ordsgn[j];
2978  }
2979
2980  omFreeSize((ADDRESS)tmp_ordsgn,(2*(n+r->N)*sizeof(long)));
2981
2982  // ----------------------------
2983  // description of orderings for setm:
2984  //
2985  r->OrdSize=typ_i;
2986  if (typ_i==0) r->typ=NULL;
2987  else
2988  {
2989    r->typ=(sro_ord*)omAlloc(typ_i*sizeof(sro_ord));
2990    memcpy(r->typ,tmp_typ,typ_i*sizeof(sro_ord));
2991  }
2992  omFreeSize((ADDRESS)tmp_typ,(2*(n+r->N)*sizeof(sro_ord)));
2993
2994  // ----------------------------
2995  // indices for (first copy of ) variable entries in exp.e vector (VarOffset):
2996  r->VarOffset=v;
2997
2998  // ----------------------------
2999  // other indicies
3000  r->pCompIndex=(r->VarOffset[0] & 0xffff); //r->VarOffset[0];
3001  i=0; // position
3002  j=0; // index in r->typ
3003  if (i==r->pCompIndex) i++;
3004  while ((j < r->OrdSize)
3005         && ((r->typ[j].ord_typ==ro_syzcomp) ||
3006             (r->typ[j].ord_typ==ro_syz) ||
3007             (r->order[r->typ[j].order_index] == ringorder_aa)))
3008  {
3009    i++; j++;
3010  }
3011  if (i==r->pCompIndex) i++;
3012  r->pOrdIndex=i;
3013
3014  // ----------------------------
3015  rSetDegStuff(r);
3016  rSetOption(r);
3017  // ----------------------------
3018  // r->p_Setm
3019  r->p_Setm = p_GetSetmProc(r);
3020
3021  // ----------------------------
3022  // set VarL_*
3023  rSetVarL(r);
3024
3025  //  ----------------------------
3026  // right-adjust VarOffset
3027  rRightAdjustVarOffset(r);
3028
3029  // ----------------------------
3030  // set NegWeightL*
3031  rSetNegWeight(r);
3032
3033  // ----------------------------
3034  // p_Procs: call AFTER NegWeightL
3035  r->p_Procs = (p_Procs_s*)omAlloc(sizeof(p_Procs_s));
3036  p_ProcsSet(r, r->p_Procs);
3037
3038  return FALSE;
3039}
3040
3041void rUnComplete(ring r)
3042{
3043  if (r == NULL) return;
3044  if (r->VarOffset != NULL)
3045  {
3046    if (r->PolyBin != NULL)
3047      omUnGetSpecBin(&(r->PolyBin));
3048
3049    omFreeSize((ADDRESS)r->VarOffset, (r->N +1)*sizeof(int));
3050    if (r->order != NULL)
3051    {
3052      if (r->order[0] == ringorder_s && r->typ[0].data.syz.limit > 0)
3053      {
3054        omFreeSize(r->typ[0].data.syz.syz_index,
3055             (r->typ[0].data.syz.limit +1)*sizeof(int));
3056      }
3057    }
3058    if (r->OrdSize!=0 && r->typ != NULL)
3059    {
3060      omFreeSize((ADDRESS)r->typ,r->OrdSize*sizeof(sro_ord));
3061    }
3062    if (r->ordsgn != NULL && r->CmpL_Size != 0)
3063      omFreeSize((ADDRESS)r->ordsgn,r->ExpL_Size*sizeof(long));
3064    if (r->p_Procs != NULL)
3065      omFreeSize(r->p_Procs, sizeof(p_Procs_s));
3066    omfreeSize(r->VarL_Offset, r->VarL_Size*sizeof(int));
3067  }
3068  if (r->NegWeightL_Offset!=NULL)
3069  {
3070    omFreeSize(r->NegWeightL_Offset, r->NegWeightL_Size*sizeof(int));
3071    r->NegWeightL_Offset=NULL;
3072  }
3073}
3074
3075// set r->VarL_Size, r->VarL_Offset, r->VarL_LowIndex
3076static void rSetVarL(ring r)
3077{
3078  int  min = INT_MAX, min_j = -1;
3079  int* VarL_Number = (int*) omAlloc0(r->ExpL_Size*sizeof(int));
3080
3081  int i,j;
3082
3083  // count how often a var long is occupied by an exponent
3084  for (i=1; i<=r->N; i++)
3085  {
3086    VarL_Number[r->VarOffset[i] & 0xffffff]++;
3087  }
3088
3089  // determine how many and min
3090  for (i=0, j=0; i<r->ExpL_Size; i++)
3091  {
3092    if (VarL_Number[i] != 0)
3093    {
3094      if (min > VarL_Number[i])
3095      {
3096        min = VarL_Number[i];
3097        min_j = j;
3098      }
3099      j++;
3100    }
3101  }
3102
3103  r->VarL_Size = j;
3104  r->VarL_Offset = (int*) omAlloc(r->VarL_Size*sizeof(int));
3105  r->VarL_LowIndex = 0;
3106
3107  // set VarL_Offset
3108  for (i=0, j=0; i<r->ExpL_Size; i++)
3109  {
3110    if (VarL_Number[i] != 0)
3111    {
3112      r->VarL_Offset[j] = i;
3113      if (j > 0 && r->VarL_Offset[j-1] != r->VarL_Offset[j] - 1)
3114        r->VarL_LowIndex = -1;
3115      j++;
3116    }
3117  }
3118  if (r->VarL_LowIndex >= 0)
3119    r->VarL_LowIndex = r->VarL_Offset[0];
3120
3121  r->MinExpPerLong = min;
3122  if (min_j != 0)
3123  {
3124    j = r->VarL_Offset[min_j];
3125    r->VarL_Offset[min_j] = r->VarL_Offset[0];
3126    r->VarL_Offset[0] = j;
3127  }
3128  omFree(VarL_Number);
3129}
3130
3131static void rRightAdjustVarOffset(ring r)
3132{
3133  int* shifts = (int*) omAlloc(r->ExpL_Size*sizeof(int));
3134  int i;
3135  // initialize shifts
3136  for (i=0;i<r->ExpL_Size;i++)
3137    shifts[i] = BIT_SIZEOF_LONG;
3138
3139  // find minimal bit in each long var
3140  for (i=1;i<=r->N;i++)
3141  {
3142    if (shifts[r->VarOffset[i] & 0xffffff] > r->VarOffset[i] >> 24)
3143      shifts[r->VarOffset[i] & 0xffffff] = r->VarOffset[i] >> 24;
3144  }
3145  // reset r->VarOffset
3146  for (i=1;i<=r->N;i++)
3147  {
3148    if (shifts[r->VarOffset[i] & 0xffffff] != 0)
3149      r->VarOffset[i]
3150        = (r->VarOffset[i] & 0xffffff) |
3151        (((r->VarOffset[i] >> 24) - shifts[r->VarOffset[i] & 0xffffff]) << 24);
3152  }
3153  omFree(shifts);
3154}
3155
3156// get r->divmask depending on bits per exponent
3157static unsigned long rGetDivMask(int bits)
3158{
3159  unsigned long divmask = 1;
3160  int i = bits;
3161
3162  while (i < BIT_SIZEOF_LONG)
3163  {
3164    divmask |= (((unsigned long) 1) << (unsigned long) i);
3165    i += bits;
3166  }
3167  return divmask;
3168}
3169
3170#ifdef RDEBUG
3171void rDebugPrint(ring r)
3172{
3173  if (r==NULL)
3174  {
3175    PrintS("NULL ?\n");
3176    return;
3177  }
3178  char *TYP[]={"ro_dp","ro_wp","ro_wp64","ro_wp_neg","ro_cp",
3179               "ro_syzcomp", "ro_syz", "ro_none"};
3180  int i,j;
3181
3182  Print("ExpL_Size:%d ",r->ExpL_Size);
3183  Print("CmpL_Size:%d ",r->CmpL_Size);
3184  Print("VarL_Size:%d\n",r->VarL_Size);
3185  Print("bitmask=0x%x (expbound=%d) \n",r->bitmask, r->bitmask);
3186  Print("BitsPerExp=%d ExpPerLong=%d MinExpPerLong=%d at L[%d]\n", r->BitsPerExp, r->ExpPerLong, r->MinExpPerLong, r->VarL_Offset[0]);
3187  PrintS("varoffset:\n");
3188  if (r->VarOffset==NULL) PrintS(" NULL\n");
3189  else
3190    for(j=0;j<=r->N;j++)
3191      Print("  v%d at e-pos %d, bit %d\n",
3192            j,r->VarOffset[j] & 0xffffff, r->VarOffset[j] >>24);
3193  Print("divmask=%p\n", r->divmask);
3194  PrintS("ordsgn:\n");
3195  for(j=0;j<r->CmpL_Size;j++)
3196    Print("  ordsgn %d at pos %d\n",r->ordsgn[j],j);
3197  Print("OrdSgn:%d\n",r->OrdSgn);
3198  PrintS("ordrec:\n");
3199  for(j=0;j<r->OrdSize;j++)
3200  {
3201    Print("  typ %s",TYP[r->typ[j].ord_typ]);
3202    Print("  place %d",r->typ[j].data.dp.place);
3203    if (r->typ[j].ord_typ!=ro_syzcomp)
3204    {
3205      Print("  start %d",r->typ[j].data.dp.start);
3206      Print("  end %d",r->typ[j].data.dp.end);
3207      if ((r->typ[j].ord_typ==ro_wp)
3208      || (r->typ[j].ord_typ==ro_wp_neg))
3209      {
3210        Print(" w:");
3211        int l;
3212        for(l=r->typ[j].data.wp.start;l<=r->typ[j].data.wp.end;l++)
3213          Print(" %d",r->typ[j].data.wp.weights[l-r->typ[j].data.wp.start]);
3214      }
3215      else if (r->typ[j].ord_typ==ro_wp64)
3216      {
3217        Print(" w64:");
3218        int l;
3219        for(l=r->typ[j].data.wp64.start;l<=r->typ[j].data.wp64.end;l++)
3220          Print(" %l",(long)(((int64*)r->typ[j].data.wp64.weights64)+l-r->typ[j].data.wp64.start));
3221      }
3222    }
3223    PrintLn();
3224  }
3225  Print("pOrdIndex:%d pCompIndex:%d\n", r->pOrdIndex, r->pCompIndex);
3226  Print("OrdSize:%d\n",r->OrdSize);
3227  PrintS("--------------------\n");
3228  for(j=0;j<r->ExpL_Size;j++)
3229  {
3230    Print("L[%d]: ",j);
3231    if (j< r->CmpL_Size)
3232      Print("ordsgn %d ", r->ordsgn[j]);
3233    else
3234      PrintS("no comp ");
3235    i=1;
3236    for(;i<=r->N;i++)
3237    {
3238      if( (r->VarOffset[i] & 0xffffff) == j )
3239      {  Print("v%d at e[%d], bit %d; ", i,r->VarOffset[i] & 0xffffff,
3240                                         r->VarOffset[i] >>24 ); }
3241    }
3242    if( r->pCompIndex==j ) PrintS("v0; ");
3243    for(i=0;i<r->OrdSize;i++)
3244    {
3245      if (r->typ[i].data.dp.place == j)
3246      {
3247        Print("ordrec:%s (start:%d, end:%d) ",TYP[r->typ[i].ord_typ],
3248          r->typ[i].data.dp.start, r->typ[i].data.dp.end);
3249      }
3250    }
3251
3252    if (j==r->pOrdIndex)
3253      PrintS("pOrdIndex\n");
3254    else
3255      PrintLn();
3256  }
3257
3258  // p_Procs stuff
3259  p_Procs_s proc_names;
3260  char* field;
3261  char* length;
3262  char* ord;
3263  p_Debug_GetProcNames(r, &proc_names);
3264  p_Debug_GetSpecNames(r, field, length, ord);
3265
3266  Print("p_Spec  : %s, %s, %s\n", field, length, ord);
3267  PrintS("p_Procs :\n");
3268  for (i=0; i<(int) (sizeof(p_Procs_s)/sizeof(void*)); i++)
3269  {
3270    Print(" %s,\n", ((char**) &proc_names)[i]);
3271  }
3272}
3273
3274void pDebugPrintR(poly p, ring r)
3275{
3276  int i,j;
3277  pWrite(p);
3278  j=2;
3279  while(p!=NULL)
3280  {
3281    Print("\nexp[0..%d]\n",r->ExpL_Size-1);
3282    for(i=0;i<r->ExpL_Size;i++)
3283      Print("%d ",p->exp[i]);
3284    PrintLn();
3285    Print("v0:%d ",p_GetComp(p, r));
3286    for(i=1;i<=r->N;i++) Print(" v%d:%d",i,p_GetExp(p,i, r));
3287    PrintLn();
3288    pIter(p);
3289    j--;
3290    if (j==0) { PrintS("...\n"); break; }
3291  }
3292}
3293
3294void pDebugPrint(poly p)
3295{
3296  pDebugPrintR(p, currRing);
3297}
3298#endif // RDEBUG
3299
3300
3301/*2
3302* asssume that rComplete was called with r
3303* assume that the first block ist ringorder_S
3304* change the block to reflect the sequence given by appending v
3305*/
3306
3307#ifdef PDEBUG
3308void rDBChangeSComps(int* currComponents,
3309                     long* currShiftedComponents,
3310                     int length,
3311                     ring r)
3312{
3313  r->typ[1].data.syzcomp.length = length;
3314  rNChangeSComps( currComponents, currShiftedComponents, r);
3315}
3316void rDBGetSComps(int** currComponents,
3317                 long** currShiftedComponents,
3318                 int *length,
3319                 ring r)
3320{
3321  *length = r->typ[1].data.syzcomp.length;
3322  rNGetSComps( currComponents, currShiftedComponents, r);
3323}
3324#endif
3325
3326void rNChangeSComps(int* currComponents, long* currShiftedComponents, ring r)
3327{
3328  assume(r->order[1]==ringorder_S);
3329
3330  r->typ[1].data.syzcomp.ShiftedComponents = currShiftedComponents;
3331  r->typ[1].data.syzcomp.Components = currComponents;
3332}
3333
3334void rNGetSComps(int** currComponents, long** currShiftedComponents, ring r)
3335{
3336  assume(r->order[1]==ringorder_S);
3337
3338  *currShiftedComponents = r->typ[1].data.syzcomp.ShiftedComponents;
3339  *currComponents =   r->typ[1].data.syzcomp.Components;
3340}
3341
3342/////////////////////////////////////////////////////////////////////////////
3343//
3344// The following routines all take as input a ring r, and return R
3345// where R has a certain property. P might be equal r in which case r
3346// had already this property
3347//
3348// Without argument, these functions work on currRing and change it,
3349// if necessary
3350
3351// for the time being, this is still here
3352static ring rAssure_SyzComp(ring r, BOOLEAN complete = TRUE);
3353
3354ring rCurrRingAssure_SyzComp()
3355{
3356  ring r = rAssure_SyzComp(currRing);
3357  if (r != currRing)
3358  {
3359    ring old_ring = currRing;
3360    rChangeCurrRing(r);
3361    if (old_ring->qideal != NULL)
3362    {
3363      r->qideal = idrCopyR_NoSort(old_ring->qideal, old_ring);
3364      assume(idRankFreeModule(r->qideal) == 0);
3365      currQuotient = r->qideal;
3366    }
3367  }
3368  return r;
3369}
3370
3371static ring rAssure_SyzComp(ring r, BOOLEAN complete)
3372{
3373  if (r->order[0] == ringorder_s) return r;
3374  ring res=rCopy0(r, FALSE, FALSE);
3375  int i=rBlocks(r);
3376  int j;
3377
3378  res->order=(int *)omAlloc0((i+1)*sizeof(int));
3379  for(j=i;j>0;j--) res->order[j]=r->order[j-1];
3380  res->order[0]=ringorder_s;
3381
3382  res->block0=(int *)omAlloc0((i+1)*sizeof(int));
3383  for(j=i;j>0;j--) res->block0[j]=r->block0[j-1];
3384
3385  res->block1=(int *)omAlloc0((i+1)*sizeof(int));
3386  for(j=i;j>0;j--) res->block1[j]=r->block1[j-1];
3387
3388  int ** wvhdl =(int **)omAlloc0((i+1)*sizeof(int**));
3389  for(j=i;j>0;j--)
3390  {
3391    if (r->wvhdl[j-1] != NULL)
3392    {
3393      wvhdl[j] = (int*) omMemDup(r->wvhdl[j-1]);
3394    }
3395  }
3396  res->wvhdl = wvhdl;
3397
3398  if (complete) rComplete(res, 1);
3399  return res;
3400}
3401
3402static ring rAssure_CompLastBlock(ring r, BOOLEAN complete = TRUE)
3403{
3404  int last_block = rBlocks(r) - 2;
3405  if (r->order[last_block] != ringorder_c &&
3406      r->order[last_block] != ringorder_C)
3407  {
3408    int c_pos = 0;
3409    int i;
3410
3411    for (i=0; i< last_block; i++)
3412    {
3413      if (r->order[i] == ringorder_c || r->order[i] == ringorder_C)
3414      {
3415        c_pos = i;
3416        break;
3417      }
3418    }
3419    if (c_pos != -1)
3420    {
3421      ring new_r = rCopy0(r, FALSE, TRUE);
3422      for (i=c_pos+1; i<=last_block; i++)
3423      {
3424        new_r->order[i-1] = new_r->order[i];
3425        new_r->block0[i-1] = new_r->block0[i];
3426        new_r->block1[i-1] = new_r->block1[i];
3427        new_r->wvhdl[i-1] = new_r->wvhdl[i];
3428      }
3429      new_r->order[last_block] = r->order[c_pos];
3430      new_r->block0[last_block] = r->block0[c_pos];
3431      new_r->block1[last_block] = r->block1[c_pos];
3432      new_r->wvhdl[last_block] = r->wvhdl[c_pos];
3433      if (complete) rComplete(new_r, 1);
3434      return new_r;
3435    }
3436  }
3437  return r;
3438}
3439
3440ring rCurrRingAssure_CompLastBlock()
3441{
3442  ring new_r = rAssure_CompLastBlock(currRing);
3443  if (currRing != new_r)
3444  {
3445    ring old_r = currRing;
3446    rChangeCurrRing(new_r);
3447    if (old_r->qideal != NULL)
3448    {
3449      new_r->qideal = idrCopyR(old_r->qideal, old_r);
3450      currQuotient = new_r->qideal;
3451    }
3452  }
3453  return new_r;
3454}
3455
3456ring rCurrRingAssure_SyzComp_CompLastBlock()
3457{
3458  ring new_r_1 = rAssure_CompLastBlock(currRing, FALSE);
3459  ring new_r = rAssure_SyzComp(new_r_1, FALSE);
3460
3461  if (new_r != currRing)
3462  {
3463    ring old_r = currRing;
3464    if (new_r_1 != new_r && new_r_1 != old_r) rDelete(new_r_1);
3465    rComplete(new_r, 1);
3466    rChangeCurrRing(new_r);
3467    if (old_r->qideal != NULL)
3468    {
3469      new_r->qideal = idrCopyR(old_r->qideal, old_r);
3470      currQuotient = new_r->qideal;
3471    }
3472    rTest(new_r);
3473    rTest(old_r);
3474  }
3475  return new_r;
3476}
3477
3478// use this for global orderings consisting of two blocks
3479static ring rCurrRingAssure_Global(rRingOrder_t b1, rRingOrder_t b2)
3480{
3481  int r_blocks = rBlocks(currRing);
3482  int i;
3483
3484  assume(b1 == ringorder_c || b1 == ringorder_C ||
3485         b2 == ringorder_c || b2 == ringorder_C ||
3486         b2 == ringorder_S);
3487  if ((r_blocks == 3) &&
3488      (currRing->order[0] == b1) &&
3489      (currRing->order[1] == b2) &&
3490      (currRing->order[2] == 0))
3491    return currRing;
3492  ring res = rCopy0(currRing, TRUE, FALSE);
3493  res->order = (int*)omAlloc0(3*sizeof(int));
3494  res->block0 = (int*)omAlloc0(3*sizeof(int));
3495  res->block1 = (int*)omAlloc0(3*sizeof(int));
3496  res->wvhdl = (int**)omAlloc0(3*sizeof(int*));
3497  res->order[0] = b1;
3498  res->order[1] = b2;
3499  if (b1 == ringorder_c || b1 == ringorder_C)
3500  {
3501    res->block0[1] = 1;
3502    res->block1[1] = currRing->N;
3503  }
3504  else
3505  {
3506    res->block0[0] = 1;
3507    res->block1[0] = currRing->N;
3508  }
3509  // HANNES: This sould be set in rComplete
3510  res->OrdSgn = 1;
3511  rComplete(res, 1);
3512  rChangeCurrRing(res);
3513  return res;
3514}
3515
3516
3517ring rCurrRingAssure_dp_S()
3518{
3519  return rCurrRingAssure_Global(ringorder_dp, ringorder_S);
3520}
3521
3522ring rCurrRingAssure_dp_C()
3523{
3524  return rCurrRingAssure_Global(ringorder_dp, ringorder_C);
3525}
3526
3527ring rCurrRingAssure_C_dp()
3528{
3529  return rCurrRingAssure_Global(ringorder_C, ringorder_dp);
3530}
3531
3532
3533void rSetSyzComp(int k)
3534{
3535  if (TEST_OPT_PROT) Print("{%d}", k);
3536  if ((currRing->typ!=NULL) && (currRing->typ[0].ord_typ==ro_syz))
3537  {
3538    assume(k > currRing->typ[0].data.syz.limit);
3539    int i;
3540    if (currRing->typ[0].data.syz.limit == 0)
3541    {
3542      currRing->typ[0].data.syz.syz_index = (int*) omAlloc0((k+1)*sizeof(int));
3543      currRing->typ[0].data.syz.syz_index[0] = 0;
3544      currRing->typ[0].data.syz.curr_index = 1;
3545    }
3546    else
3547    {
3548      currRing->typ[0].data.syz.syz_index = (int*)
3549        omReallocSize(currRing->typ[0].data.syz.syz_index,
3550                (currRing->typ[0].data.syz.limit+1)*sizeof(int),
3551                (k+1)*sizeof(int));
3552    }
3553    for (i=currRing->typ[0].data.syz.limit + 1; i<= k; i++)
3554    {
3555      currRing->typ[0].data.syz.syz_index[i] =
3556        currRing->typ[0].data.syz.curr_index;
3557    }
3558    currRing->typ[0].data.syz.limit = k;
3559    currRing->typ[0].data.syz.curr_index++;
3560  }
3561  else if ((currRing->order[0]!=ringorder_c) && (k!=0))
3562  {
3563    dReportError("syzcomp in incompatible ring");
3564  }
3565#ifdef PDEBUG
3566  extern int pDBsyzComp;
3567  pDBsyzComp=k;
3568#endif
3569}
3570
3571// return the max-comonent wchich has syzIndex i
3572int rGetMaxSyzComp(int i)
3573{
3574  if ((currRing->typ!=NULL) && (currRing->typ[0].ord_typ==ro_syz) &&
3575      currRing->typ[0].data.syz.limit > 0 && i > 0)
3576  {
3577    assume(i <= currRing->typ[0].data.syz.limit);
3578    int j;
3579    for (j=0; j<currRing->typ[0].data.syz.limit; j++)
3580    {
3581      if (currRing->typ[0].data.syz.syz_index[j] == i  &&
3582          currRing->typ[0].data.syz.syz_index[j+1] != i)
3583      {
3584        assume(currRing->typ[0].data.syz.syz_index[j+1] == i+1);
3585        return j;
3586      }
3587    }
3588    return currRing->typ[0].data.syz.limit;
3589  }
3590  else
3591  {
3592    return 0;
3593  }
3594}
3595
3596BOOLEAN rRing_is_Homog(ring r)
3597{
3598  if (r == NULL) return FALSE;
3599  int i, j, nb = rBlocks(r);
3600  for (i=0; i<nb; i++)
3601  {
3602    if (r->wvhdl[i] != NULL)
3603    {
3604      int length = r->block1[i] - r->block0[i];
3605      int* wvhdl = r->wvhdl[i];
3606      if (r->order[i] == ringorder_M) length *= length;
3607      assume(omSizeOfAddr(wvhdl) >= length*sizeof(int));
3608
3609      for (j=0; j< length; j++)
3610      {
3611        if (wvhdl[j] != 0 && wvhdl[j] != 1) return FALSE;
3612      }
3613    }
3614  }
3615  return TRUE;
3616}
3617
3618BOOLEAN rRing_has_CompLastBlock(ring r)
3619{
3620  assume(r != NULL);
3621  int lb = rBlocks(r) - 2;
3622  return (r->order[lb] == ringorder_c || r->order[lb] == ringorder_C);
3623}
3624
3625n_coeffType rFieldType(ring r)
3626{
3627  if (rField_is_Zp(r))     return n_Zp;
3628  if (rField_is_Q(r))      return n_Q;
3629  if (rField_is_R(r))      return n_R;
3630  if (rField_is_GF(r))     return n_GF;
3631  if (rField_is_long_R(r)) return n_long_R;
3632  if (rField_is_Zp_a(r))   return n_Zp_a;
3633  if (rField_is_Q_a(r))    return n_Q_a;
3634  if (rField_is_long_C(r)) return n_long_C;
3635  return n_unknown;
3636}
3637
3638int64 * rGetWeightVec(ring r)
3639{
3640  assume(r!=NULL);
3641  assume(r->OrdSize>0);
3642  int i=0;
3643  while((r->typ[i].ord_typ!=ro_wp64) && (r->typ[i].ord_typ>0)) i++;
3644  assume(r->typ[i].ord_typ==ro_wp64);
3645  return (int64*)(r->typ[i].data.wp64.weights64);
3646}
3647
3648void rSetWeightVec(ring r, int64 *wv)
3649{
3650  assume(r!=NULL);
3651  assume(r->OrdSize>0);
3652  assume(r->typ[0].ord_typ==ro_wp64);
3653  memcpy(r->typ[0].data.wp64.weights64,wv,r->N*sizeof(int64));
3654}
3655
3656#include <ctype.h>
3657
3658static int rRealloc1(ring r, ring src, int size, int pos)
3659{
3660  r->order=(int*)omReallocSize(r->order, size*sizeof(int), (size+1)*sizeof(int));
3661  r->block0=(int*)omReallocSize(r->block0, size*sizeof(int), (size+1)*sizeof(int));
3662  r->block1=(int*)omReallocSize(r->block1, size*sizeof(int), (size+1)*sizeof(int));
3663  r->wvhdl=(int_ptr*)omReallocSize(r->wvhdl,size*sizeof(int_ptr), (size+1)*sizeof(int_ptr));
3664  for(int k=size; k>pos; k--) r->wvhdl[k]=r->wvhdl[k-1];
3665  r->order[size]=0;
3666  size++;
3667  return size;
3668}
3669static int rReallocM1(ring r, ring src, int size, int pos)
3670{
3671  r->order=(int*)omReallocSize(r->order, size*sizeof(int), (size-1)*sizeof(int));
3672  r->block0=(int*)omReallocSize(r->block0, size*sizeof(int), (size-1)*sizeof(int));
3673  r->block1=(int*)omReallocSize(r->block1, size*sizeof(int), (size-1)*sizeof(int));
3674  r->wvhdl=(int_ptr*)omReallocSize(r->wvhdl,size*sizeof(int_ptr), (size-1)*sizeof(int_ptr));
3675  for(int k=pos+1; k<size; k++) r->wvhdl[k]=r->wvhdl[k+1];
3676  size--;
3677  return size;
3678}
3679static void rOppWeight(int *w, int l)
3680{
3681  int i2=(l+1)/2;
3682  for(int j=0; j<=i2; j++)
3683  {
3684    int t=w[j];
3685    w[j]=w[l-j];
3686    w[l-j]=t;
3687  }
3688}
3689
3690#define rOppVar(R,I) (rVar(R)+1-I)
3691
3692ring rOpposite(ring src)
3693  /* creates an opposite algebra of R */
3694  /* that is R^opp, where f (*^opp) g = g*f  */
3695  /* treats the case of qring */
3696{
3697  if (src == NULL) return(NULL);
3698  ring save = currRing;
3699  rChangeCurrRing(src);
3700  ring r = rCopy0(src,TRUE); /* TRUE for copy the qideal */
3701  /*  rChangeCurrRing(r); */
3702  // change vars v1..vN -> vN..v1
3703  int i;
3704  int i2 = (rVar(r)-1)/2;
3705  for(i=i2; i>=0; i--)
3706  {
3707    // index: 0..N-1
3708    //Print("ex var names: %d <-> %d\n",i,rOppVar(r,i));
3709    // exchange names
3710    char *p;
3711    p = r->names[rVar(r)-1-i];
3712    r->names[rVar(r)-1-i] = r->names[i];
3713    r->names[i] = p;
3714  }
3715//  i2=(rVar(r)+1)/2;
3716//  for(int i=i2; i>0; i--)
3717//  {
3718//    // index: 1..N
3719//    //Print("ex var places: %d <-> %d\n",i,rVar(r)+1-i);
3720//    // exchange VarOffset
3721//    int t;
3722//    t=r->VarOffset[i];
3723//    r->VarOffset[i]=r->VarOffset[rOppVar(r,i)];
3724//    r->VarOffset[rOppVar(r,i)]=t;
3725//  }
3726  // change names:
3727  for (i=rVar(r)-1; i>=0; i--)
3728  {
3729    char *p=r->names[i];
3730    if(isupper(*p)) *p = tolower(*p);
3731    else            *p = toupper(*p);
3732  }
3733  // change ordering: listing
3734  // change ordering: compare
3735//  for(i=0; i<r->OrdSize; i++)
3736//  {
3737//    int t,tt;
3738//    switch(r->typ[i].ord_typ)
3739//    {
3740//      case ro_dp:
3741//      //
3742//        t=r->typ[i].data.dp.start;
3743//        r->typ[i].data.dp.start=rOppVar(r,r->typ[i].data.dp.end);
3744//        r->typ[i].data.dp.end=rOppVar(r,t);
3745//        break;
3746//      case ro_wp:
3747//      case ro_wp_neg:
3748//      {
3749//        t=r->typ[i].data.wp.start;
3750//        r->typ[i].data.wp.start=rOppVar(r,r->typ[i].data.wp.end);
3751//        r->typ[i].data.wp.end=rOppVar(r,t);
3752//        // invert r->typ[i].data.wp.weights
3753//        rOppWeight(r->typ[i].data.wp.weights,
3754//                   r->typ[i].data.wp.end-r->typ[i].data.wp.start);
3755//        break;
3756//      }
3757//      //case ro_wp64:
3758//      case ro_syzcomp:
3759//      case ro_syz:
3760//         WerrorS("not implemented in rOpposite");
3761//         // should not happen
3762//         break;
3763//
3764//      case ro_cp:
3765//        t=r->typ[i].data.cp.start;
3766//        r->typ[i].data.cp.start=rOppVar(r,r->typ[i].data.cp.end);
3767//        r->typ[i].data.cp.end=rOppVar(r,t);
3768//        break;
3769//      case ro_none:
3770//      default:
3771//       Werror("unknown type in rOpposite(%d)",r->typ[i].ord_typ);
3772//       break;
3773//    }
3774//  }
3775  // Change order/block structures (needed for rPrint, rAdd etc.)
3776  int j=0;
3777  int l=rBlocks(src);
3778  for(i=0; src->order[i]!=0; i++)
3779  {
3780    switch (src->order[i])
3781    {
3782      case ringorder_c: /* c-> c */
3783      case ringorder_C: /* C-> C */
3784      case ringorder_no /*=0*/: /* end-of-block */
3785        r->order[j]=src->order[i];
3786        j++; break;
3787      case ringorder_lp: /* lp -> rp */
3788        r->order[j]=ringorder_rp;
3789        r->block0[j]=rOppVar(r, src->block1[i]);
3790        r->block1[j]=rOppVar(r, src->block0[i]);
3791        break;
3792      case ringorder_rp: /* rp -> lp */
3793        r->order[j]=ringorder_lp;
3794        r->block0[j]=rOppVar(r, src->block1[i]);
3795        r->block1[j]=rOppVar(r, src->block0[i]);
3796        break;
3797      case ringorder_dp: /* dp -> a(1..1),ls */
3798      {
3799        l=rRealloc1(r,src,l,j);
3800        r->order[j]=ringorder_a;
3801        r->block0[j]=rOppVar(r, src->block1[i]);
3802        r->block1[j]=rOppVar(r, src->block0[i]);
3803        r->wvhdl[j]=(int*)omAlloc((r->block1[j]-r->block0[j]+1)*sizeof(int));
3804        for(int k=r->block0[j]; k<=r->block1[j]; k++)
3805          r->wvhdl[j][k-r->block0[j]]=1;
3806        j++;
3807        r->order[j]=ringorder_ls;
3808        r->block0[j]=rOppVar(r, src->block1[i]);
3809        r->block1[j]=rOppVar(r, src->block0[i]);
3810        j++;
3811        break;
3812      }
3813      case ringorder_Dp: /* Dp -> a(1..1),rp */
3814      {
3815        l=rRealloc1(r,src,l,j);
3816        r->order[j]=ringorder_a;
3817        r->block0[j]=rOppVar(r, src->block1[i]);
3818        r->block1[j]=rOppVar(r, src->block0[i]);
3819        r->wvhdl[j]=(int*)omAlloc((r->block1[j]-r->block0[j]+1)*sizeof(int));
3820        for(int k=r->block0[j]; k<=r->block1[j]; k++)
3821          r->wvhdl[j][k-r->block0[j]]=1;
3822        j++;
3823        r->order[j]=ringorder_rp;
3824        r->block0[j]=rOppVar(r, src->block1[i]);
3825        r->block1[j]=rOppVar(r, src->block0[i]);
3826        j++;
3827        break;
3828      }
3829      case ringorder_wp: /* wp -> a(...),ls */
3830      {
3831        l=rRealloc1(r,src,l,j);
3832        r->order[j]=ringorder_a;
3833        r->block0[j]=rOppVar(r, src->block1[i]);
3834        r->block1[j]=rOppVar(r, src->block0[i]);
3835        r->wvhdl[j]=r->wvhdl[j+1]; r->wvhdl[j+1]=r->wvhdl[j+1]=NULL;
3836        rOppWeight(r->wvhdl[j], r->block1[j]-r->block0[j]);
3837        j++;
3838        r->order[j]=ringorder_ls;
3839        r->block0[j]=rOppVar(r, src->block1[i]);
3840        r->block1[j]=rOppVar(r, src->block0[i]);
3841        j++;
3842        break;
3843      }
3844      case ringorder_Wp: /* Wp -> a(...),rp */
3845      {
3846        l=rRealloc1(r,src,l,j);
3847        r->order[j]=ringorder_a;
3848        r->block0[j]=rOppVar(r, src->block1[i]);
3849        r->block1[j]=rOppVar(r, src->block0[i]);
3850        r->wvhdl[j]=r->wvhdl[j+1]; r->wvhdl[j+1]=r->wvhdl[j+1]=NULL;
3851        rOppWeight(r->wvhdl[j], r->block1[j]-r->block0[j]);
3852        j++;
3853        r->order[j]=ringorder_rp;
3854        r->block0[j]=rOppVar(r, src->block1[i]);
3855        r->block1[j]=rOppVar(r, src->block0[i]);
3856        j++;
3857        break;
3858      }
3859      case ringorder_M: /* M -> M */
3860      {
3861        r->order[j]=ringorder_M;
3862        r->block0[j]=rOppVar(r, src->block1[i]);
3863        r->block1[j]=rOppVar(r, src->block0[i]);
3864        int n=r->block1[j]-r->block0[j];
3865        /* M is a (n+1)x(n+1) matrix */
3866        for (int nn=0; nn<=n; nn++)
3867        {
3868          rOppWeight(&(r->wvhdl[j][nn*(n+1)]), n /*r->block1[j]-r->block0[j]*/);
3869        }
3870        j++;
3871        break;
3872      }
3873      case ringorder_a: /*  a(...),ls -> wp/dp */
3874      {
3875        r->block0[j]=rOppVar(r, src->block1[i]);
3876        r->block1[j]=rOppVar(r, src->block0[i]);
3877        rOppWeight(r->wvhdl[j], r->block1[j]-r->block0[j]);
3878        if (src->order[i+1]==ringorder_ls)
3879        {
3880          r->order[j]=ringorder_wp;
3881          i++;
3882          //l=rReallocM1(r,src,l,j);
3883        }
3884        else
3885        {
3886          r->order[j]=ringorder_a;
3887        }
3888        j++;
3889        break;
3890      }
3891      // not yet done:
3892      case ringorder_ls:
3893      case ringorder_ds:
3894      case ringorder_Ds:
3895      case ringorder_ws:
3896      case ringorder_Ws:
3897      // should not occur:
3898      case ringorder_S:
3899      case ringorder_s:
3900      case ringorder_aa:
3901      case ringorder_L:
3902      case ringorder_unspec:
3903        Werror("order %s not (yet) supported", rSimpleOrdStr(src->order[i]));
3904        break;
3905    }
3906  }
3907  rComplete(r);
3908#ifdef RDEBUG
3909  //   rDebugPrint(r);
3910#endif
3911  rTest(r);
3912#ifdef HAVE_PLURAL
3913  /* now, we initialize a non-comm structure on r */
3914  if (!rIsPluralRing(src))
3915  {
3916    return r;
3917  }
3918  if ( rIsPluralRing(src) )
3919  {
3920  rChangeCurrRing(r);  /* we were not in r */
3921  /* basic nc constructions  */
3922  r->nc           = (nc_struct *)omAlloc0(sizeof(nc_struct));
3923  r->nc->ref      = 1; /* in spite of rCopy(src)? */
3924  r->nc->basering = r;
3925  r->nc->type     =  src->nc->type;
3926  int *perm       = (int *)omAlloc0((rVar(r)+1)*sizeof(int));
3927  int *par_perm   = NULL;
3928  nMapFunc nMap   = nSetMap(src);
3929  int j;
3930  int ni,nj;
3931  for(i=1; i<=r->N; i++)
3932  {
3933    perm[i] = rOppVar(r,i);
3934  }
3935  matrix C = mpNew(rVar(r),rVar(r));
3936  matrix D = mpNew(rVar(r),rVar(r));
3937  for (i=1; i< rVar(r); i++)
3938  {
3939    for (j=i+1; j<=rVar(r); j++)
3940    {
3941      ni = r->N +1 - i;
3942      nj = r->N +1 - j; /* i<j ==>   nj < ni */
3943      MATELEM(C,nj,ni) = pPermPoly(MATELEM(src->nc->C,i,j),perm,src,nMap,par_perm,src->P);
3944      MATELEM(D,nj,ni) = pPermPoly(MATELEM(src->nc->D,i,j),perm,src,nMap,par_perm,src->P);
3945    }
3946  }
3947  idTest((ideal)C);
3948  idTest((ideal)D);
3949  r->nc->C = C;
3950  r->nc->D = D;
3951  if (nc_InitMultiplication(r))
3952    WarnS("Error initializing multiplication!");
3953  r->nc->IsSkewConstant =   src->nc->IsSkewConstant;
3954  omFreeSize((ADDRESS)perm,(rVar(r)+1)*sizeof(int));
3955  /* now oppose the qideal for qrings */
3956  if (src->qideal != NULL)
3957  {
3958    idDelete(&(r->qideal));
3959    r->qideal = idOppose(src, src->qideal);
3960  }
3961  rTest(r);
3962  rChangeCurrRing(save);
3963  }
3964#endif /* HAVE_PLURAL */
3965  return r;
3966}
3967
3968ring rEnvelope(ring R)
3969  /* creates an enveloping algebra of R */
3970  /* that is R^e = R \tensor_K R^opp */
3971{
3972  ring Ropp = rOpposite(R);
3973  ring Renv = NULL;
3974  int stat = rSum(R, Ropp, Renv); /* takes care of qideals */
3975  if ( stat <=0 )
3976    WarnS("Error in rEnvelope at rSum");
3977  rTest(Renv);
3978  return Renv;
3979}
3980
3981BOOLEAN nc_rComplete(ring src, ring dest)
3982/* returns TRUE is there were errors */
3983/* dest is actualy equals src with the different ordering */
3984/* we map src->nc correctly to dest->src */
3985/* to be executed after rComplete, before rChangeCurrRing */
3986
3987{
3988  if (!rIsPluralRing(src))
3989    return FALSE;
3990  int i,j;
3991  int N = dest->N;
3992  if (src->N != N)
3993  {
3994    /* should not happen */
3995    WarnS("wrong nc_rComplete call");
3996    return TRUE;
3997  }
3998  ring save = currRing;
3999  int WeChangeRing = 0;
4000  if (dest != currRing)
4001  {
4002    WeChangeRing = 1;
4003    rChangeCurrRing(dest);
4004  }
4005  matrix C = mpNew(N,N);
4006  matrix D = mpNew(N,N);
4007  matrix C0 = src->nc->C;
4008  matrix D0 = src->nc->D;
4009  poly p = NULL;
4010  number n = NULL;
4011  for (i=1; i< N; i++)
4012  {
4013    for (j= i+1; j<= N; j++)
4014    {
4015      n = n_Copy(p_GetCoeff(MATELEM(C0,i,j), src),src);
4016      p = p_ISet(1,dest);
4017      p_SetCoeff(p,n,dest);
4018      MATELEM(C,i,j) = p;
4019      p = NULL;
4020      if (MATELEM(D0,i,j) != NULL)
4021      {
4022        p = prCopyR(MATELEM(D0,i,j), src->nc->basering, dest);
4023        MATELEM(D,i,j) = nc_p_CopyPut(p, dest);
4024        p_Delete(&p, dest);
4025        p = NULL;
4026      }
4027    }
4028  }
4029  /* One must test C and D _only_ in r->nc->basering!!! not in r!!! */
4030  //  idTest((ideal)C);
4031  //  idTest((ideal)D);
4032  id_Delete((ideal *)&(dest->nc->C),dest->nc->basering);
4033  id_Delete((ideal *)&(dest->nc->D),dest->nc->basering);
4034  dest->nc->C = C;
4035  dest->nc->D = D;
4036  if ( WeChangeRing )
4037    rChangeCurrRing(save);
4038  if (nc_InitMultiplication(dest))
4039  {
4040    WarnS("Error initializing multiplication!");
4041    return TRUE;
4042  }
4043  return FALSE;
4044}
4045
4046void rModify_a_to_A(ring r)
4047// to be called BEFORE rComplete:
4048// changes every Block with a(...) to A(...)
4049{
4050   int i=0;
4051   int j;
4052   while(r->order[i]!=0)
4053   {
4054      if (r->order[i]==ringorder_a)
4055      {
4056        r->order[i]=ringorder_a64;
4057        int *w=r->wvhdl[i];
4058        int64 *w64=(int64 *)omAlloc((r->block1[i]-r->block0[i]+1)*sizeof(int64));
4059        for(j=r->block1[i]-r->block0[i];j>=0;j--)
4060                w64[j]=(int64)w[j];
4061        r->wvhdl[i]=(int*)w64;
4062        omFreeSize(w,(r->block1[i]-r->block0[i]+1)*sizeof(int));
4063      }
4064      i++;
4065   }
4066}
Note: See TracBrowser for help on using the repository browser.