source: git/Singular/ipshell.cc @ 7eb464

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