source: git/Singular/ring.cc @ 9d72fe

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