source: git/Singular/ipshell.cc @ 2dbaba4

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