source: git/Singular/ipshell.cc @ 4d5437

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