source: git/Singular/LIB/primdec.lib @ 2bbd4a

spielwiese
Last change on this file since 2bbd4a was 2bbd4a, checked in by Anne Frühbis-Krüger <anne@…>, 10 years ago
fixed corner case (minimal resolution very short) in AnnExt_R
  • Property mode set to 100644
File size: 214.6 KB
Line 
1////////////////////////////////////////////////////////////////////////////
2version="version primdec.lib 4.0.0.0 Jun_2013 "; // $Id$
3category="Commutative Algebra";
4info="
5LIBRARY: primdec.lib   Primary Decomposition and Radical of Ideals
6AUTHORS:  Gerhard Pfister, pfister@mathematik.uni-kl.de (GTZ)@*
7          Wolfram Decker, decker@math.uni-sb.de         (SY)@*
8          Hans Schoenemann, hannes@mathematik.uni-kl.de (SY)@*
9          Santiago Laplagne, slaplagn@dm.uba.ar         (GTZ)
10
11OVERVIEW:
12    Algorithms for primary decomposition based on the ideas of
13    Gianni, Trager and Zacharias (implementation by Gerhard Pfister),
14    respectively based on the ideas of Shimoyama and Yokoyama (implementation
15    by Wolfram Decker and Hans Schoenemann).@*
16    The procedures are implemented to be used in characteristic 0.@*
17    They also work in positive characteristic >> 0.@*
18    In small characteristic and for algebraic extensions, primdecGTZ
19    may not terminate.@*
20    Algorithms for the computation of the radical based on the ideas of
21    Krick, Logar, Laplagne and Kemper (implementation by Gerhard Pfister and Santiago Laplagne).
22    They work in any characteristic.@*
23    Baserings must have a global ordering and no quotient ideal.
24
25
26PROCEDURES:
27 Ann(M);           annihilator of R^n/M, R=basering, M in R^n
28 primdecGTZ(I);    complete primary decomposition via Gianni,Trager,Zacharias
29 primdecSY(I...);  complete primary decomposition via Shimoyama-Yokoyama
30 minAssGTZ(I);     the minimal associated primes via Gianni,Trager,Zacharias (with modifications by Laplagne)
31 minAssChar(I...); the minimal associated primes using characteristic sets
32 testPrimary(L,k); tests the result of the primary decomposition
33 radical(I);       computes the radical of I via Krick/Logar (with modifications by Laplagne) and Kemper
34 radicalEHV(I);    computes the radical of I via Eisenbud,Huneke,Vasconcelos
35 equiRadical(I);   the radical of the equidimensional part of the ideal I
36 prepareAss(I);    list of radicals of the equidimensional components of I
37 equidim(I);       weak equidimensional decomposition of I
38 equidimMax(I);    equidimensional locus of I
39 equidimMaxEHV(I); equidimensional locus of I via Eisenbud,Huneke,Vasconcelos
40 zerodec(I);       zerodimensional decomposition via Monico
41 absPrimdecGTZ(I); the absolute prime components of I
42 sep(f,k);         the separabel part of f as polynomial in Fp(t1,...,tm)
43";
44
45LIB "general.lib";
46LIB "elim.lib";
47LIB "poly.lib";
48LIB "random.lib";
49LIB "inout.lib";
50LIB "matrix.lib";
51LIB "triang.lib";
52LIB "absfact.lib";
53LIB "ring.lib";
54///////////////////////////////////////////////////////////////////////////////
55//
56//                      Gianni/Trager/Zacharias
57//
58///////////////////////////////////////////////////////////////////////////////
59
60static proc sat1 (ideal id, poly p)
61"USAGE:   sat1(id,j);  id ideal, j polynomial
62RETURN:  saturation of id with respect to j (= union_(k=1...) of id:j^k)
63NOTE:    result is a std basis in the basering
64"
65{
66  int @k;
67  ideal inew=std(id);
68  ideal iold;
69  intvec op=option(get);
70  option(returnSB);
71  while(specialIdealsEqual(iold,inew)==0 )
72  {
73    iold=inew;
74    inew=quotient(iold,p);
75    @k++;
76  }
77  @k--;
78  option(set,op);
79  list L =inew,p^@k;
80  return (L);
81}
82
83///////////////////////////////////////////////////////////////////////////////
84
85static proc sat2 (ideal id, ideal h)
86"USAGE:   sat2(id,j);  id ideal, j polynomial
87RETURN:  saturation of id with respect to j (= union_(k=1...) of id:j^k)
88NOTE:    result is a std basis in the basering
89"
90{
91  int @k,@i;
92  def @P= basering;
93  if(ordstr(basering)[1,2]!="dp")
94  {
95    execute("ring @Phelp=("+charstr(@P)+"),("+varstr(@P)+"),(C,dp);");
96    ideal inew=std(imap(@P,id));
97    ideal  @h=imap(@P,h);
98  }
99  else
100  {
101    ideal @h=h;
102    ideal inew=std(id);
103  }
104  ideal fac;
105
106  for(@i=1;@i<=ncols(@h);@i++)
107  {
108    if(deg(@h[@i])>0)
109    {
110      fac=fac+factorize(@h[@i],1);
111    }
112  }
113  fac=simplify(fac,6);
114  poly @f=1;
115  if(deg(fac[1])>0)
116  {
117    ideal iold;
118    for(@i=1;@i<=size(fac);@i++)
119    {
120      @f=@f*fac[@i];
121    }
122    intvec op = option(get);
123    option(returnSB);
124    while(specialIdealsEqual(iold,inew)==0 )
125    {
126      iold=inew;
127      if(deg(iold[size(iold)])!=1)
128      {
129        inew=quotient(iold,@f);
130      }
131      else
132      {
133        inew=iold;
134      }
135      @k++;
136    }
137    option(set,op);
138    @k--;
139  }
140
141  if(ordstr(@P)[1,2]!="dp")
142  {
143    setring @P;
144    ideal inew=std(imap(@Phelp,inew));
145    poly @f=imap(@Phelp,@f);
146  }
147  list L =inew,@f^@k;
148  return (L);
149}
150
151///////////////////////////////////////////////////////////////////////////////
152
153
154proc minSat(ideal inew, ideal h)
155{
156  int i,k;
157  poly f=1;
158  ideal iold,fac;
159  list quotM,l;
160
161  for(i=1;i<=ncols(h);i++)
162  {
163    if(deg(h[i])>0)
164    {
165      fac=fac+factorize(h[i],1);
166    }
167  }
168  fac=simplify(fac,6);
169  if(size(fac)==0)
170  {
171    l=inew,1;
172    return(l);
173  }
174  fac=sort(fac)[1];
175  for(i=1;i<=size(fac);i++)
176  {
177    f=f*fac[i];
178  }
179  quotM[1]=inew;
180  quotM[2]=fac;
181  quotM[3]=f;
182  f=1;
183  intvec op = option(get);
184  option(returnSB);
185  while(specialIdealsEqual(iold,quotM[1])==0)
186  {
187    if(k>0)
188    {
189      f=f*quotM[3];
190    }
191    iold=quotM[1];
192    quotM=quotMin(quotM);
193    k++;
194  }
195  option(set,op);
196  l=quotM[1],f;
197  return(l);
198}
199
200static proc quotMin(list tsil)
201{
202  int i,j,k,action;
203  ideal verg;
204  list l;
205  poly g;
206
207  ideal laedi=tsil[1];
208  ideal fac=tsil[2];
209  poly f=tsil[3];
210
211  ideal star=quotient(laedi,f);
212
213  if(specialIdealsEqual(star,laedi))
214  {
215    l=star,fac,f;
216    return(l);
217  }
218
219  action=1;
220
221  while(action==1)
222  {
223    if(size(fac)==1)
224    {
225      action=0;
226      break;
227    }
228    for(i=1;i<=size(fac);i++)
229    {
230      g=1;
231      verg=laedi;
232      for(j=1;j<=size(fac);j++)
233      {
234        if(i!=j)
235        {
236          g=g*fac[j];
237        }
238      }
239      verg=quotient(laedi,g);
240
241      if(specialIdealsEqual(verg,star)==1)
242      {
243        f=g;
244        fac[i]=0;
245        fac=simplify(fac,2);
246        break;
247      }
248      if(i==size(fac))
249      {
250        action=0;
251      }
252    }
253  }
254  l=star,fac,f;
255  return(l);
256}
257
258///////////////////////////////////////////////////////////////////////////////
259
260static proc testFactor(list act,poly p)
261{
262  poly keep=p;
263
264  int i;
265  poly q=act[1][1]^act[2][1];
266  for(i=2;i<=size(act[1]);i++)
267  {
268    q=q*act[1][i]^act[2][i];
269  }
270  q=1/leadcoef(q)*q;
271  p=1/leadcoef(p)*p;
272  if(p-q!=0)
273  {
274    "ERROR IN FACTOR, please inform the authors";
275  }
276}
277///////////////////////////////////////////////////////////////////////////////
278
279static proc factor(poly p)
280"USAGE:   factor(p) p poly
281RETURN:  list=;
282NOTE:
283EXAMPLE: example factor; shows an example
284"
285{
286  ideal @i;
287  list @l;
288  intvec @v,@w;
289  int @j,@k,@n;
290
291  @l=factorize(p);
292    for(@j=1;@j<=size(@l[1]);@j++)
293    {
294      if(leadcoef(@l[1][@j])==@l[1][@j])
295      {
296        @n++;
297      }
298    }
299    if(@n>0)
300    {
301      if(@n==size(@l[1]))
302      {
303        @l[1]=ideal(1);
304        @v=1;
305        @l[2]=@v;
306      }
307      else
308      {
309        @k=0;
310        int pleh;
311        for(@j=1;@j<=size(@l[1]);@j++)
312        {
313          if(leadcoef(@l[1][@j])!=@l[1][@j])
314          {
315            @k++;
316            @i=@i+ideal(@l[1][@j]);
317            if(size(@i)==pleh)
318            {
319              "//factorization error";
320              @l;
321              @k--;
322              @v[@k]=@v[@k]+@l[2][@j];
323            }
324            else
325            {
326              pleh++;
327              @v[@k]=@l[2][@j];
328            }
329          }
330        }
331        @l[1]=@i;
332        @l[2]=@v;
333      }
334    }
335    // }
336  return(@l);
337}
338example
339{ "EXAMPLE:"; echo = 2;
340   ring  r = 0,(x,y,z),lp;
341   poly  p = (x+y)^2*(y-z)^3;
342   list  l = factor(p);
343   l;
344   ring r1 =(0,b,d,f,g),(a,c,e),lp;
345   poly p  =(1*d)*e^2+(1*d*f^2*g);
346   list  l = factor(p);
347   l;
348   ring r2 =(0,b,f,g),(a,c,e,d),lp;
349   poly p  =(1*d)*e^2+(1*d*f^2*g);
350   list  l = factor(p);
351   l;
352}
353
354///////////////////////////////////////////////////////////////////////////////
355
356proc idealsEqual( ideal k, ideal j)
357{
358  return(stdIdealsEqual(std(k),std(j)));
359}
360
361static proc specialIdealsEqual( ideal k1, ideal k2)
362{
363  int j;
364
365  if(size(k1)==size(k2))
366  {
367    for(j=1;j<=size(k1);j++)
368    {
369      if(leadexp(k1[j])!=leadexp(k2[j]))
370      {
371        return(0);
372      }
373    }
374    return(1);
375  }
376  return(0);
377}
378
379static proc stdIdealsEqual( ideal k1, ideal k2)
380{
381  int j;
382
383  if(size(k1)==size(k2))
384  {
385    for(j=1;j<=size(k1);j++)
386    {
387      if(leadexp(k1[j])!=leadexp(k2[j]))
388      {
389        return(0);
390      }
391    }
392    attrib(k2,"isSB",1);
393    if(size(reduce(k1,k2,1))==0)
394    {
395      return(1);
396    }
397  }
398  return(0);
399}
400///////////////////////////////////////////////////////////////////////////////
401
402proc primaryTest (ideal i, poly p)
403{
404  int m=1;
405  int n=nvars(basering);
406  int e,f;
407  poly t;
408  ideal h;
409  list act;
410
411  ideal prm=p;
412  attrib(prm,"isSB",1);
413
414  while (n>1)
415  {
416    n--;
417    m++;
418
419    //search for i[m] which has a power of var(n) as leading term
420    if (n==1)
421    {
422      m=size(i);
423    }
424    else
425    {
426      while (lead(i[m])/var(n-1)==0)
427      {
428        m++;
429      }
430      m--;
431    }
432    //check whether i[m] =(c*var(n)+h)^e modulo prm for some
433    //h in K[var(n+1),...,var(nvars(basering))], c in K
434    //if not (0) is returned, else var(n)+h is added to prm
435
436    e=deg(lead(i[m]));
437    if(char(basering)!=0)
438    {
439      f=1;
440      if(e mod char(basering)==0)
441      {
442        if ( voice >=15 )
443        {
444          "// WARNING: The characteristic is perhaps too small to use";
445          "// the algorithm of Gianni/Trager/Zacharias.";
446          "// This may result in an infinte loop";
447          "// loop in primaryTest, voice:",voice;"";
448        }
449        while(e mod char(basering)==0)
450        {
451          f=f*char(basering);
452          e=e div char(basering);
453        }
454      }
455      t=leadcoef(i[m])*e*var(n)^f+(i[m]-lead(i[m]))/var(n)^((e-1)*f);
456      i[m]=poly(e)^e*leadcoef(i[m])^(e-1)*i[m];
457      if (reduce(i[m]-t^e,prm,1) !=0)
458      {
459        return(ideal(0));
460      }
461      if(f>1)
462      {
463        act=factorize(t);
464        if(size(act[1])>2)
465        {
466          return(ideal(0));
467        }
468        if(deg(act[1][2])>1)
469        {
470          return(ideal(0));
471        }
472        t=act[1][2];
473      }
474    }
475    else
476    {
477      t=leadcoef(i[m])*e*var(n)+(i[m]-lead(i[m]))/var(n)^(e-1);
478      i[m]=poly(e)^e*leadcoef(i[m])^(e-1)*i[m];
479      if (reduce(i[m]-t^e,prm,1) !=0)
480      {
481        return(ideal(0));
482      }
483    }
484
485    h=interred(t);
486    t=h[1];
487
488    prm = prm,t;
489    attrib(prm,"isSB",1);
490  }
491  return(prm);
492}
493
494///////////////////////////////////////////////////////////////////////////////
495proc gcdTest(ideal act)
496{
497  int i,j;
498  if(size(act)<=1)
499  {
500    return(0);
501  }
502  for (i=1;i<=size(act)-1;i++)
503  {
504    for(j=i+1;j<=size(act);j++)
505    {
506      if(deg(std(ideal(act[i],act[j]))[1])>0)
507      {
508        return(0);
509      }
510    }
511  }
512  return(1);
513}
514
515///////////////////////////////////////////////////////////////////////////////
516static proc splitPrimary(list l,ideal ser,int @wr,list sact)
517{
518  int i,j,k,s,r,w;
519  list keepresult,act,keepprime;
520  poly @f;
521  int sl=size(l);
522  for(i=1;i<=sl div 2;i++)
523  {
524    if(sact[2][i]>1)
525    {
526      keepprime[i]=l[2*i-1]+ideal(sact[1][i]);
527    }
528    else
529    {
530      keepprime[i]=l[2*i-1];
531    }
532  }
533  i=0;
534  while(i<size(l) div 2)
535  {
536    i++;
537    if((size(ser)>0)&&(size(reduce(ser,l[2*i-1],1))==0))
538    {
539      l[2*i-1]=ideal(1);
540      l[2*i]=ideal(1);
541      continue;
542    }
543
544    if(size(l[2*i])==0)
545    {
546      if(homog(l[2*i-1])==1)
547      {
548        l[2*i]=maxideal(1);
549        continue;
550      }
551      j=0;
552/*
553      if(i<=sl div 2)
554      {
555        j=1;
556      }
557*/
558      while(j<size(l[2*i-1]))
559      {
560        j++;
561        act=factor(l[2*i-1][j]);
562        r=size(act[1]);
563        attrib(l[2*i-1],"isSB",1);
564        if((r==1)&&(vdim(l[2*i-1])==deg(l[2*i-1][j])))
565        {
566          l[2*i]=std(l[2*i-1],act[1][1]);
567          break;
568        }
569        if((r==1)&&(act[2][1]>1))
570        {
571          keepprime[i]=interred(keepprime[i]+ideal(act[1][1]));
572          if(homog(keepprime[i])==1)
573          {
574            l[2*i]=maxideal(1);
575            break;
576          }
577        }
578        if(gcdTest(act[1])==1)
579        {
580          for(k=2;k<=r;k++)
581          {
582            keepprime[size(l) div 2+k-1]=interred(keepprime[i]+ideal(act[1][k]));
583          }
584          keepprime[i]=interred(keepprime[i]+ideal(act[1][1]));
585          for(k=1;k<=r;k++)
586          {
587            if(@wr==0)
588            {
589              keepresult[k]=std(l[2*i-1],act[1][k]^act[2][k]);
590            }
591            else
592            {
593              keepresult[k]=std(l[2*i-1],act[1][k]);
594            }
595          }
596          l[2*i-1]=keepresult[1];
597          if(vdim(keepresult[1])==deg(act[1][1]))
598          {
599            l[2*i]=keepresult[1];
600          }
601          if((homog(keepresult[1])==1)||(homog(keepprime[i])==1))
602          {
603            l[2*i]=maxideal(1);
604          }
605          s=size(l)-2;
606          for(k=2;k<=r;k++)
607          {
608            l[s+2*k-1]=keepresult[k];
609            keepprime[s div 2+k]=interred(keepresult[k]+ideal(act[1][k]));
610            if(vdim(keepresult[k])==deg(act[1][k]))
611            {
612              l[s+2*k]=keepresult[k];
613            }
614            else
615            {
616              l[s+2*k]=ideal(0);
617            }
618            if((homog(keepresult[k])==1)||(homog(keepprime[s div 2+k])==1))
619            {
620              l[s+2*k]=maxideal(1);
621            }
622          }
623          i--;
624          break;
625        }
626        if(r>=2)
627        {
628          s=size(l);
629          @f=act[1][1];
630          act=sat1(l[2*i-1],act[1][1]);
631          if(deg(act[1][1])>0)
632          {
633            l[s+1]=std(l[2*i-1],act[2]);
634            if(homog(l[s+1])==1)
635            {
636              l[s+2]=maxideal(1);
637            }
638            else
639            {
640              l[s+2]=ideal(0);
641            }
642            keepprime[s div 2+1]=interred(keepprime[i]+ideal(@f));
643            if(homog(keepprime[s div 2+1])==1)
644            {
645              l[s+2]=maxideal(1);
646            }
647            keepprime[i]=act[1];
648            l[2*i-1]=act[1];
649            attrib(l[2*i-1],"isSB",1);
650            if(homog(l[2*i-1])==1)
651            {
652              l[2*i]=maxideal(1);
653            }
654            i--;
655            break;
656          }
657        }
658      }
659    }
660  }
661  if(sl==size(l))
662  {
663    return(l);
664  }
665  for(i=1;i<=size(l) div 2;i++)
666  {
667    attrib(l[2*i-1],"isSB",1);
668
669    if((size(ser)>0)&&(size(reduce(ser,l[2*i-1],1))==0)&&(deg(l[2*i-1][1])>0))
670    {
671      "Achtung in split";
672
673      l[2*i-1]=ideal(1);
674      l[2*i]=ideal(1);
675    }
676    if((size(l[2*i])==0)&&(specialIdealsEqual(keepprime[i],l[2*i-1])!=1))
677    {
678      keepprime[i]=std(keepprime[i]);
679      if(homog(keepprime[i])==1)
680      {
681        l[2*i]=maxideal(1);
682      }
683      else
684      {
685        act=zero_decomp(keepprime[i],ideal(0),@wr,1);
686        if(size(act)==2)
687        {
688          l[2*i]=act[2];
689        }
690      }
691    }
692  }
693  return(l);
694}
695example
696{ "EXAMPLE:"; echo=2;
697   ring  r = 32003,(x,y,z),lp;
698   ideal i1=x*(x+1),yz,(z+1)*(z-1);
699   ideal i2=xy,yz,(x-2)*(x+3);
700   list l=i1,ideal(0),i2,ideal(0),i2,ideal(1);
701   list l1=splitPrimary(l,ideal(0),0);
702   l1;
703}
704///////////////////////////////////////////////////////////////////////////////
705static proc splitCharp(list l)
706{
707  if((char(basering)==0)||(npars(basering)>0))
708  {
709    return(l);
710  }
711  def op = option(get);
712  def P=basering;
713  int i,j,k,m,q,d,o;
714  int n = nvars(basering);
715  ideal s,t,u,sact;
716  poly ni;
717  string minp,gnir,va;
718  list sa,keep,rp,keep1;
719  for(i=1;i<=size(l) div 2;i++)
720  {
721    if(size(l[2*i])==0)
722    {
723      if(deg(l[2*i-1][1])==vdim(l[2*i-1]))
724      {
725        l[2*i]=l[2*i-1];
726      }
727    }
728  }
729  for(i=1;i<=size(l) div 2;i++)
730  {
731    if(size(l[2*i])==0)
732    {
733      s=factorize(l[2*i-1][1],1);   //vermeiden!!!
734      t=l[2*i-1];
735      m=size(t);
736      ni=s[1];
737      if(deg(ni)>1)
738      {
739        va=varstr(P);
740        j=size(va);
741        while(va[j]!=","){j--;}
742        va=va[1..j-1];
743        gnir="ring RL=("+string(char(P))+","+string(var(n))+"),("+va+"),lp;";
744        execute(gnir);
745        minpoly=leadcoef(imap(P,ni));
746        ideal act;
747        ideal t=imap(P,t);
748
749        for(k=2;k<=m;k++)
750        {
751          act=factorize(t[k],1);
752          if(size(act)>1){break;}
753        }
754        setring P;
755        sact=imap(RL,act);
756
757        if(size(sact)>1)
758        {
759          sa=sat1(l[2*i-1],sact[1]);
760          keep[size(keep)+1]=std(l[2*i-1],sa[2]);
761          if(sa[1][1]==l[2*i-1][1])
762          {
763             l[2*i-1]=std(sa[1]);
764             l[2*i]=primaryTest(sa[1],s[1]);
765          }
766          else
767          {
768             l[2*i-1]=std(sa[1]);
769             l[2*i]=primaryTest(sa[1],factorize(sa[1][1],1)[1]);
770          }
771        }
772        if((size(sact)==1)&&(m==2))
773        {
774          l[2*i]=l[2*i-1];
775          attrib(l[2*i],"isSB",1);
776        }
777        if((size(sact)==1)&&(m>2))
778        {
779          setring RL;
780
781          option(redSB);
782          t=std(t);
783
784          list sp=zero_decomp(t,0,0);
785
786          setring P;
787          rp=imap(RL,sp);
788          for(o=1;o<=size(rp);o++)
789          {
790            rp[o]=interred(simplify(rp[o],1)+ideal(ni));
791          }
792          l[2*i-1]=rp[1];
793          l[2*i]=rp[2];
794          rp=delete(rp,1);
795          rp=delete(rp,1);
796          keep1=keep1+rp;
797
798          option(noredSB);
799        }
800        kill RL;
801      }
802    }
803  }
804  if(size(keep)>0)
805  {
806    for(i=1;i<=size(keep);i++)
807    {
808      if(deg(keep[i][1])>0)
809      {
810        l[size(l)+1]=keep[i];
811        l[size(l)+1]=primaryTest(keep[i],factorize(keep[i][1],1)[1]);
812      }
813    }
814  }
815  l=l+keep1;
816  option(set,op);
817  return(l);
818}
819
820///////////////////////////////////////////////////////////////////////////////
821
822proc zero_decomp (ideal j,ideal ser,int @wr,list #)
823"USAGE:   zero_decomp(j,ser,@wr); j,ser ideals, @wr=0 or 1
824         (@wr=0 for primary decomposition, @wr=1 for computation of associated
825         primes)
826RETURN:  list = list of primary ideals and their radicals (at even positions
827         in the list) if the input is zero-dimensional and a standardbases
828         with respect to lex-ordering
829         If ser!=(0) and ser is contained in j or if j is not zero-dimen-
830         sional then ideal(1),ideal(1) is returned
831NOTE:    Algorithm of Gianni/Trager/Zacharias
832EXAMPLE: example zero_decomp; shows an example
833"
834{
835  def   @P = basering;
836  int uytrewq;
837  int nva = nvars(basering);
838  int @k,@s,@n,@k1,zz;
839  list primary,lres0,lres1,act,@lh,@wh;
840  map phi,psi,phi1,psi1;
841  ideal jmap,jmap1,jmap2,helpprim,@qh,@qht,ser1;
842  intvec @vh,@hilb;
843  string @ri;
844  poly @f;
845  if (dim(j)>0)
846  {
847    primary[1]=ideal(1);
848    primary[2]=ideal(1);
849    return(primary);
850  }
851  intvec save=option(get);
852  option(redSB);
853  j=interred(j);
854
855  attrib(j,"isSB",1);
856
857  if(vdim(j)==deg(j[1]))
858  {
859    act=factor(j[1]);
860    for(@k=1;@k<=size(act[1]);@k++)
861    {
862      @qh=j;
863      if(@wr==0)
864      {
865        @qh[1]=act[1][@k]^act[2][@k];
866      }
867      else
868      {
869        @qh[1]=act[1][@k];
870      }
871      primary[2*@k-1]=interred(@qh);
872      @qh=j;
873      @qh[1]=act[1][@k];
874      primary[2*@k]=interred(@qh);
875      attrib( primary[2*@k-1],"isSB",1);
876
877      if((size(ser)>0)&&(size(reduce(ser,primary[2*@k-1],1))==0))
878      {
879        primary[2*@k-1]=ideal(1);
880        primary[2*@k]=ideal(1);
881      }
882    }
883    option(set,save);
884    return(primary);
885  }
886
887  option(set,save);
888  if(homog(j)==1)
889  {
890    primary[1]=j;
891    if((size(ser)>0)&&(size(reduce(ser,j,1))==0))
892    {
893      primary[1]=ideal(1);
894      primary[2]=ideal(1);
895      return(primary);
896    }
897    if(dim(j)==-1)
898    {
899      primary[1]=ideal(1);
900      primary[2]=ideal(1);
901    }
902    else
903    {
904      primary[2]=maxideal(1);
905    }
906    return(primary);
907  }
908
909//the first element in the standardbase is factorized
910  if(deg(j[1])>0)
911  {
912    act=factor(j[1]);
913    testFactor(act,j[1]);
914  }
915  else
916  {
917    primary[1]=ideal(1);
918    primary[2]=ideal(1);
919    return(primary);
920  }
921
922//with the factors new ideals (hopefully the primary decomposition)
923//are created
924  if(size(act[1])>1)
925  {
926    if(size(#)>1)
927    {
928      primary[1]=ideal(1);
929      primary[2]=ideal(1);
930      primary[3]=ideal(1);
931      primary[4]=ideal(1);
932      return(primary);
933    }
934    for(@k=1;@k<=size(act[1]);@k++)
935    {
936      if(@wr==0)
937      {
938        primary[2*@k-1]=std(j,act[1][@k]^act[2][@k]);
939      }
940      else
941      {
942        primary[2*@k-1]=std(j,act[1][@k]);
943      }
944      if((act[2][@k]==1)&&(vdim(primary[2*@k-1])==deg(act[1][@k])))
945      {
946        primary[2*@k]   = primary[2*@k-1];
947      }
948      else
949      {
950        primary[2*@k]   = primaryTest(primary[2*@k-1],act[1][@k]);
951      }
952    }
953  }
954  else
955  {
956    primary[1]=j;
957    if((size(#)>0)&&(act[2][1]>1))
958    {
959      act[2]=1;
960      primary[1]=std(primary[1],act[1][1]);
961    }
962    if(@wr!=0)
963    {
964      primary[1]=std(j,act[1][1]);
965    }
966    if((act[2][1]==1)&&(vdim(primary[1])==deg(act[1][1])))
967    {
968      primary[2]=primary[1];
969    }
970    else
971    {
972      primary[2]=primaryTest(primary[1],act[1][1]);
973    }
974  }
975
976  if(size(#)==0)
977  {
978    primary=splitPrimary(primary,ser,@wr,act);
979  }
980
981  if((voice>=6)&&(char(basering)<=181))
982  {
983    primary=splitCharp(primary);
984  }
985
986  if((@wr==2)&&(npars(basering)>0)&&(voice>=6)&&(char(basering)>0))
987  {
988  //the prime decomposition of Yokoyama in characteristic p
989    list ke,ek;
990    @k=0;
991    while(@k<size(primary) div 2)
992    {
993      @k++;
994      if(size(primary[2*@k])==0)
995      {
996        ek=insepDecomp(primary[2*@k-1]);
997        primary=delete(primary,2*@k);
998        primary=delete(primary,2*@k-1);
999        @k--;
1000      }
1001      ke=ke+ek;
1002    }
1003    for(@k=1;@k<=size(ke);@k++)
1004    {
1005      primary[size(primary)+1]=ke[@k];
1006      primary[size(primary)+1]=ke[@k];
1007    }
1008  }
1009
1010  if(voice>=8){primary=extF(primary);};
1011
1012//test whether all ideals in the decomposition are primary and
1013//in general position
1014//if not after a random coordinate transformation of the last
1015//variable the corresponding ideal is decomposed again.
1016  if((npars(basering)>0)&&(voice>=8))
1017  {
1018    poly randp;
1019    for(zz=1;zz<nvars(basering);zz++)
1020    {
1021      randp=randp
1022              +(random(0,5)*par(1)^2+random(0,5)*par(1)+random(0,5))*var(zz);
1023    }
1024    randp=randp+var(nvars(basering));
1025  }
1026  @k=0;
1027  while(@k<(size(primary) div 2))
1028  {
1029    @k++;
1030    if (size(primary[2*@k])==0)
1031    {
1032      for(zz=1;zz<size(primary[2*@k-1])-1;zz++)
1033      {
1034        attrib(primary[2*@k-1],"isSB",1);
1035        if(vdim(primary[2*@k-1])==deg(primary[2*@k-1][zz]))
1036        {
1037          primary[2*@k]=primary[2*@k-1];
1038        }
1039      }
1040    }
1041  }
1042
1043  @k=0;
1044  ideal keep;
1045  while(@k<(size(primary) div 2))
1046  {
1047    @k++;
1048    if (size(primary[2*@k])==0)
1049    {
1050      jmap=randomLast(100);
1051      jmap1=maxideal(1);
1052      jmap2=maxideal(1);
1053      @qht=primary[2*@k-1];
1054      if((npars(basering)>0)&&(voice>=10))
1055      {
1056        jmap[size(jmap)]=randp;
1057      }
1058
1059      for(@n=2;@n<=size(primary[2*@k-1]);@n++)
1060      {
1061        if(deg(lead(primary[2*@k-1][@n]))==1)
1062        {
1063          for(zz=1;zz<=nva;zz++)
1064          {
1065            if(lead(primary[2*@k-1][@n])/var(zz)!=0)
1066            {
1067              jmap1[zz]=-1/leadcoef(primary[2*@k-1][@n])*primary[2*@k-1][@n]
1068                   +2/leadcoef(primary[2*@k-1][@n])*lead(primary[2*@k-1][@n]);
1069              jmap2[zz]=primary[2*@k-1][@n];
1070              @qht[@n]=var(zz);
1071            }
1072          }
1073          jmap[nva]=subst(jmap[nva],lead(primary[2*@k-1][@n]),0);
1074        }
1075      }
1076      if(size(subst(jmap[nva],var(1),0)-var(nva))!=0)
1077      {
1078        // jmap[nva]=subst(jmap[nva],var(1),0);
1079        //hier geaendert +untersuchen!!!!!!!!!!!!!!
1080      }
1081      phi1=@P,jmap1;
1082      phi=@P,jmap;
1083      for(@n=1;@n<=nva;@n++)
1084      {
1085        jmap[@n]=-(jmap[@n]-2*var(@n));
1086      }
1087      psi=@P,jmap;
1088      psi1=@P,jmap2;
1089      @qh=phi(@qht);
1090
1091//=================== the new part ============================
1092
1093      if (npars(basering)>1) { @qh=groebner(@qh,"par2var"); }
1094      else                   { @qh=groebner(@qh); }
1095
1096//=============================================================
1097//       if(npars(@P)>0)
1098//       {
1099//          @ri= "ring @Phelp ="
1100//                  +string(char(@P))+",
1101//                   ("+varstr(@P)+","+parstr(@P)+",@t),(C,dp);";
1102//       }
1103//       else
1104//       {
1105//          @ri= "ring @Phelp ="
1106//                  +string(char(@P))+",("+varstr(@P)+",@t),(C,dp);";
1107//       }
1108//       execute(@ri);
1109//       ideal @qh=homog(imap(@P,@qht),@t);
1110//
1111//       ideal @qh1=std(@qh);
1112//       @hilb=hilb(@qh1,1);
1113//       @ri= "ring @Phelp1 ="
1114//                  +string(char(@P))+",("+varstr(@Phelp)+"),(C,lp);";
1115//       execute(@ri);
1116//       ideal @qh=homog(imap(@P,@qh),@t);
1117//       kill @Phelp;
1118//       @qh=std(@qh,@hilb);
1119//       @qh=subst(@qh,@t,1);
1120//       setring @P;
1121//       @qh=imap(@Phelp1,@qh);
1122//       kill @Phelp1;
1123//       @qh=clearSB(@qh);
1124//       attrib(@qh,"isSB",1);
1125//=============================================================
1126
1127      ser1=phi1(ser);
1128      @lh=zero_decomp (@qh,phi(ser1),@wr);
1129
1130      kill lres0;
1131      list lres0;
1132      if(size(@lh)==2)
1133      {
1134        helpprim=@lh[2];
1135        lres0[1]=primary[2*@k-1];
1136        ser1=psi(helpprim);
1137        lres0[2]=psi1(ser1);
1138        if(size(reduce(lres0[2],lres0[1],1))==0)
1139        {
1140          primary[2*@k]=primary[2*@k-1];
1141          continue;
1142        }
1143      }
1144      else
1145      {
1146        lres1=psi(@lh);
1147        lres0=psi1(lres1);
1148      }
1149
1150//=================== the new part ============================
1151
1152      primary=delete(primary,2*@k-1);
1153      primary=delete(primary,2*@k-1);
1154      @k--;
1155      if(size(lres0)==2)
1156      {
1157        lres0[2]=groebner(lres0[2]);
1158      }
1159      else
1160      {
1161        for(@n=1;@n<=size(lres0) div 2;@n++)
1162        {
1163          if(specialIdealsEqual(lres0[2*@n-1],lres0[2*@n])==1)
1164          {
1165            lres0[2*@n-1]=groebner(lres0[2*@n-1]);
1166            lres0[2*@n]=lres0[2*@n-1];
1167            attrib(lres0[2*@n],"isSB",1);
1168          }
1169          else
1170          {
1171            lres0[2*@n-1]=groebner(lres0[2*@n-1]);
1172            lres0[2*@n]=groebner(lres0[2*@n]);
1173          }
1174        }
1175      }
1176      primary=primary+lres0;
1177
1178//=============================================================
1179//       if(npars(@P)>0)
1180//       {
1181//          @ri= "ring @Phelp ="
1182//                  +string(char(@P))+",
1183//                   ("+varstr(@P)+","+parstr(@P)+",@t),(C,dp);";
1184//       }
1185//       else
1186//       {
1187//          @ri= "ring @Phelp ="
1188//                  +string(char(@P))+",("+varstr(@P)+",@t),(C,dp);";
1189//       }
1190//       execute(@ri);
1191//       list @lvec;
1192//       list @lr=imap(@P,lres0);
1193//       ideal @lr1;
1194//
1195//       if(size(@lr)==2)
1196//       {
1197//          @lr[2]=homog(@lr[2],@t);
1198//          @lr1=std(@lr[2]);
1199//          @lvec[2]=hilb(@lr1,1);
1200//       }
1201//       else
1202//       {
1203//          for(@n=1;@n<=size(@lr) div 2;@n++)
1204//          {
1205//             if(specialIdealsEqual(@lr[2*@n-1],@lr[2*@n])==1)
1206//             {
1207//                @lr[2*@n-1]=homog(@lr[2*@n-1],@t);
1208//                @lr1=std(@lr[2*@n-1]);
1209//                @lvec[2*@n-1]=hilb(@lr1,1);
1210//                @lvec[2*@n]=@lvec[2*@n-1];
1211//             }
1212//             else
1213//             {
1214//                @lr[2*@n-1]=homog(@lr[2*@n-1],@t);
1215//                @lr1=std(@lr[2*@n-1]);
1216//                @lvec[2*@n-1]=hilb(@lr1,1);
1217//                @lr[2*@n]=homog(@lr[2*@n],@t);
1218//                @lr1=std(@lr[2*@n]);
1219//                @lvec[2*@n]=hilb(@lr1,1);
1220//
1221//             }
1222//         }
1223//       }
1224//       @ri= "ring @Phelp1 ="
1225//                  +string(char(@P))+",("+varstr(@Phelp)+"),(C,lp);";
1226//       execute(@ri);
1227//       list @lr=imap(@Phelp,@lr);
1228//
1229//       kill @Phelp;
1230//       if(size(@lr)==2)
1231//      {
1232//          @lr[2]=std(@lr[2],@lvec[2]);
1233//          @lr[2]=subst(@lr[2],@t,1);
1234//       }
1235//       else
1236//       {
1237//          for(@n=1;@n<=size(@lr) div 2;@n++)
1238//          {
1239//             if(specialIdealsEqual(@lr[2*@n-1],@lr[2*@n])==1)
1240//             {
1241//                @lr[2*@n-1]=std(@lr[2*@n-1],@lvec[2*@n-1]);
1242//                @lr[2*@n-1]=subst(@lr[2*@n-1],@t,1);
1243//                @lr[2*@n]=@lr[2*@n-1];
1244//                attrib(@lr[2*@n],"isSB",1);
1245//             }
1246//             else
1247//             {
1248//                @lr[2*@n-1]=std(@lr[2*@n-1],@lvec[2*@n-1]);
1249//                @lr[2*@n-1]=subst(@lr[2*@n-1],@t,1);
1250//                @lr[2*@n]=std(@lr[2*@n],@lvec[2*@n]);
1251//                @lr[2*@n]=subst(@lr[2*@n],@t,1);
1252//             }
1253//          }
1254//       }
1255//       kill @lvec;
1256//       setring @P;
1257//       lres0=imap(@Phelp1,@lr);
1258//       kill @Phelp1;
1259//       for(@n=1;@n<=size(lres0);@n++)
1260//       {
1261//          lres0[@n]=clearSB(lres0[@n]);
1262//          attrib(lres0[@n],"isSB",1);
1263//       }
1264//
1265//       primary[2*@k-1]=lres0[1];
1266//       primary[2*@k]=lres0[2];
1267//       @s=size(primary) div 2;
1268//       for(@n=1;@n<=size(lres0) div 2-1;@n++)
1269//       {
1270//         primary[2*@s+2*@n-1]=lres0[2*@n+1];
1271//         primary[2*@s+2*@n]=lres0[2*@n+2];
1272//       }
1273//       @k--;
1274//=============================================================
1275    }
1276  }
1277  return(primary);
1278}
1279example
1280{ "EXAMPLE:"; echo = 2;
1281   ring  r = 0,(x,y,z),lp;
1282   poly  p = z2+1;
1283   poly  q = z4+2;
1284   ideal i = p^2*q^3,(y-z3)^3,(x-yz+z4)^4;
1285   i=std(i);
1286   list  pr= zero_decomp(i,ideal(0),0);
1287   pr;
1288}
1289///////////////////////////////////////////////////////////////////////////////
1290proc extF(list l,list #)
1291{
1292//zero_dimensional primary decomposition after finite field extension
1293  def R=basering;
1294  int p=char(R);
1295
1296  if((p==0)||(p>13)||(npars(R)>0)){return(l);}
1297
1298  int ex=3;
1299  if(size(#)>0){ex=#[1];}
1300
1301  list peek,peek1;
1302  while(size(l)>0)
1303  {
1304    if(size(l[2])==0)
1305    {
1306      peek[size(peek)+1]=l[1];
1307    }
1308    else
1309    {
1310      peek1[size(peek1)+1]=l[1];
1311      peek1[size(peek1)+1]=l[2];
1312    }
1313    l=delete(l,1);
1314    l=delete(l,1);
1315  }
1316  if(size(peek)==0){return(peek1);}
1317
1318  string gnir="ring RH=("+string(p)+"^"+string(ex)+",a),("+varstr(R)+"),lp;";
1319  execute(gnir);
1320  string mp="minpoly="+string(minpoly)+";";
1321  gnir="ring RL=("+string(p)+",a),("+varstr(R)+"),lp;";
1322  execute(gnir);
1323  execute(mp);
1324  list L=imap(R,peek);
1325  list pr, keep;
1326  int i;
1327  for(i=1;i<=size(L);i++)
1328  {
1329    attrib(L[i],"isSB",1);
1330    pr=zero_decomp(L[i],0,0);
1331    keep=keep+pr;
1332  }
1333  for(i=1;i<=size(keep);i++)
1334  {
1335    keep[i]=simplify(keep[i],1);
1336  }
1337  mp="poly pp="+string(minpoly)+";";
1338
1339  string gnir1="ring RS="+string(p)+",("+varstr(R)+",a),lp;";
1340  execute(gnir1);
1341  execute(mp);
1342  list L=imap(RL,keep);
1343
1344  for(i=1;i<=size(L);i++)
1345  {
1346    L[i]=eliminate(L[i]+ideal(pp),a);
1347  }
1348  i=0;
1349  int j;
1350  while(i<size(L) div 2-1)
1351  {
1352    i++;
1353    j=i;
1354    while(j<size(L) div 2)
1355    {
1356      j++;
1357      if(idealsEqual(L[2*i-1],L[2*j-1]))
1358      {
1359        L=delete(L,2*j-1);
1360        L=delete(L,2*j-1);
1361        j--;
1362      }
1363    }
1364  }
1365  setring R;
1366  list re=imap(RS,L);
1367  re=re+peek1;
1368
1369  return(extF(re,ex+1));
1370}
1371
1372///////////////////////////////////////////////////////////////////////////////
1373proc zeroSp(ideal i)
1374{
1375//preparation for the separable closure
1376//decomposition into ideals of special type
1377//i.e. the minimal polynomials of every variable mod i are irreducible
1378//returns a list of 2 lists: rr=pe,qe
1379//the ideals in pe[l] are special, their special elements are in qe[l]
1380//pe[l] is a dp-Groebnerbasis
1381//the radical of the intersection of the pe[l] is equal to the radical of i
1382
1383  def R=basering;
1384
1385  //i has to be a reduced groebner basis
1386  ideal F=finduni(i);
1387
1388  int j,k,l,ready;
1389  list fa;
1390  fa[1]=factorize(F[1],1);
1391  poly te,ti;
1392  ideal tj;
1393  //avoid factorization of the same polynomial
1394  for(j=2;j<=size(F);j++)
1395  {
1396    for(k=1;k<=j-1;k++)
1397    {
1398      ti=F[k];
1399      te=subst(ti,var(k),var(j));
1400      if(te==F[j])
1401      {
1402        tj=fa[k];
1403        fa[j]=subst(tj,var(k),var(j));
1404        ready=1;
1405        break;
1406      }
1407    }
1408    if(!ready)
1409    {
1410      fa[j]=factorize(F[j],1);
1411    }
1412    ready=0;
1413  }
1414  execute( "ring P=("+charstr(R)+"),("+varstr(R)+"),(C,dp);");
1415  ideal i=imap(R,i);
1416  if(npars(basering)==0)
1417  {
1418    ideal J=fglm(R,i);
1419  }
1420  else
1421  {
1422    ideal J=groebner(i);
1423  }
1424  list fa=imap(R,fa);
1425  list qe=J;          //collects a dp-Groebnerbasis of the special ideals
1426  list keep=ideal(0); //collects the special elements
1427
1428  list re,em,ke;
1429  ideal K,L;
1430
1431  for(j=1;j<=nvars(basering);j++)
1432  {
1433    for(l=1;l<=size(qe);l++)
1434    {
1435      for(k=1;k<=size(fa[j]);k++)
1436      {
1437        L=std(qe[l],fa[j][k]);
1438        K=keep[l],fa[j][k];
1439        if(deg(L[1])>0)
1440        {
1441          re[size(re)+1]=L;
1442          ke[size(ke)+1]=K;
1443        }
1444      }
1445    }
1446    qe=re;
1447    re=em;
1448    keep=ke;
1449    ke=em;
1450  }
1451
1452  setring R;
1453  list qe=imap(P,keep);
1454  list pe=imap(P,qe);
1455  for(l=1;l<=size(qe);l++)
1456  {
1457    qe[l]=simplify(qe[l],2);
1458  }
1459  list rr=pe,qe;
1460  return(rr);
1461}
1462///////////////////////////////////////////////////////////////////////////////
1463
1464proc zeroSepClos(ideal I,ideal F)
1465{
1466//computes the separable closure of the special ideal I
1467//F is the set of special elements of I
1468//returns the separable closure sc(I) of I and an intvec v
1469//such that sc(I)=preimage(frobenius definde by v)
1470//i.e. var(i)----->var(i)^(p^v[i])
1471
1472  if(homog(I)==1){return(maxideal(1));}
1473
1474  //assume F[i] irreducible in I and depending only on var(i)
1475
1476  def R=basering;
1477  int n=nvars(R);
1478  int p=char(R);
1479  intvec v;
1480  v[n]=0;
1481  int i,k;
1482  list l;
1483
1484  for(i=1;i<=n;i++)
1485  {
1486    l[i]=sep(F[i],i);
1487    F[i]=l[i][1];
1488    if(l[i][2]>k){k=l[i][2];}
1489  }
1490
1491  if(k==0){return(list(I,v));}        //the separable case
1492  ideal m;
1493
1494  for(i=1;i<=n;i++)
1495  {
1496    m[i]=var(i)^(p^l[i][2]);
1497    v[i]=l[i][2];
1498  }
1499  map phi=R,m;
1500  ideal J=preimage(R,phi,I);
1501  return(list(J,v));
1502}
1503///////////////////////////////////////////////////////////////////////////////
1504
1505proc insepDecomp(ideal i)
1506{
1507//decomposes i into special ideals
1508//computes the prime decomposition of the special ideals
1509//and transforms it back to a decomposition of i
1510
1511  def R=basering;
1512  list pr=zeroSp(i);
1513  int l,k;
1514  list re,wo,qr;
1515  ideal m=maxideal(1);
1516  ideal K;
1517  map phi=R,m;
1518  int p=char(R);
1519  intvec op=option(get);
1520
1521  for(l=1;l<=size(pr[1]);l++)
1522  {
1523    wo=zeroSepClos(pr[1][l],pr[2][l]);
1524    for(k=1;k<=nvars(basering);k++)
1525    {
1526      m[k]=var(k)^(p^wo[2][k]);
1527    }
1528    phi=R,m;
1529    qr=decomp(wo[1],2);
1530
1531    option(redSB);
1532    for(k=1;k<=size(qr) div 2;k++)
1533    {
1534      K=qr[2*k];
1535      K=phi(K);
1536      K=groebner(K);
1537      re[size(re)+1]=zeroRad(K);
1538    }
1539    option(noredSB);
1540  }
1541  option(set,op);
1542  return(re);
1543}
1544
1545
1546///////////////////////////////////////////////////////////////////////////////
1547
1548static proc clearSB (ideal i,list #)
1549"USAGE:   clearSB(i); i ideal which is SB ordered by monomial ordering
1550RETURN:  ideal = minimal SB
1551NOTE:
1552EXAMPLE: example clearSB; shows an example
1553"
1554{
1555  int k,j;
1556  poly m;
1557  int c=size(i);
1558
1559  if(size(#)==0)
1560  {
1561    for(j=1;j<c;j++)
1562    {
1563      if(deg(i[j])==0)
1564      {
1565        i=ideal(1);
1566        return(i);
1567      }
1568      if(deg(i[j])>0)
1569      {
1570        m=lead(i[j]);
1571        for(k=j+1;k<=c;k++)
1572        {
1573          if(size(lead(i[k])/m)>0)
1574          {
1575            i[k]=0;
1576          }
1577        }
1578      }
1579    }
1580  }
1581  else
1582  {
1583    j=0;
1584    while(j<c-1)
1585    {
1586      j++;
1587      if(deg(i[j])==0)
1588      {
1589        i=ideal(1);
1590        return(i);
1591      }
1592      if(deg(i[j])>0)
1593      {
1594        m=lead(i[j]);
1595        for(k=j+1;k<=c;k++)
1596        {
1597          if(size(lead(i[k])/m)>0)
1598          {
1599            if((leadexp(m)!=leadexp(i[k]))||(#[j]<=#[k]))
1600            {
1601              i[k]=0;
1602            }
1603            else
1604            {
1605              i[j]=0;
1606              break;
1607            }
1608          }
1609        }
1610      }
1611    }
1612  }
1613  return(simplify(i,2));
1614}
1615example
1616{ "EXAMPLE:"; echo = 2;
1617   ring  r = (0,a,b),(x,y,z),dp;
1618   ideal i=ax2+y,a2x+y,bx;
1619   list l=1,2,1;
1620   ideal j=clearSB(i,l);
1621   j;
1622}
1623
1624///////////////////////////////////////////////////////////////////////////////
1625static proc clearSBNeu (ideal i,list #)
1626"USAGE:   clearSB(i); i ideal which is SB ordered by monomial ordering
1627RETURN:  ideal = minimal SB
1628NOTE:
1629EXAMPLE: example clearSB; shows an example
1630"
1631{
1632 int k,j;
1633 intvec m,n,v,w;
1634 int c=size(i);
1635 w=leadexp(0);
1636 v[size(i)]=0;
1637
1638 j=0;
1639 while(j<c-1)
1640 {
1641   j++;
1642   if(deg(i[j])>=0)
1643   {
1644      m=leadexp(i[j]);
1645      for(k=j+1;k<=c;k++)
1646      {
1647        n=leadexp(i[k]);
1648        if(n!=w)
1649        {
1650           if(((m==n)&&(#[j]>#[k]))||((teilt(n,m))&&(n!=m)))
1651           {
1652             i[j]=0;
1653             v[j]=1;
1654             break;
1655           }
1656           if(((m==n)&&(#[j]<=#[k]))||((teilt(m,n))&&(n!=m)))
1657           {
1658             i[k]=0;
1659             v[k]=1;
1660           }
1661        }
1662      }
1663    }
1664  }
1665  return(v);
1666}
1667
1668static proc teilt(intvec a, intvec b)
1669{
1670  int i;
1671  for(i=1;i<=size(a);i++)
1672  {
1673    if(a[i]>b[i]){return(0);}
1674  }
1675  return(1);
1676}
1677///////////////////////////////////////////////////////////////////////////////
1678
1679static proc independSet (ideal j)
1680"USAGE:   independentSet(i); i ideal
1681RETURN:  list = new varstring with the independent set at the end,
1682                ordstring with the corresponding block ordering,
1683                the integer where the independent set starts in the varstring
1684NOTE:
1685EXAMPLE: example independentSet; shows an example
1686"
1687{
1688  int n,k,di;
1689  list resu,hilf;
1690  string var1,var2;
1691  list v=indepSet(j,1);
1692
1693  for(n=1;n<=size(v);n++)
1694  {
1695    di=0;
1696    var1="";
1697    var2="";
1698    for(k=1;k<=size(v[n]);k++)
1699    {
1700      if(v[n][k]!=0)
1701      {
1702        di++;
1703        var2=var2+"var("+string(k)+"),";
1704      }
1705      else
1706      {
1707        var1=var1+"var("+string(k)+"),";
1708      }
1709    }
1710    if(di>0)
1711    {
1712      var1=var1+var2;
1713      var1=var1[1..size(var1)-1];
1714      hilf[1]=var1;
1715      hilf[2]="lp";
1716      //"lp("+string(nvars(basering)-di)+"),dp("+string(di)+")";
1717      hilf[3]=di;
1718      resu[n]=hilf;
1719    }
1720    else
1721    {
1722      resu[n]=varstr(basering),ordstr(basering),0;
1723    }
1724  }
1725  return(resu);
1726}
1727example
1728{ "EXAMPLE:"; echo = 2;
1729   ring s1=(0,x,y),(a,b,c,d,e,f,g),lp;
1730   ideal i=ea-fbg,fa+be,ec-fdg,fc+de;
1731   i=std(i);
1732   list  l=independSet(i);
1733   l;
1734   i=i,g;
1735   l=independSet(i);
1736   l;
1737
1738   ring s=0,(x,y,z),lp;
1739   ideal i=z,yx;
1740   list l=independSet(i);
1741   l;
1742
1743
1744}
1745///////////////////////////////////////////////////////////////////////////////
1746
1747static proc maxIndependSet (ideal j)
1748"USAGE:   maxIndependentSet(i); i ideal
1749RETURN:  list = new varstring with the maximal independent set at the end,
1750                ordstring with the corresponding block ordering,
1751                the integer where the independent set starts in the varstring
1752NOTE:
1753EXAMPLE: example maxIndependentSet; shows an example
1754"
1755{
1756  int n,k,di;
1757  list resu,hilf;
1758  string var1,var2;
1759  list v=indepSet(j,0);
1760
1761  for(n=1;n<=size(v);n++)
1762  {
1763    di=0;
1764    var1="";
1765    var2="";
1766    for(k=1;k<=size(v[n]);k++)
1767    {
1768      if(v[n][k]!=0)
1769      {
1770        di++;
1771        var2=var2+"var("+string(k)+"),";
1772      }
1773      else
1774      {
1775        var1=var1+"var("+string(k)+"),";
1776      }
1777    }
1778    if(di>0)
1779    {
1780      var1=var1+var2;
1781      var1=var1[1..size(var1)-1];
1782      hilf[1]=var1;
1783      hilf[2]="lp";
1784      hilf[3]=di;
1785      resu[n]=hilf;
1786    }
1787    else
1788    {
1789      resu[n]=varstr(basering),ordstr(basering),0;
1790    }
1791  }
1792  return(resu);
1793}
1794example
1795{ "EXAMPLE:"; echo = 2;
1796   ring s1=(0,x,y),(a,b,c,d,e,f,g),lp;
1797   ideal i=ea-fbg,fa+be,ec-fdg,fc+de;
1798   i=std(i);
1799   list  l=maxIndependSet(i);
1800   l;
1801   i=i,g;
1802   l=maxIndependSet(i);
1803   l;
1804
1805   ring s=0,(x,y,z),lp;
1806   ideal i=z,yx;
1807   list l=maxIndependSet(i);
1808   l;
1809
1810
1811}
1812
1813///////////////////////////////////////////////////////////////////////////////
1814
1815static proc prepareQuotientring (int nnp)
1816"USAGE:   prepareQuotientring(nnp); nnp int
1817RETURN:  string = to define Kvar(nnp+1),...,var(nvars)[..rest ]
1818NOTE:
1819EXAMPLE: example independentSet; shows an example
1820"
1821{
1822  ideal @ih,@jh;
1823  int npar=npars(basering);
1824  int @n;
1825
1826  string quotring= "ring quring = ("+charstr(basering);
1827  for(@n=nnp+1;@n<=nvars(basering);@n++)
1828  {
1829     quotring=quotring+",var("+string(@n)+")";
1830     @ih=@ih+var(@n);
1831  }
1832
1833  quotring=quotring+"),(var(1)";
1834  @jh=@jh+var(1);
1835  for(@n=2;@n<=nnp;@n++)
1836  {
1837    quotring=quotring+",var("+string(@n)+")";
1838    @jh=@jh+var(@n);
1839  }
1840  quotring=quotring+"),(C,lp);";
1841
1842  return(quotring);
1843
1844}
1845example
1846{ "EXAMPLE:"; echo = 2;
1847   ring s1=(0,x),(a,b,c,d,e,f,g),lp;
1848   def @Q=basering;
1849   list l= prepareQuotientring(3);
1850   l;
1851   execute(l[1]);
1852   execute(l[2]);
1853   basering;
1854   phi;
1855   setring @Q;
1856
1857}
1858
1859///////////////////////////////////////////////////////////////////////////////
1860static proc cleanPrimary(list l)
1861{
1862   int i,j;
1863   list lh;
1864   for(i=1;i<=size(l) div 2;i++)
1865   {
1866      if(deg(l[2*i-1][1])>0)
1867      {
1868         j++;
1869         lh[j]=l[2*i-1];
1870         j++;
1871         lh[j]=l[2*i];
1872      }
1873   }
1874   return(lh);
1875}
1876///////////////////////////////////////////////////////////////////////////////
1877
1878
1879proc minAssPrimesold(ideal i, list #)
1880"USAGE:   minAssPrimes(i); i ideal
1881         minAssPrimes(i,1); i ideal  (to use also the factorizing Groebner)
1882RETURN:  list = the minimal associated prime ideals of i
1883EXAMPLE: example minAssPrimes; shows an example
1884"
1885{
1886   def @P=basering;
1887   if(size(i)==0){return(list(ideal(0)));}
1888   list qr=simplifyIdeal(i);
1889   map phi=@P,qr[2];
1890   i=qr[1];
1891
1892   execute ("ring gnir = ("+charstr(basering)+"),("+varstr(basering)+"),("
1893             +ordstr(basering)+");");
1894
1895
1896   ideal i=fetch(@P,i);
1897   if(size(#)==0)
1898   {
1899      int @wr;
1900      list tluser,@res;
1901      list primary=decomp(i,2);
1902
1903      @res[1]=primary;
1904
1905      tluser=union(@res);
1906      setring @P;
1907      list @res=imap(gnir,tluser);
1908      return(phi(@res));
1909   }
1910   list @res,empty;
1911   ideal ser;
1912   def op = option( get );
1913   option( redSB );
1914   list @pr=facstd(i);
1915   //if(size(@pr)==1)
1916//   {
1917//      attrib(@pr[1],"isSB",1);
1918//      if((dim(@pr[1])==0)&&(homog(@pr[1])==1))
1919//      {
1920//         setring @P;
1921//         list @res=maxideal(1);
1922//         return(phi(@res));
1923//      }
1924//      if(dim(@pr[1])>1)
1925//      {
1926//         setring @P;
1927//        // kill gnir;
1928//         execute ("ring gnir1 = ("+charstr(basering)+"),
1929//                              ("+varstr(basering)+"),(C,lp);");
1930//         ideal i=fetch(@P,i);
1931//         list @pr=facstd(i);
1932//        // ideal ser;
1933//         setring gnir;
1934//         @pr=fetch(gnir1,@pr);
1935//         kill gnir1;
1936//      }
1937//   }
1938   // option( noredSB );
1939   option( set, op );
1940   int j,k,odim,ndim,count;
1941   attrib(@pr[1],"isSB",1);
1942   if(#[1]==77)
1943   {
1944     odim=dim(@pr[1]);
1945     count=1;
1946     intvec pos;
1947     pos[size(@pr)]=0;
1948     for(j=2;j<=size(@pr);j++)
1949     {
1950        attrib(@pr[j],"isSB",1);
1951        ndim=dim(@pr[j]);
1952        if(ndim>odim)
1953        {
1954           for(k=count;k<=j-1;k++)
1955           {
1956              pos[k]=1;
1957           }
1958           count=j;
1959           odim=ndim;
1960        }
1961        if(ndim<odim)
1962        {
1963           pos[j]=1;
1964        }
1965     }
1966     for(j=1;j<=size(@pr);j++)
1967     {
1968        if(pos[j]!=1)
1969        {
1970            @res[j]=decomp(@pr[j],2);
1971        }
1972        else
1973        {
1974           @res[j]=empty;
1975        }
1976     }
1977   }
1978   else
1979   {
1980     ser=ideal(1);
1981     for(j=1;j<=size(@pr);j++)
1982     {
1983//@pr[j];
1984//pause();
1985        @res[j]=decomp(@pr[j],2);
1986//       @res[j]=decomp(@pr[j],2,@pr[j],ser);
1987//       for(k=1;k<=size(@res[j]);k++)
1988//       {
1989//          ser=intersect(ser,@res[j][k]);
1990//       }
1991     }
1992   }
1993
1994   @res=union(@res);
1995   setring @P;
1996   list @res=imap(gnir,@res);
1997   return(phi(@res));
1998}
1999example
2000{ "EXAMPLE:"; echo = 2;
2001   ring  r = 32003,(x,y,z),lp;
2002   poly  p = z2+1;
2003   poly  q = z4+2;
2004   ideal i = p^2*q^3,(y-z3)^3,(x-yz+z4)^4;
2005   list pr= minAssPrimes(i);  pr;
2006
2007   minAssPrimes(i,1);
2008}
2009
2010static proc primT(ideal i)
2011{
2012   //assumes that all generators of i are irreducible
2013   //i is standard basis
2014
2015   attrib(i,"isSB",1);
2016   int j=size(i);
2017   int k;
2018   while(j>0)
2019   {
2020     if(deg(i[j])>1){break;}
2021     j--;
2022   }
2023   if(j==0){return(1);}
2024   if(deg(i[j])==vdim(i)){return(1);}
2025   return(0);
2026}
2027
2028static proc minAssPrimes(ideal i, list #)
2029"USAGE:   minAssPrimes(i); i ideal
2030      Optional parameters in list #: (can be entered in any order)
2031      0, "facstd"   ->   uses facstd to first decompose the ideal
2032      1, "noFacstd" ->  does not use facstd (default)
2033      "SL" ->     the new algorithm is used (default)
2034      "GTZ" ->     the old algorithm is used
2035RETURN:  list = the minimal associated prime ideals of i
2036EXAMPLE: example minAssPrimes; shows an example
2037"
2038{
2039  if(size(i) == 0){return(list(ideal(0)));}
2040  string algorithm;    // Algorithm to be used
2041  string facstdOption;    // To uses proc facstd
2042  int j;          // Counter
2043  def P0 = basering;
2044  list Pl=ringlist(P0);
2045  intvec dp_w;
2046  for(j=nvars(P0);j>0;j--) {dp_w[j]=1;}
2047  Pl[3]=list(list("dp",dp_w),list("C",0));
2048  def P=ring(Pl);
2049  setring P;
2050  ideal i=imap(P0,i);
2051
2052  // Set input parameters
2053  algorithm = "SL";         // Default: SL algorithm
2054  facstdOption = "Facstd";    // Default: facstd is not used
2055  if(size(#) > 0)
2056  {
2057    int valid;
2058    for(j = 1; j <= size(#); j++)
2059    {
2060      valid = 0;
2061      if((typeof(#[j]) == "int") or (typeof(#[j]) == "number"))
2062      {
2063        if (#[j] == 0) {facstdOption = "noFacstd"; valid = 1;}    // If #[j] == 0, facstd is not used.
2064        if (#[j] == 1) {facstdOption = "facstd";   valid = 1;}    // If #[j] == 1, facstd is used.
2065      }
2066      if(typeof(#[j]) == "string")
2067      {
2068        if(#[j] == "GTZ" || #[j] == "SL")
2069        {
2070          algorithm = #[j];
2071          valid = 1;
2072        }
2073        if(#[j] == "noFacstd" || #[j] == "facstd")
2074        {
2075          facstdOption = #[j];
2076          valid = 1;
2077        }
2078      }
2079      if(valid == 0)
2080      {
2081        dbprint(1, "Warning! The following input parameter was not recognized:", #[j]);
2082      }
2083    }
2084  }
2085
2086  list q = simplifyIdeal(i);
2087  list re = maxideal(1);
2088  int a, k;
2089  intvec op = option(get);
2090  map phi = P,q[2];
2091
2092  list result;
2093
2094  if(npars(P) == 0){option(redSB);}
2095
2096  if(attrib(i,"isSB")!=1)
2097  {
2098    i=groebner(q[1]);
2099  }
2100  else
2101  {
2102    for(j=1;j<=nvars(basering);j++)
2103    {
2104      if(q[2][j]!=var(j)){k=1;break;}
2105    }
2106    if(k)
2107    {
2108      i=groebner(q[1]);
2109    }
2110  }
2111
2112  if( dim(i) == -1 )
2113  {
2114    option( set,op );
2115    setring P0;
2116    return( ideal(1) );
2117  }
2118  if( (dim(i) == 0 ) && ( npars(P) == 0) )
2119  {
2120    int di = vdim(i);
2121    execute ("ring gnir=("+charstr(P)+"),("+varstr(P)+"),lp;");
2122    ideal J = std(imap(P,i));
2123    attrib(J, "isSB", 1);
2124    if(vdim(J) != di)
2125    {
2126      J = fglm(P, i);
2127    }
2128//    list pr = triangMH(J,2); HIER KOENNEN verschiedene Mengen zu gleichen
2129//                             asoziierten Primidealen fuehren
2130// Aenderung
2131    list pr = triangMH(J,2);
2132    list qr, re;
2133    for(k = 1; k <= size(pr); k++)
2134    {
2135      if(primT(pr[k])&&(0))
2136      {
2137        re[size(re) + 1] = pr[k];
2138      }
2139      else
2140      {
2141        attrib(pr[k], "isSB", 1);
2142        // Lines changed
2143        if (algorithm == "GTZ")
2144        {
2145          qr = decomp(pr[k], 2);
2146        }
2147        else
2148        {
2149          qr = minAssSL(pr[k]);
2150        }
2151        for(j = 1; j <= size(qr) div 2; j++)
2152        {
2153          re[size(re) + 1] = std(qr[2 * j]);
2154        }
2155      }
2156    }
2157    setring P;
2158    re = imap(gnir, re);
2159    re=phi(re);
2160    option(set, op);
2161    setring(P0);
2162    list re=imap(P,re);
2163    return(re);
2164  }
2165
2166  // Lines changed
2167  if ((facstdOption == "noFacstd") || (dim(i) == 0))
2168  {
2169    if (algorithm == "GTZ")
2170    {
2171      re[1] = decomp(i, 2);
2172    }
2173    else
2174    {
2175      re[1] = minAssSL(i);
2176    }
2177    re = union(re);
2178    option(set, op);
2179    re=phi(re);
2180    setring(P0);
2181    list re=imap(P,re);
2182    return(re);
2183  }
2184  q = facstd(i);
2185
2186/*
2187  if((size(q) == 1) && (dim(i) > 1))
2188  {
2189    execute ("ring gnir=("+charstr(P)+"),("+varstr(P)+"),lp;");
2190    list p = facstd(fetch(P, i));
2191    if(size(p) > 1)
2192    {
2193      a = 1;
2194      setring P;
2195      q = fetch(gnir,p);
2196    }
2197    else
2198    {
2199      setring P;
2200    }
2201    kill gnir;
2202  }
2203*/
2204  option(set,op);
2205  // Debug
2206  dbprint(printlevel - voice, "Components returned by facstd", size(q), q);
2207  for(j = 1; j <= size(q); j++)
2208  {
2209    if(a == 0){attrib(q[j], "isSB", 1);}
2210    // Debug
2211    dbprint(printlevel - voice, "We compute the decomp of component", j);
2212    // Lines changed
2213    if (algorithm == "GTZ")
2214    {
2215      re[j] = decomp(q[j], 2);
2216    }
2217    else
2218    {
2219      re[j] = minAssSL(q[j]);
2220    }
2221    // Debug
2222    dbprint(printlevel - voice, "Number of components obtained for this component:", size(re[j]) div 2);
2223    dbprint(printlevel - voice, "re[j]:", re[j]);
2224  }
2225  re = union(re);
2226  re=phi(re);
2227  setring(P0);
2228  list re=imap(P,re);
2229  return(re);
2230}
2231example
2232{ "EXAMPLE:"; echo = 2;
2233   ring  r = 32003,(x,y,z),lp;
2234   poly  p = z2+1;
2235   poly  q = z4+2;
2236   ideal i = p^2*q^3,(y-z3)^3,(x-yz+z4)^4;
2237   list pr= minAssPrimes(i);  pr;
2238
2239   minAssPrimes(i,1);
2240}
2241
2242static proc union(list li)
2243{
2244  int i,j,k;
2245
2246  def P=basering;
2247
2248  execute("ring ir = ("+charstr(basering)+"),("+varstr(basering)+"),(C,lp);");
2249  list l=fetch(P,li);
2250  list @erg;
2251
2252  for(k=1;k<=size(l);k++)
2253  {
2254     for(j=1;j<=size(l[k]) div 2;j++)
2255     {
2256        if(deg(l[k][2*j][1])!=0)
2257        {
2258           i++;
2259           @erg[i]=l[k][2*j];
2260        }
2261     }
2262  }
2263
2264  list @wos;
2265  i=0;
2266  ideal i1,i2;
2267  while(i<size(@erg)-1)
2268  {
2269     i++;
2270     k=i+1;
2271     i1=lead(@erg[i]);
2272      attrib(i1,"isSB",1);
2273      attrib(@erg[i],"isSB",1);
2274
2275     while(k<=size(@erg))
2276     {
2277        if(deg(@erg[i][1])==0)
2278        {
2279           break;
2280        }
2281        i2=lead(@erg[k]);
2282        attrib(@erg[k],"isSB",1);
2283        attrib(i2,"isSB",1);
2284
2285        if(size(reduce(i1,i2,1))==0)
2286        {
2287           if(size(reduce(@erg[i],@erg[k],1))==0)
2288           {
2289              @erg[k]=ideal(1);
2290              i2=ideal(1);
2291           }
2292        }
2293        if(size(reduce(i2,i1,1))==0)
2294        {
2295           if(size(reduce(@erg[k],@erg[i],1))==0)
2296           {
2297              break;
2298           }
2299        }
2300        k++;
2301        if(k>size(@erg))
2302        {
2303           @wos[size(@wos)+1]=@erg[i];
2304        }
2305     }
2306  }
2307  if(deg(@erg[size(@erg)][1])!=0)
2308  {
2309     @wos[size(@wos)+1]=@erg[size(@erg)];
2310  }
2311  setring P;
2312  list @ser=fetch(ir,@wos);
2313  return(@ser);
2314}
2315///////////////////////////////////////////////////////////////////////////////
2316proc equidim(ideal i,list #)
2317"USAGE:  equidim(i) or equidim(i,1) ; i ideal
2318RETURN: list of equidimensional ideals a[1],...,a[s] with:
2319        - a[s] the equidimensional locus of i, i.e. the intersection
2320          of the primary ideals of dimension of i
2321        - a[1],...,a[s-1] the lower dimensional equidimensional loci.
2322NOTE:    An embedded component q (primary ideal) of i can be replaced in the
2323         decomposition by a primary ideal q1 with the same radical as q. @*
2324         @code{equidim(i,1)} uses the algorithm of Eisenbud/Huneke/Vasconcelos.
2325
2326EXAMPLE:example equidim; shows an example
2327"
2328{
2329  if(attrib(basering,"global")!=1)
2330  {
2331      ERROR(
2332      "// Not implemented for this ordering, please change to global ordering."
2333      );
2334  }
2335  intvec op ;
2336  def  P = basering;
2337  list eq;
2338  intvec w;
2339  int n,m;
2340  int g=size(i);
2341  int a=attrib(i,"isSB");
2342  int homo=homog(i);
2343  if(size(#)!=0)
2344  {
2345     m=1;
2346  }
2347
2348  if(((homo==1)||(a==1))&&(find(ordstr(basering),"l")==0)
2349                                &&(find(ordstr(basering),"s")==0))
2350  {
2351     execute("ring gnir = ("+charstr(basering)+"),("+varstr(basering)+"),("
2352                              +ordstr(basering)+");");
2353     ideal i=imap(P,i);
2354     ideal j=i;
2355     if(a==1)
2356     {
2357       attrib(j,"isSB",1);
2358     }
2359     else
2360     {
2361       j=groebner(i);
2362     }
2363  }
2364  else
2365  {
2366     execute("ring gnir = ("+charstr(basering)+"),("+varstr(basering)+"),dp;");
2367     ideal i=imap(P,i);
2368     ideal j=groebner(i);
2369  }
2370  if(homo==1)
2371  {
2372     for(n=1;n<=nvars(basering);n++)
2373     {
2374        w[n]=ord(var(n));
2375     }
2376     intvec hil=hilb(j,1,w);
2377  }
2378
2379  if ((dim(j)==-1)||(size(j)==0)||(nvars(basering)==1)
2380                  ||(dim(j)==0)||(dim(j)+g==nvars(basering)))
2381  {
2382    setring P;
2383    eq[1]=i;
2384    return(eq);
2385  }
2386
2387  if(m==0)
2388  {
2389     ideal k=equidimMax(j);
2390  }
2391  else
2392  {
2393     ideal k=equidimMaxEHV(j);
2394  }
2395  if(size(reduce(k,j,1))==0)
2396  {
2397    setring P;
2398    eq[1]=i;
2399    kill gnir;
2400    return(eq);
2401  }
2402  op=option(get);
2403  option(returnSB);
2404  j=quotient(j,k);
2405  option(set,op);
2406
2407  list equi=equidim(j);
2408  if(deg(equi[size(equi)][1])<=0)
2409  {
2410      equi[size(equi)]=k;
2411  }
2412  else
2413  {
2414    equi[size(equi)+1]=k;
2415  }
2416  setring P;
2417  eq=imap(gnir,equi);
2418  kill gnir;
2419  return(eq);
2420}
2421example
2422{ "EXAMPLE:"; echo = 2;
2423   ring  r = 32003,(x,y,z),dp;
2424   ideal i = intersect(ideal(z),ideal(x,y),ideal(x2,z2),ideal(x5,y5,z5));
2425   equidim(i);
2426}
2427
2428///////////////////////////////////////////////////////////////////////////////
2429proc equidimMax(ideal i)
2430"USAGE:  equidimMax(i); i ideal
2431RETURN:  ideal of equidimensional locus (of maximal dimension) of i.
2432EXAMPLE: example equidimMax; shows an example
2433"
2434{
2435  if(attrib(basering,"global")!=1)
2436  {
2437      ERROR(
2438      "// Not implemented for this ordering, please change to global ordering."
2439      );
2440  }
2441  def  P = basering;
2442  ideal eq;
2443  intvec w;
2444  int n;
2445  int g=size(i);
2446  int a=attrib(i,"isSB");
2447  int homo=homog(i);
2448
2449  if(((homo==1)||(a==1))&&(find(ordstr(basering),"l")==0)
2450                                &&(find(ordstr(basering),"s")==0))
2451  {
2452     execute("ring gnir = ("+charstr(basering)+"),("+varstr(basering)+"),("
2453                              +ordstr(basering)+");");
2454     ideal i=imap(P,i);
2455     ideal j=i;
2456     if(a==1)
2457     {
2458       attrib(j,"isSB",1);
2459     }
2460     else
2461     {
2462       j=groebner(i);
2463     }
2464  }
2465  else
2466  {
2467     execute("ring gnir = ("+charstr(basering)+"),("+varstr(basering)+"),dp;");
2468     ideal i=imap(P,i);
2469     ideal j=groebner(i);
2470  }
2471  list indep;
2472  ideal equ,equi;
2473  if(homo==1)
2474  {
2475     for(n=1;n<=nvars(basering);n++)
2476     {
2477        w[n]=ord(var(n));
2478     }
2479     intvec hil=hilb(j,1,w);
2480  }
2481  if ((dim(j)==-1)||(size(j)==0)||(nvars(basering)==1)
2482                  ||(dim(j)==0)||(dim(j)+g==nvars(basering)))
2483  {
2484    setring P;
2485    return(i);
2486  }
2487
2488  indep=maxIndependSet(j);
2489
2490  execute("ring gnir1 = ("+charstr(basering)+"),("+indep[1][1]+"),("
2491                              +indep[1][2]+");");
2492  if(homo==1)
2493  {
2494     ideal j=std(imap(gnir,j),hil,w);
2495  }
2496  else
2497  {
2498     ideal j=groebner(imap(gnir,j));
2499  }
2500  string quotring=prepareQuotientring(nvars(basering)-indep[1][3]);
2501  execute(quotring);
2502  ideal j=imap(gnir1,j);
2503  kill gnir1;
2504  j=clearSB(j);
2505  ideal h;
2506  for(n=1;n<=size(j);n++)
2507  {
2508     h[n]=leadcoef(j[n]);
2509  }
2510  setring gnir;
2511  ideal h=imap(quring,h);
2512  kill quring;
2513
2514  list l=minSat(j,h);
2515
2516  if(deg(l[2])>0)
2517  {
2518    equ=l[1];
2519    attrib(equ,"isSB",1);
2520    j=std(j,l[2]);
2521
2522    if(dim(equ)==dim(j))
2523    {
2524      equi=equidimMax(j);
2525      equ=interred(intersect(equ,equi));
2526    }
2527  }
2528  else
2529  {
2530    equ=i;
2531  }
2532
2533  setring P;
2534  eq=imap(gnir,equ);
2535  kill gnir;
2536  return(eq);
2537}
2538example
2539{ "EXAMPLE:"; echo = 2;
2540   ring  r = 32003,(x,y,z),dp;
2541   ideal i = intersect(ideal(z),ideal(x,y),ideal(x2,z2),ideal(x5,y5,z5));
2542   equidimMax(i);
2543}
2544///////////////////////////////////////////////////////////////////////////////
2545static proc islp()
2546{
2547   string s=ordstr(basering);
2548   int n=find(s,"lp");
2549   if(!n){return(0);}
2550   int k=find(s,",");
2551   string t=s[k+1..size(s)];
2552   int l=find(t,",");
2553   t=s[1..k-1];
2554   int m=find(t,",");
2555   if(l+m){return(0);}
2556   return(1);
2557}
2558///////////////////////////////////////////////////////////////////////////////
2559
2560proc algeDeco(ideal i, int w)
2561{
2562//reduces primery decomposition over algebraic extensions to
2563//the other cases
2564   def R=basering;
2565   int n=nvars(R);
2566
2567   def op = option(get);
2568
2569//---Anfang Provisorium
2570   if((size(i)==2) && (w==2))
2571   {
2572      option( redSB );
2573      ideal J = std(i);
2574      option( noredSB );
2575      if ((size(J)==2)&&(deg(J[1])==1))
2576      {
2577         ideal keep;
2578         poly f;
2579         int j;
2580         for(j=1;j<=nvars(basering);j++)
2581         {
2582           f=J[2];
2583           while((f/var(j))*var(j)-f==0)
2584           {
2585             f=f/var(j);
2586             keep=keep,var(j);
2587           }
2588           J[2]=f;
2589         }
2590         ideal K=factorize(J[2],1);
2591         if(deg(K[1])==0){K=0;}
2592         K=K+std(keep);
2593         ideal L;
2594         list resu;
2595         for(j=1;j<=size(K);j++)
2596         {
2597            L=J[1],K[j];
2598            resu[j]=L;
2599         }
2600         option( set, op );
2601         return(resu);
2602      }
2603   }
2604//---Ende Provisorium
2605   string mp="poly p="+string(minpoly)+";";
2606   string gnir="ring RH="+string(char(R))+",("+varstr(R)+","+string(par(1))
2607                +"),dp;";
2608   execute(gnir);
2609   execute(mp);
2610   ideal i=imap(R,i);
2611   ideal I=subst(i,var(nvars(basering)),0);
2612   int j;
2613   for(j=1;j<=ncols(i);j++)
2614   {
2615     if(i[j]!=I[j]){break;}
2616   }
2617   if((j>ncols(i))&&(deg(p)==1))
2618   {
2619     setring R;
2620     kill RH;
2621     kill gnir;
2622     string gnir="ring RH="+string(char(R))+",("+varstr(R)+"),dp;";
2623     execute(gnir);
2624     ideal i=imap(R,i);
2625     ideal J;
2626   }
2627   else
2628   {
2629      i=i,p;
2630   }
2631   list pr;
2632
2633   if(w==0)
2634   {
2635      pr=decomp(i);
2636   }
2637   if(w==1)
2638   {
2639      pr=prim_dec(i,1);
2640      pr=reconvList(pr);
2641   }
2642   if(w==2)
2643   {
2644      pr=minAssPrimes(i);
2645   }
2646   if(n<nvars(basering))
2647   {
2648      gnir="ring RS="+string(char(R))+",("+varstr(RH)
2649                +"),(dp("+string(n)+"),lp);";
2650      execute(gnir);
2651      list pr=imap(RH,pr);
2652      ideal K;
2653      for(j=1;j<=size(pr);j++)
2654      {
2655         K=groebner(pr[j]);
2656         K=K[2..size(K)];
2657         pr[j]=K;
2658      }
2659      setring R;
2660      list pr=imap(RS,pr);
2661   }
2662   else
2663   {
2664      setring R;
2665      list pr=imap(RH,pr);
2666   }
2667   list re;
2668   if(w==2)
2669   {
2670      re=pr;
2671   }
2672   else
2673   {
2674      re=convList(pr);
2675   }
2676   option( set, op );
2677   return( re );
2678}
2679///////////////////////////////////////////////////////////////////////////////
2680static proc prepare_absprimdec(list primary)
2681{
2682  list resu,tempo;
2683  string absotto;
2684  resu[size(primary) div 2]=list();
2685  for(int ab=1;ab<=size(primary) div 2;ab++)
2686  {
2687    absotto= absFactorize(primary[2*ab][1],77);
2688    tempo=primary[2*ab-1],primary[2*ab],absotto,string(var(nvars(basering)));
2689    resu[ab]=tempo;
2690  }
2691  return(resu);
2692}
2693///////////////////////////////////////////////////////////////////////////////
2694static proc decomp(ideal i,list #)
2695"USAGE:  decomp(i); i ideal  (for primary decomposition)   (resp.
2696         decomp(i,1);        (for the associated primes of dimension of i) )
2697         decomp(i,2);        (for the minimal associated primes) )
2698         decomp(i,3);        (for the absolute primary decomposition) )
2699RETURN:  list = list of primary ideals and their associated primes
2700         (at even positions in the list)
2701         (resp. a list of the minimal associated primes)
2702NOTE:    Algorithm of Gianni/Trager/Zacharias
2703EXAMPLE: example decomp; shows an example
2704"
2705{
2706  intvec op,@vv;
2707  def  @P = basering;
2708  list primary,indep,ltras;
2709  intvec @vh,isat,@w;
2710  int @wr,@k,@n,@m,@n1,@n2,@n3,homo,seri,keepdi,abspri,ab,nn;
2711  ideal peek=i;
2712  ideal ser,tras;
2713  int isS=(attrib(i,"isSB")==1);
2714
2715
2716  if(size(#)>0)
2717  {
2718    if((#[1]==1)||(#[1]==2)||(#[1]==3))
2719    {
2720      @wr=#[1];
2721      if(@wr==3){abspri=1;@wr=0;}
2722      if(size(#)>1)
2723      {
2724        seri=1;
2725        peek=#[2];
2726        ser=#[3];
2727      }
2728    }
2729    else
2730    {
2731      seri=1;
2732      peek=#[1];
2733      ser=#[2];
2734    }
2735  }
2736  if(abspri)
2737  {
2738    list absprimary,abskeep,absprimarytmp,abskeeptmp;
2739  }
2740  homo=homog(i);
2741  if(homo==1)
2742  {
2743    if(attrib(i,"isSB")!=1)
2744    {
2745      //ltras=mstd(i);
2746      tras=groebner(i);
2747      ltras=tras,tras;
2748      attrib(ltras[1],"isSB",1);
2749    }
2750    else
2751    {
2752      ltras=i,i;
2753      attrib(ltras[1],"isSB",1);
2754    }
2755    tras=ltras[1];
2756    attrib(tras,"isSB",1);
2757    if((dim(tras)==0) && (!abspri))
2758    {
2759      primary[1]=ltras[2];
2760      primary[2]=maxideal(1);
2761      if(@wr>0)
2762      {
2763        list l;
2764        l[1]=maxideal(1);
2765        l[2]=maxideal(1);
2766        return(l);
2767      }
2768      return(primary);
2769    }
2770    for(@n=1;@n<=nvars(basering);@n++)
2771    {
2772      @w[@n]=ord(var(@n));
2773    }
2774    intvec @hilb=hilb(tras,1,@w);
2775    intvec keephilb=@hilb;
2776  }
2777
2778  //----------------------------------------------------------------
2779  //i is the zero-ideal
2780  //----------------------------------------------------------------
2781
2782  if(size(i)==0)
2783  {
2784    primary=ideal(0),ideal(0);
2785    if (abspri) { return(prepare_absprimdec(primary));}
2786    return(primary);
2787  }
2788
2789  //----------------------------------------------------------------
2790  //pass to the lexicographical ordering and compute a standardbasis
2791  //----------------------------------------------------------------
2792
2793  int lp=islp();
2794
2795  execute("ring gnir = ("+charstr(basering)+"),("+varstr(basering)+"),(C,lp);");
2796  op=option(get);
2797  option(redSB);
2798
2799  ideal ser=fetch(@P,ser);
2800
2801  if(homo==1)
2802  {
2803    if(!lp)
2804    {
2805      ideal @j=std(fetch(@P,i),@hilb,@w);
2806    }
2807    else
2808    {
2809      ideal @j=fetch(@P,tras);
2810      attrib(@j,"isSB",1);
2811    }
2812  }
2813  else
2814  {
2815    if(lp&&isS)
2816    {
2817      ideal @j=fetch(@P,i);
2818      attrib(@j,"isSB",1);
2819    }
2820    else
2821    {
2822      ideal @j=groebner(fetch(@P,i));
2823    }
2824  }
2825  option(set,op);
2826  if(seri==1)
2827  {
2828    ideal peek=fetch(@P,peek);
2829    attrib(peek,"isSB",1);
2830  }
2831  else
2832  {
2833    ideal peek=@j;
2834  }
2835  if((size(ser)==0)&&(!abspri))
2836  {
2837    ideal fried;
2838    @n=size(@j);
2839    for(@k=1;@k<=@n;@k++)
2840    {
2841      if(deg(lead(@j[@k]))==1)
2842      {
2843        fried[size(fried)+1]=@j[@k];
2844        @j[@k]=0;
2845      }
2846    }
2847    if(size(fried)==nvars(basering))
2848    {
2849      setring @P;
2850      primary[1]=i;
2851      primary[2]=i;
2852      if (abspri) { return(prepare_absprimdec(primary));}
2853      return(primary);
2854    }
2855    if(size(fried)>0)
2856    {
2857      string newva;
2858      string newma;
2859      poly f;
2860      for(@k=1;@k<=nvars(basering);@k++)
2861      {
2862        @n1=0;
2863        for(@n=1;@n<=size(fried);@n++)
2864        {
2865          if(leadmonom(fried[@n])==var(@k))
2866          {
2867            @n1=1;
2868            break;
2869          }
2870        }
2871        if(@n1==0)
2872        {
2873          newva=newva+string(var(@k))+",";
2874          newma=newma+string(var(@k))+",";
2875        }
2876        else
2877        {
2878          newma=newma+string(0)+",";
2879          fried[@n]=fried[@n]/leadcoef(fried[@n]);
2880          f=fried[@n]-lead(fried[@n]);
2881          @j=subst(@j,var(@k),-f);
2882        }
2883      }
2884      newva[size(newva)]=")";
2885      newma[size(newma)]=";";
2886      execute("ring @deirf=("+charstr(gnir)+"),("+newva+",lp;");
2887      execute("map @kappa=gnir,"+newma);
2888      ideal @j= @kappa(@j);
2889      @j=std(@j);
2890
2891      list pr=decomp(@j);
2892      setring gnir;
2893      list pr=imap(@deirf,pr);
2894      for(@k=1;@k<=size(pr);@k++)
2895      {
2896        @j=pr[@k]+fried;
2897        pr[@k]=@j;
2898      }
2899      setring @P;
2900      primary=imap(gnir,pr);
2901      if (abspri) { return(prepare_absprimdec(primary));}
2902      return(primary);
2903    }
2904  }
2905  //----------------------------------------------------------------
2906  //j is the ring
2907  //----------------------------------------------------------------
2908
2909  if (dim(@j)==-1)
2910  {
2911    setring @P;
2912    primary=ideal(1),ideal(1);
2913    if (abspri) { return(prepare_absprimdec(primary));}
2914    return(primary);
2915  }
2916
2917  //----------------------------------------------------------------
2918  //  the case of one variable
2919  //----------------------------------------------------------------
2920
2921  if(nvars(basering)==1)
2922  {
2923    list fac=factor(@j[1]);
2924    list gprimary;
2925    for(@k=1;@k<=size(fac[1]);@k++)
2926    {
2927      if(@wr==0)
2928      {
2929        gprimary[2*@k-1]=ideal(fac[1][@k]^fac[2][@k]);
2930        gprimary[2*@k]=ideal(fac[1][@k]);
2931      }
2932      else
2933      {
2934        gprimary[2*@k-1]=ideal(fac[1][@k]);
2935        gprimary[2*@k]=ideal(fac[1][@k]);
2936      }
2937    }
2938    setring @P;
2939    primary=fetch(gnir,gprimary);
2940
2941//HIER
2942    if (abspri) { return(prepare_absprimdec(primary));}
2943    return(primary);
2944  }
2945
2946 //------------------------------------------------------------------
2947 //the zero-dimensional case
2948 //------------------------------------------------------------------
2949  if (dim(@j)==0)
2950  {
2951    op=option(get);
2952    option(redSB);
2953    list gprimary= zero_decomp(@j,ser,@wr);
2954
2955    setring @P;
2956    primary=fetch(gnir,gprimary);
2957
2958    if(size(ser)>0)
2959    {
2960      primary=cleanPrimary(primary);
2961    }
2962//HIER
2963    if(abspri)
2964    {
2965      setring gnir;
2966      list primary=imap(@P,primary);
2967      list resu,tempo;
2968      string absotto;
2969      map sigma,invsigma;
2970      ideal II,jmap;
2971      nn=nvars(basering);
2972      for(ab=1;ab<=size(primary) div 2;ab++)
2973      {
2974        II=primary[2*ab];
2975        attrib(II,"isSB",1);
2976        if(deg(II[1])==vdim(II))
2977        {
2978          absotto= absFactorize(primary[2*ab][1],77);
2979          tempo=
2980            primary[2*ab-1],primary[2*ab],absotto,string(var(nvars(basering)));
2981        }
2982        else
2983        {
2984          invsigma=basering,maxideal(1);
2985          jmap=randomLast(50);
2986          sigma=basering,jmap;
2987          jmap[nn]=2*var(nn)-jmap[nn];
2988          invsigma=basering,jmap;
2989          II=groebner(sigma(II));
2990          absotto = absFactorize(II[1],77);
2991          II=var(nn);
2992          tempo= primary[2*ab-1],primary[2*ab],absotto,string(invsigma(II));
2993        }
2994        resu[ab]=tempo;
2995      }
2996      primary=resu;
2997      setring @P;
2998      primary=imap(gnir,primary);
2999    }
3000    option(set,op);
3001    return(primary);
3002  }
3003
3004  poly @gs,@gh,@p;
3005  string @va,quotring;
3006  list quprimary,htprimary,collectprimary,lsau,lnew,allindep,restindep;
3007  ideal @h;
3008  int jdim=dim(@j);
3009  list fett;
3010  int lauf,di,newtest;
3011  //------------------------------------------------------------------
3012  //search for a maximal independent set indep,i.e.
3013  //look for subring such that the intersection with the ideal is zero
3014  //j intersected with K[var(indep[3]+1),...,var(nvar] is zero,
3015  //indep[1] is the new varstring and indep[2] the string for block-ordering
3016  //------------------------------------------------------------------
3017  if(@wr!=1)
3018  {
3019    allindep=independSet(@j);
3020    for(@m=1;@m<=size(allindep);@m++)
3021    {
3022      if(allindep[@m][3]==jdim)
3023      {
3024        di++;
3025        indep[di]=allindep[@m];
3026      }
3027      else
3028      {
3029        lauf++;
3030        restindep[lauf]=allindep[@m];
3031      }
3032    }
3033  }
3034  else
3035  {
3036    indep=maxIndependSet(@j);
3037  }
3038
3039  ideal jkeep=@j;
3040  if(ordstr(@P)[1]=="w")
3041  {
3042    execute("ring @Phelp=("+charstr(gnir)+"),("+varstr(gnir)+"),("+ordstr(@P)+");");
3043  }
3044  else
3045  {
3046    execute( "ring @Phelp=("+charstr(gnir)+"),("+varstr(gnir)+"),(C,dp);");
3047  }
3048
3049  if(homo==1)
3050  {
3051    if((ordstr(@P)[3]=="d")||(ordstr(@P)[1]=="d")||(ordstr(@P)[1]=="w")
3052       ||(ordstr(@P)[3]=="w"))
3053    {
3054      ideal jwork=imap(@P,tras);
3055      attrib(jwork,"isSB",1);
3056    }
3057    else
3058    {
3059      ideal jwork=std(imap(gnir,@j),@hilb,@w);
3060    }
3061  }
3062  else
3063  {
3064    ideal jwork=groebner(imap(gnir,@j));
3065  }
3066  list hquprimary;
3067  poly @p,@q;
3068  ideal @h,fac,ser;
3069  ideal @Ptest=1;
3070  di=dim(jwork);
3071  keepdi=di;
3072
3073  setring gnir;
3074  for(@m=1;@m<=size(indep);@m++)
3075  {
3076    isat=0;
3077    @n2=0;
3078    if((indep[@m][1]==varstr(basering))&&(@m==1))
3079    //this is the good case, nothing to do, just to have the same notations
3080    //change the ring
3081    {
3082      execute("ring gnir1 = ("+charstr(basering)+"),("+varstr(basering)+"),("
3083                              +ordstr(basering)+");");
3084      ideal @j=fetch(gnir,@j);
3085      attrib(@j,"isSB",1);
3086      ideal ser=fetch(gnir,ser);
3087    }
3088    else
3089    {
3090      @va=string(maxideal(1));
3091      if(@m==1)
3092      {
3093        @j=fetch(@P,i);
3094      }
3095      execute("ring gnir1 = ("+charstr(basering)+"),("+indep[@m][1]+"),("
3096                              +indep[@m][2]+");");
3097      execute("map phi=gnir,"+@va+";");
3098      op=option(get);
3099      option(redSB);
3100      if(homo==1)
3101      {
3102        ideal @j=std(phi(@j),@hilb,@w);
3103      }
3104      else
3105      {
3106        ideal @j=groebner(phi(@j));
3107      }
3108      ideal ser=phi(ser);
3109
3110      option(set,op);
3111    }
3112    if((deg(@j[1])==0)||(dim(@j)<jdim))
3113    {
3114      setring gnir;
3115      break;
3116    }
3117    for (lauf=1;lauf<=size(@j);lauf++)
3118    {
3119      fett[lauf]=size(@j[lauf]);
3120    }
3121    //------------------------------------------------------------------------
3122    //we have now the following situation:
3123    //j intersected with K[var(nnp+1),..,var(nva)] is zero so we may pass
3124    //to this quotientring, j is their still a standardbasis, the
3125    //leading coefficients of the polynomials  there (polynomials in
3126    //K[var(nnp+1),..,var(nva)]) are collected in the list h,
3127    //we need their ggt, gh, because of the following: let
3128    //(j:gh^n)=(j:gh^infinity) then j*K(var(nnp+1),..,var(nva))[..the rest..]
3129    //intersected with K[var(1),...,var(nva)] is (j:gh^n)
3130    //on the other hand j=(j,gh^n) intersected with (j:gh^n)
3131
3132    //------------------------------------------------------------------------
3133
3134    //arrangement for quotientring K(var(nnp+1),..,var(nva))[..the rest..] and
3135    //map phi:K[var(1),...,var(nva)] --->K(var(nnpr+1),..,var(nva))[..rest..]
3136    //------------------------------------------------------------------------
3137
3138    quotring=prepareQuotientring(nvars(basering)-indep[@m][3]);
3139
3140    //---------------------------------------------------------------------
3141    //we pass to the quotientring   K(var(nnp+1),..,var(nva))[..the rest..]
3142    //---------------------------------------------------------------------
3143
3144    ideal @jj=lead(@j);               //!! vorn vereinbaren
3145    execute(quotring);
3146
3147    ideal @jj=imap(gnir1,@jj);
3148    @vv=clearSBNeu(@jj,fett);  //!! vorn vereinbaren
3149    setring gnir1;
3150    @k=size(@j);
3151    for (lauf=1;lauf<=@k;lauf++)
3152    {
3153      if(@vv[lauf]==1)
3154      {
3155        @j[lauf]=0;
3156      }
3157    }
3158    @j=simplify(@j,2);
3159    setring quring;
3160    // @j considered in the quotientring
3161    ideal @j=imap(gnir1,@j);
3162
3163    ideal ser=imap(gnir1,ser);
3164
3165    kill gnir1;
3166
3167    //j is a standardbasis in the quotientring but usually not minimal
3168    //here it becomes minimal
3169
3170    attrib(@j,"isSB",1);
3171
3172    //we need later ggt(h[1],...)=gh for saturation
3173    ideal @h;
3174    if(deg(@j[1])>0)
3175    {
3176      for(@n=1;@n<=size(@j);@n++)
3177      {
3178        @h[@n]=leadcoef(@j[@n]);
3179      }
3180      //the primary decomposition of j*K(var(nnp+1),..,var(nva))[..the rest..]
3181      op=option(get);
3182      option(redSB);
3183
3184      list uprimary= zero_decomp(@j,ser,@wr);
3185//HIER
3186      if(abspri)
3187      {
3188        ideal II;
3189        ideal jmap;
3190        map sigma;
3191        nn=nvars(basering);
3192        map invsigma=basering,maxideal(1);
3193        for(ab=1;ab<=size(uprimary) div 2;ab++)
3194        {
3195          II=uprimary[2*ab];
3196          attrib(II,"isSB",1);
3197          if(deg(II[1])!=vdim(II))
3198          {
3199            jmap=randomLast(50);
3200            sigma=basering,jmap;
3201            jmap[nn]=2*var(nn)-jmap[nn];
3202            invsigma=basering,jmap;
3203            II=groebner(sigma(II));
3204          }
3205          absprimarytmp[ab]= absFactorize(II[1],77);
3206          II=var(nn);
3207          abskeeptmp[ab]=string(invsigma(II));
3208          invsigma=basering,maxideal(1);
3209        }
3210      }
3211      option(set,op);
3212    }
3213    else
3214    {
3215      list uprimary;
3216      uprimary[1]=ideal(1);
3217      uprimary[2]=ideal(1);
3218    }
3219    //we need the intersection of the ideals in the list quprimary with the
3220    //polynomialring, i.e. let q=(f1,...,fr) in the quotientring such an ideal
3221    //but fi polynomials, then the intersection of q with the polynomialring
3222    //is the saturation of the ideal generated by f1,...,fr with respect to
3223    //h which is the lcm of the leading coefficients of the fi considered in
3224    //in the quotientring: this is coded in saturn
3225
3226    list saturn;
3227    ideal hpl;
3228
3229    for(@n=1;@n<=size(uprimary);@n++)
3230    {
3231      uprimary[@n]=interred(uprimary[@n]); // temporary fix
3232      hpl=0;
3233      for(@n1=1;@n1<=size(uprimary[@n]);@n1++)
3234      {
3235        hpl=hpl,leadcoef(uprimary[@n][@n1]);
3236      }
3237      saturn[@n]=hpl;
3238    }
3239
3240    //--------------------------------------------------------------------
3241    //we leave  the quotientring   K(var(nnp+1),..,var(nva))[..the rest..]
3242    //back to the polynomialring
3243    //---------------------------------------------------------------------
3244    setring gnir;
3245
3246    collectprimary=imap(quring,uprimary);
3247    lsau=imap(quring,saturn);
3248    @h=imap(quring,@h);
3249
3250    kill quring;
3251
3252    @n2=size(quprimary);
3253    @n3=@n2;
3254
3255    for(@n1=1;@n1<=size(collectprimary) div 2;@n1++)
3256    {
3257      if(deg(collectprimary[2*@n1][1])>0)
3258      {
3259        @n2++;
3260        quprimary[@n2]=collectprimary[2*@n1-1];
3261        lnew[@n2]=lsau[2*@n1-1];
3262        @n2++;
3263        lnew[@n2]=lsau[2*@n1];
3264        quprimary[@n2]=collectprimary[2*@n1];
3265        if(abspri)
3266        {
3267          absprimary[@n2 div 2]=absprimarytmp[@n1];
3268          abskeep[@n2 div 2]=abskeeptmp[@n1];
3269        }
3270      }
3271    }
3272    //here the intersection with the polynomialring
3273    //mentioned above is really computed
3274    for(@n=@n3 div 2+1;@n<=@n2 div 2;@n++)
3275    {
3276      if(specialIdealsEqual(quprimary[2*@n-1],quprimary[2*@n]))
3277      {
3278        quprimary[2*@n-1]=sat2(quprimary[2*@n-1],lnew[2*@n-1])[1];
3279        quprimary[2*@n]=quprimary[2*@n-1];
3280      }
3281      else
3282      {
3283        if(@wr==0)
3284        {
3285          quprimary[2*@n-1]=sat2(quprimary[2*@n-1],lnew[2*@n-1])[1];
3286        }
3287        quprimary[2*@n]=sat2(quprimary[2*@n],lnew[2*@n])[1];
3288      }
3289    }
3290
3291    if(size(@h)>0)
3292    {
3293      //---------------------------------------------------------------
3294      //we change to @Phelp to have the ordering dp for saturation
3295      //---------------------------------------------------------------
3296      setring @Phelp;
3297      @h=imap(gnir,@h);
3298      if(@wr!=1)
3299      {
3300        if(defined(@LL)){kill @LL;}
3301        list @LL=minSat(jwork,@h);
3302        @Ptest=intersect(@Ptest,@LL[1]);
3303        @q=@LL[2];
3304      }
3305      else
3306      {
3307        fac=ideal(0);
3308        for(lauf=1;lauf<=ncols(@h);lauf++)
3309        {
3310          if(deg(@h[lauf])>0)
3311          {
3312            fac=fac+factorize(@h[lauf],1);
3313          }
3314        }
3315        fac=simplify(fac,6);
3316        @q=1;
3317        for(lauf=1;lauf<=size(fac);lauf++)
3318        {
3319          @q=@q*fac[lauf];
3320        }
3321      }
3322      jwork=std(jwork,@q);
3323      keepdi=dim(jwork);
3324      if(keepdi<di)
3325      {
3326        setring gnir;
3327        @j=imap(@Phelp,jwork);
3328        break;
3329      }
3330      if(homo==1)
3331      {
3332        @hilb=hilb(jwork,1,@w);
3333      }
3334
3335      setring gnir;
3336      @j=imap(@Phelp,jwork);
3337    }
3338  }
3339
3340  if((size(quprimary)==0)&&(@wr==1))
3341  {
3342    @j=ideal(1);
3343    quprimary[1]=ideal(1);
3344    quprimary[2]=ideal(1);
3345  }
3346  if((size(quprimary)==0))
3347  {
3348    keepdi=di-1;
3349    quprimary[1]=ideal(1);
3350    quprimary[2]=ideal(1);
3351  }
3352  //---------------------------------------------------------------
3353  //notice that j=sat(j,gh) intersected with (j,gh^n)
3354  //we finished with sat(j,gh) and have to start with (j,gh^n)
3355  //---------------------------------------------------------------
3356  if((deg(@j[1])!=0)&&(@wr!=1))
3357  {
3358    if(size(quprimary)>0)
3359    {
3360      setring @Phelp;
3361      ser=imap(gnir,ser);
3362      hquprimary=imap(gnir,quprimary);
3363      if(@wr==0)
3364      {
3365        //HIER STATT DURCHSCHNITT SATURIEREN!
3366        ideal htest=@Ptest;
3367      }
3368      else
3369      {
3370        ideal htest=hquprimary[2];
3371
3372        for (@n1=2;@n1<=size(hquprimary) div 2;@n1++)
3373        {
3374          htest=intersect(htest,hquprimary[2*@n1]);
3375        }
3376      }
3377
3378      if(size(ser)>0)
3379      {
3380        ser=intersect(htest,ser);
3381      }
3382      else
3383      {
3384        ser=htest;
3385      }
3386      setring gnir;
3387      ser=imap(@Phelp,ser);
3388    }
3389    if(size(reduce(ser,peek,1))!=0)
3390    {
3391      for(@m=1;@m<=size(restindep);@m++)
3392      {
3393        // if(restindep[@m][3]>=keepdi)
3394        // {
3395        isat=0;
3396        @n2=0;
3397
3398        if(restindep[@m][1]==varstr(basering))
3399           //the good case, nothing to do, just to have the same notations
3400           //change the ring
3401        {
3402          execute("ring gnir1 = ("+charstr(basering)+"),("+
3403               varstr(basering)+"),("+ordstr(basering)+");");
3404          ideal @j=fetch(gnir,jkeep);
3405          attrib(@j,"isSB",1);
3406        }
3407        else
3408        {
3409          @va=string(maxideal(1));
3410          execute("ring gnir1 = ("+charstr(basering)+"),("+
3411                      restindep[@m][1]+"),(" +restindep[@m][2]+");");
3412          execute("map phi=gnir,"+@va+";");
3413          op=option(get);
3414          option(redSB);
3415          if(homo==1)
3416          {
3417            ideal @j=std(phi(jkeep),keephilb,@w);
3418          }
3419          else
3420          {
3421            ideal @j=groebner(phi(jkeep));
3422          }
3423          ideal ser=phi(ser);
3424          option(set,op);
3425        }
3426
3427        for (lauf=1;lauf<=size(@j);lauf++)
3428        {
3429          fett[lauf]=size(@j[lauf]);
3430        }
3431        //------------------------------------------------------------------
3432        //we have now the following situation:
3433        //j intersected with K[var(nnp+1),..,var(nva)] is zero so we may
3434        //pass to this quotientring, j is their still a standardbasis, the
3435        //leading coefficients of the polynomials  there (polynomials in
3436        //K[var(nnp+1),..,var(nva)]) are collected in the list h,
3437        //we need their ggt, gh, because of the following:
3438        //let (j:gh^n)=(j:gh^infinity) then
3439        //j*K(var(nnp+1),..,var(nva))[..the rest..]
3440        //intersected with K[var(1),...,var(nva)] is (j:gh^n)
3441        //on the other hand j=(j,gh^n) intersected with (j:gh^n)
3442
3443        //------------------------------------------------------------------
3444
3445        //the arrangement for the quotientring
3446        // K(var(nnp+1),..,var(nva))[..the rest..]
3447        //and the map phi:K[var(1),...,var(nva)] ---->
3448        //--->K(var(nnpr+1),..,var(nva))[..the rest..]
3449        //------------------------------------------------------------------
3450
3451        quotring=prepareQuotientring(nvars(basering)-restindep[@m][3]);
3452
3453        //------------------------------------------------------------------
3454        //we pass to the quotientring  K(var(nnp+1),..,var(nva))[..rest..]
3455        //------------------------------------------------------------------
3456
3457        execute(quotring);
3458
3459        // @j considered in the quotientring
3460        ideal @j=imap(gnir1,@j);
3461        ideal ser=imap(gnir1,ser);
3462
3463        kill gnir1;
3464
3465        //j is a standardbasis in the quotientring but usually not minimal
3466        //here it becomes minimal
3467        @j=clearSB(@j,fett);
3468        attrib(@j,"isSB",1);
3469
3470        //we need later ggt(h[1],...)=gh for saturation
3471        ideal @h;
3472
3473        for(@n=1;@n<=size(@j);@n++)
3474        {
3475          @h[@n]=leadcoef(@j[@n]);
3476        }
3477        //the primary decomposition of j*K(var(nnp+1),..,var(nva))[..rest..]
3478
3479        op=option(get);
3480        option(redSB);
3481        list uprimary= zero_decomp(@j,ser,@wr);
3482//HIER
3483        if(abspri)
3484        {
3485          ideal II;
3486          ideal jmap;
3487          map sigma;
3488          nn=nvars(basering);
3489          map invsigma=basering,maxideal(1);
3490          for(ab=1;ab<=size(uprimary) div 2;ab++)
3491          {
3492            II=uprimary[2*ab];
3493            attrib(II,"isSB",1);
3494            if(deg(II[1])!=vdim(II))
3495            {
3496              jmap=randomLast(50);
3497              sigma=basering,jmap;
3498              jmap[nn]=2*var(nn)-jmap[nn];
3499              invsigma=basering,jmap;
3500              II=groebner(sigma(II));
3501            }
3502            absprimarytmp[ab]= absFactorize(II[1],77);
3503            II=var(nn);
3504            abskeeptmp[ab]=string(invsigma(II));
3505            invsigma=basering,maxideal(1);
3506          }
3507        }
3508        option(set,op);
3509
3510        //we need the intersection of the ideals in the list quprimary with
3511        //the polynomialring, i.e. let q=(f1,...,fr) in the quotientring
3512        //such an ideal but fi polynomials, then the intersection of q with
3513        //the polynomialring is the saturation of the ideal generated by
3514        //f1,...,fr with respect toh which is the lcm of the leading
3515        //coefficients of the fi considered in the quotientring:
3516        //this is coded in saturn
3517
3518        list saturn;
3519        ideal hpl;
3520
3521        for(@n=1;@n<=size(uprimary);@n++)
3522        {
3523          hpl=0;
3524          for(@n1=1;@n1<=size(uprimary[@n]);@n1++)
3525          {
3526            hpl=hpl,leadcoef(uprimary[@n][@n1]);
3527          }
3528          saturn[@n]=hpl;
3529        }
3530        //------------------------------------------------------------------
3531        //we leave  the quotientring   K(var(nnp+1),..,var(nva))[..rest..]
3532        //back to the polynomialring
3533        //------------------------------------------------------------------
3534        setring gnir;
3535        collectprimary=imap(quring,uprimary);
3536        lsau=imap(quring,saturn);
3537        @h=imap(quring,@h);
3538
3539        kill quring;
3540
3541        @n2=size(quprimary);
3542        @n3=@n2;
3543
3544        for(@n1=1;@n1<=size(collectprimary) div 2;@n1++)
3545        {
3546          if(deg(collectprimary[2*@n1][1])>0)
3547          {
3548            @n2++;
3549            quprimary[@n2]=collectprimary[2*@n1-1];
3550            lnew[@n2]=lsau[2*@n1-1];
3551            @n2++;
3552            lnew[@n2]=lsau[2*@n1];
3553            quprimary[@n2]=collectprimary[2*@n1];
3554            if(abspri)
3555            {
3556              absprimary[@n2 div 2]=absprimarytmp[@n1];
3557              abskeep[@n2 div 2]=abskeeptmp[@n1];
3558            }
3559          }
3560        }
3561
3562
3563        //here the intersection with the polynomialring
3564        //mentioned above is really computed
3565
3566        for(@n=@n3 div 2+1;@n<=@n2 div 2;@n++)
3567        {
3568          if(specialIdealsEqual(quprimary[2*@n-1],quprimary[2*@n]))
3569          {
3570            quprimary[2*@n-1]=sat2(quprimary[2*@n-1],lnew[2*@n-1])[1];
3571            quprimary[2*@n]=quprimary[2*@n-1];
3572          }
3573          else
3574          {
3575            if(@wr==0)
3576            {
3577              quprimary[2*@n-1]=sat2(quprimary[2*@n-1],lnew[2*@n-1])[1];
3578            }
3579            quprimary[2*@n]=sat2(quprimary[2*@n],lnew[2*@n])[1];
3580          }
3581        }
3582        if(@n2>=@n3+2)
3583        {
3584          setring @Phelp;
3585          ser=imap(gnir,ser);
3586          hquprimary=imap(gnir,quprimary);
3587          for(@n=@n3 div 2+1;@n<=@n2 div 2;@n++)
3588          {
3589            if(@wr==0)
3590            {
3591              ser=intersect(ser,hquprimary[2*@n-1]);
3592            }
3593            else
3594            {
3595              ser=intersect(ser,hquprimary[2*@n]);
3596            }
3597          }
3598          setring gnir;
3599          ser=imap(@Phelp,ser);
3600        }
3601
3602         // }
3603      }
3604//HIER
3605      if(abspri)
3606      {
3607        list resu,tempo;
3608        for(ab=1;ab<=size(quprimary) div 2;ab++)
3609        {
3610          if (deg(quprimary[2*ab][1])!=0)
3611          {
3612            tempo=quprimary[2*ab-1],quprimary[2*ab],
3613                         absprimary[ab],abskeep[ab];
3614            resu[ab]=tempo;
3615          }
3616        }
3617        quprimary=resu;
3618        @wr=3;
3619      }
3620      if(size(reduce(ser,peek,1))!=0)
3621      {
3622        if(@wr>0)
3623        {
3624          htprimary=decomp(@j,@wr,peek,ser);
3625        }
3626        else
3627        {
3628          htprimary=decomp(@j,peek,ser);
3629        }
3630        // here we collect now both results primary(sat(j,gh))
3631        // and primary(j,gh^n)
3632        @n=size(quprimary);
3633        for (@k=1;@k<=size(htprimary);@k++)
3634        {
3635          quprimary[@n+@k]=htprimary[@k];
3636        }
3637      }
3638    }
3639  }
3640  else
3641  {
3642    if(abspri)
3643    {
3644      list resu,tempo;
3645      for(ab=1;ab<=size(quprimary) div 2;ab++)
3646      {
3647        tempo=quprimary[2*ab-1],quprimary[2*ab],
3648                   absprimary[ab],abskeep[ab];
3649        resu[ab]=tempo;
3650      }
3651      quprimary=resu;
3652    }
3653  }
3654  //---------------------------------------------------------------------------
3655  //back to the ring we started with
3656  //the final result: primary
3657  //---------------------------------------------------------------------------
3658  setring @P;
3659  primary=imap(gnir,quprimary);
3660  if(!abspri)
3661  {
3662    primary=cleanPrimary(primary);
3663  }
3664  if (abspri && (typeof(primary[1][1])=="poly"))
3665  { return(prepare_absprimdec(primary));}
3666  return(primary);
3667}
3668
3669
3670example
3671{ "EXAMPLE:"; echo = 2;
3672   ring  r = 32003,(x,y,z),lp;
3673   poly  p = z2+1;
3674   poly  q = z4+2;
3675   ideal i = p^2*q^3,(y-z3)^3,(x-yz+z4)^4;
3676   list pr= decomp(i);
3677   pr;
3678   testPrimary( pr, i);
3679}
3680
3681///////////////////////////////////////////////////////////////////////////////
3682static proc powerCoeffs(poly f,int e)
3683//computes a polynomial with the same monomials as f but coefficients
3684//the p^e th power of the coefficients of f
3685{
3686   int i;
3687   poly g;
3688   int ex=char(basering)^e;
3689   for(i=1;i<=size(f);i++)
3690   {
3691      g=g+leadcoef(f[i])^ex*leadmonom(f[i]);
3692   }
3693   return(g);
3694}
3695///////////////////////////////////////////////////////////////////////////////
3696
3697proc sep(poly f,int i, list #)
3698"USAGE:  input: a polynomial f depending on the i-th variable and optional
3699         an integer k considering the polynomial f defined over Fp(t1,...,tm)
3700         as polynomial over Fp(t(1)^(p^-k),...,t(m)^(p^-k))
3701 RETURN: the separabel part of f as polynomial in Fp(t1,...,tm)
3702        and an integer k to indicate that f should be considerd
3703        as polynomial over Fp(t(1)^(p^-k),...,t(m)^(p^-k))
3704 EXAMPLE: example sep; shows an example
3705{
3706   def R=basering;
3707   int k;
3708   if(size(#)>0){k=#[1];}
3709
3710
3711   poly h=gcd(f,diff(f,var(i)));
3712   if((reduce(f,std(h))!=0)||(reduce(diff(f,var(i)),std(h))!=0))
3713   {
3714      ERROR("FEHLER IN GCD");
3715   }
3716   poly g1=lift(h,f)[1][1];    //  f/h
3717   poly h1;
3718
3719   while(h!=h1)
3720   {
3721      h1=h;
3722      h=gcd(h,diff(h,var(i)));
3723   }
3724
3725   if(deg(h1)==0){return(list(g1,k));} //in characteristic 0 we return here
3726
3727   k++;
3728
3729   ideal ma=maxideal(1);
3730   ma[i]=var(i)^char(R);
3731   map phi=R,ma;
3732   ideal hh=h;    //this is technical because preimage works only for ideals
3733
3734   poly u=preimage(R,phi,hh)[1]; //h=u(x(i)^p)
3735
3736   list g2=sep(u,i,k);           //we consider u(t(1)^(p^-1),...,t(m)^(p^-1))
3737   g1=powerCoeffs(g1,g2[2]-k+1); //to have g1 over the same field as g2[1]
3738
3739   list g3=sep(g1*g2[1],i,g2[2]);
3740   return(g3);
3741}
3742example
3743{ "EXAMPLE:"; echo = 2;
3744   ring R=(5,t,s),(x,y,z),dp;
3745   poly f=(x^25-t*x^5+t)*(x^3+s);
3746   sep(f,1);
3747}
3748
3749///////////////////////////////////////////////////////////////////////////////
3750 proc zeroRad(ideal I,list #)
3751"USAGE:  zeroRad(I) , I a zero-dimensional ideal
3752 RETURN: the radical of I
3753 NOTE:  Algorithm of Kemper
3754 EXAMPLE: example zeroRad; shows an example
3755{
3756   if(homog(I)==1){return(maxideal(1));}
3757   //I needs to be a reduced standard basis
3758   def R=basering;
3759   int m=npars(R);
3760   int n=nvars(R);
3761   int p=char(R);
3762   int d=vdim(I);
3763   int i,k;
3764   list l;
3765   if(((p==0)||(p>d))&&(d==deg(I[1])))
3766   {
3767     intvec e=leadexp(I[1]);
3768     for(i=1;i<=nvars(basering);i++)
3769     {
3770       if(e[i]!=0) break;
3771     }
3772     I[1]=sep(I[1],i)[1];
3773     return(interred(I));
3774   }
3775   intvec op=option(get);
3776
3777   option(redSB);
3778   ideal F=finduni(I);//F[i] generates I intersected with K[var(i)]
3779
3780   option(set,op);
3781   if(size(#)>0){I=#[1];}
3782
3783   for(i=1;i<=n;i++)
3784   {
3785      l[i]=sep(F[i],i);
3786      F[i]=l[i][1];
3787      if(l[i][2]>k){k=l[i][2];}  //computation of the maximal k
3788   }
3789
3790   if((k==0)||(m==0)) //the separable case
3791   {
3792    intvec save=option(get);option(redSB);
3793    I=interred(I+F);option(set,save);return(I);
3794   }
3795   //I=simplify(I,1);
3796
3797   for(i=1;i<=n;i++)             //consider all polynomials over
3798   {                             //Fp(t(1)^(p^-k),...,t(m)^(p^-k))
3799      F[i]=powerCoeffs(F[i],k-l[i][2]);
3800   }
3801
3802   string cR="ring @R="+string(p)+",("+parstr(R)+","+varstr(R)+"),dp;";
3803   execute(cR);
3804   ideal F=imap(R,F);
3805
3806   string nR1="ring @S1="+string(p)+",("+varstr(R)+","+parstr(R)+",@y(1..m)),dp;";
3807   execute(nR1);
3808   list lR=ringlist(@S1)[2];
3809   lR=lR[(size(lR)-m+1)..(size(lR))];
3810
3811   string nR="ring @S="+string(p)+",("+string(lR)+","+varstr(R)+","+parstr(R)+"),dp;";
3812   execute(nR);
3813
3814   ideal G=fetch(@R,F);    //G[i](t(1)^(p^-k),...,t(m)^(p^-k),x(i))=sep(F[i])
3815
3816   ideal I=imap(R,I);
3817   ideal J=I+G;
3818   poly el=1;
3819   k=p^k;
3820   for(i=1;i<=m;i++)
3821   {
3822      J=J,var(i)^k-var(m+n+i);
3823      el=el*var(i);
3824   }
3825
3826   J=eliminate(J,el);
3827   setring R;
3828   ideal J=imap(@S,J);
3829   return(J);
3830}
3831example
3832{ "EXAMPLE:"; echo = 2;
3833   ring R=(5,t),(x,y),dp;
3834   ideal I=x^5-t,y^5-t;
3835   zeroRad(I);
3836}
3837
3838///////////////////////////////////////////////////////////////////////////////
3839
3840proc radicalEHV(ideal i)
3841"USAGE:   radicalEHV(i); i ideal.
3842RETURN:  ideal, the radical of i.
3843NOTE:    Uses the algorithm of Eisenbud/Huneke/Vasconcelos, which
3844         reduces the computation to the complete intersection case,
3845         by taking, in the general case, a generic linear combination
3846         of the input.
3847         Works only in characteristic 0 or p large.
3848EXAMPLE: example radicalEHV; shows an example
3849"
3850{
3851   if(attrib(basering,"global")!=1)
3852   {
3853      ERROR(
3854      "// Not implemented for this ordering, please change to global ordering."
3855      );
3856   }
3857   if((char(basering)<100)&&(char(basering)!=0))
3858   {
3859      "WARNING: The characteristic is too small, the result may be wrong";
3860   }
3861   if ( size(i)==0 ) { return(ideal(0)); }
3862
3863   ideal J,I,I0,radI0,L,radI1,I2,radI2;
3864   int l,n;
3865   intvec op=option(get);
3866   matrix M;
3867
3868   option(redSB);
3869   list m=mstd(i);
3870        I=m[2];
3871   option(set,op);
3872
3873   if ( dim(m[1])<0 ) { return(ideal(1)); }
3874
3875   int cod=nvars(basering)-dim(m[1]);
3876   //-------------------complete intersection case:----------------------
3877   if(cod==size(m[2]))
3878   {
3879     J=minor(jacob(I),cod);
3880     return(quotient(I,J));
3881   }
3882   //-----first codim elements of I are a complete intersection:---------
3883   for(l=1;l<=cod;l++)
3884   {
3885      I0[l]=I[l];
3886   }
3887   n=dim(std(I0))+cod-nvars(basering);
3888   //-----last codim elements of I are a complete intersection:----------
3889   if(n!=0)
3890   {
3891      for(l=1;l<=cod;l++)
3892      {
3893         I0[l]=I[size(I)-l+1];
3894      }
3895      n=dim(std(I0))+cod-nvars(basering);
3896   }
3897   //-----taking a generic linear combination of the input:--------------
3898   if(n!=0)
3899   {
3900      M=transpose(sparsetriag(size(m[2]),cod,95,1));
3901      I0=ideal(M*transpose(I));
3902      n=dim(std(I0))+cod-nvars(basering);
3903   }
3904   //-----taking a more generic linear combination of the input:---------
3905   if(n!=0)
3906   {
3907      M=transpose(sparsetriag(size(m[2]),cod,0,100));
3908      I0=ideal(M*transpose(I));
3909      n=dim(std(I0))+cod-nvars(basering);
3910   }
3911   if(n==0)
3912   {
3913      J=minor(jacob(I0),cod);
3914      radI0=quotient(I0,J);
3915      L=quotient(radI0,I);
3916      radI1=quotient(radI0,L);
3917
3918      if(size(reduce(radI1,m[1],1))==0)
3919      {
3920         return(I);
3921      }
3922
3923      I2=sat(I,radI1)[1];
3924
3925      if(deg(I2[1])<=0)
3926      {
3927         return(radI1);
3928      }
3929      return(intersect(radI1,radicalEHV(I2)));
3930   }
3931   //---------------------general case-------------------------------------
3932   return(radical(I));
3933}
3934example
3935{ "EXAMPLE:";  echo = 2;
3936   ring  r = 0,(x,y,z),dp;
3937   poly  p = z2+1;
3938   poly  q = z3+2;
3939   ideal i = p*q^2,y-z2;
3940   ideal pr= radicalEHV(i);
3941   pr;
3942}
3943
3944///////////////////////////////////////////////////////////////////////////////
3945
3946proc Ann(module M)
3947"USAGE:   Ann(M);  M module
3948RETURN:  ideal, the annihilator of coker(M)
3949NOTE:    The output is the ideal of all elements a of the basering R such that
3950         a * R^m is contained in M  (m=number of rows of M).
3951EXAMPLE: example Ann; shows an example
3952"
3953{
3954  M=prune(M);  //to obtain a small embedding
3955  ideal ann=quotient1(M,freemodule(nrows(M)));
3956  return(ann);
3957}
3958example
3959{ "EXAMPLE:"; echo = 2;
3960   ring  r = 0,(x,y,z),lp;
3961   module M = x2-y2,z3;
3962   Ann(M);
3963   M = [1,x2],[y,x];
3964   Ann(M);
3965   qring Q=std(xy-1);
3966   module M=imap(r,M);
3967   Ann(M);
3968}
3969
3970///////////////////////////////////////////////////////////////////////////////
3971
3972//computes the equidimensional part of the ideal i of codimension e
3973static proc int_ass_primary_e(ideal i, int e)
3974{
3975  if(homog(i)!=1)
3976  {
3977     i=std(i);
3978  }
3979  list re=sres(i,0);                   //the resolution
3980  re=minres(re);                       //minimized resolution
3981  ideal ann=AnnExt_R(e,re);
3982  if(nvars(basering)-dim(std(ann))!=e)
3983  {
3984    return(ideal(1));
3985  }
3986  return(ann);
3987}
3988
3989///////////////////////////////////////////////////////////////////////////////
3990
3991//computes the annihilator of Ext^n(R/i,R) with given resolution re
3992//n is not necessarily the number of variables
3993static proc AnnExt_R(int n,list re)
3994{
3995  if(n<nvars(basering))
3996  {
3997    if(size(re[n+1])>0)
3998    {
3999        matrix f=transpose(re[n+1]);      //Hom(_,R)
4000        module k=nres(f,2)[2];            //the kernel
4001        matrix g=transpose(re[n]);        //the image of Hom(_,R)
4002
4003        ideal ann=quotient1(g,k);         //the anihilator
4004        return(ann);
4005    }
4006  }
4007  // remaining case: re[n+1] is trivial
4008  // either n is at least number of variables or
4009  // resolution happens to be shorter
4010  ideal ann=Ann(transpose(re[n]));
4011  return(ann);
4012}
4013///////////////////////////////////////////////////////////////////////////////
4014
4015static proc analyze(list pr)
4016{
4017   int ii,jj;
4018   for(ii=1;ii<=size(pr) div 2;ii++)
4019   {
4020      dim(std(pr[2*ii]));
4021      idealsEqual(pr[2*ii-1],pr[2*ii]);
4022      "===========================";
4023   }
4024
4025   for(ii=size(pr) div 2;ii>1;ii--)
4026   {
4027      for(jj=1;jj<ii;jj++)
4028      {
4029         if(size(reduce(pr[2*jj],std(pr[2*ii],1)))==0)
4030         {
4031            "eingebette Komponente";
4032            jj;
4033            ii;
4034         }
4035      }
4036   }
4037}
4038
4039///////////////////////////////////////////////////////////////////////////////
4040//
4041//                  Shimoyama-Yokoyama
4042//
4043///////////////////////////////////////////////////////////////////////////////
4044
4045static proc simplifyIdeal(ideal i)
4046{
4047  def r=basering;
4048
4049  int j,k;
4050  map phi;
4051  poly p;
4052
4053  ideal iwork=i;
4054  ideal imap1=maxideal(1);
4055  ideal imap2=maxideal(1);
4056
4057
4058  for(j=1;j<=nvars(basering);j++)
4059  {
4060    for(k=1;k<=size(i);k++)
4061    {
4062      if(deg(iwork[k]/var(j))==0)
4063      {
4064        p=-1/leadcoef(iwork[k]/var(j))*iwork[k];
4065        imap1[j]=p+2*var(j);
4066        phi=r,imap1;
4067        iwork=phi(iwork);
4068        iwork=subst(iwork,var(j),0);
4069        iwork[k]=var(j);
4070        imap1=maxideal(1);
4071        imap2[j]=-p;
4072        break;
4073      }
4074    }
4075  }
4076  return(iwork,imap2);
4077}
4078
4079
4080///////////////////////////////////////////////////////
4081// ini_mod
4082// input: a polynomial p
4083// output: the initial term of p as needed
4084// in the context of characteristic sets
4085//////////////////////////////////////////////////////
4086
4087static proc ini_mod(poly p)
4088{
4089  if (p==0)
4090  {
4091    return(0);
4092  }
4093  int n; matrix m;
4094  for( n=nvars(basering); n>0; n--)
4095  {
4096    m=coef(p,var(n));
4097    if(m[1,1]!=1)
4098    {
4099      p=m[2,1];
4100      break;
4101    }
4102  }
4103  if(deg(p)==0)
4104  {
4105    p=0;
4106  }
4107  return(p);
4108}
4109///////////////////////////////////////////////////////
4110// min_ass_prim_charsets
4111// input: generators of an ideal PS and an integer cho
4112// If cho=0, the given ordering of the variables is used.
4113// Otherwise, the system tries to find an "optimal ordering",
4114// which in some cases may considerably speed up the algorithm
4115// output: the minimal associated primes of PS
4116// algorithm: via characteriostic sets
4117//////////////////////////////////////////////////////
4118
4119
4120static proc min_ass_prim_charsets (ideal PS, int cho)
4121{
4122  if((cho<0) and (cho>1))
4123  {
4124    ERROR("<int> must be 0 or 1");
4125  }
4126  intvec saveopt=option(get);
4127  option(notWarnSB);
4128  list L;
4129  if(cho==0)
4130  {
4131    L=min_ass_prim_charsets0(PS);
4132  }
4133  else
4134  {
4135    L=min_ass_prim_charsets1(PS);
4136  }
4137  option(set,saveopt);
4138  return(L);
4139}
4140///////////////////////////////////////////////////////
4141// min_ass_prim_charsets0
4142// input: generators of an ideal PS
4143// output: the minimal associated primes of PS
4144// algorithm: via characteristic sets
4145// the given ordering of the variables is used
4146//////////////////////////////////////////////////////
4147
4148
4149static proc min_ass_prim_charsets0 (ideal PS)
4150{
4151  intvec op;
4152  matrix m=char_series(PS);  // We compute an irreducible
4153                             // characteristic series
4154  int i,j,k;
4155  list PSI;
4156  list PHI;  // the ideals given by the characteristic series
4157  for(i=nrows(m);i>=1; i--)
4158  {
4159    PHI[i]=ideal(m[i,1..ncols(m)]);
4160  }
4161  // We compute the radical of each ideal in PHI
4162  ideal I,JS,II;
4163  int sizeJS, sizeII;
4164  for(i=size(PHI);i>=1; i--)
4165  {
4166    I=0;
4167    for(j=size(PHI[i]);j>0;j--)
4168    {
4169      I=I+ini_mod(PHI[i][j]);
4170    }
4171    JS=std(PHI[i]);
4172    sizeJS=size(JS);
4173    for(j=size(I);j>0;j--)
4174    {
4175      II=0;
4176      sizeII=0;
4177      k=0;
4178      while(k<=sizeII)                  // successive saturation
4179      {
4180        op=option(get);
4181        option(returnSB);
4182        II=quotient(JS,I[j]);
4183        option(set,op);
4184        sizeII=size(II);
4185        if(sizeII==sizeJS)
4186        {
4187          for(k=1;k<=sizeII;k++)
4188          {
4189            if(leadexp(II[k])!=leadexp(JS[k])) break;
4190          }
4191        }
4192        JS=II;
4193        sizeJS=sizeII;
4194      }
4195    }
4196    PSI=insert(PSI,JS);
4197  }
4198  int sizePSI=size(PSI);
4199  // We eliminate redundant ideals
4200  for(i=1;i<sizePSI;i++)
4201  {
4202    for(j=i+1;j<=sizePSI;j++)
4203    {
4204      if(size(PSI[i])!=0)
4205      {
4206        if(size(PSI[j])!=0)
4207        {
4208          if(size(NF(PSI[i],PSI[j],1))==0)
4209          {
4210            PSI[j]=ideal(0);
4211          }
4212          else
4213          {
4214            if(size(NF(PSI[j],PSI[i],1))==0)
4215            {
4216              PSI[i]=ideal(0);
4217            }
4218          }
4219        }
4220      }
4221    }
4222  }
4223  for(i=sizePSI;i>=1;i--)
4224  {
4225    if(size(PSI[i])==0)
4226    {
4227      PSI=delete(PSI,i);
4228    }
4229  }
4230  return (PSI);
4231}
4232
4233///////////////////////////////////////////////////////
4234// min_ass_prim_charsets1
4235// input: generators of an ideal PS
4236// output: the minimal associated primes of PS
4237// algorithm: via characteristic sets
4238// input: generators of an ideal PS and an integer i
4239// The system tries to find an "optimal ordering" of
4240// the variables
4241//////////////////////////////////////////////////////
4242
4243
4244static proc min_ass_prim_charsets1 (ideal PS)
4245{
4246  intvec op;
4247  def oldring=basering;
4248  string n=system("neworder",PS);
4249  execute("ring r=("+charstr(oldring)+"),("+n+"),dp;");
4250  ideal PS=imap(oldring,PS);
4251  matrix m=char_series(PS);  // We compute an irreducible
4252                             // characteristic series
4253  int i,j,k;
4254  ideal I;
4255  list PSI;
4256  list PHI;    // the ideals given by the characteristic series
4257  list ITPHI;  // their initial terms
4258  for(i=nrows(m);i>=1; i--)
4259  {
4260    PHI[i]=ideal(m[i,1..ncols(m)]);
4261    I=0;
4262    for(j=size(PHI[i]);j>0;j=j-1)
4263    {
4264      I=I,ini_mod(PHI[i][j]);
4265    }
4266    I=I[2..ncols(I)];
4267    ITPHI[i]=I;
4268  }
4269  setring oldring;
4270  matrix m=imap(r,m);
4271  list PHI=imap(r,PHI);
4272  list ITPHI=imap(r,ITPHI);
4273  // We compute the radical of each ideal in PHI
4274  ideal I,JS,II;
4275  int sizeJS, sizeII;
4276  for(i=size(PHI);i>=1; i--)
4277  {
4278    I=0;
4279    for(j=size(PHI[i]);j>0;j--)
4280    {
4281      I=I+ITPHI[i][j];
4282    }
4283    JS=std(PHI[i]);
4284    sizeJS=size(JS);
4285    for(j=size(I);j>0;j--)
4286    {
4287      II=0;
4288      sizeII=0;
4289      k=0;
4290      while(k<=sizeII)                  // successive iteration
4291      {
4292        op=option(get);
4293        option(returnSB);
4294        II=quotient(JS,I[j]);
4295        option(set,op);
4296//std
4297//         II=std(II);
4298        sizeII=size(II);
4299        if(sizeII==sizeJS)
4300        {
4301          for(k=1;k<=sizeII;k++)
4302          {
4303            if(leadexp(II[k])!=leadexp(JS[k])) break;
4304          }
4305        }
4306        JS=II;
4307        sizeJS=sizeII;
4308      }
4309    }
4310    PSI=insert(PSI,JS);
4311  }
4312  int sizePSI=size(PSI);
4313  // We eliminate redundant ideals
4314  for(i=1;i<sizePSI;i++)
4315  {
4316    for(j=i+1;j<=sizePSI;j++)
4317    {
4318      if(size(PSI[i])!=0)
4319      {
4320        if(size(PSI[j])!=0)
4321        {
4322          if(size(NF(PSI[i],PSI[j],1))==0)
4323          {
4324            PSI[j]=ideal(0);
4325          }
4326          else
4327          {
4328            if(size(NF(PSI[j],PSI[i],1))==0)
4329            {
4330              PSI[i]=ideal(0);
4331            }
4332          }
4333        }
4334      }
4335    }
4336  }
4337  for(i=sizePSI;i>=1;i--)
4338  {
4339    if(size(PSI[i])==0)
4340    {
4341      PSI=delete(PSI,i);
4342    }
4343  }
4344  return (PSI);
4345}
4346
4347
4348/////////////////////////////////////////////////////
4349// proc prim_dec
4350// input:  generators of an ideal I and an integer choose
4351// If choose=0, min_ass_prim_charsets with the given
4352// ordering of the variables is used.
4353// If choose=1, min_ass_prim_charsets with the "optimized"
4354// ordering of the variables is used.
4355// If choose=2, minAssPrimes from primdec.lib is used
4356// If choose=3, minAssPrimes+factorizing Buchberger from primdec.lib is used
4357// output: a primary decomposition of I, i.e., a list
4358// of pairs consisting of a standard basis of a primary component
4359// of I and a standard basis of the corresponding associated prime.
4360// To compute the minimal associated primes of a given ideal
4361// min_ass_prim_l is called, i.e., the minimal associated primes
4362// are computed via characteristic sets.
4363// In the homogeneous case, the performance of the procedure
4364// will be improved if I is already given by a minimal set of
4365// generators. Apply minbase if necessary.
4366//////////////////////////////////////////////////////////
4367
4368
4369static proc prim_dec(ideal I, int choose)
4370{
4371  if((choose<0) or (choose>3))
4372  {
4373    ERROR("ERROR: <int> must be 0 or 1 or 2 or 3");
4374  }
4375  ideal H=1; // The intersection of the primary components
4376  list U;    // the leaves of the decomposition tree, i.e.,
4377             // pairs consisting of a primary component of I
4378             // and the corresponding associated prime
4379  list W;    // the non-leaf vertices in the decomposition tree.
4380             // every entry has 6 components:
4381                // 1- the vertex itself , i.e., a standard bais of the
4382                //    given ideal I (type 1), or a standard basis of a
4383                //    pseudo-primary component arising from
4384                //    pseudo-primary decomposition (type 2), or a
4385                //    standard basis of a remaining component arising from
4386                //    pseudo-primary decomposition or extraction (type 3)
4387                // 2- the type of the vertex as indicated above
4388                // 3- the weighted_tree_depth of the vertex
4389                // 4- the tester of the vertex
4390                // 5- a standard basis of the associated prime
4391                //    of a vertex of type 2, or 0 otherwise
4392                // 6- a list of pairs consisting of a standard
4393                //    basis of a minimal associated prime ideal
4394                //    of the father of the vertex and the
4395                //    irreducible factors of the "minimal
4396                //    divisor" of the seperator or extractor
4397                //    corresponding to the prime ideal
4398                //    as computed by the procedure minsat,
4399                //    if the vertex is of type 3, or
4400                //    the empty list otherwise
4401  ideal SI=std(I);
4402  if(SI[1]==1)  // primdecSY(ideal(1))
4403  {
4404    return(list());
4405  }
4406  intvec save=option(get);
4407  option(notWarnSB);
4408  int ncolsSI=ncols(SI);
4409  int ncolsH=1;
4410  W[1]=list(I,1,0,poly(1),ideal(0),list()); // The root of the tree
4411  int weighted_tree_depth;
4412  int i,j;
4413  int check;
4414  list V;  // current vertex
4415  list VV; // new vertex
4416  list QQ;
4417  list WI;
4418  ideal Qi,SQ,SRest,fac;
4419  poly tester;
4420
4421  while(1)
4422  {
4423    i=1;
4424    while(1)
4425    {
4426      while(i<=size(W)) // find vertex V of smallest weighted tree-depth
4427      {
4428        if (W[i][3]<=weighted_tree_depth) break;
4429        i++;
4430      }
4431      if (i<=size(W)) break;
4432      i=1;
4433      weighted_tree_depth++;
4434    }
4435    V=W[i];
4436    W=delete(W,i); // delete V from W
4437
4438    // now proceed by type of vertex V
4439
4440    if (V[2]==2)  // extraction needed
4441    {
4442      SQ,SRest,fac=extraction(V[1],V[5]);
4443                        // standard basis of primary component,
4444                        // standard basis of remaining component,
4445                        // irreducible factors of
4446                        // the "minimal divisor" of the extractor
4447                        // as computed by the procedure minsat,
4448      check=0;
4449      for(j=1;j<=ncolsH;j++)
4450      {
4451        if (NF(H[j],SQ,1)!=0) // Q is not redundant
4452        {
4453          check=1;
4454          break;
4455        }
4456      }
4457      if(check==1)             // Q is not redundant
4458      {
4459        QQ=list();
4460        QQ[1]=list(SQ,V[5]);  // primary component, associated prime,
4461                              // i.e., standard bases thereof
4462        U=U+QQ;
4463        H=intersect(H,SQ);
4464        H=std(H);
4465        ncolsH=ncols(H);
4466        check=0;
4467        if(ncolsH==ncolsSI)
4468        {
4469          for(j=1;j<=ncolsSI;j++)
4470          {
4471            if(leadexp(H[j])!=leadexp(SI[j]))
4472            {
4473              check=1;
4474              break;
4475            }
4476          }
4477        }
4478        else
4479        {
4480          check=1;
4481        }
4482        if(check==0) // H==I => U is a primary decomposition
4483        {
4484          option(set,save);
4485          return(U);
4486        }
4487      }
4488      if (SRest[1]!=1)        // the remaining component is not
4489                              // the whole ring
4490      {
4491        if (rad_con(V[4],SRest)==0) // the new vertex is not the
4492                                    // root of a redundant subtree
4493        {
4494          VV[1]=SRest;     // remaining component
4495          VV[2]=3;         // pseudoprimdec_special
4496          VV[3]=V[3]+1;    // weighted depth
4497          VV[4]=V[4];      // the tester did not change
4498          VV[5]=ideal(0);
4499          VV[6]=list(list(V[5],fac));
4500          W=insert(W,VV,size(W));
4501        }
4502      }
4503    }
4504    else
4505    {
4506      if (V[2]==3) // pseudo_prim_dec_special is needed
4507      {
4508        QQ,SRest=pseudo_prim_dec_special_charsets(V[1],V[6],choose);
4509                         // QQ = quadruples:
4510                         // standard basis of pseudo-primary component,
4511                         // standard basis of corresponding prime,
4512                         // seperator, irreducible factors of
4513                         // the "minimal divisor" of the seperator
4514                         // as computed by the procedure minsat,
4515                         // SRest=standard basis of remaining component
4516      }
4517      else     // V is the root, pseudo_prim_dec is needed
4518      {
4519        QQ,SRest=pseudo_prim_dec_charsets(I,SI,choose);
4520                         // QQ = quadruples:
4521                         // standard basis of pseudo-primary component,
4522                         // standard basis of corresponding prime,
4523                         // seperator, irreducible factors of
4524                         // the "minimal divisor" of the seperator
4525                         // as computed by the procedure minsat,
4526                         // SRest=standard basis of remaining component
4527      }
4528      //check
4529      for(i=size(QQ);i>=1;i--)
4530      //for(i=1;i<=size(QQ);i++)
4531      {
4532        tester=QQ[i][3]*V[4];
4533        Qi=QQ[i][2];
4534        if(NF(tester,Qi,1)!=0)  // the new vertex is not the
4535                                // root of a redundant subtree
4536        {
4537          VV[1]=QQ[i][1];
4538          VV[2]=2;
4539          VV[3]=V[3]+1;
4540          VV[4]=tester;      // the new tester as computed above
4541          VV[5]=Qi;          // QQ[i][2];
4542          VV[6]=list();
4543          W=insert(W,VV,size(W));
4544        }
4545      }
4546      if (SRest[1]!=1)        // the remaining component is not
4547                              // the whole ring
4548      {
4549        if (rad_con(V[4],SRest)==0) // the vertex is not the root
4550                                    // of a redundant subtree
4551        {
4552          VV[1]=SRest;
4553          VV[2]=3;
4554          VV[3]=V[3]+2;
4555          VV[4]=V[4];      // the tester did not change
4556          VV[5]=ideal(0);
4557          WI=list();
4558          for(i=1;i<=size(QQ);i++)
4559          {
4560            WI=insert(WI,list(QQ[i][2],QQ[i][4]));
4561          }
4562          VV[6]=WI;
4563          W=insert(W,VV,size(W));
4564        }
4565      }
4566    }
4567  }
4568  option(set,save);
4569}
4570
4571//////////////////////////////////////////////////////////////////////////
4572// proc pseudo_prim_dec_charsets
4573// input: Generators of an arbitrary ideal I, a standard basis SI of I,
4574// and an integer choo
4575// If choo=0, min_ass_prim_charsets with the given
4576// ordering of the variables is used.
4577// If choo=1, min_ass_prim_charsets with the "optimized"
4578// ordering of the variables is used.
4579// If choo=2, minAssPrimes from primdec.lib is used
4580// If choo=3, minAssPrimes+factorizing Buchberger from primdec.lib is used
4581// output: a pseudo primary decomposition of I, i.e., a list
4582// of pseudo primary components together with a standard basis of the
4583// remaining component. Each pseudo primary component is
4584// represented by a quadrupel: A standard basis of the component,
4585// a standard basis of the corresponding associated prime, the
4586// seperator of the component, and the irreducible factors of the
4587// "minimal divisor" of the seperator as computed by the procedure minsat,
4588// calls  proc pseudo_prim_dec_i
4589//////////////////////////////////////////////////////////////////////////
4590
4591
4592static proc pseudo_prim_dec_charsets (ideal I, ideal SI, int choo)
4593{
4594  list L;          // The list of minimal associated primes,
4595                   // each one given by a standard basis
4596  if((choo==0) or (choo==1))
4597  {
4598    L=min_ass_prim_charsets(I,choo);
4599  }
4600  else
4601  {
4602    if(choo==2)
4603    {
4604      L=minAssPrimes(I);
4605    }
4606    else
4607    {
4608      L=minAssPrimes(I,1);
4609    }
4610    for(int i=size(L);i>=1;i--)
4611    {
4612      L[i]=std(L[i]);
4613    }
4614  }
4615  return (pseudo_prim_dec_i(SI,L));
4616}
4617
4618////////////////////////////////////////////////////////////////
4619// proc pseudo_prim_dec_special_charsets
4620// input: a standard basis of an ideal I whose radical is the
4621// intersection of the radicals of ideals generated by one prime ideal
4622// P_i together with one polynomial f_i, the list V6 must be the list of
4623// pairs (standard basis of P_i, irreducible factors of f_i),
4624// and an integer choo
4625// If choo=0, min_ass_prim_charsets with the given
4626// ordering of the variables is used.
4627// If choo=1, min_ass_prim_charsets with the "optimized"
4628// ordering of the variables is used.
4629// If choo=2, minAssPrimes from primdec.lib is used
4630// If choo=3, minAssPrimes+factorizing Buchberger from primdec.lib is used
4631// output: a pseudo primary decomposition of I, i.e., a list
4632// of pseudo primary components together with a standard basis of the
4633// remaining component. Each pseudo primary component is
4634// represented by a quadrupel: A standard basis of the component,
4635// a standard basis of the corresponding associated prime, the
4636// seperator of the component, and the irreducible factors of the
4637// "minimal divisor" of the seperator as computed by the procedure minsat,
4638// calls  proc pseudo_prim_dec_i
4639////////////////////////////////////////////////////////////////
4640
4641
4642static proc pseudo_prim_dec_special_charsets (ideal SI,list V6, int choo)
4643{
4644  int i,j,l;
4645  list m;
4646  list L;
4647  int sizeL;
4648  ideal P,SP; ideal fac;
4649  int dimSP;
4650  for(l=size(V6);l>=1;l--)   // creates a list of associated primes
4651                             // of I, possibly redundant
4652  {
4653    P=V6[l][1];
4654    fac=V6[l][2];
4655    for(i=ncols(fac);i>=1;i--)
4656    {
4657      SP=P+fac[i];
4658      SP=std(SP);
4659      if(SP[1]!=1)
4660      {
4661        if((choo==0) or (choo==1))
4662        {
4663          m=min_ass_prim_charsets(SP,choo);  // a list of SB
4664        }
4665        else
4666        {
4667          if(choo==2)
4668          {
4669            m=minAssPrimes(SP);
4670          }
4671          else
4672          {
4673            m=minAssPrimes(SP,1);
4674          }
4675          for(j=size(m);j>=1;j=j-1)
4676            {
4677              m[j]=std(m[j]);
4678            }
4679        }
4680        dimSP=dim(SP);
4681        for(j=size(m);j>=1; j--)
4682        {
4683          if(dim(m[j])==dimSP)
4684          {
4685            L=insert(L,m[j],size(L));
4686          }
4687        }
4688      }
4689    }
4690  }
4691  sizeL=size(L);
4692  for(i=1;i<sizeL;i++)     // get rid of redundant primes
4693  {
4694    for(j=i+1;j<=sizeL;j++)
4695    {
4696      if(size(L[i])!=0)
4697      {
4698        if(size(L[j])!=0)
4699        {
4700          if(size(NF(L[i],L[j],1))==0)
4701          {
4702            L[j]=ideal(0);
4703          }
4704          else
4705          {
4706            if(size(NF(L[j],L[i],1))==0)
4707            {
4708              L[i]=ideal(0);
4709            }
4710          }
4711        }
4712      }
4713    }
4714  }
4715  for(i=sizeL;i>=1;i--)
4716  {
4717    if(size(L[i])==0)
4718    {
4719      L=delete(L,i);
4720    }
4721  }
4722  return (pseudo_prim_dec_i(SI,L));
4723}
4724
4725
4726////////////////////////////////////////////////////////////////
4727// proc pseudo_prim_dec_i
4728// input: A standard basis of an arbitrary ideal I, and standard bases
4729// of the minimal associated primes of I
4730// output: a pseudo primary decomposition of I, i.e., a list
4731// of pseudo primary components together with a standard basis of the
4732// remaining component. Each pseudo primary component is
4733// represented by a quadrupel: A standard basis of the component Q_i,
4734// a standard basis of the corresponding associated prime P_i, the
4735// seperator of the component, and the irreducible factors of the
4736// "minimal divisor" of the seperator as computed by the procedure minsat,
4737////////////////////////////////////////////////////////////////
4738
4739
4740static proc pseudo_prim_dec_i (ideal SI, list L)
4741{
4742  list Q;
4743  if (size(L)==1)               // one minimal associated prime only
4744                                // the ideal is already pseudo primary
4745  {
4746    Q=SI,L[1],1;
4747    list QQ;
4748    QQ[1]=Q;
4749    return (QQ,ideal(1));
4750  }
4751
4752  poly f0,f,g;
4753  ideal fac;
4754  int i,j,k,l;
4755  ideal SQi;
4756  ideal I'=SI;
4757  list QP;
4758  int sizeL=size(L);
4759  for(i=1;i<=sizeL;i++)
4760  {
4761    fac=0;
4762    for(j=1;j<=sizeL;j++)           // compute the seperator sep_i
4763                                    // of the i-th component
4764    {
4765      if (i!=j)                       // search g not in L[i], but L[j]
4766      {
4767        for(k=1;k<=ncols(L[j]);k++)
4768        {
4769          if(NF(L[j][k],L[i],1)!=0)
4770          {
4771            break;
4772          }
4773        }
4774        fac=fac+L[j][k];
4775      }
4776    }
4777    // delete superfluous polynomials
4778    fac=simplify(fac,8+2);
4779    // saturation
4780    SQi,f0,f,fac=minsat_ppd(SI,fac);
4781    I'=I',f;
4782    QP=SQi,L[i],f0,fac;
4783             // the quadrupel:
4784             // a standard basis of Q_i,
4785             // a standard basis of P_i,
4786             // sep_i,
4787             // irreducible factors of
4788             // the "minimal divisor" of the seperator
4789             //  as computed by the procedure minsat,
4790    Q[i]=QP;
4791  }
4792  I'=std(I');
4793  return (Q, I');
4794                   // I' = remaining component
4795}
4796
4797
4798////////////////////////////////////////////////////////////////
4799// proc extraction
4800// input: A standard basis of a pseudo primary ideal I, and a standard
4801// basis of the unique minimal associated prime P of I
4802// output: an extraction of I, i.e., a standard basis of the primary
4803// component Q of I with associated prime P, a standard basis of the
4804// remaining component, and the irreducible factors of the
4805// "minimal divisor" of the extractor as computed by the procedure minsat
4806////////////////////////////////////////////////////////////////
4807
4808
4809static proc extraction (ideal SI, ideal SP)
4810{
4811  list indsets=indepSet(SP,0);
4812  poly f;
4813  if(size(indsets)!=0)      //check, whether dim P != 0
4814  {
4815    intvec v;               // a maximal independent set of variables
4816                            // modulo P
4817    string U;               // the independent variables
4818    string A;               // the dependent variables
4819    int j,k;
4820    int a;                  //  the size of A
4821    int degf;
4822    ideal g;
4823    list polys;
4824    int sizepolys;
4825    list newpoly;
4826    def R=basering;
4827    //intvec hv=hilb(SI,1);
4828    for (k=1;k<=size(indsets);k++)
4829    {
4830      v=indsets[k];
4831      for (j=1;j<=nvars(R);j++)
4832      {
4833        if (v[j]==1)
4834        {
4835          U=U+varstr(j)+",";
4836        }
4837        else
4838        {
4839          A=A+varstr(j)+",";
4840          a++;
4841        }
4842      }
4843
4844      U[size(U)]=")";           // we compute the extractor of I (w.r.t. U)
4845      execute("ring RAU=("+charstr(basering)+"),("+A+U+",(dp("+string(a)+"),dp);");
4846      ideal I=imap(R,SI);
4847      //I=std(I,hv);            // the standard basis in (R[U])[A]
4848      I=std(I);            // the standard basis in (R[U])[A]
4849      A[size(A)]=")";
4850      execute("ring Rloc=("+charstr(basering)+","+U+",("+A+",dp;");
4851      ideal I=imap(RAU,I);
4852      //"std in lokalisierung:"+newline,I;
4853      ideal h;
4854      for(j=ncols(I);j>=1;j--)
4855      {
4856        h[j]=leadcoef(I[j]);  // consider I in (R(U))[A]
4857      }
4858      setring R;
4859      g=imap(Rloc,h);
4860      kill RAU,Rloc;
4861      U="";
4862      A="";
4863      a=0;
4864      f=lcm(g);
4865      newpoly[1]=f;
4866      polys=polys+newpoly;
4867      newpoly=list();
4868    }
4869    f=polys[1];
4870    degf=deg(f);
4871    sizepolys=size(polys);
4872    for (k=2;k<=sizepolys;k++)
4873    {
4874      if (deg(polys[k])<degf)
4875      {
4876        f=polys[k];
4877        degf=deg(f);
4878      }
4879    }
4880  }
4881  else
4882  {
4883    f=1;
4884  }
4885  poly f0,h0; ideal SQ; ideal fac;
4886  if(f!=1)
4887  {
4888    SQ,f0,h0,fac=minsat(SI,f);
4889    return(SQ,std(SI+h0),fac);
4890             // the tripel
4891             // a standard basis of Q,
4892             // a standard basis of remaining component,
4893             // irreducible factors of
4894             // the "minimal divisor" of the extractor
4895             // as computed by the procedure minsat
4896  }
4897  else
4898  {
4899    return(SI,ideal(1),ideal(1));
4900  }
4901}
4902
4903/////////////////////////////////////////////////////
4904// proc minsat
4905// input:  a standard basis of an ideal I and a polynomial p
4906// output: a standard basis IS of the saturation of I w.r. to p,
4907// the maximal squarefree factor f0 of p,
4908// the "minimal divisor" f of f0 such that the saturation of
4909// I w.r. to f equals the saturation of I w.r. to f0 (which is IS),
4910// the irreducible factors of f
4911//////////////////////////////////////////////////////////
4912
4913
4914static proc minsat(ideal SI, poly p)
4915{
4916  ideal fac=factorize(p,1);       //the irreducible factors of p
4917  fac=sort(fac)[1];
4918  int i,k;
4919  poly f0=1;
4920  for(i=ncols(fac);i>=1;i--)
4921  {
4922    f0=f0*fac[i];
4923  }
4924  poly f=1;
4925  ideal iold;
4926  list quotM;
4927  quotM[1]=SI;
4928  quotM[2]=fac;
4929  quotM[3]=f0;
4930  // we deal seperately with the first quotient;
4931  // factors, which do not contribute to this one,
4932  // are omitted
4933  iold=quotM[1];
4934  quotM=minquot(quotM);
4935  fac=quotM[2];
4936  if(quotM[3]==1)
4937    {
4938      return(quotM[1],f0,f,fac);
4939    }
4940  while(special_ideals_equal(iold,quotM[1])==0)
4941    {
4942      f=f*quotM[3];
4943      iold=quotM[1];
4944      quotM=minquot(quotM);
4945    }
4946  return(quotM[1],f0,f,fac);           // the quadrupel ((I:p),f0,f, irr. factors of f)
4947}
4948
4949/////////////////////////////////////////////////////
4950// proc minsat_ppd
4951// input:  a standard basis of an ideal I and a polynomial p
4952// output: a standard basis IS of the saturation of I w.r. to p,
4953// the maximal squarefree factor f0 of p,
4954// the "minimal divisor" f of f0 such that the saturation of
4955// I w.r. to f equals the saturation of I w.r. to f0 (which is IS),
4956// the irreducible factors of f
4957//////////////////////////////////////////////////////////
4958
4959
4960static proc minsat_ppd(ideal SI, ideal fac)
4961{
4962  fac=sort(fac)[1];
4963  int i,k;
4964  poly f0=1;
4965  for(i=ncols(fac);i>=1;i--)
4966  {
4967    f0=f0*fac[i];
4968  }
4969  poly f=1;
4970  ideal iold;
4971  list quotM;
4972  quotM[1]=SI;
4973  quotM[2]=fac;
4974  quotM[3]=f0;
4975  // we deal seperately with the first quotient;
4976  // factors, which do not contribute to this one,
4977  // are omitted
4978  iold=quotM[1];
4979  quotM=minquot(quotM);
4980  fac=quotM[2];
4981  if(quotM[3]==1)
4982    {
4983      return(quotM[1],f0,f,fac);
4984    }
4985  while(special_ideals_equal(iold,quotM[1])==0)
4986  {
4987    f=f*quotM[3];
4988    iold=quotM[1];
4989    quotM=minquot(quotM);
4990    k++;
4991  }
4992  return(quotM[1],f0,f,fac);           // the quadrupel ((I:p),f0,f, irr. factors of f)
4993}
4994/////////////////////////////////////////////////////////////////
4995// proc minquot
4996// input: a list with 3 components: a standard basis
4997// of an ideal I, a set of irreducible polynomials, and
4998// there product f0
4999// output: a standard basis of the ideal (I:f0), the irreducible
5000// factors of the "minimal divisor" f of f0 with (I:f0) = (I:f),
5001// the "minimal divisor" f
5002/////////////////////////////////////////////////////////////////
5003
5004static proc minquot(list tsil)
5005{
5006   intvec op;
5007   int i,j,k,action;
5008   ideal verg;
5009   list l;
5010   poly g;
5011   ideal laedi=tsil[1];
5012   ideal fac=tsil[2];
5013   poly f=tsil[3];
5014
5015//std
5016//   ideal star=quotient(laedi,f);
5017//   star=std(star);
5018   op=option(get);
5019   option(returnSB);
5020   ideal star=quotient(laedi,f);
5021   option(set,op);
5022   if(special_ideals_equal(laedi,star)==1)
5023     {
5024       return(laedi,ideal(1),1);
5025     }
5026   action=1;
5027   while(action==1)
5028   {
5029      if(size(fac)==1)
5030      {
5031         action=0;
5032         break;
5033      }
5034      for(i=1;i<=size(fac);i++)
5035      {
5036        g=1;
5037         for(j=1;j<=size(fac);j++)
5038         {
5039            if(i!=j)
5040            {
5041               g=g*fac[j];
5042            }
5043         }
5044//std
5045//         verg=quotient(laedi,g);
5046//         verg=std(verg);
5047         op=option(get);
5048         option(returnSB);
5049         verg=quotient(laedi,g);
5050         option(set,op);
5051         if(special_ideals_equal(verg,star)==1)
5052         {
5053            f=g;
5054            fac[i]=0;
5055            fac=simplify(fac,2);
5056            break;
5057         }
5058         if(i==size(fac))
5059         {
5060            action=0;
5061         }
5062      }
5063   }
5064   l=star,fac,f;
5065   return(l);
5066}
5067/////////////////////////////////////////////////
5068// proc special_ideals_equal
5069// input: standard bases of ideal k1 and k2 such that
5070// k1 is contained in k2, or k2 is contained ink1
5071// output: 1, if k1 equals k2, 0 otherwise
5072//////////////////////////////////////////////////
5073
5074static proc special_ideals_equal( ideal k1, ideal k2)
5075{
5076   int j;
5077   if(size(k1)==size(k2))
5078   {
5079      for(j=1;j<=size(k1);j++)
5080      {
5081         if(leadexp(k1[j])!=leadexp(k2[j]))
5082         {
5083            return(0);
5084         }
5085      }
5086      return(1);
5087   }
5088   return(0);
5089}
5090
5091
5092///////////////////////////////////////////////////////////////////////////////
5093
5094static proc convList(list l)
5095{
5096   int i;
5097   list re,he;
5098   for(i=1;i<=size(l) div 2;i++)
5099   {
5100      he=l[2*i-1],l[2*i];
5101      re[i]=he;
5102   }
5103   return(re);
5104}
5105///////////////////////////////////////////////////////////////////////////////
5106
5107static proc reconvList(list l)
5108{
5109   int i;
5110   list re;
5111   for(i=1;i<=size(l);i++)
5112   {
5113      re[2*i-1]=l[i][1];
5114      re[2*i]=l[i][2];
5115   }
5116   return(re);
5117}
5118
5119///////////////////////////////////////////////////////////////////////////////
5120//
5121//     The main procedures
5122//
5123///////////////////////////////////////////////////////////////////////////////
5124
5125proc primdecGTZ(ideal i, list #)
5126"USAGE:   primdecGTZ(i); i ideal
5127RETURN:  a list pr of primary ideals and their associated primes:
5128@format
5129   pr[i][1]   the i-th primary component,
5130   pr[i][2]   the i-th prime component.
5131@end format
5132NOTE:    - Algorithm of Gianni/Trager/Zacharias.
5133         - Designed for characteristic 0, works also in char k > 0, if it
5134           terminates (may result in an infinite loop in small characteristic!)
5135         - For local orderings, the result is considered in the localization
5136           of the polynomial ring, not in the power series ring
5137         - For local and mixed orderings, the decomposition in the
5138           corresponding global ring is returned if the string 'global'
5139           is specified as second argument
5140EXAMPLE: example primdecGTZ; shows an example
5141"
5142{
5143   if(size(#)>0)
5144   {
5145      int keep_comp=1;
5146   }
5147   if(attrib(basering,"global")!=1)
5148   {
5149// algorithms only work in global case!
5150// pass to appropriate global ring
5151      def r=basering;
5152      def s=changeord(list(list("dp",1:nvars(basering))));
5153      setring s;
5154      ideal i=imap(r,i);
5155// decompose and go back
5156      list li=primdecGTZ(i);
5157      setring r;
5158      def li=imap(s,li);
5159// clean up
5160      if(!defined(keep_comp))
5161      {
5162         for(int k=size(li);k>=1;k--)
5163         {
5164            if(mindeg(std(lead(li[k][2]))[1])==0)
5165            {
5166// 1 contained in ideal, i.e. component does not meet origin in local ordering
5167               li=delete(li,k);
5168            }
5169         }
5170      }
5171      return(li);
5172   }
5173
5174   if(minpoly!=0)
5175   {
5176      return(algeDeco(i,0));
5177      ERROR(
5178      "// Not implemented yet for algebraic extensions.Simulate the ring extension by adding the minpoly to the ideal"
5179      );
5180   }
5181  return(convList(decomp(i)));
5182}
5183example
5184{ "EXAMPLE:";  echo = 2;
5185   ring  r = 0,(x,y,z),lp;
5186   poly  p = z2+1;
5187   poly  q = z3+2;
5188   ideal i = p*q^2,y-z2;
5189   list pr = primdecGTZ(i);
5190   pr;
5191}
5192///////////////////////////////////////////////////////////////////////////////
5193proc absPrimdecGTZ(ideal I, list #)
5194"USAGE:   absPrimdecGTZ(I); I ideal
5195ASSUME:  Ground field has characteristic 0.
5196RETURN:  a ring containing two lists: @code{absolute_primes}, the absolute
5197         prime components of I, and @code{primary_decomp}, the output of
5198         @code{primdecGTZ(I)}.
5199         The list absolute_primes has to be interpreted as follows:
5200         each entry describes a class of conjugated absolute primes,
5201@format
5202   absolute_primes[i][1]   the absolute prime component,
5203   absolute_primes[i][2]   the number of conjugates.
5204@end format
5205         The first entry of @code{absolute_primes[i][1]} is the minimal
5206         polynomial of a minimal finite field extension over which the
5207         absolute prime component is defined.
5208         For local orderings, the result is considered in the localization
5209         of the polynomial ring, not in the power series ring.
5210         For local and mixed orderings, the decomposition in the
5211         corresponding global ring is returned if the string 'global'
5212         is specified as second argument
5213NOTE:    Algorithm of Gianni/Trager/Zacharias combined with the
5214         @code{absFactorize} command.
5215SEE ALSO: primdecGTZ; absFactorize
5216EXAMPLE: example absPrimdecGTZ; shows an example
5217"
5218{
5219  if (char(basering) != 0)
5220  {
5221    ERROR("primdec.lib::absPrimdecGTZ is only implemented for "+
5222           +"characteristic 0");
5223  }
5224
5225  if(size(#)>0)
5226  {
5227     int keep_comp=1;
5228  }
5229
5230  if(attrib(basering,"global")!=1)
5231  {
5232// algorithm automatically passes to the global case
5233// hence prepare to go back to an appropriate new ring
5234      def r=basering;
5235      ideal max_of_r=maxideal(1);
5236      def s=changeord(list(list("dp",1:nvars(basering))));
5237      setring s;
5238      def I=imap(r,I);
5239      def S=absPrimdecGTZ(I);
5240      setring S;
5241      ring r1=char(basering),var(nvars(r)+1),dp;
5242      def rS=r+r1;
5243// move objects to appropriate ring and clean up
5244      setring rS;
5245      def max_of_r=imap(r,max_of_r);
5246      attrib(max_of_r,"isSB",1);
5247      def absolute_primes=imap(S,absolute_primes);
5248      def primary_decomp=imap(S,primary_decomp);
5249      if(!defined(keep_comp))
5250      {
5251         ideal tempid;
5252         for(int k=size(absolute_primes);k>=1;k--)
5253         {
5254            tempid=absolute_primes[k][1];
5255            tempid[1]=0;                  // ignore minimal polynomial
5256            if(size(reduce(lead(tempid),max_of_r))!=0)
5257            {
5258// 1 contained in ideal, i.e. component does not meet origin in local ordering
5259               absolute_primes=delete(absolute_primes,k);
5260            }
5261         }
5262         for(k=size(primary_decomp);k>=1;k--)
5263         {
5264            if(mindeg(std(lead(primary_decomp[k][2]))[1])==0)
5265            {
5266// 1 contained in ideal, i.e. component does not meet origin in local ordering
5267               primary_decomp=delete(primary_decomp,k);
5268            }
5269         }
5270         kill tempid;
5271      }
5272      export(primary_decomp);
5273      export(absolute_primes);
5274      return(rS);
5275  }
5276  if(minpoly!=0)
5277  {
5278    //return(algeDeco(i,0));
5279    ERROR(
5280      "// Not implemented yet for algebraic extensions.Simulate the ring extension by adding the minpoly to the ideal"
5281    );
5282  }
5283  def R=basering;
5284  int n=nvars(R);
5285  list L=decomp(I,3);
5286  string newvar=L[1][3];
5287  int k=find(newvar,",",find(newvar,",")+1);
5288  newvar=newvar[k+1..size(newvar)];
5289  list lR=ringlist(R);
5290  int i,de,ii;
5291  intvec vv=1:n;
5292  //for(i=1;i<=n;i++){vv[i]=1;}
5293
5294  list orst;
5295  orst[1]=list("dp",vv);
5296  orst[2]=list("dp",intvec(1));
5297  orst[3]=list("C",0);
5298  lR[3]=orst;
5299  lR[2][n+1] = newvar;
5300  def Rz = ring(lR);
5301  setring Rz;
5302  list L=imap(R,L);
5303  list absolute_primes,primary_decomp;
5304  ideal I,M,N,K;
5305  M=maxideal(1);
5306  N=maxideal(1);
5307  poly p,q,f,g;
5308  map phi,psi;
5309  string tvar;
5310  for(i=1;i<=size(L);i++)
5311  {
5312    tvar=L[i][4];
5313    ii=find(tvar,"+");
5314    while(ii)
5315    {
5316      tvar=tvar[ii+1..size(tvar)];
5317      ii=find(tvar,"+");
5318    }
5319    for(ii=1;ii<=nvars(basering);ii++)
5320    {
5321      if(tvar==string(var(ii))) break;
5322    }
5323    I=L[i][2];
5324    execute("K="+L[i][3]+";");
5325    p=K[1];
5326    q=K[2];
5327    execute("f="+L[i][4]+";");
5328    g=2*var(ii)-f;
5329    M[ii]=f;
5330    N[ii]=g;
5331    de=deg(p);
5332    psi=Rz,M;
5333    phi=Rz,N;
5334    I=phi(I),p,q;
5335    I=std(I);
5336    absolute_primes[i]=list(psi(I),de);
5337    primary_decomp[i]=list(L[i][1],L[i][2]);
5338  }
5339  export(primary_decomp);
5340  export(absolute_primes);
5341  setring R;
5342  dbprint( printlevel-voice+3,"
5343// 'absPrimdecGTZ' created a ring, in which two lists absolute_primes (the
5344// absolute prime components) and primary_decomp (the primary and prime
5345// components over the current basering) are stored.
5346// To access the list of absolute prime components, type (if the name S was
5347// assigned to the return value):
5348        setring S; absolute_primes; ");
5349
5350  return(Rz);
5351}
5352example
5353{ "EXAMPLE:";  echo = 2;
5354   ring  r = 0,(x,y,z),lp;
5355   poly  p = z2+1;
5356   poly  q = z3+2;
5357   ideal i = p*q^2,y-z2;
5358   def S = absPrimdecGTZ(i);
5359   setring S;
5360   absolute_primes;
5361}
5362
5363///////////////////////////////////////////////////////////////////////////////
5364
5365proc primdecSY(ideal i, list #)
5366"USAGE:   primdecSY(I, c); I ideal, c int (optional)
5367RETURN:  a list pr of primary ideals and their associated primes:
5368@format
5369   pr[i][1]   the i-th primary component,
5370   pr[i][2]   the i-th prime component.
5371@end format
5372NOTE:    Algorithm of Shimoyama/Yokoyama.
5373@format
5374   if c=0,  the given ordering of the variables is used,
5375   if c=1,  minAssChar tries to use an optimal ordering (default),
5376   if c=2,  minAssGTZ is used,
5377   if c=3,  minAssGTZ and facstd are used.
5378@end format
5379         For local orderings, the result is considered in the localization
5380         of the polynomial ring, not in the power series ring.
5381         For local and mixed orderings, the decomposition in the
5382         corresponding global ring is returned if the string 'global'
5383         is specified as third argument
5384EXAMPLE: example primdecSY; shows an example
5385"
5386{
5387   if(size(#)>1)
5388   {
5389      int keep_comp=1;
5390   }
5391   if(attrib(basering,"global")!=1)
5392   {
5393// algorithms only work in global case!
5394// pass to appropriate global ring
5395      def r=basering;
5396      def s=changeord(list(list("dp",1:nvars(basering))));
5397      setring s;
5398      ideal i=imap(r,i);
5399// decompose and go back
5400      list li=primdecSY(i);
5401      setring r;
5402      def li=imap(s,li);
5403// clean up
5404      if(!defined(keep_comp))
5405      {
5406         for(int k=size(li);k>=1;k--)
5407         {
5408            if(mindeg(std(lead(li[k][2]))[1])==0)
5409            {
5410// 1 contained in ideal, i.e. component does not meet origin in local ordering
5411               li=delete(li,k);
5412            }
5413         }
5414      }
5415      return(li);
5416   }
5417   i=simplify(i,2);
5418   if ((i[1]==0)||(i[1]==1))
5419   {
5420     list L=list(ideal(i[1]),ideal(i[1]));
5421     return(list(L));
5422   }
5423
5424   if(minpoly!=0)
5425   {
5426      return(algeDeco(i,1));
5427   }
5428   if (size(#)!=0)
5429   { return(prim_dec(i,#[1])); }
5430   else
5431   { return(prim_dec(i,1)); }
5432}
5433example
5434{ "EXAMPLE:";  echo = 2;
5435   ring  r = 0,(x,y,z),lp;
5436   poly  p = z2+1;
5437   poly  q = z3+2;
5438   ideal i = p*q^2,y-z2;
5439   list pr = primdecSY(i);
5440   pr;
5441}
5442///////////////////////////////////////////////////////////////////////////////
5443proc minAssGTZ(ideal i,list #)
5444"USAGE:    minAssGTZ(I[, l]); I ideal, l list (optional)
5445   @* Optional parameters in list l (can be entered in any order):
5446   @* 0, \"facstd\" -> uses facstd to first decompose the ideal (default)
5447   @* 1, \"noFacstd\" -> does not use facstd
5448   @* \"GTZ\" -> the original algorithm by Gianni, Trager and Zacharias is used
5449   @* \"SL\" -> GTZ algorithm with modificiations by Laplagne is used (default)
5450
5451RETURN:  a list, the minimal associated prime ideals of I.
5452NOTE:    - Designed for characteristic 0, works also in char k > 0 based
5453           on an algorithm of Yokoyama
5454         - For local orderings, the result is considered in the localization
5455           of the polynomial ring, not in the power series ring
5456         - For local and mixed orderings, the decomposition in the
5457           corresponding global ring is returned if the string 'global'
5458           is specified as second argument
5459EXAMPLE: example minAssGTZ; shows an example
5460"
5461{
5462   if(size(#)>0)
5463   {
5464      int keep_comp=1;
5465   }
5466
5467  if(attrib(basering,"global")!=1)
5468  {
5469  // algorithms only work in global case!
5470// pass to appropriate global ring
5471      def r=basering;
5472      def s=changeord(list(list("dp",1:nvars(basering))));
5473      setring s;
5474      ideal i=imap(r,i);
5475// decompose and go back
5476      list li=minAssGTZ(i);
5477      setring r;
5478      def li=imap(s,li);
5479// clean up
5480      if(!defined(keep_comp))
5481      {
5482         for(int k=size(li);k>=1;k--)
5483         {
5484            if(mindeg(std(lead(li[k]))[1])==0)
5485            {
5486// 1 contained in ideal, i.e. component does not meet origin in local ordering
5487               li=delete(li,k);
5488            }
5489         }
5490      }
5491      return(li);
5492  }
5493
5494  int j;
5495  string algorithm;
5496  string facstdOption;
5497  int useFac;
5498
5499  // Set input parameters
5500  algorithm = "SL";         // Default: SL algorithm
5501  facstdOption = "facstd";
5502  if(size(#) > 0)
5503  {
5504    int valid;
5505    for(j = 1; j <= size(#); j++)
5506    {
5507      valid = 0;
5508      if((typeof(#[j]) == "int") or (typeof(#[j]) == "number"))
5509      {
5510        if (#[j] == 1) {facstdOption = "noFacstd"; valid = 1;}    // If #[j] == 1, facstd is not used.
5511        if (#[j] == 0) {facstdOption = "facstd";   valid = 1;}    // If #[j] == 0, facstd is used.
5512      }
5513      if(typeof(#[j]) == "string")
5514      {
5515        if((#[j] == "GTZ") || (#[j] == "SL"))
5516        {
5517          algorithm = #[j];
5518          valid = 1;
5519        }
5520        if((#[j] == "noFacstd") || (#[j] == "facstd"))
5521        {
5522          facstdOption = #[j];
5523          valid = 1;
5524        }
5525      }
5526      if(valid == 0)
5527      {
5528        dbprint(1, "Warning! The following input parameter was not recognized:", #[j]);
5529      }
5530    }
5531  }
5532
5533  if(minpoly!=0)
5534  {
5535    return(algeDeco(i,2));
5536  }
5537
5538  list result = minAssPrimes(i, facstdOption, algorithm);
5539  return(result);
5540}
5541example
5542{ "EXAMPLE:";  echo = 2;
5543   ring  r = 0,(x,y,z),dp;
5544   poly  p = z2+1;
5545   poly  q = z3+2;
5546   ideal i = p*q^2,y-z2;
5547   list pr = minAssGTZ(i);
5548   pr;
5549}
5550
5551///////////////////////////////////////////////////////////////////////////////
5552proc minAssChar(ideal i, list #)
5553"USAGE:   minAssChar(I[,c]); i ideal, c int (optional).
5554RETURN:  list, the minimal associated prime ideals of i.
5555NOTE:    If c=0, the given ordering of the variables is used. @*
5556         Otherwise, the system tries to find an optimal ordering,
5557         which in some cases may considerably speed up the algorithm. @*
5558         For local orderings, the result is considered in the localization
5559         of the polynomial ring, not in the power series ring
5560         For local and mixed orderings, the decomposition in the
5561         corresponding global ring is returned if the string 'global'
5562         is specified as third argument
5563EXAMPLE: example minAssChar; shows an example
5564"
5565{
5566   if(size(#)>1)
5567   {
5568      int keep_comp=1;
5569   }
5570   if(attrib(basering,"global")!=1)
5571   {
5572// algorithms only work in global case!
5573// pass to appropriate global ring
5574      def r=basering;
5575      def s=changeord(list(list("dp",1:nvars(basering))));
5576      setring s;
5577      ideal i=imap(r,i);
5578// decompose and go back
5579      list li=minAssChar(i);
5580      setring r;
5581      def li=imap(s,li);
5582// clean up
5583      if(!defined(keep_comp))
5584      {
5585         for(int k=size(li);k>=1;k--)
5586         {
5587            if(mindeg(std(lead(li[k]))[1])==0)
5588            {
5589// 1 contained in ideal, i.e. component does not meet origin in local ordering
5590               li=delete(li,k);
5591            }
5592         }
5593      }
5594      return(li);
5595   }
5596   if (size(#)>0)
5597   { return(min_ass_prim_charsets(i,#[1])); }
5598   else
5599   { return(min_ass_prim_charsets(i,1)); }
5600}
5601example
5602{ "EXAMPLE:";  echo = 2;
5603   ring  r = 0,(x,y,z),dp;
5604   poly  p = z2+1;
5605   poly  q = z3+2;
5606   ideal i = p*q^2,y-z2;
5607   list pr = minAssChar(i);
5608   pr;
5609}
5610///////////////////////////////////////////////////////////////////////////////
5611proc equiRadical(ideal i)
5612"USAGE:   equiRadical(I); I ideal
5613RETURN:  ideal, intersection of associated primes of I of maximal dimension.
5614NOTE:    A combination of the algorithms of Krick/Logar (with modifications by Laplagne) and Kemper is used.
5615         Works also in positive characteristic (Kempers algorithm).
5616EXAMPLE: example equiRadical; shows an example
5617"
5618{
5619  if(attrib(basering,"global")!=1)
5620  {
5621     ERROR(
5622     "// Not implemented for this ordering, please change to global ordering."
5623     );
5624  }
5625  return(radical(i, 1));
5626}
5627example
5628{ "EXAMPLE:";  echo = 2;
5629   ring  r = 0,(x,y,z),dp;
5630   poly  p = z2+1;
5631   poly  q = z3+2;
5632   ideal i = p*q^2,y-z2;
5633   ideal pr= equiRadical(i);
5634   pr;
5635}
5636
5637///////////////////////////////////////////////////////////////////////////////
5638proc radical(ideal i, list #)
5639"USAGE: radical(I[, l]); I ideal, l list (optional)
5640 @*  Optional parameters in list l (can be entered in any order):
5641 @*  0, \"fullRad\" -> full radical is computed (default)
5642 @*  1, \"equiRad\" -> equiRadical is computed
5643 @*  \"KL\" -> Krick/Logar algorithm is used
5644 @*  \"SL\" -> modifications by Laplagne are used (default)
5645 @*  \"facstd\" -> uses facstd to first decompose the ideal (default for non homogeneous ideals)
5646 @*  \"noFacstd\" -> does not use facstd (default for homogeneous ideals)
5647RETURN:  ideal, the radical of I (or the equiradical if required in the input parameters)
5648NOTE:    A combination of the algorithms of Krick/Logar (with modifications by Laplagne) and Kemper is used.
5649         Works also in positive characteristic (Kempers algorithm).
5650EXAMPLE: example radical; shows an example
5651"
5652{
5653  dbprint(printlevel - voice, "Radical, version 2006.05.08");
5654  if(attrib(basering,"global")!=1)
5655  {
5656// algorithms only work in global case!
5657// pass to appropriate global ring
5658      def r=basering;
5659      def s=changeord(list(list("dp",1:nvars(basering))));
5660      setring s;
5661      ideal i=imap(r,i);
5662// compute radical and go back
5663      def j=radical(i);
5664      setring r;
5665      def j=imap(s,j);
5666      return(j);
5667  }
5668  if(size(i) == 0){return(ideal(0));}
5669  int j;
5670  def P0 = basering;
5671  list Pl=ringlist(P0);
5672  intvec dp_w;
5673  for(j=nvars(P0);j>0;j--) {dp_w[j]=1;}
5674  Pl[3]=list(list("dp",dp_w),list("C",0));
5675  def @P=ring(Pl);
5676  setring @P;
5677  ideal i=imap(P0,i);
5678
5679  int il;
5680  string algorithm;
5681  int useFac;
5682
5683  // Set input parameters
5684  algorithm = "SL";                                 // Default: SL algorithm
5685  il = 0;                                           // Default: Full radical (not only equiRadical)
5686  if (homog(i) == 1)
5687  {   // Default: facStd is used, except if the ideal is homogeneous.
5688    useFac = 0;
5689  }
5690  else
5691  {
5692    useFac = 1;
5693  }
5694  if(size(#) > 0)
5695  {
5696    int valid;
5697    for(j = 1; j <= size(#); j++)
5698    {
5699      valid = 0;
5700      if((typeof(#[j]) == "int") or (typeof(#[j]) == "number"))
5701      {
5702        il = #[j];          // If il == 1, equiRadical is computed
5703        valid = 1;
5704      }
5705      if(typeof(#[j]) == "string")
5706      {
5707        if(#[j] == "KL")
5708        {
5709          algorithm = "KL";
5710          valid = 1;
5711        }
5712        if(#[j] == "SL")
5713        {
5714          algorithm = "SL";
5715          valid = 1;
5716        }
5717        if(#[j] == "noFacstd")
5718        {
5719          useFac = 0;
5720          valid = 1;
5721        }
5722        if(#[j] == "facstd")
5723        {
5724          useFac = 1;
5725          valid = 1;
5726        }
5727        if(#[j] == "equiRad")
5728        {
5729          il = 1;
5730          valid = 1;
5731        }
5732        if(#[j] == "fullRad")
5733        {
5734          il = 0;
5735          valid = 1;
5736        }
5737      }
5738      if(valid == 0)
5739      {
5740        dbprint(1, "Warning! The following input parameter was not recognized:", #[j]);
5741      }
5742    }
5743  }
5744
5745  ideal rad = 1;
5746  intvec op = option(get);
5747  list qr = simplifyIdeal(i);
5748  map phi = @P, qr[2];
5749
5750  option(redSB);
5751  i = groebner(qr[1]);
5752  option(set, op);
5753  int di = dim(i);
5754
5755  if(di == 0)
5756  {
5757    i = zeroRad(i, qr[1]);
5758    option(redSB);
5759    i=interred(phi(i));
5760    option(set, op);
5761    setring(P0);
5762    i=imap(@P,i);
5763    return(i);
5764  }
5765
5766  option(redSB);
5767  list pr;
5768  if(useFac == 1)
5769  {
5770    pr = facstd(i);
5771  }
5772  else
5773  {
5774    pr = i;
5775  }
5776  option(set, op);
5777  int s = size(pr);
5778  if(useFac == 1)
5779  {
5780    dbprint(printlevel - voice, "Number of components returned by facstd: ", s);
5781  }
5782  for(j = 1; j <= s; j++)
5783  {
5784    attrib(pr[s + 1 - j], "isSB", 1);
5785    if((size(reduce(rad, pr[s + 1 - j], 1)) != 0) && ((dim(pr[s + 1 - j]) == di) || !il))
5786    {
5787      // SL Debug messages
5788      dbprint(printlevel-voice, "We shall compute the radical of ", pr[s + 1 - j]);
5789      dbprint(printlevel-voice, "The dimension is: ", dim(pr[s+1-j]));
5790
5791      if(algorithm == "KL")
5792      {
5793        rad = intersect(rad, radicalKL(pr[s + 1 - j], rad, il));
5794      }
5795      if(algorithm == "SL")
5796      {
5797        rad = intersect(rad, radicalSL(pr[s + 1 - j], il));
5798      }
5799    }
5800    else
5801    {
5802      // SL Debug
5803      dbprint(printlevel-voice, "The radical of this component is not needed.");
5804      dbprint(printlevel-voice, "size(reduce(rad, pr[s + 1 - j], 1))",
5805              size(reduce(rad, pr[s + 1 - j], 1)));
5806      dbprint(printlevel-voice, "dim(pr[s + 1 - j])", dim(pr[s + 1 - j]));
5807      dbprint(printlevel-voice, "il", il);
5808    }
5809  }
5810  rad=interred(phi(rad));
5811  setring(P0);
5812  i=imap(@P,rad);
5813  return(i);
5814}
5815example
5816{ "EXAMPLE:";  echo = 2;
5817   ring  r = 0,(x,y,z),dp;
5818   poly  p = z2+1;
5819   poly  q = z3+2;
5820   ideal i = p*q^2,y-z2;
5821   ideal pr = radical(i);
5822   pr;
5823}
5824
5825///////////////////////////////////////////////////////////////////////////////
5826//
5827// Computes the radical of I using KL algorithm.
5828// The only difference with the previous implementation of KL algorithm is
5829// that now it uses block dp instead of lp ordering for the reduction to the
5830// zerodimensional case.
5831// The reduction step has been moved to the new routine radicalReduction, so that it can be
5832// used also by radicalSL procedure.
5833//
5834static proc radicalKL(ideal I, ideal ser, list #)
5835{
5836// ideal I     The ideal for which the radical is computed
5837// ideal ser   Used to reduce components already obtained
5838// list #      If #[1] = 1, equiradical is computed.
5839
5840  // I needs to be a Groebner basis.
5841  if (attrib(I, "isSB") != 1)
5842  {
5843    I = groebner(I);
5844  }
5845
5846  ideal rad;                                // The radical
5847  int allIndep = 1;                // All max independent sets are used
5848
5849  list result = radicalReduction(I, ser, allIndep, #);
5850  int done = result[3];
5851  rad = result[1];
5852  if (done == 0)
5853  {
5854    rad = intersect(rad, radicalKL(result[2], ideal(1), #));
5855  }
5856  return(rad);
5857}
5858
5859
5860///////////////////////////////////////////////////////////////////////////////
5861//
5862// Computes the radical of I via Laplagne algorithm, using zerodimensional radical in
5863// the zero dimensional case.
5864// For the reduction to the zerodimensional case, it uses the procedure
5865// radical, with some modifications to avoid the recursion.
5866//
5867static proc radicalSL(ideal I, list #)
5868// Input = I, ideal
5869//         #, list. If #[1] = 1, then computes only the equiradical.
5870// Output = (P, primaryDec) where P = rad(I) and primaryDec is the list of the radicals
5871// obtained in intermediate steps.
5872{
5873  ideal rad = 1;
5874  ideal equiRad = 1;
5875  list primes;
5876  int k;                        // Counter
5877  int il;                 // If il = 1, only the equiradical is required.
5878  int iDim;                // The dimension of I
5879  int stop = 0;   // Checks if the radical has been obtained
5880
5881  if (attrib(I, "isSB") != 1)
5882  {
5883    I = groebner(I);
5884  }
5885  iDim = dim(I);
5886
5887  // Checks if only equiradical is required
5888  if (size(#) > 0)
5889  {
5890    il = #[1];
5891  }
5892
5893  while(stop == 0)
5894  {
5895    dbprint (printlevel-voice, "// We call radLoopR to find new prime ideals.");
5896    primes = radicalSLIteration(I, rad);                         // A list of primes or intersections of primes, not included in P
5897    dbprint (printlevel - voice, "// Output of Iteration Step:");
5898    dbprint (printlevel - voice, primes);
5899    if (size(primes) > 0)
5900    {
5901      dbprint (printlevel - voice, "// We intersect P with the ideal just obtained.");
5902      for(k = 1; k <= size(primes); k++)
5903      {
5904        rad = intersect(rad, primes[k]);
5905        if (il == 1)
5906        {
5907          if (attrib(primes[k], "isSB") != 1)
5908          {
5909            primes[k] = groebner(primes[k]);
5910          }
5911          if (iDim == dim(primes[k]))
5912          {
5913            equiRad = intersect(equiRad, primes[k]);
5914          }
5915        }
5916      }
5917    }
5918    else
5919    {
5920      stop = 1;
5921    }
5922  }
5923  if (il == 0)
5924  {
5925    return(rad);
5926  }
5927  else
5928  {
5929    return(equiRad);
5930  }
5931}
5932
5933//////////////////////////////////////////////////////////////////////////
5934// Based on radicalKL.
5935// It contains all of old version of proc radicalKL except the recursion call.
5936//
5937// Output:
5938// #1 -> output ideal, the part of the radical that has been computed
5939// #2 -> complementary ideal, the part of the ideal I whose radical remains to be computed
5940//       = (I, h) in KL algorithm
5941//       This is not used in the new algorithm. It is part of KL algorithm
5942// #3 -> done, 1: output = radical, there is no need to continue
5943//                   0: radical = output \cap \sqrt{complementary ideal}
5944//       This is not used in the new algorithm. It is part of KL algorithm
5945
5946static proc radicalReduction(ideal I, ideal ser, int allIndep, list #)
5947{
5948// allMaximal      1 -> Indicates that the reduction to the zerodim case
5949//                    must be done for all indep set of the leading terms ideal
5950//                 0 -> Otherwise
5951// ideal ser       Only for radicalKL. (Same as in radicalKL)
5952// list #          Only for radicalKL (If #[1] = 1,
5953//                    only equiradical is required.
5954//                    It is used to set the value of done.)
5955
5956  attrib(I, "isSB", 1);   // I needs to be a reduced standard basis
5957  list indep, fett;
5958  intvec @w, @hilb, op;
5959  int @wr, @n, @m, lauf, di;
5960  ideal fac, @h, collectrad, lsau;
5961  poly @q;
5962  string @va, quotring;
5963
5964  def @P = basering;
5965  int jdim = dim(I);               // Computes the dimension of I
5966  int  homo = homog(I);            // Finds out if I is homogeneous
5967  ideal rad = ideal(1);            // The unit ideal
5968  ideal te = ser;
5969  if(size(#) > 0)
5970  {
5971    @wr = #[1];
5972  }
5973  if(homo == 1)
5974  {
5975    for(@n = 1; @n <= nvars(basering); @n++)
5976    {
5977      @w[@n] = ord(var(@n));
5978    }
5979    @hilb = hilb(I, 1, @w);
5980  }
5981
5982  // SL 2006.04.11 1 Debug messages
5983  dbprint(printlevel-voice, "//Computes the radical of the ideal:", I);
5984  // SL 2006.04.11 2 Debug messages
5985
5986  //---------------------------------------------------------------------------
5987  //j is the ring
5988  //---------------------------------------------------------------------------
5989
5990  if (jdim==-1)
5991  {
5992    return(ideal(1), ideal(1), 1);
5993  }
5994
5995  //---------------------------------------------------------------------------
5996  //the zero-dimensional case
5997  //---------------------------------------------------------------------------
5998
5999  if (jdim==0)
6000  {
6001    return(zeroRad(I), ideal(1), 1);
6002  }
6003
6004  //-------------------------------------------------------------------------
6005  //search for a maximal independent set indep,i.e.
6006  //look for subring such that the intersection with the ideal is zero
6007  //j intersected with K[var(indep[3]+1),...,var(nvar)] is zero,
6008  //indep[1] is the new varstring, indep[2] the string for the block-ordering
6009  //-------------------------------------------------------------------------
6010
6011  // SL 2006-04-24 1   If allIndep = 0, then it only computes one maximal
6012  //                     independent set.
6013  //                     This looks better for the new algorithm but not for KL
6014  //                     algorithm
6015  list parameters = allIndep;
6016  indep = newMaxIndependSetDp(I, parameters);
6017  // SL 2006-04-24 2
6018
6019  for(@m = 1; @m <= size(indep); @m++)
6020  {
6021    if((indep[@m][1] == varstr(basering)) && (@m == 1))
6022    //this is the good case, nothing to do, just to have the same notations
6023    //change the ring
6024    {
6025      execute("ring gnir1 = ("+charstr(basering)+"),("+varstr(basering)+"),("
6026                              +ordstr(basering)+");");
6027      ideal @j = fetch(@P, I);
6028      attrib(@j, "isSB", 1);
6029    }
6030    else
6031    {
6032      @va = string(maxideal(1));
6033
6034      execute("ring gnir1 = (" + charstr(basering) + "), (" + indep[@m][1] + "),("
6035                              + indep[@m][2] + ");");
6036      execute("map phi = @P," + @va + ";");
6037      if(homo == 1)
6038      {
6039        ideal @j = std(phi(I), @hilb, @w);
6040      }
6041      else
6042      {
6043        ideal @j = groebner(phi(I));
6044      }
6045    }
6046    if((deg(@j[1]) == 0) || (dim(@j) < jdim))
6047    {
6048      setring @P;
6049      break;
6050    }
6051    for (lauf = 1; lauf <= size(@j); lauf++)
6052    {
6053      fett[lauf] = size(@j[lauf]);
6054    }
6055    //------------------------------------------------------------------------
6056    // We have now the following situation:
6057    // j intersected with K[var(nnp+1),..,var(nva)] is zero so we may pass
6058    // to this quotientring, j is there still a standardbasis, the
6059    // leading coefficients of the polynomials there (polynomials in
6060    // K[var(nnp+1),..,var(nva)]) are collected in the list h,
6061    // we need their LCM, gh, because of the following:
6062    // let (j:gh^n)=(j:gh^infinity) then j*K(var(nnp+1),..,var(nva))[..rest..]
6063    // intersected with K[var(1),...,var(nva)] is (j:gh^n)
6064    // on the other hand j = ((j, gh^n) intersected with (j : gh^n))
6065
6066    //------------------------------------------------------------------------
6067    // The arrangement for the quotientring K(var(nnp+1),..,var(nva))[..rest..]
6068    // and the map phi:K[var(1),...,var(nva)] ----->
6069    // K(var(nnpr+1),..,var(nva))[..the rest..]
6070    //------------------------------------------------------------------------
6071    quotring = prepareQuotientRingDp(nvars(basering) - indep[@m][3]);
6072    //------------------------------------------------------------------------
6073    // We pass to the quotientring   K(var(nnp+1),..,var(nva))[..the rest..]
6074    //------------------------------------------------------------------------
6075
6076    execute(quotring);
6077
6078    // @j considered in the quotientring
6079    ideal @j = imap(gnir1, @j);
6080
6081    kill gnir1;
6082
6083    // j is a standardbasis in the quotientring but usually not minimal
6084    // here it becomes minimal
6085
6086    @j = clearSB(@j, fett);
6087
6088    // We need later LCM(h[1],...) = gh for saturation
6089    ideal @h;
6090    if(deg(@j[1]) > 0)
6091    {
6092      for(@n = 1; @n <= size(@j); @n++)
6093      {
6094        @h[@n] = leadcoef(@j[@n]);
6095      }
6096      op = option(get);
6097      option(redSB);
6098      @j = std(@j);  //to obtain a reduced standardbasis
6099      option(set, op);
6100
6101      // SL 1 Debug messages
6102      dbprint(printlevel - voice, "zero_rad", basering, @j, dim(groebner(@j)));
6103      ideal zero_rad = zeroRad(@j);
6104      dbprint(printlevel - voice, "zero_rad passed");
6105      // SL 2
6106    }
6107    else
6108    {
6109      ideal zero_rad = ideal(1);
6110    }
6111
6112    // We need the intersection of the ideals in the list quprimary with the
6113    // polynomialring, i.e. let q=(f1,...,fr) in the quotientring such an ideal
6114    // but fi polynomials, then the intersection of q with the polynomialring
6115    // is the saturation of the ideal generated by f1,...,fr with respect to
6116    // h which is the lcm of the leading coefficients of the fi considered in
6117    // the quotientring: this is coded in saturn
6118
6119    zero_rad = std(zero_rad);
6120
6121    ideal hpl;
6122
6123    for(@n = 1; @n <= size(zero_rad); @n++)
6124    {
6125      hpl = hpl, leadcoef(zero_rad[@n]);
6126    }
6127
6128    //------------------------------------------------------------------------
6129    // We leave  the quotientring   K(var(nnp+1),..,var(nva))[..the rest..]
6130    // back to the polynomialring
6131    //------------------------------------------------------------------------
6132    setring @P;
6133
6134    collectrad = imap(quring, zero_rad);
6135    lsau = simplify(imap(quring, hpl), 2);
6136    @h = imap(quring, @h);
6137
6138    kill quring;
6139
6140    // Here the intersection with the polynomialring
6141    // mentioned above is really computed
6142
6143    collectrad = sat2(collectrad, lsau)[1];
6144    if(deg(@h[1])>=0)
6145    {
6146      fac = ideal(0);
6147      for(lauf = 1; lauf <= ncols(@h); lauf++)
6148      {
6149        if(deg(@h[lauf]) > 0)
6150        {
6151          fac = fac + factorize(@h[lauf], 1);
6152        }
6153      }
6154      fac = simplify(fac, 6);
6155      @q = 1;
6156      for(lauf = 1; lauf <= size(fac); lauf++)
6157      {
6158        @q = @q * fac[lauf];
6159      }
6160      op = option(get);
6161      option(returnSB);
6162      option(redSB);
6163      I = quotient(I + ideal(@q), rad);
6164      attrib(I, "isSB", 1);
6165      option(set, op);
6166    }
6167    if((deg(rad[1]) > 0) && (deg(collectrad[1]) > 0))
6168    {
6169      rad = intersect(rad, collectrad);
6170      te = intersect(te, collectrad);
6171      te = simplify(reduce(te, I, 1), 2);
6172    }
6173    else
6174    {
6175      if(deg(collectrad[1]) > 0)
6176      {
6177        rad = collectrad;
6178        te = intersect(te, collectrad);
6179        te = simplify(reduce(te, I, 1), 2);
6180      }
6181    }
6182
6183    if((dim(I) < jdim)||(size(te) == 0))
6184    {
6185      break;
6186    }
6187    if(homo==1)
6188    {
6189      @hilb = hilb(I, 1, @w);
6190    }
6191  }
6192
6193  // SL 2006.04.11 1 Debug messages
6194  dbprint (printlevel-voice, "// Part of the Radical already computed:", rad);
6195  dbprint (printlevel-voice, "// Dimension:", dim(groebner(rad)));
6196  // SL 2006.04.11 2 Debug messages
6197
6198  // SL 2006.04.21 1    New variable "done".
6199  //                      It tells if the radical is already computed or
6200  //                      if it still has to be computed the radical of the new ideal I
6201  int done;
6202  if(((@wr == 1) && (dim(I)<jdim)) || (deg(I[1])==0) || (size(te) == 0))
6203  {
6204    done = 1;
6205  }
6206  else
6207  {
6208    done = 0;
6209  }
6210  // SL 2006.04.21 2
6211
6212  // SL 2006.04.21 1     See details of the output at the beginning of this proc.
6213  list result = rad, I, done;
6214  return(result);
6215  // SL 2006.04.21 2
6216}
6217
6218///////////////////////////////////////////////////////////////////////////////
6219// Given an ideal I and an ideal P (intersection of some minimal prime ideals
6220// associated to I), it calculates the intersection of new minimal prime ideals
6221// associated to I which where not used to calculate P.
6222// This version uses ZD Radical in the zerodimensional case.
6223static proc radicalSLIteration (ideal I, ideal P);
6224// Input: I, ideal. The ideal from which new prime components will be obtained.
6225//        P, ideal. Intersection of some prime ideals of I.
6226// Output: ideal. Intersection of some primes of I different from the ones in P.
6227{
6228  int k = 1;                     // Counter
6229  int good  = 0;                 // Checks if an element of P is in rad(I)
6230
6231  dbprint (printlevel-voice, "// We search for an element in P - sqrt(I).");
6232  while ((k <= size(P)) and (good == 0))
6233  {
6234    dbprint (printlevel-voice, "// We try with:", P[k]);
6235    good = 1 - rad_con(P[k], I);
6236    k++;
6237  }
6238  k--;
6239  if (good == 0)
6240  {
6241    dbprint (printlevel-voice, "// No element was found, P = sqrt(I).");
6242    list emptyList = list();
6243    return (emptyList);
6244  }
6245  dbprint(printlevel - voice, "// That one was good!");
6246  dbprint(printlevel - voice, "// We saturate I with respect to this element.");
6247  if (P[k] != 1)
6248  {
6249    intvec oo=option(get);
6250    option(redSB);
6251    ideal J = sat(I, P[k])[1];
6252    option(set,oo);
6253
6254  }
6255  else
6256  {
6257    dbprint(printlevel - voice, "// The polynomial is 1, the saturation in not actually computed.");
6258    ideal J = I;
6259  }
6260
6261  // We now call proc radicalNew;
6262  dbprint(printlevel - voice, "// We do the reduction to the zerodimensional case, via radical.");
6263  dbprint(printlevel - voice, "// The ideal is ", J);
6264  dbprint(printlevel - voice, "// The dimension is ", dim(groebner(J)));
6265
6266  int allMaximal = 0;   // Compute the zerodim reduction for only one indep set.
6267  ideal re = 1;         // No reduction is need,
6268                        //    there are not redundant components.
6269  list emptyList = list();   // Look for primes of any dimension,
6270                             //   not only of max dimension.
6271  list result = radicalReduction(J, re, allMaximal, emptyList);
6272
6273  return(result[1]);
6274}
6275
6276///////////////////////////////////////////////////////////////////////////////////
6277// Based on maxIndependSet
6278// Added list # as parameter
6279// If the first element of # is 0, the output is only 1 max indep set.
6280// If no list is specified or #[1] = 1, the output is all the max indep set of the
6281// leading terms ideal. This is the original output of maxIndependSet
6282
6283// The ordering given in the output has been changed to block dp instead of lp.
6284
6285proc newMaxIndependSetDp(ideal j, list #)
6286"USAGE:   newMaxIndependentSetDp(I); I ideal (returns all maximal independent sets of the corresponding leading terms ideal)
6287          newMaxIndependentSetDp(I, 0); I ideal (returns only one maximal independent set)
6288RETURN:  list = #1. new varstring with the maximal independent set at the end,
6289                #2. ordstring with the corresponding dp block ordering,
6290                #3. the number of independent variables
6291NOTE:
6292EXAMPLE: example newMaxIndependentSetDp; shows an example
6293"
6294{
6295  int n, k, di;
6296  list resu, hilf;
6297  string var1, var2;
6298  list v = indepSet(j, 0);
6299
6300  // SL 2006.04.21 1 Lines modified to use only one independent Set
6301  int allMaximal;
6302  if (size(#) > 0)
6303  {
6304    allMaximal = #[1];
6305  }
6306  else
6307  {
6308    allMaximal = 1;
6309  }
6310
6311  int nMax;
6312  if (allMaximal == 1)
6313  {
6314    nMax = size(v);
6315  }
6316  else
6317  {
6318    nMax = 1;
6319  }
6320
6321  for(n = 1; n <= nMax; n++)
6322  // SL 2006.04.21 2
6323  {
6324    di = 0;
6325    var1 = "";
6326    var2 = "";
6327    for(k = 1; k <= size(v[n]); k++)
6328    {
6329     if(v[n][k] != 0)
6330      {
6331        di++;
6332        var2 = var2 + "var(" + string(k) + "), ";
6333      }
6334      else
6335      {
6336        var1 = var1 + "var(" + string(k) + "), ";
6337      }
6338    }
6339    if(di > 0)
6340    {
6341      var1 = var1 + var2;
6342      var1 = var1[1..size(var1) - 2];                         // The "- 2" removes the trailer comma
6343      hilf[1] = var1;
6344      // SL 2006.21.04 1 The order is now block dp instead of lp
6345      hilf[2] = "dp(" + string(nvars(basering) - di) + "), dp(" + string(di) + ")";
6346      // SL 2006.21.04 2
6347      hilf[3] = di;
6348      resu[n] = hilf;
6349    }
6350    else
6351    {
6352      resu[n] = varstr(basering), ordstr(basering), 0;
6353    }
6354  }
6355  return(resu);
6356}
6357example
6358{ "EXAMPLE:"; echo = 2;
6359   ring s1 = (0, x, y), (a, b, c, d, e, f, g), lp;
6360   ideal i = ea - fbg, fa + be, ec - fdg, fc + de;
6361   i = std(i);
6362   list l = newMaxIndependSetDp(i);
6363   l;
6364   i = i, g;
6365   l = newMaxIndependSetDp(i);
6366   l;
6367
6368   ring s = 0, (x, y, z), lp;
6369   ideal i = z, yx;
6370   list l = newMaxIndependSetDp(i);
6371   l;
6372}
6373
6374
6375///////////////////////////////////////////////////////////////////////////////
6376// based on prepareQuotientring
6377// The order returned is now (C, dp) instead of (C, lp)
6378
6379static proc prepareQuotientRingDp (int nnp)
6380"USAGE:   prepareQuotientRingDp(nnp); nnp int
6381RETURN:  string = to define Kvar(nnp+1),...,var(nvars)[..rest ]
6382NOTE:
6383EXAMPLE: example prepareQuotientRingDp; shows an example
6384"
6385{
6386  ideal @ih,@jh;
6387  int npar=npars(basering);
6388  int @n;
6389
6390  string quotring= "ring quring = ("+charstr(basering);
6391  for(@n = nnp + 1; @n <= nvars(basering); @n++)
6392  {
6393     quotring = quotring + ", var(" + string(@n) + ")";
6394     @ih = @ih + var(@n);
6395  }
6396
6397  quotring = quotring+"),(var(1)";
6398  @jh = @jh + var(1);
6399  for(@n = 2; @n <= nnp; @n++)
6400  {
6401    quotring = quotring + ", var(" + string(@n) + ")";
6402    @jh = @jh + var(@n);
6403  }
6404  // SL 2006-04-21 1 The order returned is now (C, dp) instead of (C, lp)
6405  quotring = quotring + "), (C, dp);";
6406  // SL 2006-04-21 2
6407
6408  return(quotring);
6409}
6410example
6411{ "EXAMPLE:"; echo = 2;
6412   ring s1=(0,x),(a,b,c,d,e,f,g),lp;
6413   def @Q=basering;
6414   list l= prepareQuotientRingDp(3);
6415   l;
6416   execute(l[1]);
6417   execute(l[2]);
6418   basering;
6419   phi;
6420   setring @Q;
6421
6422}
6423
6424///////////////////////////////////////////////////////////////////////////////
6425proc prepareAss(ideal i)
6426"USAGE:   prepareAss(I); I ideal
6427RETURN:  list, the radicals of the maximal dimensional components of I.
6428NOTE:    Uses algorithm of Eisenbud/Huneke/Vasconcelos.
6429EXAMPLE: example prepareAss; shows an example
6430"
6431{
6432  if(attrib(basering,"global")!=1)
6433  {
6434      ERROR(
6435      "// Not implemented for this ordering, please change to global ordering."
6436      );
6437  }
6438  ideal j=std(i);
6439  int cod=nvars(basering)-dim(j);
6440  int e;
6441  list er;
6442  ideal ann;
6443  if(homog(i)==1)
6444  {
6445     list re=sres(j,0);                   //the resolution
6446     re=minres(re);                       //minimized resolution
6447  }
6448  else
6449  {
6450    list re=mres(i,0);
6451  }
6452  for(e=cod;e<=nvars(basering);e++)
6453  {
6454     ann=AnnExt_R(e,re);
6455
6456     if(nvars(basering)-dim(std(ann))==e)
6457     {
6458        er[size(er)+1]=equiRadical(ann);
6459     }
6460  }
6461  return(er);
6462}
6463example
6464{ "EXAMPLE:";  echo = 2;
6465   ring  r = 0,(x,y,z),dp;
6466   poly  p = z2+1;
6467   poly  q = z3+2;
6468   ideal i = p*q^2,y-z2;
6469   list pr = prepareAss(i);
6470   pr;
6471}
6472///////////////////////////////////////////////////////////////////////////////
6473proc equidimMaxEHV(ideal i)
6474"USAGE:  equidimMaxEHV(I); I ideal
6475RETURN:  ideal, the equidimensional component (of maximal dimension) of I.
6476NOTE:    Uses algorithm of Eisenbud, Huneke and Vasconcelos.
6477EXAMPLE: example equidimMaxEHV; shows an example
6478"
6479{
6480  if(attrib(basering,"global")!=1)
6481  {
6482      ERROR(
6483      "// Not implemented for this ordering, please change to global ordering."
6484      );
6485  }
6486  ideal j=groebner(i);
6487  int cod=nvars(basering)-dim(j);
6488  int e;
6489  ideal ann;
6490  if(homog(i)==1)
6491  {
6492     list re=sres(j,0);                   //the resolution
6493     re=minres(re);                       //minimized resolution
6494  }
6495  else
6496  {
6497    list re=mres(i,0);
6498  }
6499  ann=AnnExt_R(cod,re);
6500  return(ann);
6501}
6502example
6503{ "EXAMPLE:";  echo = 2;
6504   ring  r = 0,(x,y,z),dp;
6505   ideal i=intersect(ideal(z),ideal(x,y),ideal(x2,z2),ideal(x5,y5,z5));
6506   equidimMaxEHV(i);
6507}
6508
6509proc testPrimary(list pr, ideal k)
6510"USAGE:   testPrimary(pr,k); pr a list, k an ideal.
6511ASSUME:  pr is the result of primdecGTZ(k) or primdecSY(k).
6512RETURN:  int, 1 if the intersection of the ideals in pr is k, 0 if not
6513EXAMPLE: example testPrimary; shows an example
6514"
6515{
6516   int i;
6517   pr=reconvList(pr);
6518   ideal j=pr[1];
6519   for (i=2;i<=size(pr) div 2;i++)
6520   {
6521       j=intersect(j,pr[2*i-1]);
6522   }
6523   return(idealsEqual(j,k));
6524}
6525example
6526{ "EXAMPLE:";  echo = 2;
6527   ring  r = 32003,(x,y,z),dp;
6528   poly  p = z2+1;
6529   poly  q = z4+2;
6530   ideal i = p^2*q^3,(y-z3)^3,(x-yz+z4)^4;
6531   list pr = primdecGTZ(i);
6532   testPrimary(pr,i);
6533}
6534
6535///////////////////////////////////////////////////////////////////////////////
6536proc zerodec(ideal I)
6537"USAGE:   zerodec(I); I ideal
6538ASSUME:  I is zero-dimensional, the characteristic of the ground field is 0
6539RETURN:  list of primary ideals, the zero-dimensional decomposition of I
6540NOTE:    The algorithm (of Monico), works well only for a small total number
6541         of solutions (@code{vdim(std(I))} should be < 100) and without
6542         parameters. In practice, it works also in large characteristic p>0
6543         but may fail for small p.
6544@*       If printlevel > 0 (default = 0) additional information is displayed.
6545EXAMPLE: example zerodec; shows an example
6546"
6547{
6548  if(attrib(basering,"global")!=1)
6549  {
6550    ERROR(
6551    "// Not implemented for this ordering, please change to global ordering."
6552    );
6553  }
6554  def R=basering;
6555  poly q;
6556  int j,time;
6557  matrix m;
6558  list re;
6559  poly va=var(1);
6560  ideal J=groebner(I);
6561  ideal ba=kbase(J);
6562  int d=vdim(J);
6563  dbprint(printlevel-voice+2,"// multiplicity of ideal : "+ string(d));
6564//------ compute matrix of multiplication on R/I with generic element p -----
6565  int e=nvars(basering);
6566  poly p=randomLast(100)[e]+random(-50,50);     //the generic element
6567  matrix n[d][d];
6568  time = timer;
6569  for(j=2;j<=e;j++)
6570  {
6571    va=va*var(j);
6572  }
6573  for(j=1;j<=d;j++)
6574  {
6575    q=reduce(p*ba[j],J);
6576    m=coeffs(q,ba,va);
6577    n[j,1..d]=m[1..d,1];
6578  }
6579  dbprint(printlevel-voice+2,
6580    "// time for computing multiplication matrix (with generic element) : "+
6581    string(timer-time));
6582//---------------- compute characteristic polynomial of matrix --------------
6583  execute("ring P1=("+charstr(R)+"),T,dp;");
6584  matrix n=imap(R,n);
6585  time = timer;
6586  poly charpol=det(n-T*freemodule(d));
6587  dbprint(printlevel-voice+2,"// time for computing char poly: "+
6588         string(timer-time));
6589//------------------- factorize characteristic polynomial -------------------
6590//check first if constant term of charpoly is != 0 (which is true for
6591//sufficiently generic element)
6592  if(charpol[size(charpol)]!=0)
6593  {
6594    time = timer;
6595    list fac=factor(charpol);
6596    testFactor(fac,charpol);
6597    dbprint(printlevel-voice+2,"// time for factorizing char poly: "+
6598            string(timer-time));
6599    int f=size(fac[1]);
6600//--------------------------- the irreducible case --------------------------
6601    if(f==1)
6602    {
6603      setring R;
6604      re=I;
6605      return(re);
6606    }
6607//---------------------------- the reducible case ---------------------------
6608//if f_i are the irreducible factors of charpoly, mult=ri, then <I,g_i^ri>
6609//are the primary components where g_i = f_i(p). However, substituting p in
6610//f_i may result in a huge object although the final result may be small.
6611//Hence it is better to simultaneously reduce with I. For this we need a new
6612//ring.
6613    execute("ring P=("+charstr(R)+"),(T,"+varstr(R)+"),(dp(1),dp);");
6614    list rfac=imap(P1,fac);
6615    intvec ov=option(get);;
6616    option(redSB);
6617    list re1;
6618    ideal new = T-imap(R,p),imap(R,J);
6619    attrib(new, "isSB",1);    //we know that new is a standard basis
6620    for(j=1;j<=f;j++)
6621    {
6622      re1[j]=reduce(rfac[1][j]^rfac[2][j],new);
6623    }
6624    setring R;
6625    re = imap(P,re1);
6626    for(j=1;j<=f;j++)
6627    {
6628      J=I,re[j];
6629      re[j]=interred(J);
6630    }
6631    option(set,ov);
6632    return(re);
6633  }
6634  else
6635//------------------- choice of generic element failed -------------------
6636  {
6637    dbprint(printlevel-voice+2,"// try new generic element!");
6638    setring R;
6639    return(zerodec(I));
6640  }
6641}
6642example
6643{ "EXAMPLE:";  echo = 2;
6644   ring r  = 0,(x,y),dp;
6645   ideal i = x2-2,y2-2;
6646   list pr = zerodec(i);
6647   pr;
6648}
6649///////////////////////////////////////////////////////////////////////////////
6650static proc newDecompStep(ideal i, list #)
6651"USAGE:  newDecompStep(i); i ideal  (for primary decomposition)
6652         newDecompStep(i,1);        (for the associated primes of dimension of i)
6653         newDecompStep(i,2);        (for the minimal associated primes)
6654         newDecompStep(i,3);        (for the absolute primary decomposition (not tested!))
6655         "oneIndep";        (for using only one max indep set)
6656         "intersect";        (returns alse the intersection of the components founded)
6657
6658RETURN:  list = list of primary ideals and their associated primes
6659         (at even positions in the list)
6660         (resp. a list of the minimal associated primes)
6661NOTE:    Algorithm of Gianni/Trager/Zacharias
6662EXAMPLE: example newDecompStep; shows an example
6663"
6664{
6665  intvec op,@vv;
6666  def  @P = basering;
6667  list primary,indep,ltras;
6668  intvec @vh,isat,@w;
6669  int @wr,@k,@n,@m,@n1,@n2,@n3,homo,seri,keepdi,abspri,ab,nn;
6670  ideal peek=i;
6671  ideal ser,tras;
6672  list data;
6673  list result;
6674  intvec @hilb;
6675  int isS=(attrib(i,"isSB")==1);
6676
6677  // Debug
6678  dbprint(printlevel - voice, "newDecompStep, v2.0");
6679
6680  string indepOption = "allIndep";
6681  string intersectOption = "noIntersect";
6682
6683  if(size(#)>0)
6684  {
6685    int count = 1;
6686    if(typeof(#[count]) == "string")
6687    {
6688      if ((#[count] == "oneIndep") or (#[count] == "allIndep"))
6689      {
6690        indepOption = #[count];
6691        count++;
6692      }
6693    }
6694    if(typeof(#[count]) == "string")
6695    {
6696      if ((#[count] == "intersect") or (#[count] == "noIntersect"))
6697      {
6698        intersectOption = #[count];
6699        count++;
6700      }
6701    }
6702    if((typeof(#[count]) == "int") or (typeof(#[count]) == "number"))
6703    {
6704      if ((#[count]==1)||(#[count]==2)||(#[count]==3))
6705      {
6706        @wr=#[count];
6707        if(@wr==3){abspri = 1; @wr = 0;}
6708        count++;
6709      }
6710    }
6711    if(size(#)>count)
6712    {
6713      seri=1;
6714      peek=#[count + 1];
6715      ser=#[count + 2];
6716    }
6717  }
6718  if(abspri)
6719  {
6720    list absprimary,abskeep,absprimarytmp,abskeeptmp;
6721  }
6722  homo=homog(i);
6723  if(homo==1)
6724  {
6725    if(attrib(i,"isSB")!=1)
6726    {
6727      //ltras=mstd(i);
6728      tras=groebner(i);
6729      ltras=tras,tras;
6730      attrib(ltras[1],"isSB",1);
6731    }
6732    else
6733    {
6734      ltras=i,i;
6735      attrib(ltras[1],"isSB",1);
6736    }
6737    tras = ltras[1];
6738    attrib(tras,"isSB",1);
6739    if(dim(tras)==0)
6740    {
6741      primary[1]=ltras[2];
6742      primary[2]=maxideal(1);
6743      if(@wr>0)
6744      {
6745        list l;
6746        l[2]=maxideal(1);
6747        l[1]=maxideal(1);
6748        if (intersectOption == "intersect")
6749        {
6750          return(list(l, maxideal(1)));
6751        }
6752        else
6753        {
6754          return(l);
6755        }
6756      }
6757      if (intersectOption == "intersect")
6758      {
6759        return(list(primary, primary[1]));
6760      }
6761      else
6762      {
6763        return(primary);
6764      }
6765    }
6766    for(@n=1;@n<=nvars(basering);@n++)
6767    {
6768      @w[@n]=ord(var(@n));
6769    }
6770    @hilb=hilb(tras,1,@w);
6771    intvec keephilb=@hilb;
6772  }
6773
6774  //----------------------------------------------------------------
6775  //i is the zero-ideal
6776  //----------------------------------------------------------------
6777
6778  if(size(i)==0)
6779  {
6780    primary=i,i;
6781    if (intersectOption == "intersect")
6782    {
6783      return(list(primary, i));
6784    }
6785    else
6786    {
6787      return(primary);
6788    }
6789  }
6790
6791  //----------------------------------------------------------------
6792  //pass to the lexicographical ordering and compute a standardbasis
6793  //----------------------------------------------------------------
6794
6795  int lp=islp();
6796
6797  execute("ring gnir = ("+charstr(basering)+"),("+varstr(basering)+"),(C,lp);");
6798  op=option(get);
6799  option(redSB);
6800
6801  ideal ser=fetch(@P,ser);
6802  if(homo==1)
6803  {
6804    if(!lp)
6805    {
6806      ideal @j=std(fetch(@P,i),@hilb,@w);
6807    }
6808    else
6809    {
6810      ideal @j=fetch(@P,tras);
6811      attrib(@j,"isSB",1);
6812    }
6813  }
6814  else
6815  {
6816    if(lp&&isS)
6817    {
6818      ideal @j=fetch(@P,i);
6819      attrib(@j,"isSB",1);
6820    }
6821    else
6822    {
6823      ideal @j=groebner(fetch(@P,i));
6824    }
6825  }
6826  option(set,op);
6827  if(seri==1)
6828  {
6829    ideal peek=fetch(@P,peek);
6830    attrib(peek,"isSB",1);
6831  }
6832  else
6833  {
6834    ideal peek=@j;
6835  }
6836  if((size(ser)==0)&&(!abspri))
6837  {
6838    ideal fried;
6839    @n=size(@j);
6840    for(@k=1;@k<=@n;@k++)
6841    {
6842      if(deg(lead(@j[@k]))==1)
6843      {
6844        fried[size(fried)+1]=@j[@k];
6845        @j[@k]=0;
6846      }
6847    }
6848    if(size(fried)==nvars(basering))
6849    {
6850      setring @P;
6851      primary[1]=i;
6852      primary[2]=i;
6853      if (intersectOption == "intersect")
6854      {
6855        return(list(primary, i));
6856      }
6857      else
6858      {
6859        return(primary);
6860      }
6861    }
6862    if(size(fried)>0)
6863    {
6864      string newva;
6865      string newma;
6866      for(@k=1;@k<=nvars(basering);@k++)
6867      {
6868        @n1=0;
6869        for(@n=1;@n<=size(fried);@n++)
6870        {
6871          if(leadmonom(fried[@n])==var(@k))
6872          {
6873            @n1=1;
6874            break;
6875          }
6876        }
6877        if(@n1==0)
6878        {
6879          newva=newva+string(var(@k))+",";
6880          newma=newma+string(var(@k))+",";
6881        }
6882        else
6883        {
6884          newma=newma+string(0)+",";
6885        }
6886      }
6887      newva[size(newva)]=")";
6888      newma[size(newma)]=";";
6889      execute("ring @deirf=("+charstr(gnir)+"),("+newva+",lp;");
6890      execute("map @kappa=gnir,"+newma);
6891      ideal @j= @kappa(@j);
6892      @j=simplify(@j, 2);
6893      attrib(@j,"isSB",1);
6894      result = newDecompStep(@j, indepOption, intersectOption, @wr);
6895      if (intersectOption == "intersect")
6896      {
6897       list pr = result[1];
6898       ideal intersection = result[2];
6899      }
6900      else
6901      {
6902        list pr = result;
6903      }
6904
6905      setring gnir;
6906      list pr=imap(@deirf,pr);
6907      for(@k=1;@k<=size(pr);@k++)
6908      {
6909        @j=pr[@k]+fried;
6910        pr[@k]=@j;
6911      }
6912      if (intersectOption == "intersect")
6913      {
6914        ideal intersection = imap(@deirf, intersection);
6915        @j = intersection + fried;
6916        intersection = @j;
6917      }
6918      setring @P;
6919      if (intersectOption == "intersect")
6920      {
6921        return(list(imap(gnir,pr), imap(gnir,intersection)));
6922      }
6923      else
6924      {
6925        return(imap(gnir,pr));
6926      }
6927    }
6928  }
6929  //----------------------------------------------------------------
6930  //j is the ring
6931  //----------------------------------------------------------------
6932
6933  if (dim(@j)==-1)
6934  {
6935    setring @P;
6936    primary=ideal(1),ideal(1);
6937    if (intersectOption == "intersect")
6938    {
6939      return(list(primary, ideal(1)));
6940    }
6941    else
6942    {
6943      return(primary);
6944    }
6945  }
6946
6947  //----------------------------------------------------------------
6948  //  the case of one variable
6949  //----------------------------------------------------------------
6950
6951  if(nvars(basering)==1)
6952  {
6953    list fac=factor(@j[1]);
6954    list gprimary;
6955    poly generator;
6956    ideal gIntersection;
6957    for(@k=1;@k<=size(fac[1]);@k++)
6958    {
6959      if(@wr==0)
6960      {
6961        gprimary[2*@k-1]=ideal(fac[1][@k]^fac[2][@k]);
6962        gprimary[2*@k]=ideal(fac[1][@k]);
6963      }
6964      else
6965      {
6966        gprimary[2*@k-1]=ideal(fac[1][@k]);
6967        gprimary[2*@k]=ideal(fac[1][@k]);
6968      }
6969      if (intersectOption == "intersect")
6970      {
6971        generator = generator * fac[1][@k];
6972      }
6973    }
6974    if (intersectOption == "intersect")
6975    {
6976      gIntersection = generator;
6977    }
6978    setring @P;
6979    primary=fetch(gnir,gprimary);
6980    if (intersectOption == "intersect")
6981    {
6982      ideal intersection = fetch(gnir,gIntersection);
6983    }
6984
6985//HIER
6986    if(abspri)
6987    {
6988      list resu,tempo;
6989      string absotto;
6990      for(ab=1;ab<=size(primary) div 2;ab++)
6991      {
6992        absotto= absFactorize(primary[2*ab][1],77);
6993        tempo=primary[2*ab-1],primary[2*ab],absotto,string(var(nvars(basering)));
6994        resu[ab]=tempo;
6995      }
6996      primary=resu;
6997      intersection = 1;
6998      for(ab=1;ab<=size(primary);ab++)
6999      {
7000        intersection = intersect(intersection, primary[ab][2]);
7001      }
7002    }
7003    if (intersectOption == "intersect")
7004    {
7005      return(list(primary, intersection));
7006    }
7007    else
7008    {
7009      return(primary);
7010    }
7011  }
7012
7013 //------------------------------------------------------------------
7014 //the zero-dimensional case
7015 //------------------------------------------------------------------
7016  if (dim(@j)==0)
7017  {
7018    op=option(get);
7019    option(redSB);
7020    list gprimary= newZero_decomp(@j,ser,@wr);
7021
7022    setring @P;
7023    primary=fetch(gnir,gprimary);
7024
7025    if(size(ser)>0)
7026    {
7027      primary=cleanPrimary(primary);
7028    }
7029//HIER
7030    if(abspri)
7031    {
7032      list resu,tempo;
7033      string absotto;
7034      for(ab=1;ab<=size(primary) div 2;ab++)
7035      {
7036        absotto= absFactorize(primary[2*ab][1],77);
7037        tempo=primary[2*ab-1],primary[2*ab],absotto,string(var(nvars(basering)));
7038        resu[ab]=tempo;
7039      }
7040      primary=resu;
7041    }
7042    option(set,op);
7043    if (intersectOption == "intersect")
7044    {
7045      return(list(primary, fetch(gnir,@j)));
7046    }
7047    else
7048    {
7049      return(primary);
7050    }
7051  }
7052
7053  poly @gs,@gh,@p;
7054  string @va,quotring;
7055  list quprimary,htprimary,collectprimary,lsau,lnew,allindep,restindep;
7056  ideal @h;
7057  int jdim=dim(@j);
7058  list fett;
7059  int lauf,di,newtest;
7060  //------------------------------------------------------------------
7061  //search for a maximal independent set indep,i.e.
7062  //look for subring such that the intersection with the ideal is zero
7063  //j intersected with K[var(indep[3]+1),...,var(nvar] is zero,
7064  //indep[1] is the new varstring and indep[2] the string for block-ordering
7065  //------------------------------------------------------------------
7066  if(@wr!=1)
7067  {
7068    allindep = newMaxIndependSetLp(@j, indepOption);
7069    for(@m=1;@m<=size(allindep);@m++)
7070    {
7071      if(allindep[@m][3]==jdim)
7072      {
7073        di++;
7074        indep[di]=allindep[@m];
7075      }
7076      else
7077      {
7078        lauf++;
7079        restindep[lauf]=allindep[@m];
7080      }
7081    }
7082  }
7083  else
7084  {
7085    indep = newMaxIndependSetLp(@j, indepOption);
7086  }
7087
7088  ideal jkeep=@j;
7089  if(ordstr(@P)[1]=="w")
7090  {
7091    execute("ring @Phelp=("+charstr(gnir)+"),("+varstr(gnir)+"),("+ordstr(@P)+");");
7092  }
7093  else
7094  {
7095    execute( "ring @Phelp=("+charstr(gnir)+"),("+varstr(gnir)+"),(C,dp);");
7096  }
7097
7098  if(homo==1)
7099  {
7100    if((ordstr(@P)[3]=="d")||(ordstr(@P)[1]=="d")||(ordstr(@P)[1]=="w")
7101       ||(ordstr(@P)[3]=="w"))
7102    {
7103      ideal jwork=imap(@P,tras);
7104      attrib(jwork,"isSB",1);
7105    }
7106    else
7107    {
7108      ideal jwork=std(imap(gnir,@j),@hilb,@w);
7109    }
7110  }
7111  else
7112  {
7113    ideal jwork=groebner(imap(gnir,@j));
7114  }
7115  list hquprimary;
7116  poly @p,@q;
7117  ideal @h,fac,ser;
7118//Aenderung================
7119  ideal @Ptest=1;
7120//=========================
7121  di=dim(jwork);
7122  keepdi=di;
7123
7124  ser = 1;
7125
7126  setring gnir;
7127  for(@m=1; @m<=size(indep); @m++)
7128  {
7129    data[1] = indep[@m];
7130    result = newReduction(@j, ser, @hilb, @w, jdim, abspri, @wr, data);
7131    quprimary = quprimary + result[1];
7132    if(abspri)
7133    {
7134      absprimary = absprimary + result[2];
7135      abskeep = abskeep + result[3];
7136    }
7137    @h = result[5];
7138    ser = result[4];
7139    if(size(@h)>0)
7140    {
7141      //---------------------------------------------------------------
7142      //we change to @Phelp to have the ordering dp for saturation
7143      //---------------------------------------------------------------
7144
7145      setring @Phelp;
7146      @h=imap(gnir,@h);
7147//Aenderung==================================
7148      if(defined(@LL)){kill @LL;}
7149      list @LL=minSat(jwork,@h);
7150      @Ptest=intersect(@Ptest,@LL[1]);
7151      ser = intersect(ser, @LL[1]);
7152//===========================================
7153
7154      if(@wr!=1)
7155      {
7156//Aenderung==================================
7157        @q=@LL[2];
7158//===========================================
7159        //@q=minSat(jwork,@h)[2];
7160      }
7161      else
7162      {
7163        fac=ideal(0);
7164        for(lauf=1;lauf<=ncols(@h);lauf++)
7165        {
7166          if(deg(@h[lauf])>0)
7167          {
7168            fac=fac+factorize(@h[lauf],1);
7169          }
7170        }
7171        fac=simplify(fac,6);
7172        @q=1;
7173        for(lauf=1;lauf<=size(fac);lauf++)
7174        {
7175          @q=@q*fac[lauf];
7176        }
7177      }
7178      jwork = std(jwork,@q);
7179      keepdi = dim(jwork);
7180      if(keepdi < di)
7181      {
7182        setring gnir;
7183        @j = imap(@Phelp, jwork);
7184        ser = imap(@Phelp, ser);
7185        break;
7186      }
7187      if(homo == 1)
7188      {
7189        @hilb = hilb(jwork, 1, @w);
7190      }
7191
7192      setring gnir;
7193      ser = imap(@Phelp, ser);
7194      @j = imap(@Phelp, jwork);
7195    }
7196  }
7197
7198  if((size(quprimary)==0)&&(@wr==1))
7199  {
7200     @j=ideal(1);
7201     quprimary[1]=ideal(1);
7202     quprimary[2]=ideal(1);
7203  }
7204  if((size(quprimary)==0))
7205  {
7206    keepdi = di - 1;
7207    quprimary[1]=ideal(1);
7208    quprimary[2]=ideal(1);
7209  }
7210  //---------------------------------------------------------------
7211  //notice that j=sat(j,gh) intersected with (j,gh^n)
7212  //we finished with sat(j,gh) and have to start with (j,gh^n)
7213  //---------------------------------------------------------------
7214  if((deg(@j[1])!=0)&&(@wr!=1))
7215  {
7216     if(size(quprimary)>0)
7217     {
7218        setring @Phelp;
7219        ser=imap(gnir,ser);
7220
7221        hquprimary=imap(gnir,quprimary);
7222        if(@wr==0)
7223        {
7224//Aenderung====================================================
7225//HIER STATT DURCHSCHNITT SATURIEREN!
7226           ideal htest=@Ptest;
7227/*
7228           ideal htest=hquprimary[1];
7229           for (@n1=2;@n1<=size(hquprimary) div 2;@n1++)
7230           {
7231              htest=intersect(htest,hquprimary[2*@n1-1]);
7232           }
7233*/
7234//=============================================================
7235        }
7236        else
7237        {
7238           ideal htest=hquprimary[2];
7239
7240           for (@n1=2;@n1<=size(hquprimary) div 2;@n1++)
7241           {
7242              htest=intersect(htest,hquprimary[2*@n1]);
7243           }
7244        }
7245
7246        if(size(ser)>0)
7247        {
7248           ser=intersect(htest,ser);
7249        }
7250        else
7251        {
7252          ser=htest;
7253        }
7254        setring gnir;
7255        ser=imap(@Phelp,ser);
7256     }
7257     if(size(reduce(ser,peek,1))!=0)
7258     {
7259        for(@m=1;@m<=size(restindep);@m++)
7260        {
7261         // if(restindep[@m][3]>=keepdi)
7262         // {
7263           isat=0;
7264           @n2=0;
7265
7266           if(restindep[@m][1]==varstr(basering))
7267           //the good case, nothing to do, just to have the same notations
7268           //change the ring
7269           {
7270              execute("ring gnir1 = ("+charstr(basering)+"),("+
7271                varstr(basering)+"),("+ordstr(basering)+");");
7272              ideal @j=fetch(gnir,jkeep);
7273              attrib(@j,"isSB",1);
7274           }
7275           else
7276           {
7277              @va=string(maxideal(1));
7278              execute("ring gnir1 = ("+charstr(basering)+"),("+
7279                      restindep[@m][1]+"),(" +restindep[@m][2]+");");
7280              execute("map phi=gnir,"+@va+";");
7281              op=option(get);
7282              option(redSB);
7283              if(homo==1)
7284              {
7285                 ideal @j=std(phi(jkeep),keephilb,@w);
7286              }
7287              else
7288              {
7289                ideal @j=groebner(phi(jkeep));
7290              }
7291              ideal ser=phi(ser);
7292              option(set,op);
7293           }
7294
7295           for (lauf=1;lauf<=size(@j);lauf++)
7296           {
7297              fett[lauf]=size(@j[lauf]);
7298           }
7299           //------------------------------------------------------------------
7300           //we have now the following situation:
7301           //j intersected with K[var(nnp+1),..,var(nva)] is zero so we may
7302           //pass to this quotientring, j is their still a standardbasis, the
7303           //leading coefficients of the polynomials  there (polynomials in
7304           //K[var(nnp+1),..,var(nva)]) are collected in the list h,
7305           //we need their ggt, gh, because of the following:
7306           //let (j:gh^n)=(j:gh^infinity) then
7307           //j*K(var(nnp+1),..,var(nva))[..the rest..]
7308           //intersected with K[var(1),...,var(nva)] is (j:gh^n)
7309           //on the other hand j=(j,gh^n) intersected with (j:gh^n)
7310
7311           //------------------------------------------------------------------
7312
7313           //the arrangement for the quotientring
7314           // K(var(nnp+1),..,var(nva))[..the rest..]
7315           //and the map phi:K[var(1),...,var(nva)] ---->
7316           //--->K(var(nnpr+1),..,var(nva))[..the rest..]
7317           //------------------------------------------------------------------
7318
7319           quotring=prepareQuotientring(nvars(basering)-restindep[@m][3]);
7320
7321           //------------------------------------------------------------------
7322           //we pass to the quotientring  K(var(nnp+1),..,var(nva))[..rest..]
7323           //------------------------------------------------------------------
7324
7325           execute(quotring);
7326
7327           // @j considered in the quotientring
7328           ideal @j=imap(gnir1,@j);
7329           ideal ser=imap(gnir1,ser);
7330
7331           kill gnir1;
7332
7333           //j is a standardbasis in the quotientring but usually not minimal
7334           //here it becomes minimal
7335           @j=clearSB(@j,fett);
7336           attrib(@j,"isSB",1);
7337
7338           //we need later ggt(h[1],...)=gh for saturation
7339           ideal @h;
7340
7341           for(@n=1;@n<=size(@j);@n++)
7342           {
7343              @h[@n]=leadcoef(@j[@n]);
7344           }
7345           //the primary decomposition of j*K(var(nnp+1),..,var(nva))[..rest..]
7346
7347           op=option(get);
7348           option(redSB);
7349           list uprimary= newZero_decomp(@j,ser,@wr);
7350//HIER
7351           if(abspri)
7352           {
7353              ideal II;
7354              ideal jmap;
7355              map sigma;
7356              nn=nvars(basering);
7357              map invsigma=basering,maxideal(1);
7358              for(ab=1;ab<=size(uprimary) div 2;ab++)
7359              {
7360                 II=uprimary[2*ab];
7361                 attrib(II,"isSB",1);
7362                 if(deg(II[1])!=vdim(II))
7363                 {
7364                    jmap=randomLast(50);
7365                    sigma=basering,jmap;
7366                    jmap[nn]=2*var(nn)-jmap[nn];
7367                    invsigma=basering,jmap;
7368                    II=groebner(sigma(II));
7369                  }
7370                  absprimarytmp[ab]= absFactorize(II[1],77);
7371                  II=var(nn);
7372                  abskeeptmp[ab]=string(invsigma(II));
7373                  invsigma=basering,maxideal(1);
7374              }
7375           }
7376           option(set,op);
7377
7378           //we need the intersection of the ideals in the list quprimary with
7379           //the polynomialring, i.e. let q=(f1,...,fr) in the quotientring
7380           //such an ideal but fi polynomials, then the intersection of q with
7381           //the polynomialring is the saturation of the ideal generated by
7382           //f1,...,fr with respect toh which is the lcm of the leading
7383           //coefficients of the fi considered in the quotientring:
7384           //this is coded in saturn
7385
7386           list saturn;
7387           ideal hpl;
7388
7389           for(@n=1;@n<=size(uprimary);@n++)
7390           {
7391              hpl=0;
7392              for(@n1=1;@n1<=size(uprimary[@n]);@n1++)
7393              {
7394                 hpl=hpl,leadcoef(uprimary[@n][@n1]);
7395              }
7396              saturn[@n]=hpl;
7397           }
7398           //------------------------------------------------------------------
7399           //we leave  the quotientring   K(var(nnp+1),..,var(nva))[..rest..]
7400           //back to the polynomialring
7401           //------------------------------------------------------------------
7402           setring gnir;
7403           collectprimary=imap(quring,uprimary);
7404           lsau=imap(quring,saturn);
7405           @h=imap(quring,@h);
7406
7407           kill quring;
7408
7409
7410           @n2=size(quprimary);
7411//================NEU=========================================
7412           if(deg(quprimary[1][1])<=0){ @n2=0; }
7413//============================================================
7414
7415           @n3=@n2;
7416
7417           for(@n1=1;@n1<=size(collectprimary) div 2;@n1++)
7418           {
7419              if(deg(collectprimary[2*@n1][1])>0)
7420              {
7421                 @n2++;
7422                 quprimary[@n2]=collectprimary[2*@n1-1];
7423                 lnew[@n2]=lsau[2*@n1-1];
7424                 @n2++;
7425                 lnew[@n2]=lsau[2*@n1];
7426                 quprimary[@n2]=collectprimary[2*@n1];
7427                 if(abspri)
7428                 {
7429                   absprimary[@n2 div 2]=absprimarytmp[@n1];
7430                   abskeep[@n2 div 2]=abskeeptmp[@n1];
7431                 }
7432              }
7433           }
7434
7435
7436           //here the intersection with the polynomialring
7437           //mentioned above is really computed
7438
7439           for(@n=@n3 div 2+1;@n<=@n2 div 2;@n++)
7440           {
7441              if(specialIdealsEqual(quprimary[2*@n-1],quprimary[2*@n]))
7442              {
7443                 quprimary[2*@n-1]=sat2(quprimary[2*@n-1],lnew[2*@n-1])[1];
7444                 quprimary[2*@n]=quprimary[2*@n-1];
7445              }
7446              else
7447              {
7448                 if(@wr==0)
7449                 {
7450                    quprimary[2*@n-1]=sat2(quprimary[2*@n-1],lnew[2*@n-1])[1];
7451                 }
7452                 quprimary[2*@n]=sat2(quprimary[2*@n],lnew[2*@n])[1];
7453              }
7454           }
7455           if(@n2>=@n3+2)
7456           {
7457              setring @Phelp;
7458              ser=imap(gnir,ser);
7459              hquprimary=imap(gnir,quprimary);
7460              for(@n=@n3 div 2+1;@n<=@n2 div 2;@n++)
7461              {
7462                if(@wr==0)
7463                {
7464                   ser=intersect(ser,hquprimary[2*@n-1]);
7465                }
7466                else
7467                {
7468                   ser=intersect(ser,hquprimary[2*@n]);
7469                }
7470              }
7471              setring gnir;
7472              ser=imap(@Phelp,ser);
7473           }
7474
7475         // }
7476        }
7477//HIER
7478        if(abspri)
7479        {
7480          list resu,tempo;
7481          for(ab=1;ab<=size(quprimary) div 2;ab++)
7482          {
7483             if (deg(quprimary[2*ab][1])!=0)
7484             {
7485               tempo=quprimary[2*ab-1],quprimary[2*ab],
7486                         absprimary[ab],abskeep[ab];
7487               resu[ab]=tempo;
7488             }
7489          }
7490          quprimary=resu;
7491          @wr=3;
7492        }
7493        if(size(reduce(ser,peek,1))!=0)
7494        {
7495           if(@wr>0)
7496           {
7497              // The following line was dropped to avoid the recursion step:
7498              //htprimary=newDecompStep(@j,@wr,peek,ser);
7499              htprimary = list();
7500           }
7501           else
7502           {
7503              // The following line was dropped to avoid the recursion step:
7504              //htprimary=newDecompStep(@j,peek,ser);
7505              htprimary = list();
7506           }
7507           // here we collect now both results primary(sat(j,gh))
7508           // and primary(j,gh^n)
7509           @n=size(quprimary);
7510           if (deg(quprimary[1][1])<=0) { @n=0; }
7511           for (@k=1;@k<=size(htprimary);@k++)
7512           {
7513              quprimary[@n+@k]=htprimary[@k];
7514           }
7515        }
7516     }
7517   }
7518   else
7519   {
7520      if(abspri)
7521      {
7522        list resu,tempo;
7523        for(ab=1;ab<=size(quprimary) div 2;ab++)
7524        {
7525           tempo=quprimary[2*ab-1],quprimary[2*ab],
7526                   absprimary[ab],abskeep[ab];
7527           resu[ab]=tempo;
7528        }
7529        quprimary=resu;
7530      }
7531   }
7532  //---------------------------------------------------------------------------
7533  //back to the ring we started with
7534  //the final result: primary
7535  //---------------------------------------------------------------------------
7536
7537  setring @P;
7538  primary=imap(gnir,quprimary);
7539
7540  if (intersectOption == "intersect")
7541  {
7542     return(list(primary, imap(gnir, ser)));
7543  }
7544  else
7545  {
7546    return(primary);
7547  }
7548}
7549example
7550{ "EXAMPLE:"; echo = 2;
7551   ring  r = 32003,(x,y,z),lp;
7552   poly  p = z2+1;
7553   poly  q = z4+2;
7554   ideal i = p^2*q^3,(y-z3)^3,(x-yz+z4)^4;
7555   list pr= newDecompStep(i);
7556   pr;
7557   testPrimary( pr, i);
7558}
7559
7560// This was part of proc decomp.
7561// In proc newDecompStep, used for the computation of the minimal associated primes,
7562// this part was separated as a soubrutine to make the code more clear.
7563// Also, since the reduction is performed twice in proc newDecompStep, it should use both times this routine.
7564// This is not yet implemented, since the reduction is not exactly the same and some changes should be made.
7565static proc newReduction(ideal @j, ideal ser, intvec @hilb, intvec @w, int jdim, int abspri, int @wr, list data)
7566{
7567   string @va;
7568   string quotring;
7569   intvec op;
7570   intvec @vv;
7571   def gnir = basering;
7572   ideal isat=0;
7573   int @n;
7574   int @n1 = 0;
7575   int @n2 = 0;
7576   int @n3 = 0;
7577   int homo = homog(@j);
7578   int lauf;
7579   int @k;
7580   list fett;
7581   int keepdi;
7582   list collectprimary;
7583   list lsau;
7584   list lnew;
7585   ideal @h;
7586
7587   list indepInfo = data[1];
7588   list quprimary = list();
7589
7590   //if(abspri)
7591   //{
7592     int ab;
7593     list absprimarytmp,abskeeptmp;
7594     list absprimary, abskeep;
7595   //}
7596   // Debug
7597   dbprint(printlevel - voice, "newReduction, v2.0");
7598
7599   if((indepInfo[1]==varstr(basering)))  // &&(@m==1)
7600   //this is the good case, nothing to do, just to have the same notations
7601   //change the ring
7602   {
7603     execute("ring gnir1 = ("+charstr(basering)+"),("+varstr(basering)+"),("
7604                              +ordstr(basering)+");");
7605     ideal @j = fetch(gnir, @j);
7606     attrib(@j,"isSB",1);
7607     ideal ser = fetch(gnir, ser);
7608   }
7609   else
7610   {
7611     @va=string(maxideal(1));
7612//Aenderung==============
7613     //if(@m==1)
7614     //{
7615     //  @j=fetch(@P,i);
7616     //}
7617//=======================
7618     execute("ring gnir1 = ("+charstr(basering)+"),("+indepInfo[1]+"),("
7619                              +indepInfo[2]+");");
7620     execute("map phi=gnir,"+@va+";");
7621     op=option(get);
7622     option(redSB);
7623     if(homo==1)
7624     {
7625       ideal @j=std(phi(@j),@hilb,@w);
7626     }
7627     else
7628     {
7629       ideal @j=groebner(phi(@j));
7630     }
7631     ideal ser=phi(ser);
7632
7633     option(set,op);
7634   }
7635   if((deg(@j[1])==0)||(dim(@j)<jdim))
7636   {
7637     setring gnir;
7638     break;
7639   }
7640   for (lauf=1;lauf<=size(@j);lauf++)
7641   {
7642     fett[lauf]=size(@j[lauf]);
7643   }
7644   //------------------------------------------------------------------------
7645   //we have now the following situation:
7646   //j intersected with K[var(nnp+1),..,var(nva)] is zero so we may pass
7647   //to this quotientring, j is their still a standardbasis, the
7648   //leading coefficients of the polynomials  there (polynomials in
7649   //K[var(nnp+1),..,var(nva)]) are collected in the list h,
7650   //we need their ggt, gh, because of the following: let
7651   //(j:gh^n)=(j:gh^infinity) then j*K(var(nnp+1),..,var(nva))[..the rest..]
7652   //intersected with K[var(1),...,var(nva)] is (j:gh^n)
7653   //on the other hand j=(j,gh^n) intersected with (j:gh^n)
7654
7655   //------------------------------------------------------------------------
7656
7657   //arrangement for quotientring K(var(nnp+1),..,var(nva))[..the rest..] and
7658   //map phi:K[var(1),...,var(nva)] --->K(var(nnpr+1),..,var(nva))[..rest..]
7659   //------------------------------------------------------------------------
7660
7661   quotring=prepareQuotientring(nvars(basering)-indepInfo[3]);
7662
7663   //---------------------------------------------------------------------
7664   //we pass to the quotientring   K(var(nnp+1),..,var(nva))[..the rest..]
7665   //---------------------------------------------------------------------
7666
7667   ideal @jj=lead(@j);               //!! vorn vereinbaren
7668   execute(quotring);
7669
7670   ideal @jj=imap(gnir1,@jj);
7671   @vv=clearSBNeu(@jj,fett);  //!! vorn vereinbaren
7672   setring gnir1;
7673   @k=size(@j);
7674   for (lauf=1;lauf<=@k;lauf++)
7675   {
7676     if(@vv[lauf]==1)
7677     {
7678       @j[lauf]=0;
7679     }
7680   }
7681   @j=simplify(@j,2);
7682   setring quring;
7683   // @j considered in the quotientring
7684   ideal @j=imap(gnir1,@j);
7685
7686   ideal ser=imap(gnir1,ser);
7687
7688   kill gnir1;
7689
7690   //j is a standardbasis in the quotientring but usually not minimal
7691   //here it becomes minimal
7692
7693   attrib(@j,"isSB",1);
7694
7695   //we need later ggt(h[1],...)=gh for saturation
7696   ideal @h;
7697   if(deg(@j[1])>0)
7698   {
7699     for(@n=1;@n<=size(@j);@n++)
7700     {
7701       @h[@n]=leadcoef(@j[@n]);
7702     }
7703     //the primary decomposition of j*K(var(nnp+1),..,var(nva))[..the rest..]
7704     op=option(get);
7705     option(redSB);
7706
7707     int zeroMinAss = @wr;
7708     if (@wr == 2) {zeroMinAss = 1;}
7709     list uprimary= newZero_decomp(@j, ser, zeroMinAss);
7710
7711//HIER
7712     if(abspri)
7713     {
7714       ideal II;
7715       ideal jmap;
7716       map sigma;
7717       nn=nvars(basering);
7718       map invsigma=basering,maxideal(1);
7719       for(ab=1;ab<=size(uprimary) div 2;ab++)
7720       {
7721         II=uprimary[2*ab];
7722         attrib(II,"isSB",1);
7723         if(deg(II[1])!=vdim(II))
7724         {
7725           jmap=randomLast(50);
7726           sigma=basering,jmap;
7727           jmap[nn]=2*var(nn)-jmap[nn];
7728           invsigma=basering,jmap;
7729           II=groebner(sigma(II));
7730         }
7731         absprimarytmp[ab]= absFactorize(II[1],77);
7732         II=var(nn);
7733         abskeeptmp[ab]=string(invsigma(II));
7734         invsigma=basering,maxideal(1);
7735       }
7736     }
7737     option(set,op);
7738   }
7739   else
7740   {
7741     list uprimary;
7742     uprimary[1]=ideal(1);
7743     uprimary[2]=ideal(1);
7744   }
7745   //we need the intersection of the ideals in the list quprimary with the
7746   //polynomialring, i.e. let q=(f1,...,fr) in the quotientring such an ideal
7747   //but fi polynomials, then the intersection of q with the polynomialring
7748   //is the saturation of the ideal generated by f1,...,fr with respect to
7749   //h which is the lcm of the leading coefficients of the fi considered in
7750   //in the quotientring: this is coded in saturn
7751
7752   list saturn;
7753   ideal hpl;
7754
7755   for(@n=1;@n<=size(uprimary);@n++)
7756   {
7757     uprimary[@n]=interred(uprimary[@n]); // temporary fix
7758     hpl=0;
7759     for(@n1=1;@n1<=size(uprimary[@n]);@n1++)
7760     {
7761       hpl=hpl,leadcoef(uprimary[@n][@n1]);
7762     }
7763     saturn[@n]=hpl;
7764   }
7765
7766   //--------------------------------------------------------------------
7767   //we leave  the quotientring   K(var(nnp+1),..,var(nva))[..the rest..]
7768   //back to the polynomialring
7769   //---------------------------------------------------------------------
7770   setring gnir;
7771
7772   collectprimary=imap(quring,uprimary);
7773   lsau=imap(quring,saturn);
7774   @h=imap(quring,@h);
7775
7776   kill quring;
7777
7778   @n2=size(quprimary);
7779   @n3=@n2;
7780
7781   for(@n1=1;@n1<=size(collectprimary) div 2;@n1++)
7782   {
7783     if(deg(collectprimary[2*@n1][1])>0)
7784     {
7785       @n2++;
7786       quprimary[@n2]=collectprimary[2*@n1-1];
7787       lnew[@n2]=lsau[2*@n1-1];
7788       @n2++;
7789       lnew[@n2]=lsau[2*@n1];
7790       quprimary[@n2]=collectprimary[2*@n1];
7791       if(abspri)
7792       {
7793         absprimary[@n2 div 2]=absprimarytmp[@n1];
7794         abskeep[@n2 div 2]=abskeeptmp[@n1];
7795       }
7796     }
7797   }
7798
7799   //here the intersection with the polynomialring
7800   //mentioned above is really computed
7801   for(@n=@n3 div 2+1;@n<=@n2 div 2;@n++)
7802   {
7803     if(specialIdealsEqual(quprimary[2*@n-1],quprimary[2*@n]))
7804     {
7805       quprimary[2*@n-1]=sat2(quprimary[2*@n-1],lnew[2*@n-1])[1];
7806       quprimary[2*@n]=quprimary[2*@n-1];
7807     }
7808     else
7809     {
7810       if(@wr==0)
7811       {
7812         quprimary[2*@n-1]=sat2(quprimary[2*@n-1],lnew[2*@n-1])[1];
7813       }
7814       quprimary[2*@n]=sat2(quprimary[2*@n],lnew[2*@n])[1];
7815     }
7816   }
7817
7818   return(quprimary, absprimary, abskeep, ser, @h);
7819}
7820
7821
7822////////////////////////////////////////////////////////////////////////////
7823
7824
7825
7826
7827///////////////////////////////////////////////////////////////////////////////
7828// Based on minAssGTZ
7829
7830proc minAss(ideal i,list #)
7831"USAGE:   minAss(I[, l]); i ideal, l list (optional) of parameters, same as minAssGTZ
7832RETURN:  a list, the minimal associated prime ideals of I.
7833NOTE:    Designed for characteristic 0, works also in char k > 0 based
7834         on an algorithm of Yokoyama
7835EXAMPLE: example minAss; shows an example
7836"
7837{
7838  return(minAssGTZ(i,#));
7839}
7840example
7841{ "EXAMPLE:";  echo = 2;
7842   ring  r = 0, (x, y, z), dp;
7843   poly  p = z2 + 1;
7844   poly  q = z3 + 2;
7845   ideal i = p * q^2, y - z2;
7846   list pr = minAss(i);
7847   pr;
7848}
7849
7850
7851///////////////////////////////////////////////////////////////////////////////
7852//
7853// Computes the minimal associated primes of I via Laplagne algorithm,
7854// using primary decomposition in the zero dimensional case.
7855// For reduction to the zerodimensional case, it uses the procedure
7856// decomp, with some modifications to avoid the recursion.
7857//
7858
7859static proc minAssSL(ideal I)
7860// Input = I, ideal
7861// Output = primaryDec where primaryDec is the list of the minimal
7862// associated primes and the primary components corresponding to these primes.
7863{
7864  ideal P = 1;
7865  list pd = list();
7866  int k;
7867  int stop = 0;
7868  list primaryDec = list();
7869
7870  while (stop == 0)
7871  {
7872    // Debug
7873    dbprint(printlevel - voice, "// We call minAssSLIteration to find new prime ideals!");
7874    pd = minAssSLIteration(I, P);
7875    // Debug
7876    dbprint(printlevel - voice, "// Output of minAssSLIteration:");
7877    dbprint(printlevel - voice, pd);
7878    if (size(pd[1]) > 0)
7879    {
7880      primaryDec = primaryDec + pd[1];
7881      // Debug
7882      dbprint(printlevel - voice, "// We intersect the prime ideals obtained.");
7883      P = intersect(P, pd[2]);
7884      // Debug
7885      dbprint(printlevel - voice, "// Intersection finished.");
7886    }
7887    else
7888    {
7889      stop = 1;
7890    }
7891  }
7892
7893  // Returns only the primary components, not the radical.
7894  return(primaryDec);
7895}
7896
7897///////////////////////////////////////////////////////////////////////////////
7898// Given an ideal I and an ideal P (intersection of some minimal prime ideals
7899// associated to I), it calculates new minimal prime ideals associated to I
7900// which were not used to calculate P.
7901// This version uses Primary Decomposition in the zerodimensional case.
7902static proc minAssSLIteration(ideal I, ideal P);
7903{
7904  int k = 1;
7905  int good  = 0;
7906  list primaryDec = list();
7907  // Debug
7908  dbprint (printlevel-voice, "// We search for an element in P - sqrt(I).");
7909  while ((k <= size(P)) and (good == 0))
7910  {
7911    good = 1 - rad_con(P[k], I);
7912    k++;
7913  }
7914  k--;
7915  if (good == 0)
7916  {
7917    // Debug
7918    dbprint (printlevel - voice, "// No element was found, P = sqrt(I).");
7919    return (list(primaryDec, ideal(0)));
7920  }
7921  // Debug
7922  dbprint (printlevel - voice, "// We found h = ", P[k]);
7923  dbprint (printlevel - voice, "// We calculate the saturation of I with respect to the element just founded.");
7924  ideal J = sat(I, P[k])[1];
7925
7926  // Uses decomp from primdec, modified to avoid the recursion.
7927  // Debug
7928  dbprint(printlevel - voice, "// We do the reduction to the zerodimensional case, via decomp.");
7929
7930  primaryDec = newDecompStep(J, "oneIndep", "intersect", 2);
7931  // Debug
7932  dbprint(printlevel - voice, "// Proc decomp has found", size(primaryDec) div 2, "new primary components.");
7933
7934  return(primaryDec);
7935}
7936
7937
7938
7939///////////////////////////////////////////////////////////////////////////////////
7940// Based on maxIndependSet
7941// Added list # as parameter
7942// If the first element of # is 0, the output is only 1 max indep set.
7943// If no list is specified or #[1] = 1, the output is all the max indep set of the
7944// leading terms ideal. This is the original output of maxIndependSet
7945
7946proc newMaxIndependSetLp(ideal j, list #)
7947"USAGE:   newMaxIndependentSetLp(i); i ideal (returns all maximal independent sets of the corresponding leading terms ideal)
7948          newMaxIndependentSetLp(i, 0); i ideal (returns only one maximal independent set)
7949RETURN:  list = #1. new varstring with the maximal independent set at the end,
7950                #2. ordstring with the lp ordering,
7951                #3. the number of independent variables
7952NOTE:
7953EXAMPLE: example newMaxIndependentSetLp; shows an example
7954"
7955{
7956  int n, k, di;
7957  list resu, hilf;
7958  string var1, var2;
7959  list v = indepSet(j, 0);
7960
7961  // SL 2006.04.21 1 Lines modified to use only one independent Set
7962  string indepOption;
7963  if (size(#) > 0)
7964  {
7965    indepOption = #[1];
7966  }
7967  else
7968  {
7969    indepOption = "allIndep";
7970  }
7971
7972  int nMax;
7973  if (indepOption == "allIndep")
7974  {
7975    nMax = size(v);
7976  }
7977  else
7978  {
7979    nMax = 1;
7980  }
7981
7982  for(n = 1; n <= nMax; n++)
7983  // SL 2006.04.21 2
7984  {
7985    di = 0;
7986    var1 = "";
7987    var2 = "";
7988    for(k = 1; k <= size(v[n]); k++)
7989    {
7990      if(v[n][k] != 0)
7991      {
7992        di++;
7993        var2 = var2 + "var(" + string(k) + "), ";
7994      }
7995      else
7996      {
7997        var1 = var1 + "var(" + string(k) + "), ";
7998      }
7999    }
8000    if(di > 0)
8001    {
8002      var1 = var1 + var2;
8003      var1 = var1[1..size(var1) - 2];       // The "- 2" removes the trailer comma
8004      hilf[1] = var1;
8005      // SL 2006.21.04 1 The order is now block dp instead of lp
8006      //hilf[2] = "dp(" + string(nvars(basering) - di) + "), dp(" + string(di) + ")";
8007      // SL 2006.21.04 2
8008      // For decomp, lp ordering is needed. Nothing is changed.
8009      hilf[2] = "lp";
8010      hilf[3] = di;
8011      resu[n] = hilf;
8012    }
8013    else
8014    {
8015      resu[n] = varstr(basering), ordstr(basering), 0;
8016    }
8017  }
8018  return(resu);
8019}
8020example
8021{ "EXAMPLE:"; echo = 2;
8022   ring s1 = (0, x, y), (a, b, c, d, e, f, g), lp;
8023   ideal i = ea - fbg, fa + be, ec - fdg, fc + de;
8024   i = std(i);
8025   list l = newMaxIndependSetLp(i);
8026   l;
8027   i = i, g;
8028   l = newMaxIndependSetLp(i);
8029   l;
8030
8031   ring s = 0, (x, y, z), lp;
8032   ideal i = z, yx;
8033   list l = newMaxIndependSetLp(i);
8034   l;
8035}
8036
8037
8038///////////////////////////////////////////////////////////////////////////////
8039
8040proc newZero_decomp (ideal j, ideal ser, int @wr, list #)
8041"USAGE:   newZero_decomp(j,ser,@wr); j,ser ideals, @wr=0 or 1
8042         (@wr=0 for primary decomposition, @wr=1 for computation of associated
8043         primes)
8044         if #[1] = "nest", then #[2] indicates the nest level (number of recursive calls)
8045         When the nest level is high it indicates that the computation is difficult,
8046         and different methods are applied.
8047RETURN:  list = list of primary ideals and their radicals (at even positions
8048         in the list) if the input is zero-dimensional and a standardbases
8049         with respect to lex-ordering
8050         If ser!=(0) and ser is contained in j or if j is not zero-dimen-
8051         sional then ideal(1),ideal(1) is returned
8052NOTE:    Algorithm of Gianni/Trager/Zacharias
8053EXAMPLE: example newZero_decomp; shows an example
8054"
8055{
8056  def   @P = basering;
8057  int uytrewq;
8058  int nva = nvars(basering);
8059  int @k,@s,@n,@k1,zz;
8060  list primary,lres0,lres1,act,@lh,@wh;
8061  map phi,psi,phi1,psi1;
8062  ideal jmap,jmap1,jmap2,helpprim,@qh,@qht,ser1;
8063  intvec @vh,@hilb;
8064  string @ri;
8065  poly @f;
8066
8067  // Debug
8068  dbprint(printlevel - voice, "proc newZero_decomp");
8069
8070  if (dim(j)>0)
8071  {
8072    primary[1]=ideal(1);
8073    primary[2]=ideal(1);
8074    return(primary);
8075  }
8076  j=interred(j);
8077
8078  attrib(j,"isSB",1);
8079
8080  int nestLevel = 0;
8081  if (size(#) > 0)
8082  {
8083    if (typeof(#[1]) == "string")
8084    {
8085      if (#[1] == "nest")
8086      {
8087        nestLevel = #[2];
8088      }
8089      # = list();
8090    }
8091  }
8092
8093  if(vdim(j)==deg(j[1]))
8094  {
8095    act=factor(j[1]);
8096    for(@k=1;@k<=size(act[1]);@k++)
8097    {
8098      @qh=j;
8099      if(@wr==0)
8100      {
8101        @qh[1]=act[1][@k]^act[2][@k];
8102      }
8103      else
8104      {
8105        @qh[1]=act[1][@k];
8106      }
8107      primary[2*@k-1]=interred(@qh);
8108      @qh=j;
8109      @qh[1]=act[1][@k];
8110      primary[2*@k]=interred(@qh);
8111      attrib( primary[2*@k-1],"isSB",1);
8112
8113      if((size(ser)>0)&&(size(reduce(ser,primary[2*@k-1],1))==0))
8114      {
8115        primary[2*@k-1]=ideal(1);
8116        primary[2*@k]=ideal(1);
8117      }
8118    }
8119    return(primary);
8120  }
8121
8122  if(homog(j)==1)
8123  {
8124    primary[1]=j;
8125    if((size(ser)>0)&&(size(reduce(ser,j,1))==0))
8126    {
8127      primary[1]=ideal(1);
8128      primary[2]=ideal(1);
8129      return(primary);
8130    }
8131    if(dim(j)==-1)
8132    {
8133      primary[1]=ideal(1);
8134      primary[2]=ideal(1);
8135    }
8136    else
8137    {
8138      primary[2]=maxideal(1);
8139    }
8140    return(primary);
8141  }
8142
8143//the first element in the standardbase is factorized
8144  if(deg(j[1])>0)
8145  {
8146    act=factor(j[1]);
8147    testFactor(act,j[1]);
8148  }
8149  else
8150  {
8151    primary[1]=ideal(1);
8152    primary[2]=ideal(1);
8153    return(primary);
8154  }
8155
8156//with the factors new ideals (hopefully the primary decomposition)
8157//are created
8158  if(size(act[1])>1)
8159  {
8160    if(size(#)>1)
8161    {
8162      primary[1]=ideal(1);
8163      primary[2]=ideal(1);
8164      primary[3]=ideal(1);
8165      primary[4]=ideal(1);
8166      return(primary);
8167    }
8168    for(@k=1;@k<=size(act[1]);@k++)
8169    {
8170      if(@wr==0)
8171      {
8172        primary[2*@k-1]=std(j,act[1][@k]^act[2][@k]);
8173      }
8174      else
8175      {
8176        primary[2*@k-1]=std(j,act[1][@k]);
8177      }
8178      if((act[2][@k]==1)&&(vdim(primary[2*@k-1])==deg(act[1][@k])))
8179      {
8180        primary[2*@k]   = primary[2*@k-1];
8181      }
8182      else
8183      {
8184        primary[2*@k]   = primaryTest(primary[2*@k-1],act[1][@k]);
8185      }
8186    }
8187  }
8188  else
8189  {
8190    primary[1]=j;
8191    if((size(#)>0)&&(act[2][1]>1))
8192    {
8193      act[2]=1;
8194      primary[1]=std(primary[1],act[1][1]);
8195    }
8196    if(@wr!=0)
8197    {
8198      primary[1]=std(j,act[1][1]);
8199    }
8200    if((act[2][1]==1)&&(vdim(primary[1])==deg(act[1][1])))
8201    {
8202      primary[2]=primary[1];
8203    }
8204    else
8205    {
8206      primary[2]=primaryTest(primary[1],act[1][1]);
8207    }
8208  }
8209
8210  if(size(#)==0)
8211  {
8212    primary=splitPrimary(primary,ser,@wr,act);
8213  }
8214
8215  if((voice>=6)&&(char(basering)<=181))
8216  {
8217    primary=splitCharp(primary);
8218  }
8219
8220  if((@wr==2)&&(npars(basering)>0)&&(voice>=6)&&(char(basering)>0))
8221  {
8222  //the prime decomposition of Yokoyama in characteristic p
8223    list ke,ek;
8224    @k=0;
8225    while(@k<size(primary) div 2)
8226    {
8227      @k++;
8228      if(size(primary[2*@k])==0)
8229      {
8230        ek=insepDecomp(primary[2*@k-1]);
8231        primary=delete(primary,2*@k);
8232        primary=delete(primary,2*@k-1);
8233        @k--;
8234      }
8235      ke=ke+ek;
8236    }
8237    for(@k=1;@k<=size(ke);@k++)
8238    {
8239      primary[size(primary)+1]=ke[@k];
8240      primary[size(primary)+1]=ke[@k];
8241    }
8242  }
8243
8244  if(nestLevel > 1){primary=extF(primary);}
8245
8246//test whether all ideals in the decomposition are primary and
8247//in general position
8248//if not after a random coordinate transformation of the last
8249//variable the corresponding ideal is decomposed again.
8250  if((npars(basering)>0)&&(nestLevel > 1))
8251  {
8252    poly randp;
8253    for(zz=1;zz<nvars(basering);zz++)
8254    {
8255      randp=randp
8256              +(random(0,5)*par(1)^2+random(0,5)*par(1)+random(0,5))*var(zz);
8257    }
8258    randp=randp+var(nvars(basering));
8259  }
8260  @k=0;
8261  while(@k<(size(primary) div 2))
8262  {
8263    @k++;
8264    if (size(primary[2*@k])==0)
8265    {
8266      for(zz=1;zz<size(primary[2*@k-1])-1;zz++)
8267      {
8268        attrib(primary[2*@k-1],"isSB",1);
8269        if(vdim(primary[2*@k-1])==deg(primary[2*@k-1][zz]))
8270        {
8271          primary[2*@k]=primary[2*@k-1];
8272        }
8273      }
8274    }
8275  }
8276
8277  @k=0;
8278  ideal keep;
8279  while(@k<(size(primary) div 2))
8280  {
8281    @k++;
8282    if (size(primary[2*@k])==0)
8283    {
8284      jmap=randomLast(100);
8285      jmap1=maxideal(1);
8286      jmap2=maxideal(1);
8287      @qht=primary[2*@k-1];
8288      if((npars(basering)>0)&&(nestLevel > 1))
8289      {
8290        jmap[size(jmap)]=randp;
8291      }
8292
8293      for(@n=2;@n<=size(primary[2*@k-1]);@n++)
8294      {
8295        if(deg(lead(primary[2*@k-1][@n]))==1)
8296        {
8297          for(zz=1;zz<=nva;zz++)
8298          {
8299            if(lead(primary[2*@k-1][@n])/var(zz)!=0)
8300            {
8301              jmap1[zz]=-1/leadcoef(primary[2*@k-1][@n])*primary[2*@k-1][@n]
8302                   +2/leadcoef(primary[2*@k-1][@n])*lead(primary[2*@k-1][@n]);
8303              jmap2[zz]=primary[2*@k-1][@n];
8304              @qht[@n]=var(zz);
8305            }
8306          }
8307          jmap[nva]=subst(jmap[nva],lead(primary[2*@k-1][@n]),0);
8308        }
8309      }
8310      if(size(subst(jmap[nva],var(1),0)-var(nva))!=0)
8311      {
8312        // jmap[nva]=subst(jmap[nva],var(1),0);
8313        //hier geaendert +untersuchen!!!!!!!!!!!!!!
8314      }
8315      phi1=@P,jmap1;
8316      phi=@P,jmap;
8317      for(@n=1;@n<=nva;@n++)
8318      {
8319        jmap[@n]=-(jmap[@n]-2*var(@n));
8320      }
8321      psi=@P,jmap;
8322      psi1=@P,jmap2;
8323      @qh=phi(@qht);
8324
8325//=================== the new part ============================
8326
8327      if (npars(basering)>1) { @qh=groebner(@qh,"par2var"); }
8328      else                   { @qh=groebner(@qh); }
8329
8330//=============================================================
8331//       if(npars(@P)>0)
8332//       {
8333//          @ri= "ring @Phelp ="
8334//                  +string(char(@P))+",
8335//                   ("+varstr(@P)+","+parstr(@P)+",@t),(C,dp);";
8336//       }
8337//       else
8338//       {
8339//          @ri= "ring @Phelp ="
8340//                  +string(char(@P))+",("+varstr(@P)+",@t),(C,dp);";
8341//       }
8342//       execute(@ri);
8343//       ideal @qh=homog(imap(@P,@qht),@t);
8344//
8345//       ideal @qh1=std(@qh);
8346//       @hilb=hilb(@qh1,1);
8347//       @ri= "ring @Phelp1 ="
8348//                  +string(char(@P))+",("+varstr(@Phelp)+"),(C,lp);";
8349//       execute(@ri);
8350//       ideal @qh=homog(imap(@P,@qh),@t);
8351//       kill @Phelp;
8352//       @qh=std(@qh,@hilb);
8353//       @qh=subst(@qh,@t,1);
8354//       setring @P;
8355//       @qh=imap(@Phelp1,@qh);
8356//       kill @Phelp1;
8357//       @qh=clearSB(@qh);
8358//       attrib(@qh,"isSB",1);
8359//=============================================================
8360
8361      ser1=phi1(ser);
8362      @lh=newZero_decomp (@qh,phi(ser1),@wr, list("nest", nestLevel + 1));
8363
8364      kill lres0;
8365      list lres0;
8366      if(size(@lh)==2)
8367      {
8368        helpprim=@lh[2];
8369        lres0[1]=primary[2*@k-1];
8370        ser1=psi(helpprim);
8371        lres0[2]=psi1(ser1);
8372        if(size(reduce(lres0[2],lres0[1],1))==0)
8373        {
8374          primary[2*@k]=primary[2*@k-1];
8375          continue;
8376        }
8377      }
8378      else
8379      {
8380        lres1=psi(@lh);
8381        lres0=psi1(lres1);
8382      }
8383
8384//=================== the new part ============================
8385
8386      primary=delete(primary,2*@k-1);
8387      primary=delete(primary,2*@k-1);
8388      @k--;
8389      if(size(lres0)==2)
8390      {
8391        if (npars(basering)>1) { lres0[2]=groebner(lres0[2],"par2var"); }
8392        else                   { lres0[2]=groebner(lres0[2]); }
8393      }
8394      else
8395      {
8396        for(@n=1;@n<=size(lres0) div 2;@n++)
8397        {
8398          if(specialIdealsEqual(lres0[2*@n-1],lres0[2*@n])==1)
8399          {
8400            lres0[2*@n-1]=groebner(lres0[2*@n-1]);
8401            lres0[2*@n]=lres0[2*@n-1];
8402            attrib(lres0[2*@n],"isSB",1);
8403          }
8404          else
8405          {
8406            lres0[2*@n-1]=groebner(lres0[2*@n-1]);
8407            lres0[2*@n]=groebner(lres0[2*@n]);
8408          }
8409        }
8410      }
8411      primary=primary+lres0;
8412
8413//=============================================================
8414//       if(npars(@P)>0)
8415//       {
8416//          @ri= "ring @Phelp ="
8417//                  +string(char(@P))+",
8418//                   ("+varstr(@P)+","+parstr(@P)+",@t),(C,dp);";
8419//       }
8420//       else
8421//       {
8422//          @ri= "ring @Phelp ="
8423//                  +string(char(@P))+",("+varstr(@P)+",@t),(C,dp);";
8424//       }
8425//       execute(@ri);
8426//       list @lvec;
8427//       list @lr=imap(@P,lres0);
8428//       ideal @lr1;
8429//
8430//       if(size(@lr)==2)
8431//       {
8432//          @lr[2]=homog(@lr[2],@t);
8433//          @lr1=std(@lr[2]);
8434//          @lvec[2]=hilb(@lr1,1);
8435//       }
8436//       else
8437//       {
8438//          for(@n=1;@n<=size(@lr) div 2;@n++)
8439//          {
8440//             if(specialIdealsEqual(@lr[2*@n-1],@lr[2*@n])==1)
8441//             {
8442//                @lr[2*@n-1]=homog(@lr[2*@n-1],@t);
8443//                @lr1=std(@lr[2*@n-1]);
8444//                @lvec[2*@n-1]=hilb(@lr1,1);
8445//                @lvec[2*@n]=@lvec[2*@n-1];
8446//             }
8447//             else
8448//             {
8449//                @lr[2*@n-1]=homog(@lr[2*@n-1],@t);
8450//                @lr1=std(@lr[2*@n-1]);
8451//                @lvec[2*@n-1]=hilb(@lr1,1);
8452//                @lr[2*@n]=homog(@lr[2*@n],@t);
8453//                @lr1=std(@lr[2*@n]);
8454//                @lvec[2*@n]=hilb(@lr1,1);
8455//
8456//             }
8457//         }
8458//       }
8459//       @ri= "ring @Phelp1 ="
8460//                  +string(char(@P))+",("+varstr(@Phelp)+"),(C,lp);";
8461//       execute(@ri);
8462//       list @lr=imap(@Phelp,@lr);
8463//
8464//       kill @Phelp;
8465//       if(size(@lr)==2)
8466//      {
8467//          @lr[2]=std(@lr[2],@lvec[2]);
8468//          @lr[2]=subst(@lr[2],@t,1);
8469//
8470//       }
8471//       else
8472//       {
8473//          for(@n=1;@n<=size(@lr) div 2;@n++)
8474//          {
8475//             if(specialIdealsEqual(@lr[2*@n-1],@lr[2*@n])==1)
8476//             {
8477//                @lr[2*@n-1]=std(@lr[2*@n-1],@lvec[2*@n-1]);
8478//                @lr[2*@n-1]=subst(@lr[2*@n-1],@t,1);
8479//                @lr[2*@n]=@lr[2*@n-1];
8480//                attrib(@lr[2*@n],"isSB",1);
8481//             }
8482//             else
8483//             {
8484//                @lr[2*@n-1]=std(@lr[2*@n-1],@lvec[2*@n-1]);
8485//                @lr[2*@n-1]=subst(@lr[2*@n-1],@t,1);
8486//                @lr[2*@n]=std(@lr[2*@n],@lvec[2*@n]);
8487//                @lr[2*@n]=subst(@lr[2*@n],@t,1);
8488//             }
8489//          }
8490//       }
8491//       kill @lvec;
8492//       setring @P;
8493//       lres0=imap(@Phelp1,@lr);
8494//       kill @Phelp1;
8495//       for(@n=1;@n<=size(lres0);@n++)
8496//       {
8497//          lres0[@n]=clearSB(lres0[@n]);
8498//          attrib(lres0[@n],"isSB",1);
8499//       }
8500//
8501//       primary[2*@k-1]=lres0[1];
8502//       primary[2*@k]=lres0[2];
8503//       @s=size(primary) div 2;
8504//       for(@n=1;@n<=size(lres0) div 2-1;@n++)
8505//       {
8506//         primary[2*@s+2*@n-1]=lres0[2*@n+1];
8507//         primary[2*@s+2*@n]=lres0[2*@n+2];
8508//       }
8509//       @k--;
8510//=============================================================
8511    }
8512  }
8513  return(primary);
8514}
8515example
8516{ "EXAMPLE:"; echo = 2;
8517   ring  r = 0,(x,y,z),lp;
8518   poly  p = z2+1;
8519   poly  q = z4+2;
8520   ideal i = p^2*q^3,(y-z3)^3,(x-yz+z4)^4;
8521   i=std(i);
8522   list  pr= newZero_decomp(i,ideal(0),0);
8523   pr;
8524}
8525///////////////////////////////////////////////////////////////////////////////
8526
8527////////////////////////////////////////////////////////////////////////////
8528/*
8529//Beispiele Wenk-Dipl (in ~/Texfiles/Diplom/Wenk/Examples/)
8530//Zeiten: Singular/Singular/Singular -r123456789 -v :wilde13 (PentiumPro200)
8531//Singular for HPUX-9 version 1-3-8  (2000060214)  Jun  2 2000 15:31:26
8532//(wilde13)
8533
8534//1. vdim=20, 3  Komponenten
8535//zerodec-time:2(1)  (matrix:1 charpoly:0 factor:1)
8536//primdecGTZ-time: 1(0)
8537ring rs= 0,(a,b,c),dp;
8538poly f1= a^2*b*c + a*b^2*c + a*b*c^2 + a*b*c + a*b + a*c + b*c;
8539poly f2= a^2*b^2*c + a*b^2*c^2 + a^2*b*c + a*b*c + b*c + a + c;
8540poly f3= a^2*b^2*c^2 + a^2*b^2*c + a*b^2*c + a*b*c + a*c + c + 1;
8541ideal gls=f1,f2,f3;
8542int time=timer;
8543printlevel =1;
8544time=timer; list pr1=zerodec(gls); timer-time;size(pr1);
8545time=timer; list pr =primdecGTZ(gls); timer-time;size(pr);
8546time=timer; ideal ra =radical(gls); timer-time;size(pr);
8547
8548//2.cyclic5  vdim=70, 20 Komponenten
8549//zerodec-time:36(28)  (matrix:1(0) charpoly:18(19) factor:17(9)
8550//primdecGTZ-time: 28(5)
8551//radical : 0
8552ring rs= 0,(a,b,c,d,e),dp;
8553poly f0= a + b + c + d + e + 1;
8554poly f1= a + b + c + d + e;
8555poly f2= a*b + b*c + c*d + a*e + d*e;
8556poly f3= a*b*c + b*c*d + a*b*e + a*d*e + c*d*e;
8557poly f4= a*b*c*d + a*b*c*e + a*b*d*e + a*c*d*e + b*c*d*e;
8558poly f5= a*b*c*d*e - 1;
8559ideal gls= f1,f2,f3,f4,f5;
8560
8561//3. random vdim=40, 1 Komponente
8562//zerodec-time:126(304)  (matrix:1 charpoly:115(298) factor:10(5))
8563//primdecGTZ-time:17 (11)
8564ring rs=0,(x,y,z),dp;
8565poly f1=2*x^2 + 4*x + 3*y^2 + 7*x*z + 9*y*z + 5*z^2;
8566poly f2=7*x^3 + 8*x*y + 12*y^2 + 18*x*z + 3*y^4*z + 10*z^3 + 12;
8567poly f3=3*x^4 + 1*x*y*z + 6*y^3 + 3*x*z^2 + 2*y*z^2 + 4*z^2 + 5;
8568ideal gls=f1,f2,f3;
8569
8570//4. introduction into resultants, sturmfels, vdim=28, 1 Komponente
8571//zerodec-time:4  (matrix:0 charpoly:0 factor:4)
8572//primdecGTZ-time:1
8573ring rs=0,(x,y),dp;
8574poly f1= x4+y4-1;
8575poly f2= x5y2-4x3y3+x2y5-1;
8576ideal gls=f1,f2;
8577
8578//5. 3 quadratic equations with random coeffs, vdim=8, 1 Komponente
8579//zerodec-time:0(0)  (matrix:0 charpoly:0 factor:0)
8580//primdecGTZ-time:1(0)
8581ring rs=0,(x,y,z),dp;
8582poly f1=2*x^2 + 4*x*y + 3*y^2 + 7*x*z + 9*y*z + 5*z^2 + 2;
8583poly f2=7*x^2 + 8*x*y + 12*y^2 + 18*x*z + 3*y*z + 10*z^2 + 12;
8584poly f3=3*x^2 + 1*x*y + 6*y^2 + 3*x*z + 2*y*z + 4*z^2 + 5;
8585ideal gls=f1,f2,f3;
8586
8587//6. 3 polys    vdim=24, 1 Komponente
8588// run("ex14",2);
8589//zerodec-time:5(4)  (matrix:0 charpoly:3(3) factor:2(1))
8590//primdecGTZ-time:4 (2)
8591ring rs=0,(x1,x2,x3,x4),dp;
8592poly f1=16*x1^2 + 3*x2^2 + 5*x3^4 - 1 - 4*x4 + x4^3;
8593poly f2=5*x1^3 + 3*x2^2 + 4*x3^2*x4 + 2*x1*x4 - 1 + x4 + 4*x1 + x2 + x3 + x4;
8594poly f3=-4*x1^2 + x2^2 + x3^2 - 3 + x4^2 + 4*x1 + x2 + x3 + x4;
8595poly f4=-4*x1 + x2 + x3 + x4;
8596ideal gls=f1,f2,f3,f4;
8597
8598//7. ex43, PoSSo, caprasse   vdim=56, 16 Komponenten
8599//zerodec-time:23(15)  (matrix:0 charpoly:16(13) factor:3(2))
8600//primdecGTZ-time:3 (2)
8601ring rs= 0,(y,z,x,t),dp;
8602ideal gls=y^2*z+2*y*x*t-z-2*x,
86034*y^2*z*x-z*x^3+2*y^3*t+4*y*x^2*t-10*y^2+4*z*x+4*x^2-10*y*t+2,
86042*y*z*t+x*t^2-2*z-x,
8605-z^3*x+4*y*z^2*t+4*z*x*t^2+2*y*t^3+4*z^2+4*z*x-10*y*t-10*t^2+2;
8606
8607//8. Arnborg-System, n=6 (II),    vdim=156, 90 Komponenten
8608//zerodec-time (char32003):127(45)(matrix:2(0) charpoly:106(37) factor:16(7))
8609//primdecGTZ-time(char32003) :81 (18)
8610//ring rs= 0,(a,b,c,d,x,f),dp;
8611ring rs= 32003,(a,b,c,d,x,f),dp;
8612ideal gls=a+b+c+d+x+f, ab+bc+cd+dx+xf+af, abc+bcd+cdx+d*xf+axf+abf,
8613abcd+bcdx+cd*xf+ad*xf+abxf+abcf, abcdx+bcd*xf+acd*xf+abd*xf+abcxf+abcdf,
8614abcd*xf-1;
8615
8616//9. ex42, PoSSo, Methan6_1, vdim=27, 2 Komponenten
8617//zerodec-time:610  (matrix:10 charpoly:557 factor:26)
8618//primdecGTZ-time: 118
8619//zerodec-time(char32003):2
8620//primdecGTZ-time(char32003):4
8621//ring rs= 0,(x1,x2,x3,x4,x5,x6,x7,x8,x9,x10),dp;
8622ring rs= 32003,(x1,x2,x3,x4,x5,x6,x7,x8,x9,x10),dp;
8623ideal gls=64*x2*x7-10*x1*x8+10*x7*x9+11*x7*x10-320000*x1,
8624-32*x2*x7-5*x2*x8-5*x2*x10+160000*x1-5000*x2,
8625-x3*x8+x6*x8+x9*x10+210*x6+1300000,
8626-x4*x8+700000,
8627x10^2-2*x5,
8628-x6*x8+x7*x9-210*x6,
8629-64*x2*x7-10*x7*x9-11*x7*x10+320000*x1-16*x7+7000000,
8630-10*x1*x8-10*x2*x8-10*x3*x8-10*x4*x8-10*x6*x8+10*x2*x10+11*x7*x10
8631    +20000*x2+14*x5,
8632x4*x8-x7*x9-x9*x10-410*x9,
863310*x2*x8+10*x3*x8+10*x6*x8+10*x7*x9-10*x2*x10-11*x7*x10-10*x9*x10
8634    -10*x10^2+1400*x6-4200*x10;
8635
8636//10. ex33, walk-s7, Diplomarbeit von Tim, vdim=114
8637//zerfaellt in unterschiedlich viele Komponenten in versch. Charkteristiken:
8638//char32003:30, char0:3(2xdeg1,1xdeg112!), char181:4(2xdeg1,1xdeg28,1xdeg84)
8639//char 0: zerodec-time:10075 (ca 3h) (matrix:3 charpoly:9367, factor:680
8640//        + 24 sec fuer Normalform (anstatt einsetzen), total [29623k])
8641//        primdecGTZ-time: 214
8642//char 32003:zerodec-time:197(68) (matrix:2(1) charpoly:173(60) factor:15(6))
8643//        primdecGTZ-time:14 (5)
8644//char 181:zerodec-time:(87) (matrix:(1) charpoly:(58) factor:(25))
8645//        primdecGTZ-time:(2)
8646//in char181 stimmen Ergebnisse von zerodec und primdecGTZ ueberein (gecheckt)
8647
8648//ring rs= 0,(a,b,c,d,e,f,g),dp;
8649ring rs= 32003,(a,b,c,d,e,f,g),dp;
8650poly f1= 2gb + 2fc + 2ed + a2 + a;
8651poly f2= 2gc + 2fd + e2 + 2ba + b;
8652poly f3= 2gd + 2fe + 2ca + c + b2;
8653poly f4= 2ge + f2 + 2da + d + 2cb;
8654poly f5= 2fg + 2ea + e + 2db + c2;
8655poly f6= g2 + 2fa + f + 2eb + 2dc;
8656poly f7= 2ga + g + 2fb + 2ec + d2;
8657ideal gls= f1,f2,f3,f4,f5,f6,f7;
8658
8659~/Singular/Singular/Singular -r123456789 -v
8660LIB"./primdec.lib";
8661timer=1;
8662int time=timer;
8663printlevel =1;
8664option(prot,mem);
8665time=timer; list pr1=zerodec(gls); timer-time;
8666
8667time=timer; list pr =primdecGTZ(gls); timer-time;
8668time=timer; list pr =primdecSY(gls); timer-time;
8669time=timer; ideal ra =radical(gls); timer-time;size(pr);
8670LIB"all.lib";
8671
8672ring R=0,(a,b,c,d,e,f),dp;
8673ideal I=cyclic(6);
8674minAssGTZ(I);
8675
8676
8677ring S=(2,a,b),(x,y),lp;
8678ideal I=x8-b,y4+a;
8679minAssGTZ(I);
8680
8681ring S1=2,(x,y,a,b),lp;
8682ideal I=x8-b,y4+a;
8683minAssGTZ(I);
8684
8685
8686ring S2=(2,z),(x,y),dp;
8687minpoly=z2+z+1;
8688ideal I=y3+y+1,x4+x+1;
8689primdecGTZ(I);
8690minAssGTZ(I);
8691
8692ring S3=2,(x,y,z),dp;
8693ideal I=y3+y+1,x4+x+1,z2+z+1;
8694primdecGTZ(I);
8695minAssGTZ(I);
8696
8697
8698ring R1=2,(x,y,z),lp;
8699ideal I=y6+y5+y3+y2+1,x4+x+1,z2+z+1;
8700primdecGTZ(I);
8701minAssGTZ(I);
8702
8703
8704ring R2=(2,z),(x,y),lp;
8705minpoly=z3+z+1;
8706ideal I=y2+y+(z2+z+1),x4+x+1;
8707primdecGTZ(I);
8708minAssGTZ(I);
8709
8710*/
Note: See TracBrowser for help on using the repository browser.