source: git/Singular/ipshell.cc @ b541aa

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