source: git/Singular/ipshell.cc @ 160f439

fieker-DuValspielwiese
Last change on this file since 160f439 was 160f439, checked in by Hans Schoenemann <hannes@…>, 12 years ago
fix: ticket:400 vraiables(ideal i) for i containing entries==0 (from master)
  • Property mode set to 100644
File size: 136.8 KB
RevLine 
[0e1846]1/****************************************
2*  Computer Algebra System SINGULAR     *
3****************************************/
4/*
5* ABSTRACT:
6*/
[762407]7#include "config.h"
[77bb59]8#include <kernel/mod2.h>
9#include <misc/auxiliary.h>
[0e1846]10
11
[6cc7f5]12#include <misc/options.h>
[77bb59]13#include <misc/mylimits.h>
14
[6cc7f5]15#ifdef HAVE_FACTORY
16#define SI_DONT_HAVE_GLOBAL_VARS
17#include <factory/factory.h>
18#endif
19
20#include <Singular/maps_ip.h>
[599326]21#include <Singular/tok.h>
[0fb34ba]22#include <misc/options.h>
[599326]23#include <Singular/ipid.h>
[0fb34ba]24#include <misc/intvec.h>
[b1dfaf]25#include <omalloc/omalloc.h>
[599326]26#include <kernel/febase.h>
[737a68]27#include <kernel/polys.h>
[6cc7f5]28#include <coeffs/numbers.h>
[0fb34ba]29#include <polys/prCopy.h>
[599326]30#include <kernel/ideals.h>
[0fb34ba]31#include <polys/matpol.h>
[599326]32#include <kernel/kstd1.h>
[0fb34ba]33#include <polys/monomials/ring.h>
[599326]34#include <Singular/subexpr.h>
[0fb34ba]35#include <polys/monomials/maps.h>
[599326]36#include <kernel/syz.h>
[0fb34ba]37#include <coeffs/numbers.h>
[599326]38#include <kernel/modulop.h>
[b787fb6]39//#include <polys/ext_fields/longalg.h>
[599326]40#include <Singular/lists.h>
41#include <Singular/attrib.h>
42#include <Singular/ipconv.h>
43#include <Singular/silink.h>
44#include <kernel/stairc.h>
[0fb34ba]45#include <polys/weight.h>
[599326]46#include <kernel/semic.h>
47#include <kernel/splist.h>
48#include <kernel/spectrum.h>
[77bb59]49////// #include <coeffs/gnumpfl.h>
[b5f5444]50//#include <kernel/mpr_base.h>
[77bb59]51////// #include <coeffs/ffields.h>
[47417b]52#include <polys/clapsing.h>
[599326]53#include <kernel/hutil.h>
[0fb34ba]54#include <polys/monomials/ring.h>
[599326]55#include <Singular/ipshell.h>
[6cc7f5]56#include <polys/ext_fields/algext.h>
57#include <coeffs/mpr_complex.h>
[f5bef2]58#include <coeffs/longrat.h>
[213d64]59
[6cc7f5]60#include <numeric/mpr_base.h>
61#include <numeric/mpr_numeric.h>
[0e1846]62
[77bb59]63#include <math.h>
[06aafe1]64#include <ctype.h>
[77bb59]65
[e7e815]66#include <polys/ext_fields/algext.h>
67#include <polys/ext_fields/transext.h>
68
[33293b6]69// define this if you want to use the fast_map routine for mapping ideals
[b9020c3]70#define FAST_MAP
[33293b6]71
72#ifdef FAST_MAP
[599326]73#include <kernel/fast_maps.h>
[33293b6]74#endif
75
[0e1846]76leftv iiCurrArgs=NULL;
[f71681]77idhdl iiCurrProc=NULL;
[85e68dd]78const char *lastreserved=NULL;
[0e1846]79
80static BOOLEAN iiNoKeepRing=TRUE;
81
82/*0 implementation*/
83
[85e68dd]84const char * iiTwoOps(int t)
[0e1846]85{
86  if (t<127)
87  {
88    static char ch[2];
89    switch (t)
90    {
91      case '&':
92        return "and";
93      case '|':
94        return "or";
95      default:
96        ch[0]=t;
97        ch[1]='\0';
98        return ch;
99    }
100  }
101  switch (t)
102  {
[057e93c]103    case COLONCOLON:  return "::";
[0e1846]104    case DOTDOT:      return "..";
105    //case PLUSEQUAL:   return "+=";
106    //case MINUSEQUAL:  return "-=";
107    case MINUSMINUS:  return "--";
108    case PLUSPLUS:    return "++";
109    case EQUAL_EQUAL: return "==";
110    case LE:          return "<=";
111    case GE:          return ">=";
112    case NOTEQUAL:    return "<>";
113    default:          return Tok2Cmdname(t);
114  }
115}
116
[7da3cd]117static void list1(const char* s, idhdl h,BOOLEAN c, BOOLEAN fullname)
[0e1846]118{
119  char buffer[22];
120  int l;
[daeb6d]121  char buf2[128];
[0e1846]122
[c62170]123  if(fullname) sprintf(buf2, "%s::%s", "", IDID(h));
124  else sprintf(buf2, "%s", IDID(h));
[daeb6d]125
126  Print("%s%-20.20s [%d]  ",s,buf2,IDLEV(h));
[0e1846]127  if (h == currRingHdl) PrintS("*");
128  PrintS(Tok2Cmdname((int)IDTYP(h)));
129
130  ipListFlag(h);
131  switch(IDTYP(h))
132  {
[c5f17b]133    case INT_CMD:   Print(" %d",IDINT(h)); break;
134    case INTVEC_CMD:Print(" (%d)",IDINTVEC(h)->length()); break;
135    case INTMAT_CMD:Print(" %d x %d",IDINTVEC(h)->rows(),IDINTVEC(h)->cols());
136                    break;
[0e1846]137    case POLY_CMD:
[c5f17b]138    case VECTOR_CMD:if (c)
139                    {
140                      PrintS(" ");wrp(IDPOLY(h));
141                      if(IDPOLY(h) != NULL)
142                      {
143                        Print(", %d monomial(s)",pLength(IDPOLY(h)));
144                      }
145                    }
146                    break;
[d3a49c]147    case MODUL_CMD: Print(", rk %d", (int)(IDIDEAL(h)->rank));
[c5f17b]148    case IDEAL_CMD: Print(", %u generator(s)",
[d3a49c]149                    IDELEMS(IDIDEAL(h))); break;
[0e1846]150    case MAP_CMD:
[c5f17b]151                    Print(" from %s",IDMAP(h)->preimage); break;
152    case MATRIX_CMD:Print(" %u x %u"
153                      ,MATROWS(IDMATRIX(h))
154                      ,MATCOLS(IDMATRIX(h))
155                    );
156                    break;
[daeb6d]157    case PACKAGE_CMD:
[0c6135]158                    PrintS(" (");
159                    switch (IDPACKAGE(h)->language)
160                    {
161                        case LANG_SINGULAR: PrintS("S"); break;
162                        case LANG_C:        PrintS("C"); break;
163                        case LANG_TOP:      PrintS("T"); break;
164                        case LANG_NONE:     PrintS("N"); break;
165                        default:            PrintS("U");
[daeb6d]166                    }
[0c6135]167                    if(IDPACKAGE(h)->libname!=NULL)
168                      Print(",%s", IDPACKAGE(h)->libname);
169                    PrintS(")");
[daeb6d]170                    break;
[fe9ee1]171    case PROC_CMD: if((IDPROC(h)->libname!=NULL)
172                   && (strlen(IDPROC(h)->libname)>0))
[c5f17b]173                     Print(" from %s",IDPROC(h)->libname);
174                   if(IDPROC(h)->is_static)
[0c6135]175                     PrintS(" (static)");
[33e521]176                   break;
[0e1846]177    case STRING_CMD:
178                   {
179                     char *s;
180                     l=strlen(IDSTRING(h));
181                     memset(buffer,0,22);
[f43a74]182                     strncpy(buffer,IDSTRING(h),si_min(l,20));
[0e1846]183                     if ((s=strchr(buffer,'\n'))!=NULL)
184                     {
185                       *s='\0';
186                     }
187                     PrintS(" ");
188                     PrintS(buffer);
189                     if((s!=NULL) ||(l>20))
190                     {
191                       Print("..., %d char(s)",l);
192                     }
193                     break;
194                   }
[c5f17b]195    case LIST_CMD: Print(", size: %d",IDLIST(h)->nr+1);
[0e1846]196                   break;
197    case QRING_CMD:
198    case RING_CMD:
[9bc0b8]199                   if ((IDRING(h)==currRing) && (currRingHdl!=h))
200                     PrintS("(*)"); /* this is an alias to currRing */
[0e1846]201#ifdef RDEBUG
[0c6135]202                   if (traceit &TRACE_SHOW_RINGS)
[d3a49c]203                     Print(" <%lx>",(long)(IDRING(h)));
[0e1846]204#endif
205                   break;
206    /*default:     break;*/
207  }
208  PrintLn();
209}
210
[103560]211void type_cmd(leftv v)
[0e1846]212{
[c5f4b9]213  BOOLEAN oldShortOut = FALSE;
[bd4cb92]214
[c5f4b9]215  if (currRing != NULL)
216  {
217    oldShortOut = currRing->ShortOut;
218    currRing->ShortOut = 1;
219  }
[103560]220  int t=v->Typ();
221  Print("// %s %s ",v->Name(),Tok2Cmdname(t));
222  switch (t)
[0e1846]223  {
[103560]224    case MAP_CMD:Print(" from %s\n",((map)(v->Data()))->preimage); break;
225    case INTMAT_CMD: Print(" %d x %d\n",((intvec*)(v->Data()))->rows(),
226                                      ((intvec*)(v->Data()))->cols()); break;
227    case MATRIX_CMD:Print(" %u x %u\n" ,
228       MATROWS((matrix)(v->Data())),
229       MATCOLS((matrix)(v->Data())));break;
230    case MODUL_CMD: Print(", rk %d\n", (int)(((ideal)(v->Data()))->rank));break;
231    case LIST_CMD: Print(", size %d\n",((lists)(v->Data()))->nr+1); break;
232
233    case PROC_CMD:
234    case RING_CMD:
235    case IDEAL_CMD:
236    case QRING_CMD: PrintLn(); break;
237
238    //case INT_CMD:
239    //case STRING_CMD:
240    //case INTVEC_CMD:
241    //case POLY_CMD:
242    //case VECTOR_CMD:
243    //case PACKAGE_CMD:
244
245    default:
246      break;
[0e1846]247  }
[103560]248  v->Print();
[c5f4b9]249  if (currRing != NULL)
250    currRing->ShortOut = oldShortOut;
[0e1846]251}
252
[860475]253static void killlocals0(int v, idhdl * localhdl, const ring r)
[0e1846]254{
255  idhdl h = *localhdl;
256  while (h!=NULL)
257  {
258    int vv;
[fca547]259    //Print("consider %s, lev: %d:",IDID(h),IDLEV(h));
[0e1846]260    if ((vv=IDLEV(h))>0)
261    {
262      if (vv < v)
263      {
[c5f17b]264        if (iiNoKeepRing)
265        {
[fca547]266          //PrintS(" break\n");
[c5f17b]267          return;
268        }
[0e1846]269        h = IDNEXT(h);
[fca547]270        //PrintLn();
[0e1846]271      }
[b99381]272      else //if (vv >= v)
[0e1846]273      {
274        idhdl nexth = IDNEXT(h);
[860475]275        killhdl2(h,localhdl,r);
[0e1846]276        h = nexth;
[fca547]277        //PrintS("kill\n");
[0e1846]278      }
279    }
280    else
[fca547]281    {
[0e1846]282      h = IDNEXT(h);
[fca547]283      //PrintLn();
284    }
[0e1846]285  }
286}
[57f94a]287void killlocals_list(lists l,int v)
288{
289  int i;
290  for(i=l->nr; i>=0; i--)
291  {
292    if (l->m[i].rtyp == LIST_CMD)
293      killlocals_list((lists)l->m[i].data,v);
294    else if ((l->m[i].rtyp == RING_CMD) || (l->m[i].rtyp == QRING_CMD))
295      killlocals0(v,&(((ring)(l->m[i].data))->idroot),currRing);
296  }
297}
[16acb0]298void killlocals_rec(idhdl *root,int v, ring r)
[3b1a83c]299{
300  idhdl h=*root;
301  while (h!=NULL)
302  {
303    if (IDLEV(h)>=v)
304    {
305//      Print("kill %s, lev %d for lev %d\n",IDID(h),IDLEV(h),v);
306      idhdl n=IDNEXT(h);
[16acb0]307      killhdl2(h,root,r);
[3b1a83c]308      h=n;
309    }
310    else if (IDTYP(h)==PACKAGE_CMD)
311    {
312 //     Print("into pack %s, lev %d for lev %d\n",IDID(h),IDLEV(h),v);
313      if (IDPACKAGE(h)!=basePack)
[16acb0]314        killlocals_rec(&(IDRING(h)->idroot),v,r);
[3b1a83c]315      h=IDNEXT(h);
316    }
317    else if ((IDTYP(h)==RING_CMD)
318    ||(IDTYP(h)==QRING_CMD))
319    {
[e2efbe9]320      if ((IDRING(h)!=NULL) && (IDRING(h)->idroot!=NULL))
321      // we have to test IDRING(h)!=NULL: qring Q=groebner(...): killlocals
[3b1a83c]322      {
323  //    Print("into ring %s, lev %d for lev %d\n",IDID(h),IDLEV(h),v);
[16acb0]324        killlocals_rec(&(IDRING(h)->idroot),v,IDRING(h));
[3b1a83c]325      }
326      h=IDNEXT(h);
327    }
328    else
329    {
330//      Print("skip %s lev %d for lev %d\n",IDID(h),IDLEV(h),v);
331      h=IDNEXT(h);
332    }
333  }
334}
[0f28d9]335BOOLEAN killlocals_list(int v, lists L)
336{
337  if (L==NULL) return FALSE;
338  BOOLEAN changed=FALSE;
339  int n=L->nr;
340  for(;n>=0;n--)
341  {
342    leftv h=&(L->m[n]);
343    void *d=h->data;
344    if (((h->rtyp==RING_CMD) || (h->rtyp==QRING_CMD))
345    && (((ring)d)->idroot!=NULL))
346    {
347      if (d!=currRing) {changed=TRUE;rChangeCurrRing((ring)d);}
[860475]348      killlocals0(v,&(((ring)h->data)->idroot),(ring)h->data);
[0f28d9]349    }
350    else if (h->rtyp==LIST_CMD)
351      changed|=killlocals_list(v,(lists)d);
352  }
353  return changed;
354}
[3b1a83c]355void killlocals(int v)
356{
357  BOOLEAN changed=FALSE;
358  idhdl sh=currRingHdl;
[0f28d9]359  ring cr=currRing;
[6f3743]360  if (sh!=NULL) changed=((IDLEV(sh)<v) || (IDRING(sh)->ref>0));
361  //if (changed) Print("currRing=%s(%x), lev=%d,ref=%d\n",IDID(sh),IDRING(sh),IDLEV(sh),IDRING(sh)->ref);
[3b1a83c]362
[16acb0]363  killlocals_rec(&(basePack->idroot),v,currRing);
[3b1a83c]364
[0f28d9]365  if (iiRETURNEXPR_len > myynest)
[3b1a83c]366  {
[0f28d9]367    int t=iiRETURNEXPR[myynest].Typ();
368    if ((/*iiRETURNEXPR[myynest].Typ()*/ t==RING_CMD)
369    || (/*iiRETURNEXPR[myynest].Typ()*/ t==QRING_CMD))
370    {
371      leftv h=&iiRETURNEXPR[myynest];
372      if (((ring)h->data)->idroot!=NULL)
[860475]373        killlocals0(v,&(((ring)h->data)->idroot),(ring)h->data);
[0f28d9]374    }
375    else if (/*iiRETURNEXPR[myynest].Typ()*/ t==LIST_CMD)
376    {
377      leftv h=&iiRETURNEXPR[myynest];
378      changed |=killlocals_list(v,(lists)h->data);
379    }
[3b1a83c]380  }
381  if (changed)
382  {
[0f28d9]383    currRingHdl=rFindHdl(cr,NULL,NULL);
[7035b2]384    if (currRingHdl==NULL)
[23f2f57]385      currRing=NULL;
386    else
387      rChangeCurrRing(cr);
[3b1a83c]388  }
389
390  if (myynest<=1) iiNoKeepRing=TRUE;
391  //Print("end killlocals  >= %d\n",v);
392  //listall();
393}
[0e1846]394
[7da3cd]395void list_cmd(int typ, const char* what, const char *prefix,BOOLEAN iterate, BOOLEAN fullname)
[0e1846]396{
397  idhdl h,start;
[c62170]398  BOOLEAN all = typ<0;
[0e1846]399  BOOLEAN really_all=FALSE;
[daeb6d]400  BOOLEAN do_packages=FALSE;
[0c6135]401
[c62170]402  if ( typ == -1 ) do_packages=TRUE;
[0e1846]403  if ( typ==0 )
404  {
405    if (strcmp(what,"all")==0)
406    {
407      really_all=TRUE;
[bd4cb92]408      h=basePack->idroot;
[0e1846]409    }
410    else
411    {
412      h = ggetid(what);
413      if (h!=NULL)
414      {
[daeb6d]415        if (iterate) list1(prefix,h,TRUE,fullname);
[7cbe8e]416        if (IDTYP(h)==ALIAS_CMD) PrintS("A");
[c5f17b]417        if ((IDTYP(h)==RING_CMD)
[bd4cb92]418            || (IDTYP(h)==QRING_CMD)
419            //|| (IDTYP(h)==PACKE_CMD)
420        )
[c5f17b]421        {
422          h=IDRING(h)->idroot;
423        }
[46d09b]424        else if((IDTYP(h)==PACKAGE_CMD) || (IDTYP(h)==POINTER_CMD))
425        {
[2ef280]426          //Print("list_cmd:package or pointer\n");
[d66a7d]427          all=TRUE;typ=PROC_CMD;fullname=TRUE;really_all=TRUE;
[bd4cb92]428          h=IDPACKAGE(h)->idroot;
[46d09b]429        }
[c5f17b]430        else
431          return;
[0e1846]432      }
433      else
434      {
435        Werror("%s is undefined",what);
436        return;
437      }
438    }
439    all=TRUE;
440  }
[df5fc1]441  else if (RingDependend(typ))
[0e1846]442  {
443    h = currRing->idroot;
444  }
445  else
[46d09b]446    h = IDROOT;
[0e1846]447  start=h;
448  while (h!=NULL)
449  {
[f2dff02]450    if ((all && (IDTYP(h)!=PROC_CMD) &&(IDTYP(h)!=PACKAGE_CMD))
451    || (typ == IDTYP(h))
[0e1846]452    || ((IDTYP(h)==QRING_CMD) && (typ==RING_CMD)))
453    {
[daeb6d]454      list1(prefix,h,start==currRingHdl, fullname);
[46d09b]455      if (((IDTYP(h)==RING_CMD)||(IDTYP(h)==QRING_CMD))
[0e1846]456        && (really_all || (all && (h==currRingHdl)))
457        && ((IDLEV(h)==0)||(IDLEV(h)==myynest)))
458      {
459        list_cmd(0,IDID(h),"//      ",FALSE);
460      }
[bd4cb92]461      if (IDTYP(h)==PACKAGE_CMD && really_all)
462      {
[925a4b9]463        package save_p=currPack;
464        currPack=IDPACKAGE(h);
[bd4cb92]465        list_cmd(0,IDID(h),"//      ",FALSE);
[925a4b9]466        currPack=save_p;
[bd4cb92]467      }
[0e1846]468    }
469    h = IDNEXT(h);
470  }
471}
472
473void test_cmd(int i)
474{
[7cdf2b1]475  int ii;
[0e1846]476
[7cdf2b1]477  if (i<0)
[0e1846]478  {
[7cdf2b1]479    ii= -i;
480    if (ii < 32)
[0e1846]481    {
[7cdf2b1]482      test &= ~Sy_bit(ii);
[0e1846]483    }
[7cdf2b1]484    else if (ii < 64)
[0e1846]485    {
[7cdf2b1]486      verbose &= ~Sy_bit(ii-32);
[0e1846]487    }
[7cdf2b1]488    else
489      WerrorS("out of bounds\n");
[0e1846]490  }
[7cdf2b1]491  else if (i<32)
492  {
493    ii=i;
494    if (Sy_bit(ii) & kOptions)
495    {
496      Warn("Gerhard, use the option command");
497      test |= Sy_bit(ii);
498    }
499    else if (Sy_bit(ii) & validOpts)
500      test |= Sy_bit(ii);
501  }
502  else if (i<64)
503  {
504    ii=i-32;
505    verbose |= Sy_bit(ii);
506  }
507  else
508    WerrorS("out of bounds\n");
[0e1846]509}
510
511int exprlist_length(leftv v)
512{
513  int rc = 0;
514  while (v!=NULL)
515  {
516    switch (v->Typ())
517    {
518      case INT_CMD:
519      case POLY_CMD:
520      case VECTOR_CMD:
521      case NUMBER_CMD:
522        rc++;
523        break;
524      case INTVEC_CMD:
525      case INTMAT_CMD:
526        rc += ((intvec *)(v->Data()))->length();
527        break;
528      case MATRIX_CMD:
529      case IDEAL_CMD:
530      case MODUL_CMD:
531        {
532          matrix mm = (matrix)(v->Data());
533          rc += mm->rows() * mm->cols();
534        }
535        break;
536      case LIST_CMD:
537        rc+=((lists)v->Data())->nr+1;
538        break;
539      default:
540        rc++;
541    }
542    v = v->next;
543  }
544  return rc;
545}
546
[f30fdc]547int iiIsPrime0(unsigned p)  /* brute force !!!! */
[0e1846]548{
[282c8d]549  unsigned i,j=0 /*only to avoid compiler warnings*/;
[2eeb7d]550#ifdef HAVE_FACTORY
[f30fdc]551  if (p<=32749) // max. small prime in factory
[2eeb7d]552  {
[cd22d1a]553    int a=0;
554    int e=cf_getNumSmallPrimes()-1;
555    i=e/2;
556    do
557    {
[282c8d]558      j=cf_getSmallPrime(i);
559      if (p==j) return p;
[cd22d1a]560      if (p<j) e=i-1;
561      else     a=i+1;
562      i=a+(e-a)/2;
563    } while ( a<= e);
564    if (p>j) return j;
565    else     return cf_getSmallPrime(i-1);
566  }
567#endif
568#ifdef HAVE_FACTORY
[f30fdc]569  unsigned end_i=cf_getNumSmallPrimes()-1;
[26ac996]570#else
[f30fdc]571  unsigned end_i=p/2;
[7035b2]572#endif
[f30fdc]573  unsigned end_p=(unsigned)sqrt((double)p);
[cd22d1a]574restart:
575  for (i=0; i<end_i; i++)
[0e1846]576  {
[cd22d1a]577#ifdef HAVE_FACTORY
578    j=cf_getSmallPrime(i);
579#else
580    if (i==0) j=2;
581    else j=2*i-1;
[7035b2]582#endif
[cd22d1a]583    if ((p%j) == 0)
584    {
585    #ifdef HAVE_FACTORY
[f30fdc]586      if (p<=32751) return iiIsPrime0(p-2);
[7035b2]587    #endif
[cd22d1a]588      p-=2;
589      goto restart;
590    }
591    if (j > end_p) return p;
[0e1846]592  }
[96f9be8]593#ifdef HAVE_FACTORY
594  if (i>=end_i)
595  {
596    while(j<=end_p)
597    {
598      j+=2;
599      if ((p%j) == 0)
600      {
601        if (p<=32751) return iiIsPrime0(p-2);
602        p-=2;
603        goto restart;
604      }
605    }
606  }
607#endif
[0e1846]608  return p;
609}
[f30fdc]610int IsPrime(int p)  /* brute force !!!! */
611{
612  if      (p == 0)    return 0;
613  else if (p == 1)    return 1/*1*/;
614  else if ((p == 2)||(p==3))    return p;
[6bcda60]615  else if (p < 0)     return 2; //(iiIsPrime0((unsigned)(-p)));
[f30fdc]616  else if ((p & 1)==0) return iiIsPrime0((unsigned)(p-1));
617  return iiIsPrime0((unsigned)(p));
618}
[0e1846]619
[69672d]620BOOLEAN iiWRITE(leftv,leftv v)
[0e1846]621{
622  sleftv vf;
623  if (iiConvert(v->Typ(),LINK_CMD,iiTestConvert(v->Typ(),LINK_CMD),v,&vf))
624  {
[da97958]625    WerrorS("link expected");
[0e1846]626    return TRUE;
627  }
628  si_link l=(si_link)vf.Data();
[d754b7]629  if (vf.next == NULL)
630  {
[da97958]631    WerrorS("write: need at least two arguments");
[d754b7]632    return TRUE;
633  }
634
[0e1846]635  BOOLEAN b=slWrite(l,vf.next); /* iiConvert preserves next */
636  if (b)
637  {
638    const char *s;
639    if ((l!=NULL)&&(l->name!=NULL)) s=l->name;
640    else                            s=sNoName;
641    Werror("cannot write to %s",s);
642  }
643  vf.CleanUp();
644  return b;
645}
646
[85e68dd]647leftv iiMap(map theMap, const char * what)
[0e1846]648{
649  idhdl w,r;
650  leftv v;
651  int i;
[4508ce5]652  nMapFunc nMap;
[0e1846]653
[bd4cb92]654  r=IDROOT->get(theMap->preimage,myynest);
[a3bc95e]655  if ((currPack!=basePack)
656  &&((r==NULL) || ((r->typ != RING_CMD) && (r->typ != QRING_CMD))))
657    r=basePack->idroot->get(theMap->preimage,myynest);
[fba8c99]658  if ((r==NULL) && (currRingHdl!=NULL)
659  && (strcmp(theMap->preimage,IDID(currRingHdl))==0))
660  {
661    r=currRingHdl;
662  }
[0e1846]663  if ((r!=NULL) && ((r->typ == RING_CMD) || (r->typ== QRING_CMD)))
664  {
[4508ce5]665    //if ((nMap=nSetMap(rInternalChar(IDRING(r)),
[d4373f]666    //             IDRING(r)->parameter,
667    //             rPar(IDRING(r)),
[4508ce5]668    //             IDRING(r)->minpoly)))
[77bb59]669    if ((nMap=n_SetMap(IDRING(r)->cf, currRing->cf))==NULL)
[0e1846]670    {
[77bb59]671////////// WTF?
672//      if (rEqual(IDRING(r),currRing))
673//      {
674//        nMap = n_SetMap(currRing->cf, currRing->cf);
675//      }
676//      else
677//      {
[f13dc47]678        Werror("can not map from ground field of %s to current ground field",
679          theMap->preimage);
680        return NULL;
[77bb59]681//      }
[0e1846]682    }
683    if (IDELEMS(theMap)<IDRING(r)->N)
684    {
[c232af]685      theMap->m=(polyset)omReallocSize((ADDRESS)theMap->m,
[c5f17b]686                                 IDELEMS(theMap)*sizeof(poly),
687                                 (IDRING(r)->N)*sizeof(poly));
[0e1846]688      for(i=IDELEMS(theMap);i<IDRING(r)->N;i++)
689        theMap->m[i]=NULL;
690      IDELEMS(theMap)=IDRING(r)->N;
691    }
692    if (what==NULL)
693    {
[da97958]694      WerrorS("argument of a map must have a name");
[0e1846]695    }
696    else if ((w=IDRING(r)->idroot->get(what,myynest))!=NULL)
697    {
[5d466e]698      char *save_r=NULL;
[c232af]699      v=(leftv)omAlloc0Bin(sleftv_bin);
[0e1846]700      sleftv tmpW;
701      memset(&tmpW,0,sizeof(sleftv));
702      tmpW.rtyp=IDTYP(w);
[392682]703      if (tmpW.rtyp==MAP_CMD)
704      {
[5d466e]705        tmpW.rtyp=IDEAL_CMD;
706        save_r=IDMAP(w)->preimage;
707        IDMAP(w)->preimage=0;
708      }
[0e1846]709      tmpW.data=IDDATA(w);
[f5bef2]710#if 0
[0ea97e]711      if (((tmpW.rtyp==IDEAL_CMD)||(tmpW.rtyp==MODUL_CMD)) && idIs0(IDIDEAL(w)))
[33293b6]712      {
[0ea97e]713        v->rtyp=tmpW.rtyp;
714        v->data=idInit(IDELEMS(IDIDEAL(w)),IDIDEAL(w)->rank);
[33293b6]715      }
716      else
[f5bef2]717#endif
[0e1846]718      {
[f5bef2]719#ifdef FAST_MAP
720        if ((tmpW.rtyp==IDEAL_CMD) && (nMap == ndCopyMap)
721#ifdef HAVE_PLURAL
[0ea97e]722        && (!rIsPluralRing(currRing))
[f5bef2]723#endif
[0ea97e]724        )
725        {
726          v->rtyp=IDEAL_CMD;
727          v->data=fast_map(IDIDEAL(w), IDRING(r), (ideal)theMap, currRing);
728        }
729        else
[f5bef2]730#endif
[0ea97e]731        if (maApplyFetch(MAP_CMD,theMap,v,&tmpW,IDRING(r),NULL,NULL,0,nMap))
732        {
733          Werror("cannot map %s(%d)",Tok2Cmdname(w->typ),w->typ);
734          omFreeBin((ADDRESS)v, sleftv_bin);
735          if (save_r!=NULL) IDMAP(w)->preimage=save_r;
736          return NULL;
737        }
[0e1846]738      }
[5d466e]739      if (save_r!=NULL)
[392682]740      {
[5d466e]741        IDMAP(w)->preimage=save_r;
742        IDMAP((idhdl)v)->preimage=omStrDup(save_r);
743        v->rtyp=MAP_CMD;
744      }
[0e1846]745      return v;
746    }
747    else
[c5f17b]748    {
[0e1846]749      Werror("%s undefined in %s",what,theMap->preimage);
[c5f17b]750    }
[0e1846]751  }
752  else
[c5f17b]753  {
[0e1846]754    Werror("cannot find preimage %s",theMap->preimage);
[c5f17b]755  }
[0e1846]756  return NULL;
757}
758
759#ifdef OLD_RES
760void  iiMakeResolv(resolvente r, int length, int rlen, char * name, int typ0,
761                   intvec ** weights)
762{
763  lists L=liMakeResolv(r,length,rlen,typ0,weights);
764  int i=0;
765  idhdl h;
[c232af]766  char * s=(char *)omAlloc(strlen(name)+5);
[0e1846]767
768  while (i<=L->nr)
769  {
770    sprintf(s,"%s(%d)",name,i+1);
771    if (i==0)
[3b1a83c]772      h=enterid(s,myynest,typ0,&(currRing->idroot), FALSE);
[0e1846]773    else
[3b1a83c]774      h=enterid(s,myynest,MODUL_CMD,&(currRing->idroot), FALSE);
[0e1846]775    if (h!=NULL)
776    {
777      h->data.uideal=(ideal)L->m[i].data;
778      h->attribute=L->m[i].attribute;
779      if (BVERBOSE(V_DEF_RES))
780        Print("//defining: %s as %d-th syzygy module\n",s,i+1);
781    }
782    else
783    {
784      idDelete((ideal *)&(L->m[i].data));
785      Warn("cannot define %s",s);
786    }
787    //L->m[i].data=NULL;
788    //L->m[i].rtyp=0;
789    //L->m[i].attribute=NULL;
790    i++;
791  }
[c232af]792  omFreeSize((ADDRESS)L->m,(L->nr+1)*sizeof(sleftv));
793  omFreeBin((ADDRESS)L, slists_bin);
794  omFreeSize((ADDRESS)s,strlen(name)+5);
[0e1846]795}
796#endif
797
798//resolvente iiFindRes(char * name, int * len, int *typ0)
799//{
[c232af]800//  char *s=(char *)omAlloc(strlen(name)+5);
[0e1846]801//  int i=-1;
802//  resolvente r;
803//  idhdl h;
804//
805//  do
806//  {
807//    i++;
808//    sprintf(s,"%s(%d)",name,i+1);
809//    h=currRing->idroot->get(s,myynest);
810//  } while (h!=NULL);
811//  *len=i-1;
812//  if (*len<=0)
813//  {
814//    Werror("no objects %s(1),.. found",name);
[c232af]815//    omFreeSize((ADDRESS)s,strlen(name)+5);
[0e1846]816//    return NULL;
817//  }
[c232af]818//  r=(ideal *)omAlloc(/*(len+1)*/ i*sizeof(ideal));
[0e1846]819//  memset(r,0,(*len)*sizeof(ideal));
820//  i=-1;
821//  *typ0=MODUL_CMD;
822//  while (i<(*len))
823//  {
824//    i++;
825//    sprintf(s,"%s(%d)",name,i+1);
826//    h=currRing->idroot->get(s,myynest);
827//    if (h->typ != MODUL_CMD)
828//    {
829//      if ((i!=0) || (h->typ!=IDEAL_CMD))
830//      {
831//        Werror("%s is not of type module",s);
[c232af]832//        omFreeSize((ADDRESS)r,(*len)*sizeof(ideal));
833//        omFreeSize((ADDRESS)s,strlen(name)+5);
[0e1846]834//        return NULL;
835//      }
836//      *typ0=IDEAL_CMD;
837//    }
838//    if ((i>0) && (idIs0(r[i-1])))
839//    {
840//      *len=i-1;
841//      break;
842//    }
843//    r[i]=IDIDEAL(h);
844//  }
[c232af]845//  omFreeSize((ADDRESS)s,strlen(name)+5);
[0e1846]846//  return r;
847//}
848
[4145db]849static resolvente iiCopyRes(resolvente r, int l)
[0e1846]850{
851  int i;
[c232af]852  resolvente res=(ideal *)omAlloc0((l+1)*sizeof(ideal));
[0e1846]853
854  for (i=0; i<l; i++)
855    res[i]=idCopy(r[i]);
856  return res;
857}
858
859BOOLEAN jjMINRES(leftv res, leftv v)
860{
861  int len=0;
862  int typ0;
[f43a74]863  lists L=(lists)v->Data();
864  intvec *weights=(intvec*)atGet(v,"isHomog",INTVEC_CMD);
865  int add_row_shift = 0;
866  if (weights==NULL)
[7035b2]867    weights=(intvec*)atGet(&(L->m[0]),"isHomog",INTVEC_CMD);
[f43a74]868  if (weights!=NULL)  add_row_shift=weights->min_in();
869  resolvente rr=liFindRes(L,&len,&typ0);
[0e1846]870  if (rr==NULL) return TRUE;
871  resolvente r=iiCopyRes(rr,len);
872
873  syMinimizeResolvente(r,len,0);
[c232af]874  omFreeSize((ADDRESS)rr,len*sizeof(ideal));
[0e1846]875  len++;
[f43a74]876  res->data=(char *)liMakeResolv(r,len,-1,typ0,NULL,add_row_shift);
[0e1846]877  return FALSE;
878}
879
[7f14f2]880BOOLEAN jjBETTI(leftv res, leftv u)
881{
882  sleftv tmp;
883  memset(&tmp,0,sizeof(tmp));
884  tmp.rtyp=INT_CMD;
[7035b2]885  tmp.data=(void *)1;
[709ab0]886  if ((u->Typ()==IDEAL_CMD)
887  || (u->Typ()==MODUL_CMD))
888    return jjBETTI2_ID(res,u,&tmp);
889  else
890    return jjBETTI2(res,u,&tmp);
891}
892
893BOOLEAN jjBETTI2_ID(leftv res, leftv u, leftv v)
894{
895  lists l=(lists) omAllocBin(slists_bin);
896  l->Init(1);
897  l->m[0].rtyp=u->Typ();
898  l->m[0].data=u->Data();
[c227a2f]899  attr *a=u->Attribute();
900  if (a!=NULL)
901  l->m[0].attribute=*a;
[709ab0]902  sleftv tmp2;
903  memset(&tmp2,0,sizeof(tmp2));
904  tmp2.rtyp=LIST_CMD;
905  tmp2.data=(void *)l;
906  BOOLEAN r=jjBETTI2(res,&tmp2,v);
907  l->m[0].data=NULL;
908  l->m[0].attribute=NULL;
909  l->m[0].rtyp=DEF_CMD;
910  l->Clean();
911  return r;
[7f14f2]912}
913
914BOOLEAN jjBETTI2(leftv res, leftv u, leftv v)
[0e1846]915{
916  resolvente r;
917  int len;
918  int reg,typ0;
[7f14f2]919  lists l=(lists)u->Data();
920
[709ab0]921  intvec *weights=NULL;
922  int add_row_shift=0;
[7035b2]923  intvec *ww=(intvec *)atGet(&(l->m[0]),"isHomog",INTVEC_CMD);
[709ab0]924  if (ww!=NULL)
925  {
926     weights=ivCopy(ww);
927     add_row_shift = ww->min_in();
928     (*weights) -= add_row_shift;
929  }
[7f14f2]930  //Print("attr:%x\n",weights);
[0e1846]931
[7f14f2]932  r=liFindRes(l,&len,&typ0);
[0e1846]933  if (r==NULL) return TRUE;
[7447d8]934  res->data=(char *)syBetti(r,len,&reg,weights,(int)(long)v->Data());
[c232af]935  omFreeSize((ADDRESS)r,(len)*sizeof(ideal));
[327eae8]936  atSet(res,omStrDup("rowShift"),(void*)add_row_shift,INT_CMD);
[709ab0]937  if (weights!=NULL) delete weights;
[0e1846]938  return FALSE;
939}
940
941int iiRegularity(lists L)
942{
943  int len,reg,typ0;
944
[26ac996]945  resolvente r=liFindRes(L,&len,&typ0);
946
947  if (r==NULL)
948    return -2;
[178d03]949  intvec *weights=NULL;
950  int add_row_shift=0;
951  intvec *ww=(intvec *)atGet(&(L->m[0]),"isHomog",INTVEC_CMD);
952  if (ww!=NULL)
953  {
954     weights=ivCopy(ww);
955     add_row_shift = ww->min_in();
956     (*weights) -= add_row_shift;
957  }
958  //Print("attr:%x\n",weights);
959
960  intvec *dummy=syBetti(r,len,&reg,weights);
961  if (weights!=NULL) delete weights;
[0e1846]962  delete dummy;
[178d03]963  omFreeSize((ADDRESS)r,len*sizeof(ideal));
964  return reg+1+add_row_shift;
[0e1846]965}
966
967BOOLEAN iiDebugMarker=TRUE;
[b1dd2f]968#define BREAK_LINE_LENGTH 80
[0e1846]969void iiDebug()
970{
971  Print("\n-- break point in %s --\n",VoiceName());
[057e93c]972  if (iiDebugMarker) VoiceBackTrack();
[0e1846]973  char * s;
974  iiDebugMarker=FALSE;
[c232af]975  s = (char *)omAlloc(BREAK_LINE_LENGTH+4);
[b1dd2f]976  loop
977  {
978    memset(s,0,80);
979    fe_fgets_stdin("",s,BREAK_LINE_LENGTH);
980    if (s[BREAK_LINE_LENGTH-1]!='\0')
981    {
982      Print("line too long, max is %d chars\n",BREAK_LINE_LENGTH);
983    }
984    else
985      break;
986  }
[0e1846]987  if (*s=='\n')
988  {
989    iiDebugMarker=TRUE;
990  }
[9ccebb]991#if MDEBUG
992  else if(strncmp(s,"cont;",5)==0)
993  {
994    iiDebugMarker=TRUE;
995  }
996#endif /* MDEBUG */
[0e1846]997  else
998  {
999    strcat( s, "\n;~\n");
1000    newBuffer(s,BT_execute);
1001  }
1002}
1003
[938688]1004lists scIndIndset(ideal S, BOOLEAN all, ideal Q)
1005{
1006  int i;
1007  indset save;
1008  lists res=(lists)omAlloc0Bin(slists_bin);
1009
1010  hexist = hInit(S, Q, &hNexist);
[883eacf]1011  if (hNexist == 0)
1012  {
[7fccc79]1013    intvec *iv=new intvec(rVar(currRing));
1014    for(i=0; i<rVar(currRing); i++) (*iv)[i]=1;
[883eacf]1015    res->Init(1);
1016    res->m[0].rtyp=INTVEC_CMD;
1017    res->m[0].data=(intvec*)iv;
1018    return res;
1019  }
1020  else if (hisModule!=0)
[938688]1021  {
1022    res->Init(0);
1023    return res;
1024  }
1025  save = ISet = (indset)omAlloc0Bin(indlist_bin);
1026  hMu = 0;
1027  hwork = (scfmon)omAlloc(hNexist * sizeof(scmon));
[7fccc79]1028  hvar = (varset)omAlloc((rVar(currRing) + 1) * sizeof(int));
1029  hpure = (scmon)omAlloc((1 + (rVar(currRing) * rVar(currRing))) * sizeof(long));
[938688]1030  hrad = hexist;
1031  hNrad = hNexist;
[7fccc79]1032  radmem = hCreate(rVar(currRing) - 1);
1033  hCo = rVar(currRing) + 1;
1034  hNvar = rVar(currRing);
[938688]1035  hRadical(hrad, &hNrad, hNvar);
1036  hSupp(hrad, hNrad, hvar, &hNvar);
1037  if (hNvar)
1038  {
1039    hCo = hNvar;
[7fccc79]1040    memset(hpure, 0, (rVar(currRing) + 1) * sizeof(long));
[938688]1041    hPure(hrad, 0, &hNrad, hvar, hNvar, hpure, &hNpure);
1042    hLexR(hrad, hNrad, hvar, hNvar);
1043    hDimSolve(hpure, hNpure, hrad, hNrad, hvar, hNvar);
1044  }
[7fccc79]1045  if (hCo && (hCo < rVar(currRing)))
[938688]1046  {
1047    hIndMult(hpure, hNpure, hrad, hNrad, hvar, hNvar);
1048  }
1049  if (hMu!=0)
1050  {
1051    ISet = save;
1052    hMu2 = 0;
[7fccc79]1053    if (all && (hCo+1 < rVar(currRing)))
[938688]1054    {
1055      JSet = (indset)omAlloc0Bin(indlist_bin);
1056      hIndAllMult(hpure, hNpure, hrad, hNrad, hvar, hNvar);
1057      i=hMu+hMu2;
1058      res->Init(i);
1059      if (hMu2 == 0)
1060      {
1061        omFreeBin((ADDRESS)JSet, indlist_bin);
1062      }
1063    }
1064    else
1065    {
1066      res->Init(hMu);
1067    }
1068    for (i=0;i<hMu;i++)
1069    {
1070      res->m[i].data = (void *)save->set;
1071      res->m[i].rtyp = INTVEC_CMD;
1072      ISet = save;
1073      save = save->nx;
1074      omFreeBin((ADDRESS)ISet, indlist_bin);
1075    }
1076    omFreeBin((ADDRESS)save, indlist_bin);
1077    if (hMu2 != 0)
1078    {
1079      save = JSet;
1080      for (i=hMu;i<hMu+hMu2;i++)
1081      {
1082        res->m[i].data = (void *)save->set;
1083        res->m[i].rtyp = INTVEC_CMD;
1084        JSet = save;
1085        save = save->nx;
1086        omFreeBin((ADDRESS)JSet, indlist_bin);
1087      }
1088      omFreeBin((ADDRESS)save, indlist_bin);
1089    }
1090  }
1091  else
1092  {
1093    res->Init(0);
1094    omFreeBin((ADDRESS)ISet,  indlist_bin);
1095  }
[7fccc79]1096  hKill(radmem, rVar(currRing) - 1);
1097  omFreeSize((ADDRESS)hpure, (1 + (rVar(currRing) * rVar(currRing))) * sizeof(long));
1098  omFreeSize((ADDRESS)hvar, (rVar(currRing) + 1) * sizeof(int));
[938688]1099  omFreeSize((ADDRESS)hwork, hNexist * sizeof(scmon));
1100  hDelete(hexist, hNexist);
1101  return res;
1102}
1103
[0a3ddd]1104int iiDeclCommand(leftv sy, leftv name, int lev,int t, idhdl* root,BOOLEAN isring, BOOLEAN init_b)
[0e1846]1105{
1106  BOOLEAN res=FALSE;
[85e68dd]1107  const char *id = name->name;
[0c6135]1108
[0e1846]1109  memset(sy,0,sizeof(sleftv));
1110  if ((name->name==NULL)||(isdigit(name->name[0])))
1111  {
[da97958]1112    WerrorS("object to declare is not a name");
[0e1846]1113    res=TRUE;
1114  }
1115  else
1116  {
[4b5c87]1117    //if (name->rtyp!=0)
1118    //{
1119    //  Warn("`%s` is already in use",name->name);
1120    //}
[0a3ddd]1121    {
1122      sy->data = (char *)enterid(id,lev,t,root,init_b);
1123    }
[0e1846]1124    if (sy->data!=NULL)
1125    {
1126      sy->rtyp=IDHDL;
1127      currid=sy->name=IDID((idhdl)sy->data);
[3b1a83c]1128      // name->name=NULL; /* used in enterid */
[0e1846]1129      //sy->e = NULL;
1130      if (name->next!=NULL)
1131      {
[c232af]1132        sy->next=(leftv)omAllocBin(sleftv_bin);
[0a3ddd]1133        res=iiDeclCommand(sy->next,name->next,lev,t,root, isring);
[0e1846]1134      }
1135    }
1136    else res=TRUE;
1137  }
1138  name->CleanUp();
1139  return res;
1140}
1141
[f71681]1142BOOLEAN iiDefaultParameter(leftv p)
1143{
1144  attr at=NULL;
1145  if (iiCurrProc!=NULL)
1146     at=iiCurrProc->attribute->get("default_arg");
1147  if (at==NULL)
1148    return FALSE;
1149  sleftv tmp;
1150  memset(&tmp,0,sizeof(sleftv));
1151  tmp.rtyp=at->atyp;
1152  tmp.data=at->CopyA();
1153  return iiAssign(p,&tmp);
1154}
[0e1846]1155BOOLEAN iiParameter(leftv p)
1156{
1157  if (iiCurrArgs==NULL)
1158  {
[f71681]1159    if (strcmp(p->name,"#")==0)
1160      return iiDefaultParameter(p);
[0e1846]1161    Werror("not enough arguments for proc %s",VoiceName());
1162    p->CleanUp();
1163    return TRUE;
1164  }
1165  leftv h=iiCurrArgs;
1166  if (strcmp(p->name,"#")==0)
1167  {
1168    iiCurrArgs=NULL;
1169  }
1170  else
1171  {
1172    iiCurrArgs=h->next;
1173    h->next=NULL;
1174  }
1175  BOOLEAN res=iiAssign(p,h);
[1059a1]1176  h->CleanUp();
[c232af]1177  omFreeBin((ADDRESS)h, sleftv_bin);
[0e1846]1178  return res;
1179}
[ea947e]1180BOOLEAN iiAlias(leftv p)
1181{
1182  if (iiCurrArgs==NULL)
1183  {
1184    Werror("not enough arguments for proc %s",VoiceName());
1185    p->CleanUp();
1186    return TRUE;
1187  }
1188  leftv h=iiCurrArgs;
1189  iiCurrArgs=h->next;
1190  h->next=NULL;
1191  if (h->rtyp!=IDHDL)
1192  {
1193    WerrorS("identifier required");
1194    return TRUE;
1195  }
1196  if (h->Typ()!=p->Typ())
1197  {
1198    WerrorS("type mismatch");
1199    return TRUE;
1200  }
1201  idhdl pp=(idhdl)p->data;
1202  switch(pp->typ)
1203  {
1204      case INT_CMD:
1205        break;
1206      case INTVEC_CMD:
1207      case INTMAT_CMD:
1208         delete IDINTVEC(pp);
1209         break;
1210      case NUMBER_CMD:
1211         nDelete(&IDNUMBER(pp));
1212         break;
1213      case BIGINT_CMD:
[6cc7f5]1214         n_Delete(&IDNUMBER(pp),currRing->cf);
[ea947e]1215         break;
1216      case MAP_CMD:
1217         {
1218           map im = IDMAP(pp);
1219           omFree((ADDRESS)im->preimage);
1220         }
1221         // continue as ideal:
1222      case IDEAL_CMD:
1223      case MODUL_CMD:
1224      case MATRIX_CMD:
1225          idDelete(&IDIDEAL(pp));
1226         break;
1227      case PROC_CMD:
1228      case RESOLUTION_CMD:
1229      case STRING_CMD:
1230         omFree((ADDRESS)IDSTRING(pp));
1231         break;
1232      case LIST_CMD:
1233         IDLIST(pp)->Clean();
1234         break;
1235      case LINK_CMD:
1236         omFreeBin(IDLINK(pp),sip_link_bin);
1237         break;
1238       // case ring: cannot happen
1239       default:
1240         Werror("unknown type %d",p->Typ());
1241         return TRUE;
1242  }
1243  pp->typ=ALIAS_CMD;
1244  IDDATA(pp)=(char*)h->data;
1245  h->CleanUp();
1246  omFreeBin((ADDRESS)h, sleftv_bin);
1247  return FALSE;
1248}
[0e1846]1249
[0a3ddd]1250static BOOLEAN iiInternalExport (leftv v, int toLev)
[0e1846]1251{
[0a3ddd]1252  idhdl h=(idhdl)v->data;
1253  //Print("iiInternalExport('%s',%d)%s\n", v->name, toLev,"");
1254  if (IDLEV(h)==0) Warn("`%s` is already global",IDID(h));
1255  else
[0e1846]1256  {
[0a3ddd]1257    h=IDROOT->get(v->name,toLev);
1258    idhdl *root=&IDROOT;
1259    if ((h==NULL)&&(currRing!=NULL))
[0e1846]1260    {
[0a3ddd]1261      h=currRing->idroot->get(v->name,toLev);
1262      root=&currRing->idroot;
[0e1846]1263    }
[1aa559b]1264    BOOLEAN keepring=FALSE;
[0a3ddd]1265    if ((h!=NULL)&&(IDLEV(h)==toLev))
[0e1846]1266    {
[0a3ddd]1267      if (IDTYP(h)==v->Typ())
[0e1846]1268      {
[1aa559b]1269        if (((IDTYP(h)==RING_CMD)||(IDTYP(h)==QRING_CMD))
1270        && (v->Data()==IDDATA(h)))
1271        {
1272          IDRING(h)->ref++;
1273          keepring=TRUE;
1274          IDLEV(h)=toLev;
1275          //WarnS("keepring");
1276          return FALSE;
1277        }
[ef9012]1278        if (BVERBOSE(V_REDEFINE))
1279        {
[bb354a]1280          Warn("redefining %s",IDID(h));
[ef9012]1281        }
[77ff8e]1282#ifdef USE_IILOCALRING
[1aa559b]1283        if (iiLocalRing[0]==IDRING(h) && (!keepring)) iiLocalRing[0]=NULL;
[77ff8e]1284#else
[573da6]1285        proclevel *p=procstack;
1286        while (p->next!=NULL) p=p->next;
[1aa559b]1287        if ((p->cRing==IDRING(h)) && (!keepring))
[573da6]1288        {
1289          p->cRing=NULL;
1290          p->cRingHdl=NULL;
1291        }
[3b1a83c]1292#endif
[16acb0]1293        killhdl2(h,root,currRing);
[0a3ddd]1294      }
1295      else
1296      {
1297        return TRUE;
1298      }
1299    }
1300    h=(idhdl)v->data;
1301    IDLEV(h)=toLev;
[1aa559b]1302    if (keepring) IDRING(h)->ref--;
[0a3ddd]1303    iiNoKeepRing=FALSE;
[6f3743]1304    //Print("export %s\n",IDID(h));
[0a3ddd]1305  }
1306  return FALSE;
1307}
1308
[bd4cb92]1309BOOLEAN iiInternalExport (leftv v, int toLev, idhdl roothdl)
1310{
1311  idhdl h=(idhdl)v->data;
1312  if(h==NULL)
1313  {
1314    Warn("'%s': no such identifier\n", v->name);
1315    return FALSE;
1316  }
[7035b2]1317  package frompack=v->req_packhdl;
[75d7c7]1318  if (frompack==NULL) frompack=currPack;
[bd4cb92]1319  package rootpack = IDPACKAGE(roothdl);
[573da6]1320//  Print("iiInternalExport('%s',%d,%s->%s) typ:%d\n", v->name, toLev, IDID(currPackHdl),IDID(roothdl),v->Typ());
[f913a2]1321  if ((RingDependend(IDTYP(h)))
1322  || ((IDTYP(h)==LIST_CMD)
1323     && (lRingDependend(IDLIST(h)))
1324     )
1325  )
[bd4cb92]1326  {
1327    //Print("// ==> Ringdependent set nesting to 0\n");
[6f3743]1328    return (iiInternalExport(v, toLev));
[bd4cb92]1329  }
1330  else
1331  {
[573da6]1332    IDLEV(h)=toLev;
1333    v->req_packhdl=rootpack;
[75d7c7]1334    if (h==frompack->idroot)
[bd4cb92]1335    {
[75d7c7]1336      frompack->idroot=h->next;
[bd4cb92]1337    }
1338    else
1339    {
[75d7c7]1340      idhdl hh=frompack->idroot;
[6f3743]1341      while ((hh!=NULL) && (hh->next!=h))
[bd4cb92]1342        hh=hh->next;
[6f3743]1343      if ((hh!=NULL) && (hh->next==h))
[bd4cb92]1344        hh->next=h->next;
1345      else
1346      {
[75d7c7]1347        Werror("`%s` not found",v->Name());
[bd4cb92]1348        return TRUE;
[954cf2]1349      }
[bd4cb92]1350    }
1351    h->next=rootpack->idroot;
1352    rootpack->idroot=h;
1353  }
1354  return FALSE;
1355}
[0a3ddd]1356
1357BOOLEAN iiExport (leftv v, int toLev)
1358{
[5c5638]1359#ifndef NDEBUG
[a3bc95e]1360  checkall();
[3b1a83c]1361#endif
[0a3ddd]1362  BOOLEAN nok=FALSE;
1363  leftv r=v;
1364  while (v!=NULL)
1365  {
1366    if ((v->name==NULL)||(v->rtyp==0)||(v->e!=NULL))
1367    {
1368      WerrorS("cannot export");
1369      nok=TRUE;
1370    }
1371    else
1372    {
[f2dff02]1373      if(iiInternalExport(v, toLev))
1374      {
[0a3ddd]1375        r->CleanUp();
1376        return TRUE;
[0e1846]1377      }
1378    }
1379    v=v->next;
1380  }
1381  r->CleanUp();
[5c5638]1382#ifndef NDEBUG
[a3bc95e]1383  checkall();
[3b1a83c]1384#endif
[0e1846]1385  return nok;
1386}
1387
1388/*assume root!=idroot*/
[bd4cb92]1389BOOLEAN iiExport (leftv v, int toLev, idhdl root)
1390{
[5c5638]1391#ifndef NDEBUG
[a3bc95e]1392  checkall();
[5c5638]1393#endif
[f913a2]1394  //  Print("iiExport1: pack=%s\n",IDID(root));
[922a71f]1395  package pack=IDPACKAGE(root);
[bd4cb92]1396  BOOLEAN nok=FALSE;
1397  leftv rv=v;
1398  while (v!=NULL)
1399  {
1400    if ((v->name==NULL)||(v->rtyp==0)||(v->e!=NULL)
1401    )
1402    {
1403      WerrorS("cannot export");
1404      nok=TRUE;
1405    }
1406    else
1407    {
[24a57d]1408      idhdl old=pack->idroot->get( v->name,toLev);
[bd4cb92]1409      if (old!=NULL)
1410      {
[922a71f]1411        if ((pack==currPack) && (old==(idhdl)v->data))
1412        {
1413          Warn("`%s` is already global",IDID(old));
1414          break;
1415        }
1416        else if (IDTYP(old)==v->Typ())
[bd4cb92]1417        {
1418          if (BVERBOSE(V_REDEFINE))
1419          {
1420            Warn("redefining %s",IDID(old));
1421          }
[283160]1422          v->name=omStrDup(v->name);
[24a57d]1423          killhdl2(old,&(pack->idroot),currRing);
[bd4cb92]1424        }
1425        else
1426        {
1427          rv->CleanUp();
1428          return TRUE;
1429        }
1430      }
[75d7c7]1431      //Print("iiExport: pack=%s\n",IDID(root));
[bd4cb92]1432      if(iiInternalExport(v, toLev, root))
1433      {
1434        rv->CleanUp();
1435        return TRUE;
1436      }
1437    }
1438    v=v->next;
1439  }
1440  rv->CleanUp();
[5c5638]1441#ifndef NDEBUG
[a3bc95e]1442  checkall();
[5c5638]1443#endif
[bd4cb92]1444  return nok;
1445}
[0e1846]1446
1447BOOLEAN iiCheckRing(int i)
1448{
[7d58b6]1449  if (currRing==NULL)
[0e1846]1450  {
1451    #ifdef SIQ
1452    if (siq<=0)
1453    {
1454    #endif
[df5fc1]1455      if (RingDependend(i))
[0e1846]1456      {
[da97958]1457        WerrorS("no ring active");
[0e1846]1458        return TRUE;
1459      }
1460    #ifdef SIQ
1461    }
1462    #endif
1463  }
1464  return FALSE;
1465}
[f99917f]1466
1467poly    iiHighCorner(ideal I, int ak)
1468{
[d609e1]1469  int i;
1470  if(!idIsZeroDim(I)) return NULL; // not zero-dim.
1471  poly po=NULL;
[753f9d2]1472  if (rHasLocalOrMixedOrdering_currRing())
[f99917f]1473  {
[e08ae6]1474    scComputeHC(I,currQuotient,ak,po);
[f99917f]1475    if (po!=NULL)
1476    {
1477      pGetCoeff(po)=nInit(1);
[7fccc79]1478      for (i=rVar(currRing); i>0; i--)
[f99917f]1479      {
1480        if (pGetExp(po, i) > 0) pDecrExp(po,i);
1481      }
[4e3468]1482      pSetComp(po,ak);
1483      pSetm(po);
[f99917f]1484    }
1485  }
[4e3468]1486  else
1487    po=pOne();
[f99917f]1488  return po;
1489}
[d66a7d]1490
1491void iiCheckPack(package &p)
1492{
1493  if (p==basePack) return;
1494
1495  idhdl t=basePack->idroot;
1496
[bb483c]1497  while ((t!=NULL) && (IDTYP(t)!=PACKAGE_CMD) && (IDPACKAGE(t)!=p)) t=t->next;
[d66a7d]1498
1499  if (t==NULL)
1500  {
1501    WarnS("package not found\n");
1502    p=basePack;
1503  }
1504  return;
1505}
[938688]1506
[85e68dd]1507idhdl rDefault(const char *s)
[938688]1508{
1509  idhdl tmp=NULL;
1510
1511  if (s!=NULL) tmp = enterid(s, myynest, RING_CMD, &IDROOT);
1512  if (tmp==NULL) return NULL;
1513
[07f3b73]1514// if ((currRing->ppNoether)!=NULL) pDelete(&(currRing->ppNoether));
[938688]1515  if (sLastPrinted.RingDependend())
1516  {
1517    sLastPrinted.CleanUp();
1518    memset(&sLastPrinted,0,sizeof(sleftv));
1519  }
1520
1521  ring r = IDRING(tmp);
1522
[07f3b73]1523  r->cf = nInitChar(n_Zp, (void*)32003); //   r->cf->ch = 32003;
[6cc7f5]1524  r->N      = 3;
[938688]1525  /*r->P     = 0; Alloc0 in idhdl::set, ipid.cc*/
1526  /*names*/
1527  r->names = (char **) omAlloc0(3 * sizeof(char_ptr));
1528  r->names[0]  = omStrDup("x");
1529  r->names[1]  = omStrDup("y");
1530  r->names[2]  = omStrDup("z");
1531  /*weights: entries for 3 blocks: NULL*/
1532  r->wvhdl = (int **)omAlloc0(3 * sizeof(int_ptr));
1533  /*order: dp,C,0*/
1534  r->order = (int *) omAlloc(3 * sizeof(int *));
1535  r->block0 = (int *)omAlloc0(3 * sizeof(int *));
1536  r->block1 = (int *)omAlloc0(3 * sizeof(int *));
1537  /* ringorder dp for the first block: var 1..3 */
1538  r->order[0]  = ringorder_dp;
1539  r->block0[0] = 1;
1540  r->block1[0] = 3;
1541  /* ringorder C for the second block: no vars */
1542  r->order[1]  = ringorder_C;
1543  /* the last block: everything is 0 */
1544  r->order[2]  = 0;
1545  /*polynomial ring*/
1546  r->OrdSgn    = 1;
1547
1548  /* complete ring intializations */
1549  rComplete(r);
1550  rSetHdl(tmp);
1551  return currRingHdl;
1552}
1553
[69672d]1554idhdl rFindHdl(ring r, idhdl n, idhdl)
[938688]1555{
1556  idhdl h=rSimpleFindHdl(r,IDROOT,n);
1557  if (h!=NULL)  return h;
1558  if (IDROOT!=basePack->idroot) h=rSimpleFindHdl(r,basePack->idroot,n);
1559  if (h!=NULL)  return h;
1560  proclevel *p=procstack;
1561  while(p!=NULL)
1562  {
1563    if ((p->cPack!=basePack)
1564    && (p->cPack!=currPack))
1565      h=rSimpleFindHdl(r,p->cPack->idroot,n);
1566    if (h!=NULL)  return h;
1567    p=p->next;
1568  }
1569  idhdl tmp=basePack->idroot;
1570  while (tmp!=NULL)
1571  {
1572    if (IDTYP(tmp)==PACKAGE_CMD)
1573      h=rSimpleFindHdl(r,IDPACKAGE(tmp)->idroot,n);
1574    if (h!=NULL)  return h;
1575    tmp=IDNEXT(tmp);
1576  }
1577  return NULL;
1578}
1579
[c82e549]1580void rDecomposeCF(leftv h,const ring r,const ring R)
[938688]1581{
[c82e549]1582  lists L=(lists)omAlloc0Bin(slists_bin);
1583  L->Init(4);
1584  h->rtyp=LIST_CMD;
1585  h->data=(void *)L;
[938688]1586  // 0: char/ cf - ring
1587  // 1: list (var)
1588  // 2: list (ord)
1589  // 3: qideal
[c82e549]1590  // ----------------------------------------
1591  // 0: char/ cf - ring
1592  L->m[0].rtyp=INT_CMD;
[6cc7f5]1593  L->m[0].data=(void *)r->cf->ch;
[c82e549]1594  // ----------------------------------------
1595  // 1: list (var)
1596  lists LL=(lists)omAlloc0Bin(slists_bin);
1597  LL->Init(r->N);
1598  int i;
1599  for(i=0; i<r->N; i++)
1600  {
1601    LL->m[i].rtyp=STRING_CMD;
1602    LL->m[i].data=(void *)omStrDup(r->names[i]);
1603  }
1604  L->m[1].rtyp=LIST_CMD;
1605  L->m[1].data=(void *)LL;
1606  // ----------------------------------------
1607  // 2: list (ord)
1608  LL=(lists)omAlloc0Bin(slists_bin);
1609  i=rBlocks(r)-1;
1610  LL->Init(i);
1611  i--;
1612  lists LLL;
1613  for(; i>=0; i--)
1614  {
1615    intvec *iv;
1616    int j;
1617    LL->m[i].rtyp=LIST_CMD;
1618    LLL=(lists)omAlloc0Bin(slists_bin);
1619    LLL->Init(2);
1620    LLL->m[0].rtyp=STRING_CMD;
1621    LLL->m[0].data=(void *)omStrDup(rSimpleOrdStr(r->order[i]));
1622    if (r->block1[i]-r->block0[i] >=0 )
1623    {
1624      j=r->block1[i]-r->block0[i];
[7035b2]1625      if(r->order[i]==ringorder_M) j=(j+1)*(j+1)-1;
[c82e549]1626      iv=new intvec(j+1);
1627      if ((r->wvhdl!=NULL) && (r->wvhdl[i]!=NULL))
1628      {
1629        for(;j>=0; j--) (*iv)[j]=r->wvhdl[i][j];
1630      }
1631      else switch (r->order[i])
1632      {
1633        case ringorder_dp:
1634        case ringorder_Dp:
1635        case ringorder_ds:
1636        case ringorder_Ds:
1637        case ringorder_lp:
1638          for(;j>=0; j--) (*iv)[j]=1;
1639          break;
1640        default: /* do nothing */;
1641      }
1642    }
1643    else
1644    {
1645      iv=new intvec(1);
1646    }
1647    LLL->m[1].rtyp=INTVEC_CMD;
1648    LLL->m[1].data=(void *)iv;
1649    LL->m[i].data=(void *)LLL;
1650  }
1651  L->m[2].rtyp=LIST_CMD;
1652  L->m[2].data=(void *)LL;
1653  // ----------------------------------------
1654  // 3: qideal
1655  L->m[3].rtyp=IDEAL_CMD;
[f5bef2]1656  if (rMinpolyIsNULL(R))
[c82e549]1657    L->m[3].data=(void *)idInit(1,1);
1658  else
1659  {
[f5bef2]1660    const ring RR = R->cf->extRing;
[f16c61c]1661
[f5bef2]1662    L->m[3].data=(void *) idCopy(RR->minideal, RR);
1663//    I->m[0] = pNSet(R->minpoly);
[c82e549]1664  }
1665  // ----------------------------------------
1666}
1667void rDecomposeC(leftv h,const ring R)
[4b6ab7]1668/* field is R or C */
[c82e549]1669{
[938688]1670  lists L=(lists)omAlloc0Bin(slists_bin);
[4b6ab7]1671  if (rField_is_long_C(R)) L->Init(3);
1672  else                     L->Init(2);
[c82e549]1673  h->rtyp=LIST_CMD;
1674  h->data=(void *)L;
1675  // 0: char/ cf - ring
1676  // 1: list (var)
1677  // 2: list (ord)
[938688]1678  // ----------------------------------------
1679  // 0: char/ cf - ring
[c82e549]1680  L->m[0].rtyp=INT_CMD;
[4b6ab7]1681  L->m[0].data=(void *)0;
[c82e549]1682  // ----------------------------------------
[7035b2]1683  // 1:
[c82e549]1684  lists LL=(lists)omAlloc0Bin(slists_bin);
[4b6ab7]1685  LL->Init(2);
1686    LL->m[0].rtyp=INT_CMD;
[a06b98]1687    LL->m[0].data=(void *)si_max(R->cf->float_len,SHORT_REAL_LENGTH/2);
[4b6ab7]1688    LL->m[1].rtyp=INT_CMD;
[a06b98]1689    LL->m[1].data=(void *)si_max(R->cf->float_len2,SHORT_REAL_LENGTH);
[c82e549]1690  L->m[1].rtyp=LIST_CMD;
1691  L->m[1].data=(void *)LL;
1692  // ----------------------------------------
[4b6ab7]1693  // 2: list (par)
1694  if (rField_is_long_C(R))
[c82e549]1695  {
[4b6ab7]1696    L->m[2].rtyp=STRING_CMD;
[47ab5b]1697    L->m[2].data=(void *)omStrDup(*rParameter(R));
[c82e549]1698  }
1699  // ----------------------------------------
1700}
1701
[c81a40]1702#ifdef HAVE_RINGS
1703void rDecomposeRing(leftv h,const ring R)
1704/* field is R or C */
1705{
1706  lists L=(lists)omAlloc0Bin(slists_bin);
1707  if (rField_is_Ring_Z(R)) L->Init(1);
[20704f]1708  else                     L->Init(2);
[c81a40]1709  h->rtyp=LIST_CMD;
1710  h->data=(void *)L;
1711  // 0: char/ cf - ring
1712  // 1: list (module)
1713  // ----------------------------------------
1714  // 0: char/ cf - ring
1715  L->m[0].rtyp=STRING_CMD;
1716  L->m[0].data=(void *)omStrDup("integer");
1717  // ----------------------------------------
1718  // 1: module
1719  if (rField_is_Ring_Z(R)) return;
1720  lists LL=(lists)omAlloc0Bin(slists_bin);
1721  LL->Init(2);
1722  LL->m[0].rtyp=BIGINT_CMD;
[6cc7f5]1723  LL->m[0].data=nlMapGMP((number) R->cf->modBase, R->cf, R->cf);
[c81a40]1724  LL->m[1].rtyp=INT_CMD;
[6cc7f5]1725  LL->m[1].data=(void *) R->cf->modExponent;
[c81a40]1726  L->m[1].rtyp=LIST_CMD;
1727  L->m[1].data=(void *)LL;
1728}
1729#endif
1730
1731
[cb5cac]1732lists rDecompose(const ring r)
[c82e549]1733{
[6815af]1734  // sanity check: require currRing==r for rings with polynomial data
[f5bef2]1735  if ( (r!=currRing) && (!rMinpolyIsNULL(r)
[6815af]1736#ifdef HAVE_PLURAL
1737  || (rIsPluralRing(r))
1738#endif
1739  ))
[cb5cac]1740  {
[6815af]1741    WerrorS("ring with polynomial data must be the base ring or compatible");
[cb5cac]1742    return NULL;
1743  }
[c82e549]1744  // 0: char/ cf - ring
1745  // 1: list (var)
1746  // 2: list (ord)
1747  // 3: qideal
1748  // possibly:
1749  // 4: C
1750  // 5: D
1751  lists L=(lists)omAlloc0Bin(slists_bin);
1752  if (rIsPluralRing(r))
1753    L->Init(6);
1754  else
1755    L->Init(4);
1756  // ----------------------------------------
1757  // 0: char/ cf - ring
[4b6ab7]1758  if (rField_is_numeric(r))
[c82e549]1759  {
[4b6ab7]1760    rDecomposeC(&(L->m[0]),r);
1761  }
[c81a40]1762#ifdef HAVE_RINGS
1763  else if (rField_is_Ring(r))
1764  {
1765    rDecomposeRing(&(L->m[0]),r);
1766  }
1767#endif
[4b6ab7]1768  else if (rIsExtension(r))
1769  {
[5d18675]1770    if ( rField_is_Extension(r) )// nCoeff_is_algExt(r->cf))
1771    {
[fe9ee1]1772      assume( r->cf != NULL );
[5d18675]1773      assume( r->cf->extRing != NULL );
[fe9ee1]1774
[5d18675]1775      rDecomposeCF(&(L->m[0]), r->cf->extRing, r);
[47ab5b]1776    }
1777    else
[5eef8d]1778    {
[5d18675]1779      assume( nCoeff_is_GF(r->cf) );
[fe9ee1]1780
[9502424]1781      lists Lc=(lists)omAlloc0Bin(slists_bin);
[5eef8d]1782      Lc->Init(4);
1783      // char:
1784      Lc->m[0].rtyp=INT_CMD;
[5d5d79]1785      Lc->m[0].data=(void*)r->cf->m_nfCharQ;
[fe9ee1]1786      // var:
[5eef8d]1787      lists Lv=(lists)omAlloc0Bin(slists_bin);
1788      Lv->Init(1);
1789      Lv->m[0].rtyp=STRING_CMD;
[fe9ee1]1790      Lv->m[0].data=(void *)omStrDup(*rParameter(r));
[5eef8d]1791      Lc->m[1].rtyp=LIST_CMD;
1792      Lc->m[1].data=(void*)Lv;
1793      // ord:
1794      lists Lo=(lists)omAlloc0Bin(slists_bin);
1795      Lo->Init(1);
1796      lists Loo=(lists)omAlloc0Bin(slists_bin);
1797      Loo->Init(2);
1798      Loo->m[0].rtyp=STRING_CMD;
1799      Loo->m[0].data=(void *)omStrDup(rSimpleOrdStr(ringorder_lp));
[fe9ee1]1800
[5eef8d]1801      intvec *iv=new intvec(1); (*iv)[0]=1;
1802      Loo->m[1].rtyp=INTVEC_CMD;
1803      Loo->m[1].data=(void *)iv;
[fe9ee1]1804
[5eef8d]1805      Lo->m[0].rtyp=LIST_CMD;
1806      Lo->m[0].data=(void*)Loo;
1807
1808      Lc->m[2].rtyp=LIST_CMD;
1809      Lc->m[2].data=(void*)Lo;
1810      // q-ideal:
1811      Lc->m[3].rtyp=IDEAL_CMD;
1812      Lc->m[3].data=(void *)idInit(1,1);
1813      // ----------------------
1814      L->m[0].rtyp=LIST_CMD;
1815      L->m[0].data=(void*)Lc;
1816    }
[cb5cac]1817    if (L->m[0].rtyp==0)
1818    {
[6e3cab]1819      //omFreeBin(slists_bin,(void *)L);
[cb5cac]1820      return NULL;
1821    }
[c82e549]1822  }
[938688]1823  else
1824  {
1825    L->m[0].rtyp=INT_CMD;
[6cc7f5]1826    L->m[0].data=(void *)r->cf->ch;
[938688]1827  }
1828  // ----------------------------------------
1829  // 1: list (var)
1830  lists LL=(lists)omAlloc0Bin(slists_bin);
1831  LL->Init(r->N);
1832  int i;
1833  for(i=0; i<r->N; i++)
1834  {
1835    LL->m[i].rtyp=STRING_CMD;
1836    LL->m[i].data=(void *)omStrDup(r->names[i]);
1837  }
1838  L->m[1].rtyp=LIST_CMD;
1839  L->m[1].data=(void *)LL;
1840  // ----------------------------------------
1841  // 2: list (ord)
1842  LL=(lists)omAlloc0Bin(slists_bin);
1843  i=rBlocks(r)-1;
1844  LL->Init(i);
1845  i--;
1846  lists LLL;
1847  for(; i>=0; i--)
1848  {
1849    intvec *iv;
1850    int j;
1851    LL->m[i].rtyp=LIST_CMD;
1852    LLL=(lists)omAlloc0Bin(slists_bin);
1853    LLL->Init(2);
1854    LLL->m[0].rtyp=STRING_CMD;
1855    LLL->m[0].data=(void *)omStrDup(rSimpleOrdStr(r->order[i]));
[273fed]1856
1857    if(r->order[i] == ringorder_IS) //  || r->order[i] == ringorder_s || r->order[i] == ringorder_S)
1858    {
1859      assume( r->block0[i] == r->block1[i] );
1860      const int s = r->block0[i];
1861      assume( -2 < s && s < 2);
1862
1863      iv=new intvec(1);
1864      (*iv)[0] = s;
[f93c5e9]1865    }
1866    else if (r->block1[i]-r->block0[i] >=0 )
[938688]1867    {
[f93c5e9]1868      int bl=j=r->block1[i]-r->block0[i];
1869      if (r->order[i]==ringorder_M)
1870      {
1871        j=(j+1)*(j+1)-1;
1872        bl=j+1;
1873      }
1874      else if (r->order[i]==ringorder_am)
1875      {
1876        j+=r->wvhdl[i][bl+1];
1877      }
[938688]1878      iv=new intvec(j+1);
1879      if ((r->wvhdl!=NULL) && (r->wvhdl[i]!=NULL))
1880      {
[f93c5e9]1881        for(;j>=0; j--) (*iv)[j]=r->wvhdl[i][j+(j>bl)];
[938688]1882      }
1883      else switch (r->order[i])
1884      {
1885        case ringorder_dp:
1886        case ringorder_Dp:
1887        case ringorder_ds:
1888        case ringorder_Ds:
1889        case ringorder_lp:
1890          for(;j>=0; j--) (*iv)[j]=1;
1891          break;
1892        default: /* do nothing */;
1893      }
1894    }
1895    else
1896    {
1897      iv=new intvec(1);
1898    }
1899    LLL->m[1].rtyp=INTVEC_CMD;
1900    LLL->m[1].data=(void *)iv;
1901    LL->m[i].data=(void *)LLL;
1902  }
1903  L->m[2].rtyp=LIST_CMD;
1904  L->m[2].data=(void *)LL;
1905  // ----------------------------------------
1906  // 3: qideal
1907  L->m[3].rtyp=IDEAL_CMD;
1908  if (r->qideal==NULL)
1909    L->m[3].data=(void *)idInit(1,1);
1910  else
1911    L->m[3].data=(void *)idCopy(r->qideal);
1912  // ----------------------------------------
[47ab5b]1913#ifdef HAVE_PLURAL // NC! in rDecompose
[7cbe8e]1914  if (rIsPluralRing(r))
[c82e549]1915  {
1916    L->m[4].rtyp=MATRIX_CMD;
[6cc7f5]1917    L->m[4].data=(void *)mp_Copy(r->GetNC()->C, r, r);
[c82e549]1918    L->m[5].rtyp=MATRIX_CMD;
[6cc7f5]1919    L->m[5].data=(void *)mp_Copy(r->GetNC()->D, r, r);
[c82e549]1920  }
[47ab5b]1921#endif
[938688]1922  return L;
1923}
1924
[4b6ab7]1925void rComposeC(lists L, ring R)
1926/* field is R or C */
1927{
1928  // ----------------------------------------
1929  // 0: char/ cf - ring
1930  if ((L->m[0].rtyp!=INT_CMD) || (L->m[0].data!=(char *)0))
[a0e57c]1931  {
[4b6ab7]1932    Werror("invald coeff. field description, expecting 0");
1933    return;
[a0e57c]1934  }
[47ab5b]1935//  R->cf->ch=0;
[4b6ab7]1936  // ----------------------------------------
[7035b2]1937  // 1:
1938  if (L->m[1].rtyp!=LIST_CMD)
[4b6ab7]1939    Werror("invald coeff. field description, expecting precision list");
1940  lists LL=(lists)L->m[1].data;
[7447d8]1941  int r1=(int)(long)LL->m[0].data;
1942  int r2=(int)(long)LL->m[1].data;
[4b6ab7]1943  if ((r1<=SHORT_REAL_LENGTH)
1944  && (r2=SHORT_REAL_LENGTH))
1945  {
[a06b98]1946    R->cf->float_len=SHORT_REAL_LENGTH/2;
1947    R->cf->float_len2=SHORT_REAL_LENGTH;
[4b6ab7]1948  }
1949  else
1950  {
[a06b98]1951    R->cf->float_len=si_min(r1,32767);
1952    R->cf->float_len2=si_min(r2,32767);
[4b6ab7]1953  }
1954  // ----------------------------------------
1955  // 2: list (par)
1956  if (L->nr==2)
1957  {
[6cc7f5]1958    R->cf->extRing->N=1;
[4b6ab7]1959    if (L->m[2].rtyp!=STRING_CMD)
1960    {
1961      Werror("invald coeff. field description, expecting parameter name");
1962      return;
1963    }
[6cc7f5]1964    R->cf->extRing->names=(char**)omAlloc0(rPar(R)*sizeof(char_ptr));
1965    R->cf->extRing->names[0]=omStrDup((char *)L->m[2].data);
[4b6ab7]1966  }
1967  // ----------------------------------------
1968}
[20704f]1969
1970#ifdef HAVE_RINGS
1971void rComposeRing(lists L, ring R)
1972/* field is R or C */
1973{
1974  // ----------------------------------------
1975  // 0: string: integer
1976  // no further entries --> Z
[6cc7f5]1977  R->cf->modBase = (int_number) omAlloc(sizeof(mpz_t));
[20704f]1978  if (L->nr == 0)
1979  {
[6cc7f5]1980    mpz_init_set_ui(R->cf->modBase,0);
1981    R->cf->modExponent = 1;
[20704f]1982  }
1983  // ----------------------------------------
1984  // 1:
[e74fb8]1985  else
[20704f]1986  {
[e74fb8]1987    if (L->m[1].rtyp!=LIST_CMD) Werror("invald data, expecting list of numbers");
[20704f]1988    lists LL=(lists)L->m[1].data;
[6cc7f5]1989    mpz_init(R->cf->modBase);
[350a6d]1990    if ((LL->nr >= 0) && LL->m[0].rtyp == BIGINT_CMD)
[e74fb8]1991    {
[6cc7f5]1992      number modBase = (number) LL->m[0].data;
1993      nlGMP(modBase, (number) R->cf->modBase, R->cf);
1994      LL->m[0].data = (void *)modBase;
[e74fb8]1995    }
[350a6d]1996    else if ((LL->nr >= 0) && LL->m[0].rtyp == INT_CMD)
[e74fb8]1997    {
[6cc7f5]1998      mpz_set_ui(R->cf->modBase,(unsigned long) LL->m[0].data);
[e74fb8]1999    }
2000    else
2001    {
[6cc7f5]2002      mpz_set_ui(R->cf->modBase,0);
[e74fb8]2003    }
2004    if (LL->nr >= 1)
2005    {
[6cc7f5]2006      R->cf->modExponent = (unsigned long) LL->m[1].data;
[e74fb8]2007    }
2008    else
2009    {
[6cc7f5]2010      R->cf->modExponent = 1;
[e74fb8]2011    }
[20704f]2012  }
2013  // ----------------------------------------
[6cc7f5]2014  if ((mpz_cmp_ui(R->cf->modBase, 1) == 0) && (mpz_cmp_ui(R->cf->modBase, 0) < 0))
[20704f]2015  {
2016    Werror("Wrong ground ring specification (module is 1)");
2017    return;
2018  }
[6cc7f5]2019  if (R->cf->modExponent < 1)
[20704f]2020  {
2021    Werror("Wrong ground ring specification (exponent smaller than 1");
2022    return;
2023  }
2024  // module is 0 ---> integers
[6cc7f5]2025  if (mpz_cmp_ui(R->cf->modBase, 0) == 0)
[20704f]2026  {
[6cc7f5]2027    R->cf->ch = 0;
2028    R->cf->ringtype = 4;
[20704f]2029  }
2030  // we have an exponent
[6cc7f5]2031  else if (R->cf->modExponent > 1)
[20704f]2032  {
[6cc7f5]2033    R->cf->ch = R->cf->modExponent;
2034    if ((mpz_cmp_ui(R->cf->modBase, 2) == 0) && (R->cf->modExponent <= 8*sizeof(NATNUMBER)))
[7cbe8e]2035    {
[6cc7f5]2036      /* this branch should be active for modExponent = 2..32 resp. 2..64,
[cf21dd4]2037           depending on the size of a long on the respective platform */
[6cc7f5]2038      R->cf->ringtype = 1;       // Use Z/2^ch
[20704f]2039    }
2040    else
2041    {
[6cc7f5]2042      R->cf->ringtype = 3;
[20704f]2043    }
2044  }
2045  // just a module m > 1
2046  else
2047  {
[6cc7f5]2048    R->cf->ringtype = 2;
2049    R->cf->ch = mpz_get_ui(R->cf->modBase);
[20704f]2050  }
2051}
2052#endif
2053
[7c5dd1]2054static void rRenameVars(ring R)
2055{
2056  int i,j;
2057  for(i=0;i<R->N-1;i++)
2058  {
2059    for(j=i+1;j<R->N;j++)
2060    {
2061      if (strcmp(R->names[i],R->names[j])==0)
2062      {
2063        Warn("name conflict var(%d) and var(%d): `%s`, rename to `@(%d)`",i+1,j+1,R->names[i],j+1);
2064        omFree(R->names[j]);
2065        R->names[j]=(char *)omAlloc(10);
2066        sprintf(R->names[j],"@(%d)",j+1);
2067      }
2068    }
2069  }
[6cc7f5]2070  for(i=0;i<rPar(R); i++)
[7c5dd1]2071  {
2072    for(j=0;j<R->N;j++)
2073    {
[6cc7f5]2074      if (strcmp(rParameter(R)[i],R->names[j])==0)
[7c5dd1]2075      {
2076        Warn("name conflict par(%d) and var(%d): `%s`, rename to `@@(%d)`",i+1,j+1,R->names[j],i+1);
[6cc7f5]2077        omFree(rParameter(R)[i]);
2078        rParameter(R)[i]=(char *)omAlloc(10);
2079        sprintf(rParameter(R)[i],"@@(%d)",i+1);
[7c5dd1]2080      }
2081    }
2082  }
2083}
2084
[cb5cac]2085ring rCompose(const lists  L)
[938688]2086{
[c82e549]2087  if ((L->nr!=3)
2088#ifdef HAVE_PLURAL
2089  &&(L->nr!=5)
2090#endif
2091  )
2092    return NULL;
[f16c61c]2093  int is_gf_char=0;
[938688]2094  // 0: char/ cf - ring
2095  // 1: list (var)
2096  // 2: list (ord)
2097  // 3: qideal
[c82e549]2098  // possibly:
2099  // 4: C
2100  // 5: D
[f16c61c]2101
2102  ring R = (ring) omAlloc0Bin(sip_sring_bin); // why
2103
2104
2105  //assume( R->cf == NULL );
2106
[d143376]2107  // ------------------------------------------------------------------
2108  // 0: char:
2109  if (L->m[0].Typ()==INT_CMD)
2110  {
[e7e815]2111    int ch = (int)(long)L->m[0].Data();
[d143376]2112    assume( ch >= 0 );
[e7e815]2113
2114    if (ch == 0) // Q?
2115      R->cf = nInitChar(n_Q, NULL);
2116    else
2117    {
2118      int l = IsPrime(ch); // Zp?
2119      if( l != ch )
[d143376]2120      {
[e7e815]2121        Warn("%d is invalid characteristic of ground field. %d is used.", ch, l);
[d143376]2122        ch = l;
[f16c61c]2123      }
2124      R->cf = nInitChar(n_Zp, (void*)ch);
[d143376]2125    }
2126  }
[e7e815]2127  else if (L->m[0].Typ()==LIST_CMD) // something complicated...
[d143376]2128  {
2129    lists LL=(lists)L->m[0].Data();
[f16c61c]2130
[d143376]2131#ifdef HAVE_RINGS
[e7e815]2132    if (LL->m[0].Typ() == STRING_CMD) // 1st comes a string?
[d143376]2133    {
[e7e815]2134      rComposeRing(LL, R); // Ring!?
[d143376]2135    }
2136    else
2137#endif
[e7e815]2138    if (LL->nr < 3)
2139      rComposeC(LL,R); // R, long_R, long_C
[d143376]2140    else
[f16c61c]2141    {
[d143376]2142      if (LL->m[0].Typ()==INT_CMD)
[f16c61c]2143      {
[f5bef2]2144        int ch = (int)(long)LL->m[0].Data();
[f16c61c]2145        while ((ch!=fftable[is_gf_char]) && (fftable[is_gf_char])) is_gf_char++;
2146        if (fftable[is_gf_char]==0) is_gf_char=-1;
[e7e815]2147
[f16c61c]2148        if(is_gf_char!= -1)
[e7e815]2149        {
2150          GFInfo param;
[f16c61c]2151
2152          param.GFChar = ch;
[e7e815]2153          param.GFDegree = 1;
2154          param.GFPar_name = (const char*)(((lists)(LL->m[1].Data()))->m[0].Data());
2155
2156          // nfInitChar should be able to handle the case when ch is in fftables!
2157          R->cf = nInitChar(n_GF, (void*)&param);
2158        }
[d143376]2159      }
[e7e815]2160
2161      if( R->cf == NULL )
[d143376]2162      {
2163        ring extRing = rCompose((lists)L->m[0].Data());
[f16c61c]2164
[d143376]2165        if (extRing==NULL)
2166        {
[e7e815]2167          WerrorS("could not create the specified coefficient field");
[d143376]2168          goto rCompose_err;
2169        }
[e7e815]2170
2171        if( extRing->qideal != NULL ) // Algebraic extension
[d143376]2172        {
[e7e815]2173          AlgExtInfo extParam;
[f16c61c]2174
[e7e815]2175          extParam.i = extRing->qideal;
2176          extParam.r = extRing;
2177
2178          extRing->qideal = NULL; // ???
2179
[f16c61c]2180          R->cf = nInitChar(n_algExt, (void*)&extParam);
2181        }
2182        else // Transcendental extension
[e7e815]2183        {
2184          TransExtInfo extParam;
[f5bef2]2185          extParam.r = extRing;
[e7e815]2186
2187          R->cf = nInitChar(n_transExt, &extParam);
[d143376]2188        }
[f16c61c]2189      }
[d143376]2190    }
2191  }
2192  else
2193  {
2194    WerrorS("coefficient field must be described by `int` or `list`");
2195    goto rCompose_err;
2196  }
[e7e815]2197
2198  if( R->cf == NULL )
[d143376]2199  {
[e7e815]2200    WerrorS("could not create coefficient field described by the input!");
[d143376]2201    goto rCompose_err;
2202  }
[e7e815]2203
[938688]2204  // ------------------------- VARS ---------------------------
2205  if (L->m[1].Typ()==LIST_CMD)
2206  {
2207    lists v=(lists)L->m[1].Data();
2208    R->N = v->nr+1;
2209    R->names   = (char **)omAlloc0(R->N * sizeof(char_ptr));
2210    int i;
2211    for(i=0;i<R->N;i++)
2212    {
2213      if (v->m[i].Typ()==STRING_CMD)
2214        R->names[i]=omStrDup((char *)v->m[i].Data());
2215      else if (v->m[i].Typ()==POLY_CMD)
2216      {
2217        poly p=(poly)v->m[i].Data();
2218        int nr=pIsPurePower(p);
2219        if (nr>0)
2220          R->names[i]=omStrDup(currRing->names[nr-1]);
2221        else
2222        {
2223          Werror("var name %d must be a string or a ring variable",i+1);
2224          goto rCompose_err;
2225        }
2226      }
2227      else
2228      {
2229        Werror("var name %d must be `string`",i+1);
2230        goto rCompose_err;
2231      }
2232    }
2233  }
2234  else
2235  {
2236    WerrorS("variable must be given as `list`");
2237    goto rCompose_err;
2238  }
2239  // ------------------------ ORDER ------------------------------
2240  if (L->m[2].Typ()==LIST_CMD)
2241  {
2242    lists v=(lists)L->m[2].Data();
2243    int n= v->nr+2;
2244    int j;
2245    // initialize fields of R
2246    R->order=(int *)omAlloc0(n*sizeof(int));
2247    R->block0=(int *)omAlloc0(n*sizeof(int));
2248    R->block1=(int *)omAlloc0(n*sizeof(int));
2249    R->wvhdl=(int**)omAlloc0(n*sizeof(int_ptr));
2250    // init order, so that rBlocks works correctly
[cf022c7]2251    for (j=0; j < n-1; j++)
[938688]2252      R->order[j] = (int) ringorder_unspec;
2253    // orderings
2254    R->OrdSgn=1;
2255    for(j=0;j<n-1;j++)
2256    {
2257    // todo: a(..), M
2258      if (v->m[j].Typ()!=LIST_CMD)
2259      {
2260        WerrorS("ordering must be list of lists");
2261        goto rCompose_err;
2262      }
2263      lists vv=(lists)v->m[j].Data();
2264      if ((vv->nr!=1)
2265      || (vv->m[0].Typ()!=STRING_CMD)
2266      || ((vv->m[1].Typ()!=INTVEC_CMD) && (vv->m[1].Typ()!=INT_CMD)))
2267      {
2268        WerrorS("ordering name must be a (string,intvec)");
2269        goto rCompose_err;
2270      }
2271      R->order[j]=rOrderName(omStrDup((char*)vv->m[0].Data())); // assume STRING
[22579cf]2272
[938688]2273      if (j==0) R->block0[0]=1;
[392682]2274      else
[99e6fde]2275      {
2276         int jj=j-1;
[cf022c7]2277         while((jj>=0)
[392682]2278         && ((R->order[jj]== ringorder_a)
[ad408c]2279            || (R->order[jj]== ringorder_aa)
[3a8a0d9]2280            || (R->order[jj]== ringorder_am)
[ad408c]2281            || (R->order[jj]== ringorder_c)
2282            || (R->order[jj]== ringorder_C)
[273fed]2283            || (R->order[jj]== ringorder_s)
2284            || (R->order[jj]== ringorder_S)
[ad408c]2285         ))
[cf022c7]2286         {
2287           //Print("jj=%, skip %s\n",rSimpleOrdStr(R->order[jj]));
[99e6fde]2288           jj--;
[cf022c7]2289         }
2290         if (jj<0) R->block0[j]=1;
[ad408c]2291         else       R->block0[j]=R->block1[jj]+1;
[99e6fde]2292      }
[938688]2293      intvec *iv;
2294      if (vv->m[1].Typ()==INT_CMD)
[7447d8]2295        iv=new intvec((int)(long)vv->m[1].Data(),(int)(long)vv->m[1].Data());
[938688]2296      else
2297        iv=ivCopy((intvec*)vv->m[1].Data()); //assume INTVEC
[091b0e8]2298      int iv_len=iv->length();
2299      R->block1[j]=si_max(R->block0[j],R->block0[j]+iv_len-1);
2300      if (R->block1[j]>R->N)
2301      {
[3373e32]2302        R->block1[j]=R->N;
2303        iv_len=R->block1[j]-R->block0[j]+1;
[091b0e8]2304      }
[99e6fde]2305      //Print("block %d from %d to %d\n",j,R->block0[j], R->block1[j]);
[938688]2306      int i;
2307      switch (R->order[j])
2308      {
2309         case ringorder_ws:
2310         case ringorder_Ws:
2311            R->OrdSgn=-1;
[99e6fde]2312         case ringorder_aa:
2313         case ringorder_a:
[938688]2314         case ringorder_wp:
2315         case ringorder_Wp:
[091b0e8]2316           R->wvhdl[j] =( int *)omAlloc(iv_len*sizeof(int));
2317           for (i=0; i<iv_len;i++)
[c2d114]2318           {
2319             R->wvhdl[j][i]=(*iv)[i];
2320           }
[938688]2321           break;
[ece1ce]2322         case ringorder_am:
2323           R->wvhdl[j] =( int *)omAlloc((iv->length()+1)*sizeof(int));
2324           for (i=0; i<iv_len;i++)
2325           {
2326             R->wvhdl[j][i]=(*iv)[i];
2327           }
2328           R->wvhdl[j][i]=iv->length() - iv_len;
2329           //printf("ivlen:%d,iv->len:%d,mod:%d\n",iv_len,iv->length(),R->wvhdl[j][i]);
2330           for (; i<iv->length(); i++)
2331           {
2332              R->wvhdl[j][i+1]=(*iv)[i];
2333           }
2334           break;
[62fb0b4]2335         case ringorder_M:
2336           R->wvhdl[j] =( int *)omAlloc((iv->length())*sizeof(int));
2337           for (i=0; i<iv->length();i++) R->wvhdl[j][i]=(*iv)[i];
[8c7e81]2338           R->block1[j]=si_max(R->block0[j],R->block0[j]+(int)sqrt((double)(iv->length()-1)));
[091b0e8]2339           if (R->block1[j]>R->N)
[3373e32]2340           {
2341             WerrorS("ordering matrix too big");
2342             goto rCompose_err;
2343           }
[62fb0b4]2344           break;
[938688]2345         case ringorder_ls:
2346         case ringorder_ds:
2347         case ringorder_Ds:
[529aad]2348         case ringorder_rs:
[938688]2349           R->OrdSgn=-1;
2350         case ringorder_lp:
2351         case ringorder_dp:
2352         case ringorder_Dp:
2353         case ringorder_rp:
2354           break;
2355         case ringorder_S:
2356           break;
2357         case ringorder_c:
2358         case ringorder_C:
[c05b46]2359           R->block1[j]=R->block0[j]=0;
[938688]2360           break;
[273fed]2361
2362         case ringorder_s:
2363           break;
2364
2365         case ringorder_IS:
2366         {
2367           R->block1[j] = R->block0[j] = 0;
2368           if( iv->length() > 0 )
2369           {
2370             const int s = (*iv)[0];
2371             assume( -2 < s && s < 2 );
2372             R->block1[j] = R->block0[j] = s;
2373           }
2374           break;
2375         }
[99e6fde]2376         case 0:
[cf022c7]2377         case ringorder_unspec:
[99e6fde]2378           break;
[938688]2379      }
[4be9b80]2380      delete iv;
[938688]2381    }
2382    // sanity check
2383    j=n-2;
2384    if ((R->order[j]==ringorder_c)
[cf022c7]2385    || (R->order[j]==ringorder_C)
2386    || (R->order[j]==ringorder_unspec)) j--;
[938688]2387    if (R->block1[j] != R->N)
2388    {
2389      if (((R->order[j]==ringorder_dp) ||
2390           (R->order[j]==ringorder_ds) ||
2391           (R->order[j]==ringorder_Dp) ||
2392           (R->order[j]==ringorder_Ds) ||
2393           (R->order[j]==ringorder_rp) ||
[529aad]2394           (R->order[j]==ringorder_rs) ||
[938688]2395           (R->order[j]==ringorder_lp) ||
2396           (R->order[j]==ringorder_ls))
2397          &&
2398            R->block0[j] <= R->N)
2399      {
2400        R->block1[j] = R->N;
2401      }
2402      else
2403      {
2404        Werror("ordering incomplete: size (%d) should be %d",R->block1[j],R->N);
2405        goto rCompose_err;
2406      }
2407    }
2408  }
2409  else
2410  {
2411    WerrorS("ordering must be given as `list`");
2412    goto rCompose_err;
2413  }
[e7e815]2414
2415  // ------------------------ ??????? --------------------
2416
2417  rRenameVars(R);
2418  rComplete(R);
2419
[f16c61c]2420#ifdef HAVE_RINGS
[e7e815]2421  // This was a BUG IN SINGULAR: There is no HABE_RINGS!!!
2422
2423// currently, coefficients which are ring elements require a global ordering:
[f5bef2]2424  if (rField_is_Ring(R) && (R->OrdSgn==-1))
[e7e815]2425  {
2426    WerrorS("global ordering required for these coefficients");
2427    goto rCompose_err;
2428  }
2429#endif
2430
2431
[1bf1c0]2432  // ------------------------ Q-IDEAL ------------------------
[e6f922f]2433
[938688]2434  if (L->m[3].Typ()==IDEAL_CMD)
2435  {
2436    ideal q=(ideal)L->m[3].Data();
2437    if (q->m[0]!=NULL)
[392682]2438    {
[42d26c]2439      if (R->cf != currRing->cf) //->cf->ch!=currRing->cf->ch)
[392682]2440      {
[7e1643]2441      #if 0
[0d0763]2442            WerrorS("coefficient fields must be equal if q-ideal !=0");
2443            goto rCompose_err;
2444      #else
2445        ring orig_ring=currRing;
2446        rChangeCurrRing(R);
2447        int *perm=NULL;
2448        int *par_perm=NULL;
2449        int par_perm_size=0;
2450        nMapFunc nMap;
2451
[6cc7f5]2452        if ((nMap=nSetMap(orig_ring->cf))==NULL)
[0d0763]2453        {
2454          if (rEqual(orig_ring,currRing))
2455          {
[6cc7f5]2456            nMap=n_SetMap(currRing->cf, currRing->cf);
[0d0763]2457          }
2458          else
2459          // Allow imap/fetch to be make an exception only for:
2460          if ( (rField_is_Q_a(orig_ring) &&  // Q(a..) -> Q(a..) || Q || Zp || Zp(a)
[6cc7f5]2461            (rField_is_Q(currRing) || rField_is_Q_a(currRing) ||
2462             (rField_is_Zp(currRing) || rField_is_Zp_a(currRing))))
[0d0763]2463           ||
2464           (rField_is_Zp_a(orig_ring) &&  // Zp(a..) -> Zp(a..) || Zp
2465            (rField_is_Zp(currRing, rInternalChar(orig_ring)) ||
2466             rField_is_Zp_a(currRing, rInternalChar(orig_ring)))) )
2467          {
2468            par_perm_size=rPar(orig_ring);
2469            BITSET save_test=test;
[f16c61c]2470
[f5bef2]2471//            if ((orig_ring->minpoly != NULL) || (orig_ring->minideal != NULL))
2472//              naSetChar(rInternalChar(orig_ring),orig_ring);
2473//            else ntSetChar(rInternalChar(orig_ring),orig_ring);
[f16c61c]2474
[6cc7f5]2475            nSetChar(currRing->cf);
[0d0763]2476            test=save_test;
2477          }
2478          else
2479          {
2480            WerrorS("coefficient fields must be equal if q-ideal !=0");
2481            goto rCompose_err;
2482          }
2483        }
[7e1643]2484        perm=(int *)omAlloc0((orig_ring->N+1)*sizeof(int));
2485        if (par_perm_size!=0)
2486          par_perm=(int *)omAlloc0(par_perm_size*sizeof(int));
[27afa1]2487        int i;
[0ea97e]2488        #if 0
2489        // use imap:
[7e1643]2490        maFindPerm(orig_ring->names,orig_ring->N,orig_ring->parameter,orig_ring->P,
2491          currRing->names,currRing->N,currRing->parameter, currRing->P,
2492          perm,par_perm, currRing->ch);
[0ea97e]2493        #else
2494        // use fetch
2495        if ((rPar(orig_ring)>0) && (rPar(currRing)==0))
2496        {
2497          for(i=si_min(rPar(orig_ring),rVar(currRing))-1;i>=0;i--) par_perm[i]=i+1;
2498        }
2499        else if (par_perm_size!=0)
2500          for(i=si_min(rPar(orig_ring),rPar(currRing))-1;i>=0;i--) par_perm[i]=-(i+1);
[7fccc79]2501        for(i=si_min(orig_ring->N,rVar(currRing));i>0;i--) perm[i]=i;
[0ea97e]2502        #endif
[7e1643]2503        ideal dest_id=idInit(IDELEMS(q),1);
2504        for(i=IDELEMS(q)-1; i>=0; i--)
[0d0763]2505        {
[6cc7f5]2506          dest_id->m[i]=p_PermPoly(q->m[i],perm,orig_ring, currRing,nMap,
[7e1643]2507                                  par_perm,par_perm_size);
[0ea97e]2508          //  PrintS("map:");pWrite(dest_id->m[i]);PrintLn();
[fe62d0]2509          pTest(dest_id->m[i]);
[0d0763]2510        }
[7e1643]2511        R->qideal=dest_id;
[0d0763]2512        if (perm!=NULL)
2513          omFreeSize((ADDRESS)perm,(orig_ring->N+1)*sizeof(int));
2514        if (par_perm!=NULL)
2515          omFreeSize((ADDRESS)par_perm,par_perm_size*sizeof(int));
2516        rChangeCurrRing(orig_ring);
2517      #endif
[392682]2518      }
[0d0763]2519      else
2520        R->qideal=idrCopyR(q,currRing,R);
[392682]2521    }
[938688]2522  }
2523  else
2524  {
2525    WerrorS("q-ideal must be given as `ideal`");
2526    goto rCompose_err;
2527  }
2528
[c82e549]2529
2530  // ---------------------------------------------------------------
2531  #ifdef HAVE_PLURAL
2532  if (L->nr==5)
2533  {
[e5a4ba]2534    if (nc_CallPlural((matrix)L->m[4].Data(),
2535                      (matrix)L->m[5].Data(),
2536                      NULL,NULL,
2537                      R,
2538                      true, // !!!
2539                      true, false,
2540                      currRing, FALSE)) goto rCompose_err;
[3f78cb]2541    // takes care about non-comm. quotient! i.e. calls "nc_SetupQuotient" due to last true
[c82e549]2542  }
2543  #endif
[938688]2544  return R;
2545
2546rCompose_err:
2547  if (R->N>0)
2548  {
2549    int i;
2550    if (R->names!=NULL)
2551    {
[a4240cf]2552      i=R->N-1;
[938688]2553      while (i>=0) { if (R->names[i]!=NULL) omFree(R->names[i]); i--; }
2554      omFree(R->names);
2555    }
2556  }
2557  if (R->order!=NULL) omFree(R->order);
2558  if (R->block0!=NULL) omFree(R->block0);
2559  if (R->block1!=NULL) omFree(R->block1);
2560  if (R->wvhdl!=NULL) omFree(R->wvhdl);
2561  omFree(R);
2562  return NULL;
2563}
2564
2565// from matpol.cc
2566
2567/*2
2568* compute the jacobi matrix of an ideal
2569*/
2570BOOLEAN mpJacobi(leftv res,leftv a)
2571{
2572  int     i,j;
2573  matrix result;
2574  ideal id=(ideal)a->Data();
2575
[7fccc79]2576  result =mpNew(IDELEMS(id),rVar(currRing));
[938688]2577  for (i=1; i<=IDELEMS(id); i++)
2578  {
[7fccc79]2579    for (j=1; j<=rVar(currRing); j++)
[938688]2580    {
2581      MATELEM(result,i,j) = pDiff(id->m[i-1],j);
2582    }
2583  }
2584  res->data=(char *)result;
2585  return FALSE;
2586}
2587
2588/*2
2589* returns the Koszul-matrix of degree d of a vectorspace with dimension n
2590* uses the first n entrees of id, if id <> NULL
2591*/
2592BOOLEAN mpKoszul(leftv res,leftv c/*ip*/, leftv b/*in*/, leftv id)
2593{
[7447d8]2594  int n=(int)(long)b->Data();
2595  int d=(int)(long)c->Data();
[938688]2596  int     k,l,sign,row,col;
2597  matrix  result;
2598  ideal temp;
2599  BOOLEAN bo;
2600  poly    p;
2601
2602  if ((d>n) || (d<1) || (n<1))
2603  {
2604    res->data=(char *)mpNew(1,1);
2605    return FALSE;
2606  }
2607  int *choise = (int*)omAlloc(d*sizeof(int));
2608  if (id==NULL)
2609    temp=idMaxIdeal(1);
2610  else
2611    temp=(ideal)id->Data();
2612
2613  k = binom(n,d);
2614  l = k*d;
2615  l /= n-d+1;
2616  result =mpNew(l,k);
2617  col = 1;
2618  idInitChoise(d,1,n,&bo,choise);
2619  while (!bo)
2620  {
2621    sign = 1;
2622    for (l=1;l<=d;l++)
2623    {
2624      if (choise[l-1]<=IDELEMS(temp))
2625      {
2626        p = pCopy(temp->m[choise[l-1]-1]);
2627        if (sign == -1) p = pNeg(p);
2628        sign *= -1;
2629        row = idGetNumberOfChoise(l-1,d,1,n,choise);
2630        MATELEM(result,row,col) = p;
2631      }
2632    }
2633    col++;
2634    idGetNextChoise(d,n,&bo,choise);
2635  }
2636  if (id==NULL) idDelete(&temp);
2637
2638  res->data=(char *)result;
2639  return FALSE;
2640}
2641
2642// from syz1.cc
2643/*2
2644* read out the Betti numbers from resolution
2645* (interpreter interface)
2646*/
2647BOOLEAN syBetti2(leftv res, leftv u, leftv w)
2648{
2649  syStrategy syzstr=(syStrategy)u->Data();
[22579cf]2650
[7447d8]2651  BOOLEAN minim=(int)(long)w->Data();
[938688]2652  int row_shift=0;
[7f14f2]2653  int add_row_shift=0;
2654  intvec *weights=NULL;
2655  intvec *ww=(intvec *)atGet(u,"isHomog",INTVEC_CMD);
2656  if (ww!=NULL)
2657  {
2658     weights=ivCopy(ww);
2659     add_row_shift = ww->min_in();
2660     (*weights) -= add_row_shift;
2661  }
[750e70]2662
[7f14f2]2663  res->data=(void *)syBettiOfComputation(syzstr,minim,&row_shift,weights);
2664  //row_shift += add_row_shift;
2665  //Print("row_shift=%d, add_row_shift=%d\n",row_shift,add_row_shift);
2666  atSet(res,omStrDup("rowShift"),(void*)add_row_shift,INT_CMD);
[22579cf]2667
[938688]2668  return FALSE;
2669}
2670BOOLEAN syBetti1(leftv res, leftv u)
2671{
[7f14f2]2672  sleftv tmp;
2673  memset(&tmp,0,sizeof(tmp));
2674  tmp.rtyp=INT_CMD;
[7035b2]2675  tmp.data=(void *)1;
[7f14f2]2676  return syBetti2(res,u,&tmp);
[938688]2677}
2678
2679/*3
2680* converts a resolution into a list of modules
2681*/
[f43a74]2682lists syConvRes(syStrategy syzstr,BOOLEAN toDel,int add_row_shift)
[938688]2683{
[22579cf]2684  resolvente fullres = syzstr->fullres;
2685  resolvente minres = syzstr->minres;
2686
2687  const int length = syzstr->length;
2688
2689  if ((fullres==NULL) && (minres==NULL))
[938688]2690  {
2691    if (syzstr->hilb_coeffs==NULL)
[750e70]2692    { // La Scala
[22579cf]2693      fullres = syReorder(syzstr->res, length, syzstr);
[938688]2694    }
2695    else
[750e70]2696    { // HRES
[22579cf]2697      minres = syReorder(syzstr->orderedRes, length, syzstr);
2698      syKillEmptyEntres(minres, length);
[938688]2699    }
2700  }
[22579cf]2701
[938688]2702  resolvente tr;
2703  int typ0=IDEAL_CMD;
[22579cf]2704
2705  if (minres!=NULL)
2706    tr = minres;
[938688]2707  else
[22579cf]2708    tr = fullres;
[750e70]2709
[22579cf]2710  resolvente trueres=NULL; intvec ** w=NULL;
2711
2712  if (length>0)
[938688]2713  {
[22579cf]2714    trueres = (resolvente)omAlloc0((length)*sizeof(ideal));
2715    for (int i=(length)-1;i>=0;i--)
[938688]2716    {
2717      if (tr[i]!=NULL)
2718      {
2719        trueres[i] = idCopy(tr[i]);
2720      }
2721    }
[8156a7]2722    if ( id_RankFreeModule(trueres[0], currRing) > 0)
[938688]2723      typ0 = MODUL_CMD;
2724    if (syzstr->weights!=NULL)
2725    {
[22579cf]2726      w = (intvec**)omAlloc0(length*sizeof(intvec*));
2727      for (int i=length-1;i>=0;i--)
[938688]2728      {
2729        if (syzstr->weights[i]!=NULL) w[i] = ivCopy(syzstr->weights[i]);
2730      }
2731    }
2732  }
[750e70]2733
[22579cf]2734  lists li = liMakeResolv(trueres, length, syzstr->list_length,typ0,
2735                          w, add_row_shift);
2736
2737  if (w != NULL) omFreeSize(w, length*sizeof(intvec*));
[750e70]2738
[22579cf]2739  if (toDel)
2740    syKillComputation(syzstr);
2741  else
2742  {
2743    if( fullres != NULL && syzstr->fullres == NULL )
2744      syzstr->fullres = fullres;
2745
2746    if( minres != NULL && syzstr->minres == NULL )
2747      syzstr->minres = minres;
2748  }
[750e70]2749
[938688]2750  return li;
[22579cf]2751
[750e70]2752
[938688]2753}
2754
2755/*3
2756* converts a list of modules into a resolution
2757*/
2758syStrategy syConvList(lists li,BOOLEAN toDel)
2759{
2760  int typ0;
2761  syStrategy result=(syStrategy)omAlloc0(sizeof(ssyStrategy));
2762
2763  resolvente fr = liFindRes(li,&(result->length),&typ0,&(result->weights));
2764  if (fr != NULL)
2765  {
2766
2767    result->fullres = (resolvente)omAlloc0((result->length+1)*sizeof(ideal));
2768    for (int i=result->length-1;i>=0;i--)
2769    {
2770      if (fr[i]!=NULL)
2771        result->fullres[i] = idCopy(fr[i]);
2772    }
2773    result->list_length=result->length;
2774    omFreeSize((ADDRESS)fr,(result->length)*sizeof(ideal));
2775  }
2776  else
2777  {
2778    omFreeSize(result, sizeof(ssyStrategy));
2779    result = NULL;
2780  }
2781  if (toDel) li->Clean();
2782  return result;
2783}
2784
2785/*3
2786* converts a list of modules into a minimal resolution
2787*/
2788syStrategy syForceMin(lists li)
2789{
2790  int typ0;
2791  syStrategy result=(syStrategy)omAlloc0(sizeof(ssyStrategy));
2792
2793  resolvente fr = liFindRes(li,&(result->length),&typ0);
2794  result->minres = (resolvente)omAlloc0((result->length+1)*sizeof(ideal));
2795  for (int i=result->length-1;i>=0;i--)
2796  {
2797    if (fr[i]!=NULL)
2798      result->minres[i] = idCopy(fr[i]);
2799  }
2800  omFreeSize((ADDRESS)fr,(result->length)*sizeof(ideal));
2801  return result;
2802}
2803// from weight.cc
2804BOOLEAN kWeight(leftv res,leftv id)
2805{
2806  ideal F=(ideal)id->Data();
[7fccc79]2807  intvec * iv = new intvec(rVar(currRing));
[938688]2808  polyset s;
2809  int  sl, n, i;
2810  int  *x;
2811
2812  res->data=(char *)iv;
2813  s = F->m;
2814  sl = IDELEMS(F) - 1;
[7fccc79]2815  n = rVar(currRing);
[6aacb6]2816  double wNsqr = (double)2.0 / (double)n;
[938688]2817  wFunctional = wFunctionalBuch;
2818  x = (int * )omAlloc(2 * (n + 1) * sizeof(int));
[6cc7f5]2819  wCall(s, sl, x, wNsqr, currRing);
[938688]2820  for (i = n; i!=0; i--)
2821    (*iv)[i-1] = x[i + n + 1];
2822  omFreeSize((ADDRESS)x, 2 * (n + 1) * sizeof(int));
2823  return FALSE;
2824}
2825
2826BOOLEAN kQHWeight(leftv res,leftv v)
2827{
[d84a4d]2828  res->data=(char *)id_QHomWeight((ideal)v->Data(), currRing);
[938688]2829  if (res->data==NULL)
[7fccc79]2830    res->data=(char *)new intvec(rVar(currRing));
[938688]2831  return FALSE;
2832}
2833/*==============================================================*/
2834// from clapsing.cc
2835#if 0
2836BOOLEAN jjIS_SQR_FREE(leftv res, leftv u)
2837{
[e07e7d1]2838  BOOLEAN b=singclap_factorize((poly)(u->CopyD()), &v, 0);
[938688]2839  res->data=(void *)b;
2840}
2841#endif
2842
2843BOOLEAN jjRESULTANT(leftv res, leftv u, leftv v, leftv w)
2844{
[f0168a5]2845#ifdef HAVE_FACTORY
[6cc7f5]2846  res->data=singclap_resultant((poly)u->CopyD(),(poly)v->CopyD(),
[3373e32]2847                  (poly)w->CopyD(), currRing);
[938688]2848  return errorreported;
[f0168a5]2849#else
2850  Werror("Sorry: not yet re-factored: see libpolys/polys/clapsing.cc");
2851  return FALSE;
2852#endif
[938688]2853}
[f0168a5]2854
[938688]2855BOOLEAN jjCHARSERIES(leftv res, leftv u)
2856{
[f0168a5]2857#if defined(HAVE_FACTORY) && defined(HAVE_LIBFAC)
[6cc7f5]2858  res->data=singclap_irrCharSeries((ideal)u->Data(), currRing);
[938688]2859  return (res->data==NULL);
[f0168a5]2860#else
2861  Werror("Sorry: not yet re-factored: see libpolys/polys/clapsing.cc");
2862  return FALSE;
[3aa9b6]2863#endif
[938688]2864}
2865
2866// from semic.cc
2867#ifdef HAVE_SPECTRUM
2868
2869// ----------------------------------------------------------------------------
2870//  Initialize a  spectrum  deep from a  singular  lists
2871// ----------------------------------------------------------------------------
2872
[47a4c2]2873void copy_deep( spectrum& spec, lists l )
[938688]2874{
[47a4c2]2875    spec.mu = (int)(long)(l->m[0].Data( ));
2876    spec.pg = (int)(long)(l->m[1].Data( ));
2877    spec.= (int)(long)(l->m[2].Data( ));
[938688]2878
[47a4c2]2879    spec.copy_new( spec.n );
[938688]2880
2881    intvec  *num = (intvec*)l->m[3].Data( );
2882    intvec  *den = (intvec*)l->m[4].Data( );
2883    intvec  *mul = (intvec*)l->m[5].Data( );
2884
[47a4c2]2885    for( int i=0; i<spec.n; i++ )
[938688]2886    {
[47a4c2]2887        spec.s[i] = (Rational)((*num)[i])/(Rational)((*den)[i]);
2888        spec.w[i] = (*mul)[i];
[938688]2889    }
2890}
2891
2892// ----------------------------------------------------------------------------
2893//  singular lists  constructor for  spectrum
2894// ----------------------------------------------------------------------------
2895
[47a4c2]2896spectrum /*former spectrum::spectrum ( lists l )*/
2897spectrumFromList( lists l )
[938688]2898{
[47a4c2]2899    spectrum result;
2900    copy_deep( result, l );
2901    return result;
[938688]2902}
2903
2904// ----------------------------------------------------------------------------
2905//  generate a Singular  lists  from a spectrum
2906// ----------------------------------------------------------------------------
2907
[47a4c2]2908/* former spectrum::thelist ( void )*/
2909lists   getList( spectrum& spec )
[938688]2910{
2911    lists   L  = (lists)omAllocBin( slists_bin);
2912
2913    L->Init( 6 );
2914
[47a4c2]2915    intvec            *num  = new intvec( spec.n );
2916    intvec            *den  = new intvec( spec.n );
2917    intvec            *mult = new intvec( spec.n );
[938688]2918
[47a4c2]2919    for( int i=0; i<spec.n; i++ )
[938688]2920    {
[47a4c2]2921        (*num) [i] = spec.s[i].get_num_si( );
2922        (*den) [i] = spec.s[i].get_den_si( );
2923        (*mult)[i] = spec.w[i];
[938688]2924    }
2925
2926    L->m[0].rtyp = INT_CMD;    //  milnor number
2927    L->m[1].rtyp = INT_CMD;    //  geometrical genus
2928    L->m[2].rtyp = INT_CMD;    //  # of spectrum numbers
2929    L->m[3].rtyp = INTVEC_CMD; //  numerators
2930    L->m[4].rtyp = INTVEC_CMD; //  denomiantors
2931    L->m[5].rtyp = INTVEC_CMD; //  multiplicities
2932
[47a4c2]2933    L->m[0].data = (void*)spec.mu;
2934    L->m[1].data = (void*)spec.pg;
2935    L->m[2].data = (void*)spec.n;
[938688]2936    L->m[3].data = (void*)num;
2937    L->m[4].data = (void*)den;
2938    L->m[5].data = (void*)mult;
2939
2940    return  L;
2941}
2942// from spectrum.cc
2943// ----------------------------------------------------------------------------
2944//  print out an error message for a spectrum list
2945// ----------------------------------------------------------------------------
2946
[47a4c2]2947typedef enum
2948{
2949    semicOK,
2950    semicMulNegative,
2951
2952    semicListTooShort,
2953    semicListTooLong,
2954
2955    semicListFirstElementWrongType,
2956    semicListSecondElementWrongType,
2957    semicListThirdElementWrongType,
2958    semicListFourthElementWrongType,
2959    semicListFifthElementWrongType,
2960    semicListSixthElementWrongType,
2961
2962    semicListNNegative,
2963    semicListWrongNumberOfNumerators,
2964    semicListWrongNumberOfDenominators,
2965    semicListWrongNumberOfMultiplicities,
2966
2967    semicListMuNegative,
2968    semicListPgNegative,
2969    semicListNumNegative,
2970    semicListDenNegative,
2971    semicListMulNegative,
2972
2973    semicListNotSymmetric,
2974    semicListNotMonotonous,
2975
2976    semicListMilnorWrong,
2977    semicListPGWrong
2978
2979} semicState;
2980
[938688]2981void    list_error( semicState state )
2982{
2983    switch( state )
2984    {
2985        case semicListTooShort:
2986            WerrorS( "the list is too short" );
2987            break;
2988        case semicListTooLong:
2989            WerrorS( "the list is too long" );
2990            break;
2991
2992        case semicListFirstElementWrongType:
2993            WerrorS( "first element of the list should be int" );
2994            break;
2995        case semicListSecondElementWrongType:
2996            WerrorS( "second element of the list should be int" );
2997            break;
2998        case semicListThirdElementWrongType:
2999            WerrorS( "third element of the list should be int" );
3000            break;
3001        case semicListFourthElementWrongType:
3002            WerrorS( "fourth element of the list should be intvec" );
3003            break;
3004        case semicListFifthElementWrongType:
3005            WerrorS( "fifth element of the list should be intvec" );
3006            break;
3007        case semicListSixthElementWrongType:
3008            WerrorS( "sixth element of the list should be intvec" );
3009            break;
3010
3011        case semicListNNegative:
3012            WerrorS( "first element of the list should be positive" );
3013            break;
3014        case semicListWrongNumberOfNumerators:
3015            WerrorS( "wrong number of numerators" );
3016            break;
3017        case semicListWrongNumberOfDenominators:
3018            WerrorS( "wrong number of denominators" );
3019            break;
3020        case semicListWrongNumberOfMultiplicities:
3021            WerrorS( "wrong number of multiplicities" );
3022            break;
3023
3024        case semicListMuNegative:
3025            WerrorS( "the Milnor number should be positive" );
3026            break;
3027        case semicListPgNegative:
3028            WerrorS( "the geometrical genus should be nonnegative" );
3029            break;
3030        case semicListNumNegative:
3031            WerrorS( "all numerators should be positive" );
3032            break;
3033        case semicListDenNegative:
3034            WerrorS( "all denominators should be positive" );
3035            break;
3036        case semicListMulNegative:
3037            WerrorS( "all multiplicities should be positive" );
3038            break;
3039
3040        case semicListNotSymmetric:
3041            WerrorS( "it is not symmetric" );
3042            break;
3043        case semicListNotMonotonous:
3044            WerrorS( "it is not monotonous" );
3045            break;
3046
3047        case semicListMilnorWrong:
3048            WerrorS( "the Milnor number is wrong" );
3049            break;
3050        case semicListPGWrong:
3051            WerrorS( "the geometrical genus is wrong" );
3052            break;
3053
3054        default:
3055            WerrorS( "unspecific error" );
3056            break;
3057    }
3058}
3059// ----------------------------------------------------------------------------
3060//  this is the main spectrum computation function
3061// ----------------------------------------------------------------------------
3062
[47a4c2]3063enum    spectrumState
3064{
3065    spectrumOK,
3066    spectrumZero,
3067    spectrumBadPoly,
3068    spectrumNoSingularity,
3069    spectrumNotIsolated,
3070    spectrumDegenerate,
3071    spectrumWrongRing,
3072    spectrumNoHC,
3073    spectrumUnspecErr
3074};
3075
[f5bef2]3076// from splist.cc
3077// ----------------------------------------------------------------------------
3078//  Compute the spectrum of a  spectrumPolyList
3079// ----------------------------------------------------------------------------
3080
3081/* former spectrumPolyList::spectrum ( lists*, int) */
3082spectrumState   spectrumStateFromList( spectrumPolyList& speclist, lists *L,int fast )
3083{
3084  spectrumPolyNode  **node = &speclist.root;
3085  spectrumPolyNode  *search;
3086
3087  poly              f,tmp;
3088  int               found,cmp;
3089
3090  Rational smax( ( fast==0 ? 0 : rVar(currRing) ),
3091                 ( fast==2 ? 2 : 1 ) );
3092
3093  Rational weight_prev( 0,1 );
3094
3095  int     mu = 0;          // the milnor number
3096  int     pg = 0;          // the geometrical genus
3097  int     n  = 0;          // number of different spectral numbers
3098  int     z  = 0;          // number of spectral number equal to smax
3099
3100  while( (*node)!=(spectrumPolyNode*)NULL &&
3101         ( fast==0 || (*node)->weight<=smax ) )
3102  {
3103        // ---------------------------------------
3104        //  determine the first normal form which
3105        //  contains the monomial  node->mon
3106        // ---------------------------------------
3107
3108    found  = FALSE;
3109    search = *node;
3110
3111    while( search!=(spectrumPolyNode*)NULL && found==FALSE )
3112    {
3113      if( search->nf!=(poly)NULL )
3114      {
3115        f = search->nf;
3116
3117        do
3118        {
3119                    // --------------------------------
3120                    //  look for  (*node)->mon  in   f
3121                    // --------------------------------
3122
3123          cmp = pCmp( (*node)->mon,f );
3124
3125          if( cmp<0 )
3126          {
3127            f = pNext( f );
3128          }
3129          else if( cmp==0 )
3130          {
3131                        // -----------------------------
3132                        //  we have found a normal form
3133                        // -----------------------------
3134
3135            found = TRUE;
3136
3137                        //  normalize coefficient
3138
3139            number inv = nInvers( pGetCoeff( f ) );
3140            pMult_nn( search->nf,inv );
3141            nDelete( &inv );
3142
3143                        //  exchange  normal forms
3144
3145            tmp         = (*node)->nf;
3146            (*node)->nf = search->nf;
3147            search->nf  = tmp;
3148          }
3149        }
3150        while( cmp<0 && f!=(poly)NULL );
3151      }
3152      search = search->next;
3153    }
3154
3155    if( found==FALSE )
3156    {
3157            // ------------------------------------------------
3158            //  the weight of  node->mon  is a spectrum number
3159            // ------------------------------------------------
3160
3161      mu++;
3162
3163      if( (*node)->weight<=(Rational)1 )              pg++;
3164      if( (*node)->weight==smax )           z++;
3165      if( (*node)->weight>weight_prev )     n++;
3166
3167      weight_prev = (*node)->weight;
3168      node = &((*node)->next);
3169    }
3170    else
3171    {
3172            // -----------------------------------------------
3173            //  determine all other normal form which contain
3174            //  the monomial  node->mon
3175            //  replace for  node->mon  its normal form
3176            // -----------------------------------------------
3177
3178      while( search!=(spectrumPolyNode*)NULL )
3179      {
3180        if( search->nf!=(poly)NULL )
3181        {
3182          f = search->nf;
3183
3184          do
3185          {
3186                        // --------------------------------
3187                        //  look for  (*node)->mon  in   f
3188                        // --------------------------------
3189
3190            cmp = pCmp( (*node)->mon,f );
3191
3192            if( cmp<0 )
3193            {
3194              f = pNext( f );
3195            }
3196            else if( cmp==0 )
3197            {
3198              search->nf = pSub( search->nf,
3199                                 ppMult_nn( (*node)->nf,pGetCoeff( f ) ) );
3200              pNorm( search->nf );
3201            }
3202          }
3203          while( cmp<0 && f!=(poly)NULL );
3204        }
3205        search = search->next;
3206      }
3207      speclist.delete_node( node );
3208    }
3209
3210  }
3211
3212    // --------------------------------------------------------
3213    //  fast computation exploits the symmetry of the spectrum
3214    // --------------------------------------------------------
3215
3216  if( fast==2 )
3217  {
3218    mu = 2*mu - z;
3219    n  = ( z > 0 ? 2*n - 1 : 2*n );
3220  }
3221
3222    // --------------------------------------------------------
3223    //  compute the spectrum numbers with their multiplicities
3224    // --------------------------------------------------------
3225
3226  intvec            *nom  = new intvec( n );
3227  intvec            *den  = new intvec( n );
3228  intvec            *mult = new intvec( n );
3229
3230  int count         = 0;
3231  int multiplicity  = 1;
3232
3233  for( search=speclist.root; search!=(spectrumPolyNode*)NULL &&
3234              ( fast==0 || search->weight<=smax );
3235       search=search->next )
3236  {
3237    if( search->next==(spectrumPolyNode*)NULL ||
3238        search->weight<search->next->weight )
3239    {
3240      (*nom) [count] = search->weight.get_num_si( );
3241      (*den) [count] = search->weight.get_den_si( );
3242      (*mult)[count] = multiplicity;
3243
3244      multiplicity=1;
3245      count++;
3246    }
3247    else
3248    {
3249      multiplicity++;
3250    }
3251  }
3252
3253    // --------------------------------------------------------
3254    //  fast computation exploits the symmetry of the spectrum
3255    // --------------------------------------------------------
3256
3257  if( fast==2 )
3258  {
3259    int n1,n2;
3260    for( n1=0, n2=n-1; n1<n2; n1++, n2-- )
3261    {
3262      (*nom) [n2] = rVar(currRing)*(*den)[n1]-(*nom)[n1];
3263      (*den) [n2] = (*den)[n1];
3264      (*mult)[n2] = (*mult)[n1];
3265    }
3266  }
3267
3268    // -----------------------------------
3269    //  test if the spectrum is symmetric
3270    // -----------------------------------
3271
3272  if( fast==0 || fast==1 )
3273  {
3274    int symmetric=TRUE;
3275
3276    for( int n1=0, n2=n-1 ; n1<n2 && symmetric==TRUE; n1++, n2-- )
3277    {
3278      if( (*mult)[n1]!=(*mult)[n2] ||
3279          (*den) [n1]!= (*den)[n2] ||
3280          (*nom)[n1]+(*nom)[n2]!=rVar(currRing)*(*den) [n1] )
3281      {
3282        symmetric = FALSE;
3283      }
3284    }
3285
3286    if( symmetric==FALSE )
3287    {
3288            // ---------------------------------------------
3289            //  the spectrum is not symmetric => degenerate
3290            //  principal part
3291            // ---------------------------------------------
3292
3293      *L = (lists)omAllocBin( slists_bin);
3294      (*L)->Init( 1 );
3295      (*L)->m[0].rtyp = INT_CMD;    //  milnor number
3296      (*L)->m[0].data = (void*)mu;
3297
3298      return spectrumDegenerate;
3299    }
3300  }
3301
3302  *L = (lists)omAllocBin( slists_bin);
3303
3304  (*L)->Init( 6 );
3305
3306  (*L)->m[0].rtyp = INT_CMD;    //  milnor number
3307  (*L)->m[1].rtyp = INT_CMD;    //  geometrical genus
3308  (*L)->m[2].rtyp = INT_CMD;    //  number of spectrum values
3309  (*L)->m[3].rtyp = INTVEC_CMD; //  nominators
3310  (*L)->m[4].rtyp = INTVEC_CMD; //  denomiantors
3311  (*L)->m[5].rtyp = INTVEC_CMD; //  multiplicities
3312
3313  (*L)->m[0].data = (void*)mu;
3314  (*L)->m[1].data = (void*)pg;
3315  (*L)->m[2].data = (void*)n;
3316  (*L)->m[3].data = (void*)nom;
3317  (*L)->m[4].data = (void*)den;
3318  (*L)->m[5].data = (void*)mult;
3319
3320  return  spectrumOK;
3321}
3322
[938688]3323spectrumState   spectrumCompute( poly h,lists *L,int fast )
3324{
[69672d]3325  int i;
[938688]3326
3327  #ifdef SPECTRUM_DEBUG
3328  #ifdef SPECTRUM_PRINT
3329  #ifdef SPECTRUM_IOSTREAM
3330    cout << "spectrumCompute\n";
3331    if( fast==0 ) cout << "    no optimization" << endl;
3332    if( fast==1 ) cout << "    weight optimization" << endl;
3333    if( fast==2 ) cout << "    symmetry optimization" << endl;
3334  #else
3335    fprintf( stdout,"spectrumCompute\n" );
3336    if( fast==0 ) fprintf( stdout,"    no optimization\n" );
3337    if( fast==1 ) fprintf( stdout,"    weight optimization\n" );
3338    if( fast==2 ) fprintf( stdout,"    symmetry optimization\n" );
3339  #endif
3340  #endif
3341  #endif
3342
3343  // ----------------------
3344  //  check if  h  is zero
3345  // ----------------------
3346
3347  if( h==(poly)NULL )
3348  {
3349    return  spectrumZero;
3350  }
3351
3352  // ----------------------------------
3353  //  check if  h  has a constant term
3354  // ----------------------------------
3355
[6cc7f5]3356  if( hasConstTerm( h, currRing ) )
[938688]3357  {
3358    return  spectrumBadPoly;
3359  }
3360
3361  // --------------------------------
3362  //  check if  h  has a linear term
3363  // --------------------------------
3364
[6cc7f5]3365  if( hasLinearTerm( h, currRing ) )
[938688]3366  {
3367    *L = (lists)omAllocBin( slists_bin);
3368    (*L)->Init( 1 );
3369    (*L)->m[0].rtyp = INT_CMD;    //  milnor number
3370    /* (*L)->m[0].data = (void*)0;a  -- done by Init */
3371
3372    return  spectrumNoSingularity;
3373  }
3374
3375  // ----------------------------------
3376  //  compute the jacobi ideal of  (h)
3377  // ----------------------------------
3378
3379  ideal J = NULL;
[7fccc79]3380  J = idInit( rVar(currRing),1 );
[938688]3381
3382  #ifdef SPECTRUM_DEBUG
3383  #ifdef SPECTRUM_PRINT
3384  #ifdef SPECTRUM_IOSTREAM
3385    cout << "\n   computing the Jacobi ideal...\n";
3386  #else
3387    fprintf( stdout,"\n   computing the Jacobi ideal...\n" );
3388  #endif
3389  #endif
3390  #endif
3391
[7fccc79]3392  for( i=0; i<rVar(currRing); i++ )
[938688]3393  {
3394    J->m[i] = pDiff( h,i+1); //j );
3395
3396    #ifdef SPECTRUM_DEBUG
3397    #ifdef SPECTRUM_PRINT
3398    #ifdef SPECTRUM_IOSTREAM
3399      cout << "        ";
3400    #else
3401      fprintf( stdout,"        " );
3402    #endif
3403      pWrite( J->m[i] );
3404    #endif
3405    #endif
3406  }
3407
3408  // --------------------------------------------
3409  //  compute a standard basis  stdJ  of  jac(h)
3410  // --------------------------------------------
3411
3412  #ifdef SPECTRUM_DEBUG
3413  #ifdef SPECTRUM_PRINT
3414  #ifdef SPECTRUM_IOSTREAM
3415    cout << endl;
3416    cout << "    computing a standard basis..." << endl;
3417  #else
3418    fprintf( stdout,"\n" );
3419    fprintf( stdout,"    computing a standard basis...\n" );
3420  #endif
3421  #endif
3422  #endif
3423
3424  ideal stdJ = kStd(J,currQuotient,isNotHomog,NULL);
3425  idSkipZeroes( stdJ );
3426
3427  #ifdef SPECTRUM_DEBUG
3428  #ifdef SPECTRUM_PRINT
3429    for( i=0; i<IDELEMS(stdJ); i++ )
3430    {
3431      #ifdef SPECTRUM_IOSTREAM
3432        cout << "        ";
3433      #else
3434        fprintf( stdout,"        " );
3435      #endif
3436
3437      pWrite( stdJ->m[i] );
3438    }
3439  #endif
3440  #endif
3441
3442  idDelete( &J );
3443
3444  // ------------------------------------------
3445  //  check if the  h  has a singularity
3446  // ------------------------------------------
3447
[6cc7f5]3448  if( hasOne( stdJ, currRing ) )
[938688]3449  {
3450    // -------------------------------
3451    //  h is smooth in the origin
3452    //  return only the Milnor number
3453    // -------------------------------
3454
3455    *L = (lists)omAllocBin( slists_bin);
3456    (*L)->Init( 1 );
3457    (*L)->m[0].rtyp = INT_CMD;    //  milnor number
3458    /* (*L)->m[0].data = (void*)0;a  -- done by Init */
3459
3460    return  spectrumNoSingularity;
3461  }
3462
3463  // ------------------------------------------
3464  //  check if the singularity  h  is isolated
3465  // ------------------------------------------
3466
[7fccc79]3467  for( i=rVar(currRing); i>0; i-- )
[938688]3468  {
[6cc7f5]3469    if( hasAxis( stdJ,i, currRing )==FALSE )
[938688]3470    {
3471      return  spectrumNotIsolated;
3472    }
3473  }
3474
3475  // ------------------------------------------
3476  //  compute the highest corner  hc  of  stdJ
3477  // ------------------------------------------
3478
3479  #ifdef SPECTRUM_DEBUG
3480  #ifdef SPECTRUM_PRINT
3481  #ifdef SPECTRUM_IOSTREAM
3482    cout << "\n    computing the highest corner...\n";
3483  #else
3484    fprintf( stdout,"\n    computing the highest corner...\n" );
3485  #endif
3486  #endif
3487  #endif
3488
3489  poly hc = (poly)NULL;
3490
3491  scComputeHC( stdJ,currQuotient, 0,hc );
3492
3493  if( hc!=(poly)NULL )
3494  {
3495    pGetCoeff(hc) = nInit(1);
3496
[7fccc79]3497    for( i=rVar(currRing); i>0; i-- )
[938688]3498    {
3499      if( pGetExp( hc,i )>0 ) pDecrExp( hc,i );
3500    }
3501    pSetm( hc );
3502  }
3503  else
3504  {
3505    return  spectrumNoHC;
3506  }
3507
3508  #ifdef SPECTRUM_DEBUG
3509  #ifdef SPECTRUM_PRINT
3510  #ifdef SPECTRUM_IOSTREAM
3511    cout << "       ";
3512  #else
3513    fprintf( stdout,"       " );
3514  #endif
3515    pWrite( hc );
3516  #endif
3517  #endif
3518
3519  // ----------------------------------------
3520  //  compute the Newton polygon  nph  of  h
3521  // ----------------------------------------
3522
3523  #ifdef SPECTRUM_DEBUG
3524  #ifdef SPECTRUM_PRINT
3525  #ifdef SPECTRUM_IOSTREAM
3526    cout << "\n    computing the newton polygon...\n";
3527  #else
3528    fprintf( stdout,"\n    computing the newton polygon...\n" );
3529  #endif
3530  #endif
3531  #endif
3532
[47a4c2]3533  newtonPolygon nph( h, currRing );
[938688]3534
3535  #ifdef SPECTRUM_DEBUG
3536  #ifdef SPECTRUM_PRINT
3537    cout << nph;
3538  #endif
3539  #endif
3540
3541  // -----------------------------------------------
3542  //  compute the weight corner  wc  of  (stdj,nph)
3543  // -----------------------------------------------
3544
3545  #ifdef SPECTRUM_DEBUG
3546  #ifdef SPECTRUM_PRINT
3547  #ifdef SPECTRUM_IOSTREAM
3548    cout << "\n    computing the weight corner...\n";
3549  #else
3550    fprintf( stdout,"\n    computing the weight corner...\n" );
3551  #endif
3552  #endif
3553  #endif
3554
3555  poly    wc = ( fast==0 ? pCopy( hc ) :
[6cc7f5]3556               ( fast==1 ? computeWC( nph,(Rational)rVar(currRing), currRing ) :
3557              /* fast==2 */computeWC( nph,
[3373e32]3558                      ((Rational)rVar(currRing))/(Rational)2, currRing ) ) );
[938688]3559
3560  #ifdef SPECTRUM_DEBUG
3561  #ifdef SPECTRUM_PRINT
3562  #ifdef SPECTRUM_IOSTREAM
3563    cout << "        ";
3564  #else
3565    fprintf( stdout,"        " );
3566  #endif
3567    pWrite( wc );
3568  #endif
3569  #endif
3570
3571  // -------------
3572  //  compute  NF
3573  // -------------
3574
3575  #ifdef SPECTRUM_DEBUG
3576  #ifdef SPECTRUM_PRINT
3577  #ifdef SPECTRUM_IOSTREAM
3578    cout << "\n    computing NF...\n" << endl;
3579  #else
3580    fprintf( stdout,"\n    computing NF...\n" );
3581  #endif
3582  #endif
3583  #endif
3584
3585  spectrumPolyList NF( &nph );
3586
[6cc7f5]3587  computeNF( stdJ,hc,wc,&NF, currRing );
[938688]3588
3589  #ifdef SPECTRUM_DEBUG
3590  #ifdef SPECTRUM_PRINT
3591    cout << NF;
3592  #ifdef SPECTRUM_IOSTREAM
3593    cout << endl;
3594  #else
3595    fprintf( stdout,"\n" );
3596  #endif
3597  #endif
3598  #endif
3599
3600  // ----------------------------
3601  //  compute the spectrum of  h
3602  // ----------------------------
[f5bef2]3603//  spectrumState spectrumStateFromList( spectrumPolyList& speclist, lists *L, int fast );
[938688]3604
[f5bef2]3605  return spectrumStateFromList(NF, L, fast );
[938688]3606}
3607
3608// ----------------------------------------------------------------------------
3609//  this procedure is called from the interpreter
3610// ----------------------------------------------------------------------------
3611//  first  = polynomial
3612//  result = list of spectrum numbers
3613// ----------------------------------------------------------------------------
3614
[47a4c2]3615void spectrumPrintError(spectrumState state)
3616{
3617  switch( state )
3618  {
3619    case spectrumZero:
3620      WerrorS( "polynomial is zero" );
3621      break;
3622    case spectrumBadPoly:
3623      WerrorS( "polynomial has constant term" );
3624      break;
3625    case spectrumNoSingularity:
3626      WerrorS( "not a singularity" );
3627      break;
3628    case spectrumNotIsolated:
3629      WerrorS( "the singularity is not isolated" );
3630      break;
3631    case spectrumNoHC:
3632      WerrorS( "highest corner cannot be computed" );
3633      break;
3634    case spectrumDegenerate:
3635      WerrorS( "principal part is degenerate" );
3636      break;
3637    case spectrumOK:
3638      break;
3639
3640    default:
3641      WerrorS( "unknown error occurred" );
3642      break;
3643  }
3644}
3645
[938688]3646BOOLEAN spectrumProc( leftv result,leftv first )
3647{
3648  spectrumState state = spectrumOK;
3649
3650  // -------------------
3651  //  check consistency
3652  // -------------------
3653
3654  //  check for a local ring
3655
[6cc7f5]3656  if( !ringIsLocal(currRing ) )
[938688]3657  {
3658    WerrorS( "only works for local orderings" );
3659    state = spectrumWrongRing;
3660  }
3661
3662  //  no quotient rings are allowed
3663
3664  else if( currRing->qideal != NULL )
3665  {
3666    WerrorS( "does not work in quotient rings" );
3667    state = spectrumWrongRing;
3668  }
3669  else
3670  {
3671    lists   L    = (lists)NULL;
3672    int     flag = 1; // weight corner optimization is safe
3673
3674    state = spectrumCompute( (poly)first->Data( ),&L,flag );
3675
3676    if( state==spectrumOK )
3677    {
3678      result->rtyp = LIST_CMD;
3679      result->data = (char*)L;
3680    }
3681    else
3682    {
3683      spectrumPrintError(state);
3684    }
3685  }
3686
3687  return  (state!=spectrumOK);
3688}
3689
3690// ----------------------------------------------------------------------------
3691//  this procedure is called from the interpreter
3692// ----------------------------------------------------------------------------
3693//  first  = polynomial
3694//  result = list of spectrum numbers
3695// ----------------------------------------------------------------------------
3696
3697BOOLEAN spectrumfProc( leftv result,leftv first )
3698{
3699  spectrumState state = spectrumOK;
3700
3701  // -------------------
3702  //  check consistency
3703  // -------------------
3704
3705  //  check for a local polynomial ring
3706
3707  if( currRing->OrdSgn != -1 )
3708  // ?? HS: the test above is also true for k[x][[y]], k[[x]][y]
3709  // or should we use:
3710  //if( !ringIsLocal( ) )
3711  {
3712    WerrorS( "only works for local orderings" );
3713    state = spectrumWrongRing;
3714  }
3715  else if( currRing->qideal != NULL )
3716  {
3717    WerrorS( "does not work in quotient rings" );
3718    state = spectrumWrongRing;
3719  }
3720  else
3721  {
3722    lists   L    = (lists)NULL;
3723    int     flag = 2; // symmetric optimization
3724
3725    state = spectrumCompute( (poly)first->Data( ),&L,flag );
3726
3727    if( state==spectrumOK )
3728    {
3729      result->rtyp = LIST_CMD;
3730      result->data = (char*)L;
3731    }
3732    else
3733    {
3734      spectrumPrintError(state);
3735    }
3736  }
3737
3738  return  (state!=spectrumOK);
3739}
3740
3741// ----------------------------------------------------------------------------
3742//  check if a list is a spectrum
3743//  check for:
3744//      list has 6 elements
3745//      1st element is int (mu=Milnor number)
3746//      2nd element is int (pg=geometrical genus)
3747//      3rd element is int (n =number of different spectrum numbers)
3748//      4th element is intvec (num=numerators)
3749//      5th element is intvec (den=denomiantors)
3750//      6th element is intvec (mul=multiplicities)
3751//      exactly n numerators
3752//      exactly n denominators
3753//      exactly n multiplicities
3754//      mu>0
3755//      pg>=0
3756//      n>0
3757//      num>0
3758//      den>0
3759//      mul>0
3760//      symmetriy with respect to numberofvariables/2
3761//      monotony
3762//      mu = sum of all multiplicities
3763//      pg = sum of all multiplicities where num/den<=1
3764// ----------------------------------------------------------------------------
3765
3766semicState  list_is_spectrum( lists l )
3767{
3768    // -------------------
3769    //  check list length
3770    // -------------------
3771
3772    if( l->nr < 5 )
3773    {
3774        return  semicListTooShort;
3775    }
3776    else if( l->nr > 5 )
3777    {
3778        return  semicListTooLong;
3779    }
3780
3781    // -------------
3782    //  check types
3783    // -------------
3784
3785    if( l->m[0].rtyp != INT_CMD )
3786    {
3787        return  semicListFirstElementWrongType;
3788    }
3789    else if( l->m[1].rtyp != INT_CMD )
3790    {
3791        return  semicListSecondElementWrongType;
3792    }
3793    else if( l->m[2].rtyp != INT_CMD )
3794    {
3795        return  semicListThirdElementWrongType;
3796    }
3797    else if( l->m[3].rtyp != INTVEC_CMD )
3798    {
3799        return  semicListFourthElementWrongType;
3800    }
3801    else if( l->m[4].rtyp != INTVEC_CMD )
3802    {
3803        return  semicListFifthElementWrongType;
3804    }
3805    else if( l->m[5].rtyp != INTVEC_CMD )
3806    {
3807        return  semicListSixthElementWrongType;
3808    }
3809
3810    // -------------------------
3811    //  check number of entries
3812    // -------------------------
3813
[7447d8]3814    int     mu = (int)(long)(l->m[0].Data( ));
3815    int     pg = (int)(long)(l->m[1].Data( ));
3816    int     n  = (int)(long)(l->m[2].Data( ));
[938688]3817
3818    if( n <= 0 )
3819    {
3820        return  semicListNNegative;
3821    }
3822
3823    intvec  *num = (intvec*)l->m[3].Data( );
3824    intvec  *den = (intvec*)l->m[4].Data( );
3825    intvec  *mul = (intvec*)l->m[5].Data( );
3826
3827    if( n != num->length( ) )
3828    {
3829        return  semicListWrongNumberOfNumerators;
3830    }
3831    else if( n != den->length( ) )
3832    {
3833        return  semicListWrongNumberOfDenominators;
3834    }
3835    else if( n != mul->length( ) )
3836    {
3837        return  semicListWrongNumberOfMultiplicities;
3838    }
3839
3840    // --------
3841    //  values
3842    // --------
3843
3844    if( mu <= 0 )
3845    {
3846        return  semicListMuNegative;
3847    }
3848    if( pg < 0 )
3849    {
3850        return  semicListPgNegative;
3851    }
3852
3853    int i;
3854
3855    for( i=0; i<n; i++ )
3856    {
3857        if( (*num)[i] <= 0 )
3858        {
3859            return  semicListNumNegative;
3860        }
3861        if( (*den)[i] <= 0 )
3862        {
3863            return  semicListDenNegative;
3864        }
3865        if( (*mul)[i] <= 0 )
3866        {
3867            return  semicListMulNegative;
3868        }
3869    }
3870
3871    // ----------------
3872    //  check symmetry
3873    // ----------------
3874
3875    int     j;
3876
3877    for( i=0, j=n-1; i<=j; i++,j-- )
3878    {
[7fccc79]3879        if( (*num)[i] != rVar(currRing)*((*den)[i]) - (*num)[j] ||
[938688]3880            (*den)[i] != (*den)[j] ||
3881            (*mul)[i] != (*mul)[j] )
3882        {
3883            return  semicListNotSymmetric;
3884        }
3885    }
3886
3887    // ----------------
3888    //  check monotony
3889    // ----------------
3890
3891    for( i=0, j=1; i<n/2; i++,j++ )
3892    {
3893        if( (*num)[i]*(*den)[j] >= (*num)[j]*(*den)[i] )
3894        {
3895            return  semicListNotMonotonous;
3896        }
3897    }
3898
3899    // ---------------------
3900    //  check Milnor number
3901    // ---------------------
3902
3903    for( mu=0, i=0; i<n; i++ )
3904    {
3905        mu += (*mul)[i];
3906    }
3907
[7447d8]3908    if( mu != (int)(long)(l->m[0].Data( )) )
[938688]3909    {
3910        return  semicListMilnorWrong;
3911    }
3912
3913    // -------------------------
3914    //  check geometrical genus
3915    // -------------------------
3916
3917    for( pg=0, i=0; i<n; i++ )
3918    {
3919        if( (*num)[i]<=(*den)[i] )
3920        {
3921            pg += (*mul)[i];
3922        }
3923    }
3924
[7447d8]3925    if( pg != (int)(long)(l->m[1].Data( )) )
[938688]3926    {
3927        return  semicListPGWrong;
3928    }
3929
3930    return  semicOK;
3931}
3932
3933// ----------------------------------------------------------------------------
3934//  this procedure is called from the interpreter
3935// ----------------------------------------------------------------------------
3936//  first  = list of spectrum numbers
3937//  second = list of spectrum numbers
3938//  result = sum of the two lists
3939// ----------------------------------------------------------------------------
3940
3941BOOLEAN spaddProc( leftv result,leftv first,leftv second )
3942{
3943    semicState  state;
3944
3945    // -----------------
3946    //  check arguments
3947    // -----------------
3948
3949    lists l1 = (lists)first->Data( );
3950    lists l2 = (lists)second->Data( );
3951
3952    if( (state=list_is_spectrum( l1 )) != semicOK )
3953    {
3954        WerrorS( "first argument is not a spectrum:" );
3955        list_error( state );
3956    }
3957    else if( (state=list_is_spectrum( l2 )) != semicOK )
3958    {
3959        WerrorS( "second argument is not a spectrum:" );
3960        list_error( state );
3961    }
3962    else
3963    {
[47a4c2]3964        spectrum s1= spectrumFromList ( l1 );
3965        spectrum s2= spectrumFromList ( l2 );
[938688]3966        spectrum sum( s1+s2 );
3967
3968        result->rtyp = LIST_CMD;
[47a4c2]3969        result->data = (char*)(getList(sum));
[938688]3970    }
3971
3972    return  (state!=semicOK);
3973}
3974
3975// ----------------------------------------------------------------------------
3976//  this procedure is called from the interpreter
3977// ----------------------------------------------------------------------------
3978//  first  = list of spectrum numbers
3979//  second = integer
3980//  result = the multiple of the first list by the second factor
3981// ----------------------------------------------------------------------------
3982
3983BOOLEAN spmulProc( leftv result,leftv first,leftv second )
3984{
3985    semicState  state;
3986
3987    // -----------------
3988    //  check arguments
3989    // -----------------
3990
3991    lists   l = (lists)first->Data( );
[7447d8]3992    int     k = (int)(long)second->Data( );
[938688]3993
3994    if( (state=list_is_spectrum( l ))!=semicOK )
3995    {
3996        WerrorS( "first argument is not a spectrum" );
3997        list_error( state );
3998    }
3999    else if( k < 0 )
4000    {
4001        WerrorS( "second argument should be positive" );
4002        state = semicMulNegative;
4003    }
4004    else
4005    {
[47a4c2]4006        spectrum s= spectrumFromList( l );
[938688]4007        spectrum product( k*s );
4008
4009        result->rtyp = LIST_CMD;
[47a4c2]4010        result->data = (char*)getList(product);
[938688]4011    }
4012
4013    return  (state!=semicOK);
4014}
4015
4016// ----------------------------------------------------------------------------
4017//  this procedure is called from the interpreter
4018// ----------------------------------------------------------------------------
4019//  first  = list of spectrum numbers
4020//  second = list of spectrum numbers
4021//  result = semicontinuity index
4022// ----------------------------------------------------------------------------
4023
4024BOOLEAN    semicProc3   ( leftv res,leftv u,leftv v,leftv w )
4025{
4026  semicState  state;
[7447d8]4027  BOOLEAN qh=(((int)(long)w->Data())==1);
[938688]4028
4029  // -----------------
4030  //  check arguments
4031  // -----------------
4032
4033  lists l1 = (lists)u->Data( );
4034  lists l2 = (lists)v->Data( );
4035
4036  if( (state=list_is_spectrum( l1 ))!=semicOK )
4037  {
4038    WerrorS( "first argument is not a spectrum" );
4039    list_error( state );
4040  }
4041  else if( (state=list_is_spectrum( l2 ))!=semicOK )
4042  {
4043    WerrorS( "second argument is not a spectrum" );
4044    list_error( state );
4045  }
4046  else
4047  {
[47a4c2]4048    spectrum s1= spectrumFromList( l1 );
4049    spectrum s2= spectrumFromList( l2 );
[938688]4050
4051    res->rtyp = INT_CMD;
4052    if (qh)
4053      res->data = (void*)(s1.mult_spectrumh( s2 ));
4054    else
4055      res->data = (void*)(s1.mult_spectrum( s2 ));
4056  }
4057
4058  // -----------------
4059  //  check status
4060  // -----------------
4061
4062  return  (state!=semicOK);
4063}
4064BOOLEAN    semicProc   ( leftv res,leftv u,leftv v )
4065{
4066  sleftv tmp;
4067  memset(&tmp,0,sizeof(tmp));
4068  tmp.rtyp=INT_CMD;
4069  /* tmp.data = (void *)0;  -- done by memset */
4070
4071  return  semicProc3(res,u,v,&tmp);
4072}
4073
4074#endif
4075
4076//from mpr_inout.cc
[117518]4077extern void nPrint(number n);
[dc2d3d]4078
[938688]4079BOOLEAN loNewtonP( leftv res, leftv arg1 )
4080{
4081  res->data= (void*)loNewtonPolytope( (ideal)arg1->Data() );
4082  return FALSE;
4083}
4084
4085BOOLEAN loSimplex( leftv res, leftv args )
4086{
[6cc7f5]4087  if ( !(rField_is_long_R(currRing)) )
[938688]4088  {
4089    WerrorS("Ground field not implemented!");
4090    return TRUE;
4091  }
4092
4093  simplex * LP;
4094  matrix m;
4095
4096  leftv v= args;
4097  if ( v->Typ() != MATRIX_CMD ) // 1: matrix
4098    return TRUE;
4099  else
4100    m= (matrix)(v->CopyD());
4101
4102  LP = new simplex(MATROWS(m),MATCOLS(m));
4103  LP->mapFromMatrix(m);
4104
4105  v= v->next;
4106  if ( v->Typ() != INT_CMD )    // 2: m = number of constraints
4107    return TRUE;
4108  else
[7447d8]4109    LP->m= (int)(long)(v->Data());
[938688]4110
4111  v= v->next;
4112  if ( v->Typ() != INT_CMD )    // 3: n = number of variables
4113    return TRUE;
4114  else
[7447d8]4115    LP->n= (int)(long)(v->Data());
[938688]4116
4117  v= v->next;
4118  if ( v->Typ() != INT_CMD )    // 4: m1 = number of <= constraints
4119    return TRUE;
4120  else
[7447d8]4121    LP->m1= (int)(long)(v->Data());
[938688]4122
4123  v= v->next;
4124  if ( v->Typ() != INT_CMD )    // 5: m2 = number of >= constraints
4125    return TRUE;
4126  else
[7447d8]4127    LP->m2= (int)(long)(v->Data());
[938688]4128
4129  v= v->next;
4130  if ( v->Typ() != INT_CMD )    // 6: m3 = number of == constraints
4131    return TRUE;
4132  else
[7447d8]4133    LP->m3= (int)(long)(v->Data());
[938688]4134
4135#ifdef mprDEBUG_PROT
4136  Print("m (constraints) %d\n",LP->m);
4137  Print("n (columns) %d\n",LP->n);
4138  Print("m1 (<=) %d\n",LP->m1);
4139  Print("m2 (>=) %d\n",LP->m2);
4140  Print("m3 (==) %d\n",LP->m3);
4141#endif
4142
4143  LP->compute();
4144
4145  lists lres= (lists)omAlloc( sizeof(slists) );
4146  lres->Init( 6 );
4147
4148  lres->m[0].rtyp= MATRIX_CMD; // output matrix
4149  lres->m[0].data=(void*)LP->mapToMatrix(m);
4150
4151  lres->m[1].rtyp= INT_CMD;   // found a solution?
4152  lres->m[1].data=(void*)LP->icase;
4153
4154  lres->m[2].rtyp= INTVEC_CMD;
4155  lres->m[2].data=(void*)LP->posvToIV();
4156
4157  lres->m[3].rtyp= INTVEC_CMD;
4158  lres->m[3].data=(void*)LP->zrovToIV();
4159
4160  lres->m[4].rtyp= INT_CMD;
4161  lres->m[4].data=(void*)LP->m;
4162
4163  lres->m[5].rtyp= INT_CMD;
4164  lres->m[5].data=(void*)LP->n;
4165
4166  res->data= (void*)lres;
4167
4168  return FALSE;
4169}
4170
4171BOOLEAN nuMPResMat( leftv res, leftv arg1, leftv arg2 )
4172{
4173  ideal gls = (ideal)(arg1->Data());
[7447d8]4174  int imtype= (int)(long)arg2->Data();
[938688]4175
4176  uResultant::resMatType mtype= determineMType( imtype );
4177
4178  // check input ideal ( = polynomial system )
4179  if ( mprIdealCheck( gls, arg1->Name(), mtype, true ) != mprOk )
4180  {
4181    return TRUE;
4182  }
4183
4184  uResultant *resMat= new uResultant( gls, mtype, false );
[566961]4185  if (resMat!=NULL)
4186  {
4187    res->rtyp = MODUL_CMD;
4188    res->data= (void*)resMat->accessResMat()->getMatrix();
4189    if (!errorreported) delete resMat;
4190  }
4191  return errorreported;
[938688]4192}
4193
4194BOOLEAN nuLagSolve( leftv res, leftv arg1, leftv arg2, leftv arg3 )
4195{
4196
4197  poly gls;
4198  gls= (poly)(arg1->Data());
[7447d8]4199  int howclean= (int)(long)arg3->Data();
[938688]4200
[6cc7f5]4201  if ( !(rField_is_R(currRing) ||
4202         rField_is_Q(currRing) ||
4203         rField_is_long_R(currRing) ||
4204         rField_is_long_C(currRing)) )
[938688]4205  {
4206    WerrorS("Ground field not implemented!");
4207    return TRUE;
4208  }
4209
[6cc7f5]4210  if ( !(rField_is_R(currRing) || rField_is_long_R(currRing) || \
[3373e32]4211                          rField_is_long_C(currRing)) )
[938688]4212  {
4213    unsigned long int ii = (unsigned long int)arg2->Data();
4214    setGMPFloatDigits( ii, ii );
4215  }
4216
4217  if ( gls == NULL || pIsConstant( gls ) )
4218  {
4219    WerrorS("Input polynomial is constant!");
4220    return TRUE;
4221  }
4222
4223  int ldummy;
[3373e32]4224  int deg= currRing->pLDeg( gls, &ldummy, currRing );
[938688]4225  //  int deg= pDeg( gls );
[69672d]4226  //  int len= pLength( gls );
[6b4ff12]4227  int i,vpos=0;
[938688]4228  poly piter;
4229  lists elist;
4230  lists rlist;
4231
4232  elist= (lists)omAlloc( sizeof(slists) );
4233  elist->Init( 0 );
4234
[7fccc79]4235  if ( rVar(currRing) > 1 )
[938688]4236  {
4237    piter= gls;
[7fccc79]4238    for ( i= 1; i <= rVar(currRing); i++ )
[938688]4239      if ( pGetExp( piter, i ) )
4240      {
4241        vpos= i;
4242        break;
4243      }
4244    while ( piter )
4245    {
[7fccc79]4246      for ( i= 1; i <= rVar(currRing); i++ )
[938688]4247        if ( (vpos != i) && (pGetExp( piter, i ) != 0) )
4248        {
4249          WerrorS("The input polynomial must be univariate!");
4250          return TRUE;
4251        }
4252      pIter( piter );
4253    }
4254  }
4255
4256  rootContainer * roots= new rootContainer();
4257  number * pcoeffs= (number *)omAlloc( (deg+1) * sizeof( number ) );
4258  piter= gls;
4259  for ( i= deg; i >= 0; i-- )
4260  {
4261    //if ( piter ) Print("deg %d, pDeg(piter) %d\n",i,pTotaldegree(piter));
4262    if ( piter && pTotaldegree(piter) == i )
4263    {
4264      pcoeffs[i]= nCopy( pGetCoeff( piter ) );
4265      //nPrint( pcoeffs[i] );PrintS("  ");
4266      pIter( piter );
4267    }
4268    else
4269    {
4270      pcoeffs[i]= nInit(0);
4271    }
4272  }
4273
4274#ifdef mprDEBUG_PROT
4275  for (i=deg; i >= 0; i--)
4276  {
4277    nPrint( pcoeffs[i] );PrintS("  ");
4278  }
4279  PrintLn();
4280#endif
4281
4282  roots->fillContainer( pcoeffs, NULL, 1, deg, rootContainer::onepoly, 1 );
4283  roots->solver( howclean );
4284
4285  int elem= roots->getAnzRoots();
4286  char *dummy;
4287  int j;
4288
4289  rlist= (lists)omAlloc( sizeof(slists) );
4290  rlist->Init( elem );
4291
[6cc7f5]4292  if (rField_is_long_C(currRing))
[938688]4293  {
4294    for ( j= 0; j < elem; j++ )
4295    {
4296      rlist->m[j].rtyp=NUMBER_CMD;
4297      rlist->m[j].data=(void *)nCopy((number)(roots->getRoot(j)));
4298      //rlist->m[j].data=(void *)(number)(roots->getRoot(j));
4299    }
4300  }
4301  else
4302  {
4303    for ( j= 0; j < elem; j++ )
4304    {
[6cc7f5]4305      dummy = complexToStr( (*roots)[j], gmp_output_digits, currRing->cf );
[938688]4306      rlist->m[j].rtyp=STRING_CMD;
4307      rlist->m[j].data=(void *)dummy;
4308    }
4309  }
4310
4311  elist->Clean();
4312  //omFreeSize( (ADDRESS) elist, sizeof(slists) );
4313
[41cf23]4314  // this is (via fillContainer) the same data as in root
4315  //for ( i= deg; i >= 0; i-- ) nDelete( &pcoeffs[i] );
4316  //omFreeSize( (ADDRESS) pcoeffs, (deg+1) * sizeof( number ) );
4317
4318  delete roots;
[938688]4319
4320  res->rtyp= LIST_CMD;
4321  res->data= (void*)rlist;
4322
4323  return FALSE;
4324}
4325
4326BOOLEAN nuVanderSys( leftv res, leftv arg1, leftv arg2, leftv arg3)
4327{
4328  int i;
4329  ideal p,w;
4330  p= (ideal)arg1->Data();
4331  w= (ideal)arg2->Data();
4332
4333  // w[0] = f(p^0)
4334  // w[1] = f(p^1)
4335  // ...
4336  // p can be a vector of numbers (multivariate polynom)
4337  //   or one number (univariate polynom)
4338  // tdg = deg(f)
4339
4340  int n= IDELEMS( p );
4341  int m= IDELEMS( w );
[7447d8]4342  int tdg= (int)(long)arg3->Data();
[938688]4343
4344  res->data= (void*)NULL;
4345
4346  // check the input
4347  if ( tdg < 1 )
4348  {
4349    WerrorS("Last input parameter must be > 0!");
4350    return TRUE;
4351  }
[7fccc79]4352  if ( n != rVar(currRing) )
[938688]4353  {
[7fccc79]4354    Werror("Size of first input ideal must be equal to %d!",rVar(currRing));
[938688]4355    return TRUE;
4356  }
[6ff007]4357  if ( m != (int)pow((double)tdg+1,(double)n) )
[938688]4358  {
4359    Werror("Size of second input ideal must be equal to %d!",
[6ff007]4360      (int)pow((double)tdg+1,(double)n));
[938688]4361    return TRUE;
4362  }
[6cc7f5]4363  if ( !(rField_is_Q(currRing) /* ||
[938688]4364         rField_is_R() || rField_is_long_R() ||
4365         rField_is_long_C()*/ ) )
4366         {
4367    WerrorS("Ground field not implemented!");
4368    return TRUE;
4369  }
4370
4371  number tmp;
4372  number *pevpoint= (number *)omAlloc( n * sizeof( number ) );
4373  for ( i= 0; i < n; i++ )
4374  {
4375    pevpoint[i]=nInit(0);
4376    if (  (p->m)[i] )
4377    {
4378      tmp = pGetCoeff( (p->m)[i] );
4379      if ( nIsZero(tmp) || nIsOne(tmp) || nIsMOne(tmp) )
4380      {
4381        omFreeSize( (ADDRESS)pevpoint, n * sizeof( number ) );
4382        WerrorS("Elements of first input ideal must not be equal to -1, 0, 1!");
4383        return TRUE;
4384      }
4385    } else tmp= NULL;
4386    if ( !nIsZero(tmp) )
4387    {
4388      if ( !pIsConstant((p->m)[i]))
4389      {
4390        omFreeSize( (ADDRESS)pevpoint, n * sizeof( number ) );
4391        WerrorS("Elements of first input ideal must be numbers!");
4392        return TRUE;
4393      }
4394      pevpoint[i]= nCopy( tmp );
4395    }
4396  }
4397
4398  number *wresults= (number *)omAlloc( m * sizeof( number ) );
4399  for ( i= 0; i < m; i++ )
4400  {
4401    wresults[i]= nInit(0);
4402    if ( (w->m)[i] && !nIsZero(pGetCoeff((w->m)[i])) )
4403    {
4404      if ( !pIsConstant((w->m)[i]))
4405      {
4406        omFreeSize( (ADDRESS)pevpoint, n * sizeof( number ) );
4407        omFreeSize( (ADDRESS)wresults, m * sizeof( number ) );
4408        WerrorS("Elements of second input ideal must be numbers!");
4409        return TRUE;
4410      }
4411      wresults[i]= nCopy(pGetCoeff((w->m)[i]));
4412    }
4413  }
4414
4415  vandermonde vm( m, n, tdg, pevpoint, FALSE );
4416  number *ncpoly= vm.interpolateDense( wresults );
4417  // do not free ncpoly[]!!
4418  poly rpoly= vm.numvec2poly( ncpoly );
4419
4420  omFreeSize( (ADDRESS)pevpoint, n * sizeof( number ) );
4421  omFreeSize( (ADDRESS)wresults, m * sizeof( number ) );
4422
4423  res->data= (void*)rpoly;
4424  return FALSE;
4425}
4426
4427BOOLEAN nuUResSolve( leftv res, leftv args )
4428{
4429  leftv v= args;
4430
4431  ideal gls;
4432  int imtype;
4433  int howclean;
4434
4435  // get ideal
4436  if ( v->Typ() != IDEAL_CMD )
4437    return TRUE;
4438  else gls= (ideal)(v->Data());
4439  v= v->next;
4440
4441  // get resultant matrix type to use (0,1)
4442  if ( v->Typ() != INT_CMD )
4443    return TRUE;
[7447d8]4444  else imtype= (int)(long)v->Data();
[938688]4445  v= v->next;
4446
[695341]4447  if (imtype==0)
4448  {
4449    ideal test_id=idInit(1,1);
4450    int j;
4451    for(j=IDELEMS(gls)-1;j>=0;j--)
4452    {
4453      if (gls->m[j]!=NULL)
4454      {
4455        test_id->m[0]=gls->m[j];
[d84a4d]4456        intvec *dummy_w=id_QHomWeight(test_id, currRing);
[695341]4457        if (dummy_w!=NULL)
4458        {
4459          WerrorS("Newton polytope not of expected dimension");
4460          delete dummy_w;
4461          return TRUE;
4462        }
4463      }
4464    }
4465  }
4466
[938688]4467  // get and set precision in digits ( > 0 )
4468  if ( v->Typ() != INT_CMD )
4469    return TRUE;
[6cc7f5]4470  else if ( !(rField_is_R(currRing) || rField_is_long_R(currRing) || \
[3373e32]4471                          rField_is_long_C(currRing)) )
[938688]4472  {
4473    unsigned long int ii=(unsigned long int)v->Data();
4474    setGMPFloatDigits( ii, ii );
4475  }
4476  v= v->next;
4477
4478  // get interpolation steps (0,1,2)
4479  if ( v->Typ() != INT_CMD )
4480    return TRUE;
[7447d8]4481  else howclean= (int)(long)v->Data();
[938688]4482
4483  uResultant::resMatType mtype= determineMType( imtype );
[f93c5e9]4484  int i,count;
[938688]4485  lists listofroots= NULL;
4486  number smv= NULL;
4487  BOOLEAN interpolate_det= (mtype==uResultant::denseResMat)?TRUE:FALSE;
4488
4489  //emptylist= (lists)omAlloc( sizeof(slists) );
4490  //emptylist->Init( 0 );
4491
4492  //res->rtyp = LIST_CMD;
4493  //res->data= (void *)emptylist;
4494
4495  // check input ideal ( = polynomial system )
4496  if ( mprIdealCheck( gls, args->Name(), mtype ) != mprOk )
4497  {
4498    return TRUE;
4499  }
4500
4501  uResultant * ures;
4502  rootContainer ** iproots;
4503  rootContainer ** muiproots;
4504  rootArranger * arranger;
4505
4506  // main task 1: setup of resultant matrix
4507  ures= new uResultant( gls, mtype );
4508  if ( ures->accessResMat()->initState() != resMatrixBase::ready )
4509  {
4510    WerrorS("Error occurred during matrix setup!");
4511    return TRUE;
4512  }
4513
4514  // if dense resultant, check if minor nonsingular
4515  if ( mtype == uResultant::denseResMat )
4516  {
4517    smv= ures->accessResMat()->getSubDet();
4518#ifdef mprDEBUG_PROT
4519    PrintS("// Determinant of submatrix: ");nPrint(smv);PrintLn();
4520#endif
4521    if ( nIsZero(smv) )
4522    {
4523      WerrorS("Unsuitable input ideal: Minor of resultant matrix is singular!");
4524      return TRUE;
4525    }
4526  }
4527
4528  // main task 2: Interpolate specialized resultant polynomials
4529  if ( interpolate_det )
4530    iproots= ures->interpolateDenseSP( false, smv );
4531  else
4532    iproots= ures->specializeInU( false, smv );
4533
4534  // main task 3: Interpolate specialized resultant polynomials
4535  if ( interpolate_det )
4536    muiproots= ures->interpolateDenseSP( true, smv );
4537  else
4538    muiproots= ures->specializeInU( true, smv );
4539
4540#ifdef mprDEBUG_PROT
[f93c5e9]4541  int c= iproots[0]->getAnzElems();
[938688]4542  for (i=0; i < c; i++) pWrite(iproots[i]->getPoly());
4543  c= muiproots[0]->getAnzElems();
4544  for (i=0; i < c; i++) pWrite(muiproots[i]->getPoly());
4545#endif
4546
4547  // main task 4: Compute roots of specialized polys and match them up
4548  arranger= new rootArranger( iproots, muiproots, howclean );
4549  arranger->solve_all();
4550
4551  // get list of roots
4552  if ( arranger->success() )
4553  {
4554    arranger->arrange();
[213d64]4555    listofroots= listOfRoots(arranger, gmp_output_digits );
[938688]4556  }
4557  else
4558  {
4559    WerrorS("Solver was unable to find any roots!");
4560    return TRUE;
4561  }
4562
4563  // free everything
4564  count= iproots[0]->getAnzElems();
4565  for (i=0; i < count; i++) delete iproots[i];
4566  omFreeSize( (ADDRESS) iproots, count * sizeof(rootContainer*) );
4567  count= muiproots[0]->getAnzElems();
4568  for (i=0; i < count; i++) delete muiproots[i];
4569  omFreeSize( (ADDRESS) muiproots, count * sizeof(rootContainer*) );
4570
4571  delete ures;
4572  delete arranger;
4573  nDelete( &smv );
4574
4575  res->data= (void *)listofroots;
4576
4577  //emptylist->Clean();
4578  //  omFreeSize( (ADDRESS) emptylist, sizeof(slists) );
4579
4580  return FALSE;
4581}
4582
4583// from mpr_numeric.cc
[213d64]4584lists listOfRoots( rootArranger* self, const unsigned int oprec )
[938688]4585{
[69672d]4586  int i,j;
[213d64]4587  int count= self->roots[0]->getAnzRoots(); // number of roots
4588  int elem= self->roots[0]->getAnzElems();  // number of koordinates per root
[938688]4589
4590  lists listofroots= (lists)omAlloc( sizeof(slists) ); // must be done this way!
4591
[213d64]4592  if ( self->found_roots )
[938688]4593  {
4594    listofroots->Init( count );
4595
4596    for (i=0; i < count; i++)
4597    {
4598      lists onepoint= (lists)omAlloc(sizeof(slists)); // must be done this way!
4599      onepoint->Init(elem);
4600      for ( j= 0; j < elem; j++ )
4601      {
[6cc7f5]4602        if ( !rField_is_long_C(currRing) )
[938688]4603        {
4604          onepoint->m[j].rtyp=STRING_CMD;
[213d64]4605          onepoint->m[j].data=(void *)complexToStr((*self->roots[j])[i],oprec, currRing->cf);
[938688]4606        }
4607        else
4608        {
4609          onepoint->m[j].rtyp=NUMBER_CMD;
[213d64]4610          onepoint->m[j].data=(void *)n_Copy((number)(self->roots[j]->getRoot(i)), currRing->cf);
[938688]4611        }
4612        onepoint->m[j].next= NULL;
4613        onepoint->m[j].name= NULL;
4614      }
4615      listofroots->m[i].rtyp=LIST_CMD;
4616      listofroots->m[i].data=(void *)onepoint;
4617      listofroots->m[j].next= NULL;
4618      listofroots->m[j].name= NULL;
4619    }
4620
4621  }
4622  else
4623  {
4624    listofroots->Init( 0 );
4625  }
4626
4627  return listofroots;
4628}
4629
[f22093e]4630// from ring.cc
4631void rSetHdl(idhdl h)
4632{
4633  ring rg = NULL;
4634  if (h!=NULL)
4635  {
4636//   Print(" new ring:%s (l:%d)\n",IDID(h),IDLEV(h));
4637    rg = IDRING(h);
[e2efbe9]4638    if (rg==NULL) return; //id <>NULL, ring==NULL
[f22093e]4639    omCheckAddrSize((ADDRESS)h,sizeof(idrec));
4640    if (IDID(h))  // OB: ????
4641      omCheckAddr((ADDRESS)IDID(h));
4642    rTest(rg);
4643  }
4644
4645  // clean up history
4646  if (sLastPrinted.RingDependend())
4647  {
4648    sLastPrinted.CleanUp();
4649    memset(&sLastPrinted,0,sizeof(sleftv));
4650  }
4651
[9502424]4652  // test for valid "currRing":
[3901ebf]4653  if ((rg!=NULL) && (rg->idroot==NULL))
4654  {
4655    ring old=rg;
4656    rg=rAssure_HasComp(rg);
4657    if (old!=rg)
4658    {
4659      rKill(old);
4660      IDRING(h)=rg;
4661    }
4662  }
[f22093e]4663   /*------------ change the global ring -----------------------*/
4664  rChangeCurrRing(rg);
4665  currRingHdl = h;
4666}
4667
4668BOOLEAN rSleftvOrdering2Ordering(sleftv *ord, ring R)
4669{
4670  int last = 0, o=0, n = 1, i=0, typ = 1, j;
4671  sleftv *sl = ord;
4672
4673  // determine nBlocks
4674  while (sl!=NULL)
4675  {
4676    intvec *iv = (intvec *)(sl->data);
[5ca534]4677    if (((*iv)[1]==ringorder_c)||((*iv)[1]==ringorder_C))
4678      i++;
[f22093e]4679    else if ((*iv)[1]==ringorder_L)
4680    {
4681      R->bitmask=(*iv)[2];
4682      n--;
4683    }
[4f3177]4684    else if (((*iv)[1]!=ringorder_a)
[f93c5e9]4685    && ((*iv)[1]!=ringorder_a64)
4686    && ((*iv)[1]!=ringorder_am))
[5ca534]4687      o++;
[f22093e]4688    n++;
4689    sl=sl->next;
4690  }
4691  // check whether at least one real ordering
4692  if (o==0)
4693  {
4694    WerrorS("invalid combination of orderings");
4695    return TRUE;
4696  }
4697  // if no c/C ordering is given, increment n
4698  if (i==0) n++;
4699  else if (i != 1)
4700  {
4701    // throw error if more than one is given
4702    WerrorS("more than one ordering c/C specified");
4703    return TRUE;
4704  }
4705
4706  // initialize fields of R
4707  R->order=(int *)omAlloc0(n*sizeof(int));
4708  R->block0=(int *)omAlloc0(n*sizeof(int));
4709  R->block1=(int *)omAlloc0(n*sizeof(int));
4710  R->wvhdl=(int**)omAlloc0(n*sizeof(int_ptr));
4711
[8078c8]4712  int *weights=(int*)omAlloc0((R->N+1)*sizeof(int));
4713
[f22093e]4714  // init order, so that rBlocks works correctly
4715  for (j=0; j < n-1; j++)
4716    R->order[j] = (int) ringorder_unspec;
4717  // set last _C order, if no c/C order was given
4718  if (i == 0) R->order[n-2] = ringorder_C;
4719
4720  /* init orders */
4721  sl=ord;
4722  n=-1;
4723  while (sl!=NULL)
4724  {
4725    intvec *iv;
4726    iv = (intvec *)(sl->data);
4727    if ((*iv)[1]!=ringorder_L)
4728    {
4729      n++;
4730
4731      /* the format of an ordering:
4732       *  iv[0]: factor
4733       *  iv[1]: ordering
4734       *  iv[2..end]: weights
4735       */
4736      R->order[n] = (*iv)[1];
[8078c8]4737      typ=1;
[f22093e]4738      switch ((*iv)[1])
4739      {
4740          case ringorder_ws:
4741          case ringorder_Ws:
4742            typ=-1;
4743          case ringorder_wp:
4744          case ringorder_Wp:
4745            R->wvhdl[n]=(int*)omAlloc((iv->length()-1)*sizeof(int));
[8078c8]4746            R->block0[n] = last+1;
[f22093e]4747            for (i=2; i<iv->length(); i++)
[c2d114]4748            {
[f22093e]4749              R->wvhdl[n][i-2] = (*iv)[i];
[8078c8]4750              last++;
4751              if (weights[last]==0) weights[last]=(*iv)[i]*typ;
[c2d114]4752            }
[f22093e]4753            R->block1[n] = last;
4754            break;
4755          case ringorder_ls:
4756          case ringorder_ds:
4757          case ringorder_Ds:
[529aad]4758          case ringorder_rs:
[f22093e]4759            typ=-1;
4760          case ringorder_lp:
4761          case ringorder_dp:
4762          case ringorder_Dp:
4763          case ringorder_rp:
4764            R->block0[n] = last+1;
4765            if (iv->length() == 3) last+=(*iv)[2];
4766            else last += (*iv)[0];
4767            R->block1[n] = last;
[b9e18a3]4768            //if ((R->block0[n]>R->block1[n])
[ea947e]4769            //|| (R->block1[n]>rVar(R)))
4770            //{
4771            //  R->block1[n]=rVar(R);
4772            //  //WerrorS("ordering larger than number of variables");
4773            //  break;
4774            //}
[f22093e]4775            if (rCheckIV(iv)) return TRUE;
[b9e18a3]4776            for(i=si_min(rVar(R),R->block1[n]);i>=R->block0[n];i--)
[8078c8]4777            {
4778              if (weights[i]==0) weights[i]=typ;
4779            }
[f22093e]4780            break;
[273fed]4781
4782          case ringorder_s: // no 'rank' params!
4783          {
[750e70]4784
[273fed]4785            if(iv->length() > 3)
4786              return TRUE;
4787
4788            if(iv->length() == 3)
4789            {
4790              const int s = (*iv)[2];
[750e70]4791              R->block0[n] = s;
[273fed]4792              R->block1[n] = s;
4793            }
[750e70]4794            break;
[273fed]4795          }
4796          case ringorder_IS:
4797          {
4798            if(iv->length() != 3) return TRUE;
[750e70]4799
[273fed]4800            const int s = (*iv)[2];
4801
4802            if( 1 < s || s < -1 ) return TRUE;
[750e70]4803
4804            R->block0[n] = s;
[273fed]4805            R->block1[n] = s;
4806            break;
[750e70]4807          }
[f22093e]4808          case ringorder_S:
4809          case ringorder_c:
4810          case ringorder_C:
[273fed]4811          {
[f22093e]4812            if (rCheckIV(iv)) return TRUE;
4813            break;
[273fed]4814          }
[f22093e]4815          case ringorder_aa:
4816          case ringorder_a:
[273fed]4817          {
[f22093e]4818            R->block0[n] = last+1;
[b9e18a3]4819            R->block1[n] = si_min(last+iv->length()-2 , rVar(R));
[f22093e]4820            R->wvhdl[n] = (int*)omAlloc((iv->length()-1)*sizeof(int));
4821            for (i=2; i<iv->length(); i++)
4822            {
4823              R->wvhdl[n][i-2]=(*iv)[i];
[8078c8]4824              last++;
4825              if (weights[last]==0) weights[last]=(*iv)[i]*typ;
[f22093e]4826            }
[8078c8]4827            last=R->block0[n]-1;
[f22093e]4828            break;
[273fed]4829          }
[f93c5e9]4830          case ringorder_am:
4831          {
4832            R->block0[n] = last+1;
4833            R->block1[n] = si_min(last+iv->length()-2 , rVar(R));
4834            R->wvhdl[n] = (int*)omAlloc(iv->length()*sizeof(int));
4835            if (R->block1[n]- R->block0[n]+2>=iv->length())
4836               WarnS("missing module weights");
4837            for (i=2; i<=(R->block1[n]-R->block0[n]+2); i++)
4838            {
4839              R->wvhdl[n][i-2]=(*iv)[i];
4840              last++;
4841              if (weights[last]==0) weights[last]=(*iv)[i]*typ;
4842            }
4843            R->wvhdl[n][i-2]=iv->length() -3 -(R->block1[n]- R->block0[n]);
4844            for (; i<iv->length(); i++)
4845            {
4846              R->wvhdl[n][i-1]=(*iv)[i];
4847            }
4848            last=R->block0[n]-1;
4849            break;
4850          }
[4f3177]4851          case ringorder_a64:
4852          {
4853            R->block0[n] = last+1;
[b9e18a3]4854            R->block1[n] = si_min(last+iv->length()-2 , rVar(R));
[4f3177]4855            R->wvhdl[n] = (int*)omAlloc((iv->length()-1)*sizeof(int64));
4856            int64 *w=(int64 *)R->wvhdl[n];
4857            for (i=2; i<iv->length(); i++)
4858            {
4859              w[i-2]=(*iv)[i];
[8078c8]4860              last++;
4861              if (weights[last]==0) weights[last]=(*iv)[i]*typ;
[4f3177]4862            }
[8078c8]4863            last=R->block0[n]-1;
[4f3177]4864            break;
4865          }
[f22093e]4866          case ringorder_M:
4867          {
4868            int Mtyp=rTypeOfMatrixOrder(iv);
4869            if (Mtyp==0) return TRUE;
4870            if (Mtyp==-1) typ = -1;
4871
4872            R->wvhdl[n] =( int *)omAlloc((iv->length()-1)*sizeof(int));
4873            for (i=2; i<iv->length();i++)
4874              R->wvhdl[n][i-2]=(*iv)[i];
4875
4876            R->block0[n] = last+1;
4877            last += (int)sqrt((double)(iv->length()-2));
4878            R->block1[n] = last;
[b9e18a3]4879            for(i=si_min(rVar(R),R->block1[n]);i>=R->block0[n];i--)
[cb9e63]4880            {
4881              if (weights[i]==0) weights[i]=typ;
4882            }
[f22093e]4883            break;
4884          }
4885
4886          case ringorder_no:
4887            R->order[n] = ringorder_unspec;
4888            return TRUE;
4889
4890          default:
4891            Werror("Internal Error: Unknown ordering %d", (*iv)[1]);
4892            R->order[n] = ringorder_unspec;
4893            return TRUE;
4894      }
4895    }
4896    sl=sl->next;
4897  }
4898
4899  // check for complete coverage
[273fed]4900  while ( n >= 0 && (
4901          (R->order[n]==ringorder_c)
4902      ||  (R->order[n]==ringorder_C)
4903      ||  (R->order[n]==ringorder_s)
4904      ||  (R->order[n]==ringorder_S)
4905      ||  (R->order[n]==ringorder_IS)
4906                    )) n--;
4907
4908  assume( n >= 0 );
[750e70]4909
[f22093e]4910  if (R->block1[n] != R->N)
4911  {
4912    if (((R->order[n]==ringorder_dp) ||
4913         (R->order[n]==ringorder_ds) ||
4914         (R->order[n]==ringorder_Dp) ||
4915         (R->order[n]==ringorder_Ds) ||
4916         (R->order[n]==ringorder_rp) ||
[529aad]4917         (R->order[n]==ringorder_rs) ||
[f22093e]4918         (R->order[n]==ringorder_lp) ||
4919         (R->order[n]==ringorder_ls))
4920        &&
4921        R->block0[n] <= R->N)
4922    {
4923      R->block1[n] = R->N;
4924    }
4925    else
4926    {
4927      Werror("mismatch of number of vars (%d) and ordering (%d vars)",
4928             R->N,R->block1[n]);
4929      return TRUE;
4930    }
4931  }
[8078c8]4932  // find OrdSgn:
4933  R->OrdSgn = 1;
4934  for(i=1;i<=R->N;i++)
4935  { if (weights[i]<0) { R->OrdSgn=-1;break; }}
4936  omFree(weights);
[f22093e]4937  return FALSE;
4938}
4939
4940BOOLEAN rSleftvList2StringArray(sleftv* sl, char** p)
4941{
4942
4943  while(sl!=NULL)
4944  {
4945    if (sl->Name() == sNoName)
4946    {
4947      if (sl->Typ()==POLY_CMD)
4948      {
4949        sleftv s_sl;
4950        iiConvert(POLY_CMD,ANY_TYPE,-1,sl,&s_sl);
4951        if (s_sl.Name() != sNoName)
4952          *p = omStrDup(s_sl.Name());
4953        else
4954          *p = NULL;
4955        sl->next = s_sl.next;
4956        s_sl.next = NULL;
4957        s_sl.CleanUp();
4958        if (*p == NULL) return TRUE;
4959      }
4960      else
4961        return TRUE;
4962    }
4963    else
4964      *p = omStrDup(sl->Name());
4965    p++;
4966    sl=sl->next;
4967  }
4968  return FALSE;
4969}
4970
[51c97f]4971const short MAX_SHORT = 32767; // (1 << (sizeof(short)*8)) - 1;
[77bb59]4972
[f22093e]4973////////////////////
4974//
4975// rInit itself:
4976//
4977// INPUT:  s: name, pn: ch & parameter (names), rv: variable (names)
4978//         ord: ordering
4979// RETURN: currRingHdl on success
4980//         NULL        on error
4981// NOTE:   * makes new ring to current ring, on success
4982//         * considers input sleftv's as read-only
4983//idhdl rInit(char *s, sleftv* pn, sleftv* rv, sleftv* ord)
4984ring rInit(sleftv* pn, sleftv* rv, sleftv* ord)
4985{
[4bebba]4986#ifdef HAVE_RINGS
[122981]4987  unsigned int ringtype = 0;
[6cc7f5]4988  int_number modBase = NULL;
4989  unsigned int modExponent = 1;
[392682]4990#endif
[f22093e]4991  int float_len=0;
4992  int float_len2=0;
4993  ring R = NULL;
4994  BOOLEAN ffChar=FALSE;
4995
4996  /* ch -------------------------------------------------------*/
4997  // get ch of ground field
[f16c61c]4998
[393651]4999  // allocated ring
5000  R = (ring) omAlloc0Bin(sip_sring_bin);
[f22093e]5001
[e20910]5002  coeffs cf = NULL;
5003
5004  assume( pn != NULL );
5005  const int P = pn->listLength();
[f16c61c]5006
[f22093e]5007  if (pn->Typ()==INT_CMD)
5008  {
[6179c1]5009    int ch = (int)(long)pn->Data();
[f16c61c]5010
[e20910]5011    /* parameter? -------------------------------------------------------*/
5012    pn = pn->next;
[f16c61c]5013
[e20910]5014    if (pn == NULL) // no params!?
[6179c1]5015    {
5016      if (ch!=0)
5017      {
5018        ch=IsPrime(ch);
5019        cf = nInitChar(n_Zp, (void*)(long)ch);
5020      }
5021      else
5022        cf = nInitChar(n_Q, (void*)(long)ch);
5023    }
[3373e32]5024    else
5025    {
[e20910]5026      const int pars = pn->listLength();
5027
5028      assume( pars > 0 );
5029
5030      // predefined finite field: (p^k, a)
5031      if ((ch!=0) && (ch!=IsPrime(ch)) && (pars == 1))
[3373e32]5032      {
[3da9f4]5033        GFInfo param;
[f16c61c]5034
5035        param.GFChar = ch;
5036        param.GFDegree = 1;
[e20910]5037        param.GFPar_name = pn->name;
[f16c61c]5038
5039        cf = nInitChar(n_GF, &param);
[3373e32]5040      }
[e20910]5041      else // (0/p, a, b, ..., z)
[3373e32]5042      {
[e20910]5043        assume( (ch == 0) || (ch==IsPrime(ch)) );
5044
5045//         if ((pars > 1) && (ffChar))
5046//         {
5047//           WerrorS("too many parameters");
5048//           goto rInitError;
5049//         }
[f16c61c]5050
[e20910]5051        char ** names = (char**)omAlloc0(pars * sizeof(char_ptr));
5052
5053        if (rSleftvList2StringArray(pn, names))
[3373e32]5054        {
5055          WerrorS("parameter expected");
5056          goto rInitError;
5057        }
[e20910]5058
5059        TransExtInfo extParam;
[f16c61c]5060
[e20910]5061        extParam.r = rDefault( ch, pars, names); // Q/Zp [ p_1, ... p_pars ]
[f16c61c]5062
[e20910]5063        cf = nInitChar(n_transExt, &extParam);
[3373e32]5064      }
5065    }
[f16c61c]5066
[e20910]5067//    if (cf==NULL) goto rInitError;
5068    assume( cf != NULL );
[f22093e]5069  }
5070  else if ((pn->name != NULL)
5071  && ((strcmp(pn->name,"real")==0) || (strcmp(pn->name,"complex")==0)))
5072  {
5073    BOOLEAN complex_flag=(strcmp(pn->name,"complex")==0);
5074    if ((pn->next!=NULL) && (pn->next->Typ()==INT_CMD))
5075    {
[7447d8]5076      float_len=(int)(long)pn->next->Data();
[f22093e]5077      float_len2=float_len;
5078      pn=pn->next;
5079      if ((pn->next!=NULL) && (pn->next->Typ()==INT_CMD))
5080      {
[7447d8]5081        float_len2=(int)(long)pn->next->Data();
[f22093e]5082        pn=pn->next;
5083      }
5084    }
[046a94]5085    assume( float_len <= float_len2 );
[fe9ee1]5086
[046a94]5087    if( !complex_flag && (float_len2 <= (short)SHORT_REAL_LENGTH) )
5088       cf=nInitChar(n_R, NULL);
5089    else // longR or longC?
[fe9ee1]5090    {
[046a94]5091       LongComplexInfo param;
[fe9ee1]5092
[046a94]5093       param.float_len = float_len;
5094       param.float_len2 = float_len2;
[fe9ee1]5095
[046a94]5096       // set the parameter name
[47ab5b]5097       if (complex_flag)
5098       {
5099         if (pn->next == NULL)
5100           param.par_name=(const char*)"i"; //default to i
5101         else
5102           param.par_name = (const char*)pn->next->name;
[046a94]5103       }
5104
5105       cf = nInitChar(complex_flag ? n_long_C: n_long_R, (void*)&param);
[fe9ee1]5106    }
[e20910]5107    assume( cf != NULL );
[f22093e]5108  }
[d351d8]5109#ifdef HAVE_RINGS
5110  else if ((pn->name != NULL) && (strcmp(pn->name, "integer") == 0))
[b44622]5111  {
[6cc7f5]5112    modBase = (int_number) omAlloc(sizeof(mpz_t));
5113    mpz_init_set_si(modBase, 0);
[b44622]5114    if ((pn->next!=NULL) && (pn->next->Typ()==INT_CMD))
5115    {
[6cc7f5]5116      mpz_set_ui(modBase, (int)(long) pn->next->Data());
[b44622]5117      pn=pn->next;
5118      if ((pn->next!=NULL) && (pn->next->Typ()==INT_CMD))
5119      {
[6cc7f5]5120        modExponent = (long) pn->next->Data();
[b44622]5121        pn=pn->next;
5122      }
[d351d8]5123      while ((pn->next!=NULL) && (pn->next->Typ()==INT_CMD))
5124      {
[6cc7f5]5125        mpz_mul_ui(modBase, modBase, (int)(long) pn->next->Data());
[d351d8]5126        pn=pn->next;
5127      }
[c81a40]5128    }
[3373e32]5129    else
5130      cf=nInitChar(n_Z,NULL);
[f16c61c]5131
[6cc7f5]5132    if ((mpz_cmp_ui(modBase, 1) == 0) && (mpz_cmp_ui(modBase, 0) < 0))
[c81a40]5133    {
5134      Werror("Wrong ground ring specification (module is 1)");
5135      goto rInitError;
5136    }
[6cc7f5]5137    if (modExponent < 1)
[c81a40]5138    {
5139      Werror("Wrong ground ring specification (exponent smaller than 1");
5140      goto rInitError;
5141    }
[3373e32]5142    // module is 0 ---> integers ringtype = 4;
[c81a40]5143    // we have an exponent
[9e26458]5144    if (modExponent > 1 && cf == NULL)
[c81a40]5145    {
[6cc7f5]5146      if ((mpz_cmp_ui(modBase, 2) == 0) && (modExponent <= 8*sizeof(NATNUMBER)))
[7cbe8e]5147      {
[6cc7f5]5148        /* this branch should be active for modExponent = 2..32 resp. 2..64,
[cf21dd4]5149           depending on the size of a long on the respective platform */
[c81a40]5150        ringtype = 1;       // Use Z/2^ch
[3373e32]5151        cf=nInitChar(n_Z2m,(void*)(long)modExponent);
[d351d8]5152      }
5153      else
5154      {
[c81a40]5155        ringtype = 3;
[3373e32]5156        cf=nInitChar(n_Zn,(void*)(long)modBase);
[d351d8]5157      }
[b44622]5158    }
[c81a40]5159    // just a module m > 1
[9e26458]5160    else if (cf == NULL)
[b44622]5161    {
[c81a40]5162      ringtype = 2;
[e20910]5163      const int ch = mpz_get_ui(modBase);
5164      cf=nInitChar(n_Zn,(void*)(long)ch);
[b44622]5165    }
[e20910]5166    assume( cf != NULL );
[b44622]5167  }
5168#endif
[e20910]5169  // ring NEW = OLD, (), (); where OLD is a polynomial ring...
5170  else if ((pn->Typ()==RING_CMD) && (P == 1))
5171  {
5172    TransExtInfo extParam;
5173    extParam.r = (ring)pn->Data();
5174    cf = nInitChar(n_transExt, &extParam);
5175  }
5176  else if ((pn->Typ()==QRING_CMD) && (P == 1)) // same for qrings - which should be fields!?
5177  {
5178    AlgExtInfo extParam;
5179    extParam.r = (ring)pn->Data();
5180    extParam.i = (extParam.r->qideal);
[f16c61c]5181
[e20910]5182    cf = nInitChar(n_algExt, &extParam);   // Q[a]/<minideal>
5183  }
[f22093e]5184  else
5185  {
[e20910]5186    sleftv* p = pn;
5187    Werror("Wrong or unknown ground field specification");
5188#ifndef NDEBUG
5189    while (p != NULL)
5190    {
[69672d]5191      Print( "pn[%p]: type: %d [%s]: %p, name: %s", (void*)p, p->Typ(), Tok2Cmdname(p->Typ()), p->Data(), (p->name == NULL? "NULL" : p->name) );
[e20910]5192      PrintLn();
5193      p = p->next;
5194    }
[f16c61c]5195#endif
[f22093e]5196    goto rInitError;
5197  }
[e20910]5198//  pn=pn->next;
[f22093e]5199
[69672d]5200  int l;
[f22093e]5201  /*every entry in the new ring is initialized to 0*/
5202
5203  /* characteristic -----------------------------------------------*/
5204  /* input: 0 ch=0 : Q     parameter=NULL    ffChar=FALSE   float_len
5205   *         0    1 : Q(a,...)        *names         FALSE
5206   *         0   -1 : R               NULL           FALSE  0
5207   *         0   -1 : R               NULL           FALSE  prec. >6
5208   *         0   -1 : C               *names         FALSE  prec. 0..?
5209   *         p    p : Fp              NULL           FALSE
5210   *         p   -p : Fp(a)           *names         FALSE
5211   *         q    q : GF(q=p^n)       *names         TRUE
5212  */
[3373e32]5213  l = 0;
[f22093e]5214
[3373e32]5215  if (cf==NULL)
5216  {
[e20910]5217    const int ch=32003;
5218    Warn("Invalid ground field specification: using the default field: Z_{%d}", ch);
[3373e32]5219    cf=nInitChar(n_Zp, (void*)(long)ch);
[f22093e]5220  }
[e20910]5221
5222  assume( R != NULL );
[f16c61c]5223
[e20910]5224  R->cf = cf;
[f16c61c]5225
[4bebba]5226#ifdef HAVE_RINGS
[e20910]5227  // the following should have beed set already into cf, right?!
5228//  R->cf->ringtype = ringtype;
5229//  R->cf->modBase = modBase;
5230//  R->cf->modExponent = modExponent;
[6a972af]5231#endif
[f22093e]5232
5233  /* names and number of variables-------------------------------------*/
5234  {
5235    int l=rv->listLength();
[77bb59]5236
[f22093e]5237    if (l>MAX_SHORT)
5238    {
5239      Werror("too many ring variables(%d), max is %d",l,MAX_SHORT);
5240       goto rInitError;
5241    }
5242    R->N = l; /*rv->listLength();*/
5243  }
5244  R->names   = (char **)omAlloc0(R->N * sizeof(char_ptr));
5245  if (rSleftvList2StringArray(rv, R->names))
5246  {
5247    WerrorS("name of ring variable expected");
5248    goto rInitError;
5249  }
5250
5251  /* check names and parameters for conflicts ------------------------- */
[7c5dd1]5252  rRenameVars(R); // conflicting variables will be renamed
[f22093e]5253  /* ordering -------------------------------------------------------------*/
5254  if (rSleftvOrdering2Ordering(ord, R))
5255    goto rInitError;
5256
5257  // Complete the initialization
5258  if (rComplete(R,1))
5259    goto rInitError;
5260
[7cbe8e]5261#ifdef HABE_RINGS
5262// currently, coefficients which are ring elements require a global ordering:
[f5bef2]5263  if (rField_is_Ring(R) && (R->OrdSgn==-1))
[7cbe8e]5264  {
5265    WerrorS("global ordering required for these coefficients");
5266    goto rInitError;
5267  }
5268#endif
5269
[f22093e]5270  rTest(R);
5271
5272  // try to enter the ring into the name list
5273  // need to clean up sleftv here, before this ring can be set to
5274  // new currRing or currRing can be killed beacuse new ring has
5275  // same name
5276  if (pn != NULL) pn->CleanUp();
5277  if (rv != NULL) rv->CleanUp();
5278  if (ord != NULL) ord->CleanUp();
5279  //if ((tmp = enterid(s, myynest, RING_CMD, &IDROOT))==NULL)
5280  //  goto rInitError;
5281
5282  //memcpy(IDRING(tmp),R,sizeof(*R));
5283  // set current ring
5284  //omFreeBin(R,  ip_sring_bin);
5285  //return tmp;
5286  return R;
5287
5288  // error case:
5289  rInitError:
[393651]5290  if  ((R != NULL)&&(R->cf!=NULL)) rDelete(R);
[f22093e]5291  if (pn != NULL) pn->CleanUp();
5292  if (rv != NULL) rv->CleanUp();
5293  if (ord != NULL) ord->CleanUp();
5294  return NULL;
5295}
5296
[11d9d6a]5297ring rSubring(ring org_ring, sleftv* rv)
5298{
5299  ring R = rCopy0(org_ring);
5300  int *perm=(int *)omAlloc0((org_ring->N+1)*sizeof(int));
[69672d]5301  int n = rBlocks(org_ring), i=0, j;
[11d9d6a]5302
5303  /* names and number of variables-------------------------------------*/
5304  {
5305    int l=rv->listLength();
5306    if (l>MAX_SHORT)
5307    {
5308      Werror("too many ring variables(%d), max is %d",l,MAX_SHORT);
5309       goto rInitError;
5310    }
5311    R->N = l; /*rv->listLength();*/
5312  }
5313  omFree(R->names);
5314  R->names   = (char **)omAlloc0(R->N * sizeof(char_ptr));
5315  if (rSleftvList2StringArray(rv, R->names))
5316  {
5317    WerrorS("name of ring variable expected");
5318    goto rInitError;
5319  }
5320
5321  /* check names for subring in org_ring ------------------------- */
5322  {
5323    i=0;
[9502424]5324
[11d9d6a]5325    for(j=0;j<R->N;j++)
5326    {
5327      for(;i<org_ring->N;i++)
5328      {
5329        if (strcmp(org_ring->names[i],R->names[j])==0)
5330        {
5331          perm[i+1]=j+1;
5332          break;
5333        }
5334      }
5335      if (i>org_ring->N)
5336      {
5337        Werror("variable %d (%s) not in basering",j+1,R->names[j]);
5338        break;
5339      }
5340    }
5341  }
[9502424]5342  //Print("perm=");
5343  //for(i=1;i<org_ring->N;i++) Print("v%d -> v%d\n",i,perm[i]);
[11d9d6a]5344  /* ordering -------------------------------------------------------------*/
5345
5346  for(i=0;i<n;i++)
5347  {
5348    int min_var=-1;
5349    int max_var=-1;
5350    for(j=R->block0[i];j<=R->block1[i];j++)
5351    {
5352      if (perm[j]>0)
5353      {
5354        if (min_var==-1) min_var=perm[j];
5355        max_var=perm[j];
5356      }
5357    }
5358    if (min_var!=-1)
5359    {
5360      //Print("block %d: old %d..%d, now:%d..%d\n",
5361      //      i,R->block0[i],R->block1[i],min_var,max_var);
5362      R->block0[i]=min_var;
5363      R->block1[i]=max_var;
5364      if (R->wvhdl[i]!=NULL)
5365      {
5366        omFree(R->wvhdl[i]);
5367        R->wvhdl[i]=(int*)omAlloc0((max_var-min_var+1)*sizeof(int));
[9502424]5368        for(j=org_ring->block0[i];j<=org_ring->block1[i];j++)
[11d9d6a]5369        {
5370          if (perm[j]>0)
[9502424]5371          {
5372            R->wvhdl[i][perm[j]-R->block0[i]]=
5373                org_ring->wvhdl[i][j-org_ring->block0[i]];
5374            //Print("w%d=%d (orig_w%d)\n",perm[j],R->wvhdl[i][perm[j]-R->block0[i]],j);
5375          }
[11d9d6a]5376        }
5377      }
5378    }
5379    else
5380    {
5381      if(R->block0[i]>0)
[9502424]5382      {
[11d9d6a]5383        //Print("skip block %d\n",i);
5384        R->order[i]=ringorder_unspec;
5385        if (R->wvhdl[i] !=NULL) omFree(R->wvhdl[i]);
5386        R->wvhdl[i]=NULL;
5387      }
5388      //else Print("keep block %d\n",i);
5389    }
[9502424]5390  }
[11d9d6a]5391  i=n-1;
5392  while(i>0)
5393  {
5394    // removed unneded blocks
5395    if(R->order[i-1]==ringorder_unspec)
5396    {
5397      for(j=i;j<=n;j++)
5398      {
5399        R->order[j-1]=R->order[j];
5400        R->block0[j-1]=R->block0[j];
5401        R->block1[j-1]=R->block1[j];
5402        if (R->wvhdl[j-1] !=NULL) omFree(R->wvhdl[j-1]);
5403        R->wvhdl[j-1]=R->wvhdl[j];
5404      }
5405      R->order[n]=ringorder_unspec;
5406      n--;
5407    }
5408    i--;
5409  }
[9502424]5410  n=rBlocks(org_ring)-1;
[11d9d6a]5411  while (R->order[n]==0)  n--;
5412  while (R->order[n]==ringorder_unspec)  n--;
5413  if ((R->order[n]==ringorder_c) ||  (R->order[n]==ringorder_C)) n--;
5414  if (R->block1[n] != R->N)
5415  {
5416    if (((R->order[n]==ringorder_dp) ||
5417         (R->order[n]==ringorder_ds) ||
5418         (R->order[n]==ringorder_Dp) ||
5419         (R->order[n]==ringorder_Ds) ||
5420         (R->order[n]==ringorder_rp) ||
5421         (R->order[n]==ringorder_rs) ||
5422         (R->order[n]==ringorder_lp) ||
5423         (R->order[n]==ringorder_ls))
5424        &&
5425        R->block0[n] <= R->N)
5426    {
5427      R->block1[n] = R->N;
5428    }
5429    else
5430    {
5431      Werror("mismatch of number of vars (%d) and ordering (%d vars) in block %d",
5432             R->N,R->block1[n],n);
5433      return NULL;
5434    }
5435  }
5436  omFree(perm);
5437  // find OrdSgn:
5438  R->OrdSgn = org_ring->OrdSgn; // IMPROVE!
5439  //for(i=1;i<=R->N;i++)
5440  //{ if (weights[i]<0) { R->OrdSgn=-1;break; }}
5441  //omFree(weights);
5442  // Complete the initialization
5443  if (rComplete(R,1))
5444    goto rInitError;
5445
5446  rTest(R);
5447
5448  if (rv != NULL) rv->CleanUp();
5449
5450  return R;
5451
5452  // error case:
5453  rInitError:
5454  if  (R != NULL) rDelete(R);
5455  if (rv != NULL) rv->CleanUp();
5456  return NULL;
5457}
5458
[f22093e]5459void rKill(ring r)
5460{
5461  if ((r->ref<=0)&&(r->order!=NULL))
5462  {
5463#ifdef RDEBUG
[d3a49c]5464    if (traceit &TRACE_SHOW_RINGS) Print("kill ring %lx\n",(long)r);
[f22093e]5465#endif
[ac1953e]5466    if (r->qideal!=NULL)
[f22093e]5467    {
5468      id_Delete(&r->qideal, r);
5469      r->qideal = NULL;
5470    }
5471    int j;
5472#ifdef USE_IILOCALRING
5473    for (j=0;j<iiRETURNEXPR_len;j++)
5474    {
5475      if (iiLocalRing[j]==r)
5476      {
5477        if (j<myynest) Warn("killing the basering for level %d",j);
5478        iiLocalRing[j]=NULL;
5479      }
5480    }
5481#else /* USE_IILOCALRING */
5482//#endif /* USE_IILOCALRING */
5483    {
5484      proclevel * nshdl = procstack;
5485      int lev=myynest-1;
5486
5487      for(; nshdl != NULL; nshdl = nshdl->next)
5488      {
5489        if (nshdl->cRing==r)
5490        {
5491          Warn("killing the basering for level %d",lev);
5492          nshdl->cRing=NULL;
5493          nshdl->cRingHdl=NULL;
5494        }
5495      }
5496    }
5497#endif /* USE_IILOCALRING */
[9e79fc]5498// any variables depending on r ?
5499    while (r->idroot!=NULL)
5500    {
5501      killhdl2(r->idroot,&(r->idroot),r);
5502    }
[2dbaba4]5503    if (r==currRing)
5504    {
5505      // all dependend stuff is done, clean global vars:
5506      if (r->qideal!=NULL)
5507      {
5508        currQuotient=NULL;
5509      }
[993ae2]5510      if ((currRing->ppNoether)!=NULL) pDelete(&(currRing->ppNoether));
[2dbaba4]5511      if (sLastPrinted.RingDependend())
5512      {
5513        sLastPrinted.CleanUp();
5514      }
5515      if ((myynest>0) && (iiRETURNEXPR[myynest].RingDependend()))
5516      {
5517        WerrorS("return value depends on local ring variable (export missing ?)");
5518        iiRETURNEXPR[myynest].CleanUp();
5519      }
5520      currRing=NULL;
5521      currRingHdl=NULL;
5522    }
[f22093e]5523
[266695]5524    /* nKillChar(r); will be called from inside of rDelete */
[f22093e]5525    rDelete(r);
5526    return;
5527  }
5528  r->ref--;
5529}
5530
5531void rKill(idhdl h)
5532{
5533  ring r = IDRING(h);
5534  int ref=0;
5535  if (r!=NULL)
5536  {
5537    ref=r->ref;
5538    rKill(r);
5539  }
5540  if (h==currRingHdl)
5541  {
5542    if (ref<=0) { currRing=NULL; currRingHdl=NULL;}
5543    else
5544    {
5545      currRingHdl=rFindHdl(r,currRingHdl,NULL);
5546    }
5547  }
5548}
5549
[6cc7f5]5550idhdl rSimpleFindHdl(ring r, idhdl root, idhdl n)
[f22093e]5551{
[9bc0b8]5552  //idhdl next_best=NULL;
[f22093e]5553  idhdl h=root;
5554  while (h!=NULL)
5555  {
5556    if (((IDTYP(h)==RING_CMD)||(IDTYP(h)==QRING_CMD))
5557    && (h!=n)
[9bc0b8]5558    && (IDRING(h)==r)
[f22093e]5559    )
[9bc0b8]5560    {
5561   //   if (IDLEV(h)==myynest)
5562   //     return h;
5563   //   if ((IDLEV(h)==0) || (next_best==NULL))
5564   //     next_best=h;
5565   //   else if (IDLEV(next_best)<IDLEV(h))
5566   //     next_best=h;
[f22093e]5567      return h;
[9bc0b8]5568    }
[f22093e]5569    h=IDNEXT(h);
5570  }
[9bc0b8]5571  //return next_best;
[f22093e]5572  return NULL;
5573}
[e07e7d1]5574
5575extern BOOLEAN jjPROC(leftv res, leftv u, leftv v);
5576ideal kGroebner(ideal F, ideal Q)
5577{
5578  //test|=Sy_bit(OPT_PROT);
5579  idhdl save_ringhdl=currRingHdl;
5580  ideal resid;
5581  idhdl new_ring=NULL;
5582  if ((currRingHdl==NULL) || (IDRING(currRingHdl)!=currRing))
5583  {
5584    currRingHdl=enterid(omStrDup(" GROEBNERring"),0,RING_CMD,&IDROOT,FALSE);
5585    new_ring=currRingHdl;
5586    IDRING(currRingHdl)=currRing;
5587  }
5588  sleftv v; memset(&v,0,sizeof(v)); v.rtyp=IDEAL_CMD; v.data=(char *) F;
[d2c80d]5589  idhdl h=ggetid("groebner");
[e07e7d1]5590  sleftv u; memset(&u,0,sizeof(u)); u.rtyp=IDHDL; u.data=(char *) h;
5591            u.name=IDID(h);
[0ea97e]5592
5593  sleftv res; memset(&res,0,sizeof(res));
[e07e7d1]5594  if(jjPROC(&res,&u,&v))
5595  {
5596    resid=kStd(F,Q,testHomog,NULL);
5597  }
5598  else
5599  {
5600    //printf("typ:%d\n",res.rtyp);
5601    resid=(ideal)(res.data);
5602  }
5603  // cleanup GROEBNERring, save_ringhdl, u,v,(res )
5604  if (new_ring!=NULL)
5605  {
5606    idhdl h=IDROOT;
5607    if (h==new_ring) IDROOT=h->next;
5608    else
5609    {
5610      while ((h!=NULL) &&(h->next!=new_ring)) h=h->next;
5611      if (h!=NULL) h->next=h->next->next;
5612    }
5613    if (h!=NULL) omFreeSize(h,sizeof(*h));
5614  }
5615  currRingHdl=save_ringhdl;
5616  u.CleanUp();
5617  v.CleanUp();
5618  return resid;
5619}
[f46646]5620
[ebb58fc]5621static void jjINT_S_TO_ID(int n,int *e, leftv res)
[f46646]5622{
[44bf84]5623  if (n==0) n=1;
5624  ideal l=idInit(n,1);
[f46646]5625  int i;
5626  poly p;
[7fccc79]5627  for(i=rVar(currRing);i>0;i--)
[f46646]5628  {
5629    if (e[i]>0)
5630    {
5631      n--;
5632      p=pOne();
5633      pSetExp(p,i,1);
5634      pSetm(p);
[44bf84]5635      l->m[n]=p;
[f46646]5636      if (n==0) break;
5637    }
5638  }
5639  res->data=(char*)l;
[ebb58fc]5640  setFlag(res,FLAG_STD);
[7fccc79]5641  omFreeSize((ADDRESS)e,(rVar(currRing)+1)*sizeof(int));
[f46646]5642}
5643BOOLEAN jjVARIABLES_P(leftv res, leftv u)
5644{
[7fccc79]5645  int *e=(int *)omAlloc0((rVar(currRing)+1)*sizeof(int));
[f46646]5646  int n=pGetVariables((poly)u->Data(),e);
[44bf84]5647  jjINT_S_TO_ID(n,e,res);
[f46646]5648  return FALSE;
5649}
[9502424]5650
[f46646]5651BOOLEAN jjVARIABLES_ID(leftv res, leftv u)
5652{
[7fccc79]5653  int *e=(int *)omAlloc0((rVar(currRing)+1)*sizeof(int));
[f46646]5654  ideal I=(ideal)u->Data();
5655  int i;
5656  int n=0;
5657  for(i=I->nrows*I->ncols-1;i>=0;i--)
5658  {
[160f439]5659    int n0=pGetVariables(I->m[i],e);
5660    if (n0>n) n=n0;
[f46646]5661  }
[44bf84]5662  jjINT_S_TO_ID(n,e,res);
[f46646]5663  return FALSE;
5664}
Note: See TracBrowser for help on using the repository browser.