source: git/Singular/LIB/primdec.lib @ ca1650

spielwiese
Last change on this file since ca1650 was ca1650, checked in by Jakob Kröker <kroeker@…>, 10 years ago
fix bug 597
  • Property mode set to 100644
File size: 214.4 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     matrix f=transpose(re[n+1]);      //Hom(_,R)
3998     module k=nres(f,2)[2];            //the kernel
3999     matrix g=transpose(re[n]);        //the image of Hom(_,R)
4000
4001     ideal ann=quotient1(g,k);           //the anihilator
4002  }
4003  else
4004  {
4005     ideal ann=Ann(transpose(re[n]));
4006  }
4007  return(ann);
4008}
4009///////////////////////////////////////////////////////////////////////////////
4010
4011static proc analyze(list pr)
4012{
4013   int ii,jj;
4014   for(ii=1;ii<=size(pr) div 2;ii++)
4015   {
4016      dim(std(pr[2*ii]));
4017      idealsEqual(pr[2*ii-1],pr[2*ii]);
4018      "===========================";
4019   }
4020
4021   for(ii=size(pr) div 2;ii>1;ii--)
4022   {
4023      for(jj=1;jj<ii;jj++)
4024      {
4025         if(size(reduce(pr[2*jj],std(pr[2*ii],1)))==0)
4026         {
4027            "eingebette Komponente";
4028            jj;
4029            ii;
4030         }
4031      }
4032   }
4033}
4034
4035///////////////////////////////////////////////////////////////////////////////
4036//
4037//                  Shimoyama-Yokoyama
4038//
4039///////////////////////////////////////////////////////////////////////////////
4040
4041static proc simplifyIdeal(ideal i)
4042{
4043  def r=basering;
4044
4045  int j,k;
4046  map phi;
4047  poly p;
4048
4049  ideal iwork=i;
4050  ideal imap1=maxideal(1);
4051  ideal imap2=maxideal(1);
4052
4053
4054  for(j=1;j<=nvars(basering);j++)
4055  {
4056    for(k=1;k<=size(i);k++)
4057    {
4058      if(deg(iwork[k]/var(j))==0)
4059      {
4060        p=-1/leadcoef(iwork[k]/var(j))*iwork[k];
4061        imap1[j]=p+2*var(j);
4062        phi=r,imap1;
4063        iwork=phi(iwork);
4064        iwork=subst(iwork,var(j),0);
4065        iwork[k]=var(j);
4066        imap1=maxideal(1);
4067        imap2[j]=-p;
4068        break;
4069      }
4070    }
4071  }
4072  return(iwork,imap2);
4073}
4074
4075
4076///////////////////////////////////////////////////////
4077// ini_mod
4078// input: a polynomial p
4079// output: the initial term of p as needed
4080// in the context of characteristic sets
4081//////////////////////////////////////////////////////
4082
4083static proc ini_mod(poly p)
4084{
4085  if (p==0)
4086  {
4087    return(0);
4088  }
4089  int n; matrix m;
4090  for( n=nvars(basering); n>0; n--)
4091  {
4092    m=coef(p,var(n));
4093    if(m[1,1]!=1)
4094    {
4095      p=m[2,1];
4096      break;
4097    }
4098  }
4099  if(deg(p)==0)
4100  {
4101    p=0;
4102  }
4103  return(p);
4104}
4105///////////////////////////////////////////////////////
4106// min_ass_prim_charsets
4107// input: generators of an ideal PS and an integer cho
4108// If cho=0, the given ordering of the variables is used.
4109// Otherwise, the system tries to find an "optimal ordering",
4110// which in some cases may considerably speed up the algorithm
4111// output: the minimal associated primes of PS
4112// algorithm: via characteriostic sets
4113//////////////////////////////////////////////////////
4114
4115
4116static proc min_ass_prim_charsets (ideal PS, int cho)
4117{
4118  if((cho<0) and (cho>1))
4119  {
4120    ERROR("<int> must be 0 or 1");
4121  }
4122  intvec saveopt=option(get);
4123  option(notWarnSB);
4124  list L;
4125  if(cho==0)
4126  {
4127    L=min_ass_prim_charsets0(PS);
4128  }
4129  else
4130  {
4131    L=min_ass_prim_charsets1(PS);
4132  }
4133  option(set,saveopt);
4134  return(L);
4135}
4136///////////////////////////////////////////////////////
4137// min_ass_prim_charsets0
4138// input: generators of an ideal PS
4139// output: the minimal associated primes of PS
4140// algorithm: via characteristic sets
4141// the given ordering of the variables is used
4142//////////////////////////////////////////////////////
4143
4144
4145static proc min_ass_prim_charsets0 (ideal PS)
4146{
4147  intvec op;
4148  matrix m=char_series(PS);  // We compute an irreducible
4149                             // characteristic series
4150  int i,j,k;
4151  list PSI;
4152  list PHI;  // the ideals given by the characteristic series
4153  for(i=nrows(m);i>=1; i--)
4154  {
4155    PHI[i]=ideal(m[i,1..ncols(m)]);
4156  }
4157  // We compute the radical of each ideal in PHI
4158  ideal I,JS,II;
4159  int sizeJS, sizeII;
4160  for(i=size(PHI);i>=1; i--)
4161  {
4162    I=0;
4163    for(j=size(PHI[i]);j>0;j--)
4164    {
4165      I=I+ini_mod(PHI[i][j]);
4166    }
4167    JS=std(PHI[i]);
4168    sizeJS=size(JS);
4169    for(j=size(I);j>0;j--)
4170    {
4171      II=0;
4172      sizeII=0;
4173      k=0;
4174      while(k<=sizeII)                  // successive saturation
4175      {
4176        op=option(get);
4177        option(returnSB);
4178        II=quotient(JS,I[j]);
4179        option(set,op);
4180        sizeII=size(II);
4181        if(sizeII==sizeJS)
4182        {
4183          for(k=1;k<=sizeII;k++)
4184          {
4185            if(leadexp(II[k])!=leadexp(JS[k])) break;
4186          }
4187        }
4188        JS=II;
4189        sizeJS=sizeII;
4190      }
4191    }
4192    PSI=insert(PSI,JS);
4193  }
4194  int sizePSI=size(PSI);
4195  // We eliminate redundant ideals
4196  for(i=1;i<sizePSI;i++)
4197  {
4198    for(j=i+1;j<=sizePSI;j++)
4199    {
4200      if(size(PSI[i])!=0)
4201      {
4202        if(size(PSI[j])!=0)
4203        {
4204          if(size(NF(PSI[i],PSI[j],1))==0)
4205          {
4206            PSI[j]=ideal(0);
4207          }
4208          else
4209          {
4210            if(size(NF(PSI[j],PSI[i],1))==0)
4211            {
4212              PSI[i]=ideal(0);
4213            }
4214          }
4215        }
4216      }
4217    }
4218  }
4219  for(i=sizePSI;i>=1;i--)
4220  {
4221    if(size(PSI[i])==0)
4222    {
4223      PSI=delete(PSI,i);
4224    }
4225  }
4226  return (PSI);
4227}
4228
4229///////////////////////////////////////////////////////
4230// min_ass_prim_charsets1
4231// input: generators of an ideal PS
4232// output: the minimal associated primes of PS
4233// algorithm: via characteristic sets
4234// input: generators of an ideal PS and an integer i
4235// The system tries to find an "optimal ordering" of
4236// the variables
4237//////////////////////////////////////////////////////
4238
4239
4240static proc min_ass_prim_charsets1 (ideal PS)
4241{
4242  intvec op;
4243  def oldring=basering;
4244  string n=system("neworder",PS);
4245  execute("ring r=("+charstr(oldring)+"),("+n+"),dp;");
4246  ideal PS=imap(oldring,PS);
4247  matrix m=char_series(PS);  // We compute an irreducible
4248                             // characteristic series
4249  int i,j,k;
4250  ideal I;
4251  list PSI;
4252  list PHI;    // the ideals given by the characteristic series
4253  list ITPHI;  // their initial terms
4254  for(i=nrows(m);i>=1; i--)
4255  {
4256    PHI[i]=ideal(m[i,1..ncols(m)]);
4257    I=0;
4258    for(j=size(PHI[i]);j>0;j=j-1)
4259    {
4260      I=I,ini_mod(PHI[i][j]);
4261    }
4262    I=I[2..ncols(I)];
4263    ITPHI[i]=I;
4264  }
4265  setring oldring;
4266  matrix m=imap(r,m);
4267  list PHI=imap(r,PHI);
4268  list ITPHI=imap(r,ITPHI);
4269  // We compute the radical of each ideal in PHI
4270  ideal I,JS,II;
4271  int sizeJS, sizeII;
4272  for(i=size(PHI);i>=1; i--)
4273  {
4274    I=0;
4275    for(j=size(PHI[i]);j>0;j--)
4276    {
4277      I=I+ITPHI[i][j];
4278    }
4279    JS=std(PHI[i]);
4280    sizeJS=size(JS);
4281    for(j=size(I);j>0;j--)
4282    {
4283      II=0;
4284      sizeII=0;
4285      k=0;
4286      while(k<=sizeII)                  // successive iteration
4287      {
4288        op=option(get);
4289        option(returnSB);
4290        II=quotient(JS,I[j]);
4291        option(set,op);
4292//std
4293//         II=std(II);
4294        sizeII=size(II);
4295        if(sizeII==sizeJS)
4296        {
4297          for(k=1;k<=sizeII;k++)
4298          {
4299            if(leadexp(II[k])!=leadexp(JS[k])) break;
4300          }
4301        }
4302        JS=II;
4303        sizeJS=sizeII;
4304      }
4305    }
4306    PSI=insert(PSI,JS);
4307  }
4308  int sizePSI=size(PSI);
4309  // We eliminate redundant ideals
4310  for(i=1;i<sizePSI;i++)
4311  {
4312    for(j=i+1;j<=sizePSI;j++)
4313    {
4314      if(size(PSI[i])!=0)
4315      {
4316        if(size(PSI[j])!=0)
4317        {
4318          if(size(NF(PSI[i],PSI[j],1))==0)
4319          {
4320            PSI[j]=ideal(0);
4321          }
4322          else
4323          {
4324            if(size(NF(PSI[j],PSI[i],1))==0)
4325            {
4326              PSI[i]=ideal(0);
4327            }
4328          }
4329        }
4330      }
4331    }
4332  }
4333  for(i=sizePSI;i>=1;i--)
4334  {
4335    if(size(PSI[i])==0)
4336    {
4337      PSI=delete(PSI,i);
4338    }
4339  }
4340  return (PSI);
4341}
4342
4343
4344/////////////////////////////////////////////////////
4345// proc prim_dec
4346// input:  generators of an ideal I and an integer choose
4347// If choose=0, min_ass_prim_charsets with the given
4348// ordering of the variables is used.
4349// If choose=1, min_ass_prim_charsets with the "optimized"
4350// ordering of the variables is used.
4351// If choose=2, minAssPrimes from primdec.lib is used
4352// If choose=3, minAssPrimes+factorizing Buchberger from primdec.lib is used
4353// output: a primary decomposition of I, i.e., a list
4354// of pairs consisting of a standard basis of a primary component
4355// of I and a standard basis of the corresponding associated prime.
4356// To compute the minimal associated primes of a given ideal
4357// min_ass_prim_l is called, i.e., the minimal associated primes
4358// are computed via characteristic sets.
4359// In the homogeneous case, the performance of the procedure
4360// will be improved if I is already given by a minimal set of
4361// generators. Apply minbase if necessary.
4362//////////////////////////////////////////////////////////
4363
4364
4365static proc prim_dec(ideal I, int choose)
4366{
4367  if((choose<0) or (choose>3))
4368  {
4369    ERROR("ERROR: <int> must be 0 or 1 or 2 or 3");
4370  }
4371  ideal H=1; // The intersection of the primary components
4372  list U;    // the leaves of the decomposition tree, i.e.,
4373             // pairs consisting of a primary component of I
4374             // and the corresponding associated prime
4375  list W;    // the non-leaf vertices in the decomposition tree.
4376             // every entry has 6 components:
4377                // 1- the vertex itself , i.e., a standard bais of the
4378                //    given ideal I (type 1), or a standard basis of a
4379                //    pseudo-primary component arising from
4380                //    pseudo-primary decomposition (type 2), or a
4381                //    standard basis of a remaining component arising from
4382                //    pseudo-primary decomposition or extraction (type 3)
4383                // 2- the type of the vertex as indicated above
4384                // 3- the weighted_tree_depth of the vertex
4385                // 4- the tester of the vertex
4386                // 5- a standard basis of the associated prime
4387                //    of a vertex of type 2, or 0 otherwise
4388                // 6- a list of pairs consisting of a standard
4389                //    basis of a minimal associated prime ideal
4390                //    of the father of the vertex and the
4391                //    irreducible factors of the "minimal
4392                //    divisor" of the seperator or extractor
4393                //    corresponding to the prime ideal
4394                //    as computed by the procedure minsat,
4395                //    if the vertex is of type 3, or
4396                //    the empty list otherwise
4397  ideal SI=std(I);
4398  if(SI[1]==1)  // primdecSY(ideal(1))
4399  {
4400    return(list());
4401  }
4402  intvec save=option(get);
4403  option(notWarnSB);
4404  int ncolsSI=ncols(SI);
4405  int ncolsH=1;
4406  W[1]=list(I,1,0,poly(1),ideal(0),list()); // The root of the tree
4407  int weighted_tree_depth;
4408  int i,j;
4409  int check;
4410  list V;  // current vertex
4411  list VV; // new vertex
4412  list QQ;
4413  list WI;
4414  ideal Qi,SQ,SRest,fac;
4415  poly tester;
4416
4417  while(1)
4418  {
4419    i=1;
4420    while(1)
4421    {
4422      while(i<=size(W)) // find vertex V of smallest weighted tree-depth
4423      {
4424        if (W[i][3]<=weighted_tree_depth) break;
4425        i++;
4426      }
4427      if (i<=size(W)) break;
4428      i=1;
4429      weighted_tree_depth++;
4430    }
4431    V=W[i];
4432    W=delete(W,i); // delete V from W
4433
4434    // now proceed by type of vertex V
4435
4436    if (V[2]==2)  // extraction needed
4437    {
4438      SQ,SRest,fac=extraction(V[1],V[5]);
4439                        // standard basis of primary component,
4440                        // standard basis of remaining component,
4441                        // irreducible factors of
4442                        // the "minimal divisor" of the extractor
4443                        // as computed by the procedure minsat,
4444      check=0;
4445      for(j=1;j<=ncolsH;j++)
4446      {
4447        if (NF(H[j],SQ,1)!=0) // Q is not redundant
4448        {
4449          check=1;
4450          break;
4451        }
4452      }
4453      if(check==1)             // Q is not redundant
4454      {
4455        QQ=list();
4456        QQ[1]=list(SQ,V[5]);  // primary component, associated prime,
4457                              // i.e., standard bases thereof
4458        U=U+QQ;
4459        H=intersect(H,SQ);
4460        H=std(H);
4461        ncolsH=ncols(H);
4462        check=0;
4463        if(ncolsH==ncolsSI)
4464        {
4465          for(j=1;j<=ncolsSI;j++)
4466          {
4467            if(leadexp(H[j])!=leadexp(SI[j]))
4468            {
4469              check=1;
4470              break;
4471            }
4472          }
4473        }
4474        else
4475        {
4476          check=1;
4477        }
4478        if(check==0) // H==I => U is a primary decomposition
4479        {
4480          option(set,save);
4481          return(U);
4482        }
4483      }
4484      if (SRest[1]!=1)        // the remaining component is not
4485                              // the whole ring
4486      {
4487        if (rad_con(V[4],SRest)==0) // the new vertex is not the
4488                                    // root of a redundant subtree
4489        {
4490          VV[1]=SRest;     // remaining component
4491          VV[2]=3;         // pseudoprimdec_special
4492          VV[3]=V[3]+1;    // weighted depth
4493          VV[4]=V[4];      // the tester did not change
4494          VV[5]=ideal(0);
4495          VV[6]=list(list(V[5],fac));
4496          W=insert(W,VV,size(W));
4497        }
4498      }
4499    }
4500    else
4501    {
4502      if (V[2]==3) // pseudo_prim_dec_special is needed
4503      {
4504        QQ,SRest=pseudo_prim_dec_special_charsets(V[1],V[6],choose);
4505                         // QQ = quadruples:
4506                         // standard basis of pseudo-primary component,
4507                         // standard basis of corresponding prime,
4508                         // seperator, irreducible factors of
4509                         // the "minimal divisor" of the seperator
4510                         // as computed by the procedure minsat,
4511                         // SRest=standard basis of remaining component
4512      }
4513      else     // V is the root, pseudo_prim_dec is needed
4514      {
4515        QQ,SRest=pseudo_prim_dec_charsets(I,SI,choose);
4516                         // QQ = quadruples:
4517                         // standard basis of pseudo-primary component,
4518                         // standard basis of corresponding prime,
4519                         // seperator, irreducible factors of
4520                         // the "minimal divisor" of the seperator
4521                         // as computed by the procedure minsat,
4522                         // SRest=standard basis of remaining component
4523      }
4524      //check
4525      for(i=size(QQ);i>=1;i--)
4526      //for(i=1;i<=size(QQ);i++)
4527      {
4528        tester=QQ[i][3]*V[4];
4529        Qi=QQ[i][2];
4530        if(NF(tester,Qi,1)!=0)  // the new vertex is not the
4531                                // root of a redundant subtree
4532        {
4533          VV[1]=QQ[i][1];
4534          VV[2]=2;
4535          VV[3]=V[3]+1;
4536          VV[4]=tester;      // the new tester as computed above
4537          VV[5]=Qi;          // QQ[i][2];
4538          VV[6]=list();
4539          W=insert(W,VV,size(W));
4540        }
4541      }
4542      if (SRest[1]!=1)        // the remaining component is not
4543                              // the whole ring
4544      {
4545        if (rad_con(V[4],SRest)==0) // the vertex is not the root
4546                                    // of a redundant subtree
4547        {
4548          VV[1]=SRest;
4549          VV[2]=3;
4550          VV[3]=V[3]+2;
4551          VV[4]=V[4];      // the tester did not change
4552          VV[5]=ideal(0);
4553          WI=list();
4554          for(i=1;i<=size(QQ);i++)
4555          {
4556            WI=insert(WI,list(QQ[i][2],QQ[i][4]));
4557          }
4558          VV[6]=WI;
4559          W=insert(W,VV,size(W));
4560        }
4561      }
4562    }
4563  }
4564  option(set,save);
4565}
4566
4567//////////////////////////////////////////////////////////////////////////
4568// proc pseudo_prim_dec_charsets
4569// input: Generators of an arbitrary ideal I, a standard basis SI of I,
4570// and an integer choo
4571// If choo=0, min_ass_prim_charsets with the given
4572// ordering of the variables is used.
4573// If choo=1, min_ass_prim_charsets with the "optimized"
4574// ordering of the variables is used.
4575// If choo=2, minAssPrimes from primdec.lib is used
4576// If choo=3, minAssPrimes+factorizing Buchberger from primdec.lib is used
4577// output: a pseudo primary decomposition of I, i.e., a list
4578// of pseudo primary components together with a standard basis of the
4579// remaining component. Each pseudo primary component is
4580// represented by a quadrupel: A standard basis of the component,
4581// a standard basis of the corresponding associated prime, the
4582// seperator of the component, and the irreducible factors of the
4583// "minimal divisor" of the seperator as computed by the procedure minsat,
4584// calls  proc pseudo_prim_dec_i
4585//////////////////////////////////////////////////////////////////////////
4586
4587
4588static proc pseudo_prim_dec_charsets (ideal I, ideal SI, int choo)
4589{
4590  list L;          // The list of minimal associated primes,
4591                   // each one given by a standard basis
4592  if((choo==0) or (choo==1))
4593  {
4594    L=min_ass_prim_charsets(I,choo);
4595  }
4596  else
4597  {
4598    if(choo==2)
4599    {
4600      L=minAssPrimes(I);
4601    }
4602    else
4603    {
4604      L=minAssPrimes(I,1);
4605    }
4606    for(int i=size(L);i>=1;i--)
4607    {
4608      L[i]=std(L[i]);
4609    }
4610  }
4611  return (pseudo_prim_dec_i(SI,L));
4612}
4613
4614////////////////////////////////////////////////////////////////
4615// proc pseudo_prim_dec_special_charsets
4616// input: a standard basis of an ideal I whose radical is the
4617// intersection of the radicals of ideals generated by one prime ideal
4618// P_i together with one polynomial f_i, the list V6 must be the list of
4619// pairs (standard basis of P_i, irreducible factors of f_i),
4620// and an integer choo
4621// If choo=0, min_ass_prim_charsets with the given
4622// ordering of the variables is used.
4623// If choo=1, min_ass_prim_charsets with the "optimized"
4624// ordering of the variables is used.
4625// If choo=2, minAssPrimes from primdec.lib is used
4626// If choo=3, minAssPrimes+factorizing Buchberger from primdec.lib is used
4627// output: a pseudo primary decomposition of I, i.e., a list
4628// of pseudo primary components together with a standard basis of the
4629// remaining component. Each pseudo primary component is
4630// represented by a quadrupel: A standard basis of the component,
4631// a standard basis of the corresponding associated prime, the
4632// seperator of the component, and the irreducible factors of the
4633// "minimal divisor" of the seperator as computed by the procedure minsat,
4634// calls  proc pseudo_prim_dec_i
4635////////////////////////////////////////////////////////////////
4636
4637
4638static proc pseudo_prim_dec_special_charsets (ideal SI,list V6, int choo)
4639{
4640  int i,j,l;
4641  list m;
4642  list L;
4643  int sizeL;
4644  ideal P,SP; ideal fac;
4645  int dimSP;
4646  for(l=size(V6);l>=1;l--)   // creates a list of associated primes
4647                             // of I, possibly redundant
4648  {
4649    P=V6[l][1];
4650    fac=V6[l][2];
4651    for(i=ncols(fac);i>=1;i--)
4652    {
4653      SP=P+fac[i];
4654      SP=std(SP);
4655      if(SP[1]!=1)
4656      {
4657        if((choo==0) or (choo==1))
4658        {
4659          m=min_ass_prim_charsets(SP,choo);  // a list of SB
4660        }
4661        else
4662        {
4663          if(choo==2)
4664          {
4665            m=minAssPrimes(SP);
4666          }
4667          else
4668          {
4669            m=minAssPrimes(SP,1);
4670          }
4671          for(j=size(m);j>=1;j=j-1)
4672            {
4673              m[j]=std(m[j]);
4674            }
4675        }
4676        dimSP=dim(SP);
4677        for(j=size(m);j>=1; j--)
4678        {
4679          if(dim(m[j])==dimSP)
4680          {
4681            L=insert(L,m[j],size(L));
4682          }
4683        }
4684      }
4685    }
4686  }
4687  sizeL=size(L);
4688  for(i=1;i<sizeL;i++)     // get rid of redundant primes
4689  {
4690    for(j=i+1;j<=sizeL;j++)
4691    {
4692      if(size(L[i])!=0)
4693      {
4694        if(size(L[j])!=0)
4695        {
4696          if(size(NF(L[i],L[j],1))==0)
4697          {
4698            L[j]=ideal(0);
4699          }
4700          else
4701          {
4702            if(size(NF(L[j],L[i],1))==0)
4703            {
4704              L[i]=ideal(0);
4705            }
4706          }
4707        }
4708      }
4709    }
4710  }
4711  for(i=sizeL;i>=1;i--)
4712  {
4713    if(size(L[i])==0)
4714    {
4715      L=delete(L,i);
4716    }
4717  }
4718  return (pseudo_prim_dec_i(SI,L));
4719}
4720
4721
4722////////////////////////////////////////////////////////////////
4723// proc pseudo_prim_dec_i
4724// input: A standard basis of an arbitrary ideal I, and standard bases
4725// of the minimal associated primes of I
4726// output: a pseudo primary decomposition of I, i.e., a list
4727// of pseudo primary components together with a standard basis of the
4728// remaining component. Each pseudo primary component is
4729// represented by a quadrupel: A standard basis of the component Q_i,
4730// a standard basis of the corresponding associated prime P_i, the
4731// seperator of the component, and the irreducible factors of the
4732// "minimal divisor" of the seperator as computed by the procedure minsat,
4733////////////////////////////////////////////////////////////////
4734
4735
4736static proc pseudo_prim_dec_i (ideal SI, list L)
4737{
4738  list Q;
4739  if (size(L)==1)               // one minimal associated prime only
4740                                // the ideal is already pseudo primary
4741  {
4742    Q=SI,L[1],1;
4743    list QQ;
4744    QQ[1]=Q;
4745    return (QQ,ideal(1));
4746  }
4747
4748  poly f0,f,g;
4749  ideal fac;
4750  int i,j,k,l;
4751  ideal SQi;
4752  ideal I'=SI;
4753  list QP;
4754  int sizeL=size(L);
4755  for(i=1;i<=sizeL;i++)
4756  {
4757    fac=0;
4758    for(j=1;j<=sizeL;j++)           // compute the seperator sep_i
4759                                    // of the i-th component
4760    {
4761      if (i!=j)                       // search g not in L[i], but L[j]
4762      {
4763        for(k=1;k<=ncols(L[j]);k++)
4764        {
4765          if(NF(L[j][k],L[i],1)!=0)
4766          {
4767            break;
4768          }
4769        }
4770        fac=fac+L[j][k];
4771      }
4772    }
4773    // delete superfluous polynomials
4774    fac=simplify(fac,8+2);
4775    // saturation
4776    SQi,f0,f,fac=minsat_ppd(SI,fac);
4777    I'=I',f;
4778    QP=SQi,L[i],f0,fac;
4779             // the quadrupel:
4780             // a standard basis of Q_i,
4781             // a standard basis of P_i,
4782             // sep_i,
4783             // irreducible factors of
4784             // the "minimal divisor" of the seperator
4785             //  as computed by the procedure minsat,
4786    Q[i]=QP;
4787  }
4788  I'=std(I');
4789  return (Q, I');
4790                   // I' = remaining component
4791}
4792
4793
4794////////////////////////////////////////////////////////////////
4795// proc extraction
4796// input: A standard basis of a pseudo primary ideal I, and a standard
4797// basis of the unique minimal associated prime P of I
4798// output: an extraction of I, i.e., a standard basis of the primary
4799// component Q of I with associated prime P, a standard basis of the
4800// remaining component, and the irreducible factors of the
4801// "minimal divisor" of the extractor as computed by the procedure minsat
4802////////////////////////////////////////////////////////////////
4803
4804
4805static proc extraction (ideal SI, ideal SP)
4806{
4807  list indsets=indepSet(SP,0);
4808  poly f;
4809  if(size(indsets)!=0)      //check, whether dim P != 0
4810  {
4811    intvec v;               // a maximal independent set of variables
4812                            // modulo P
4813    string U;               // the independent variables
4814    string A;               // the dependent variables
4815    int j,k;
4816    int a;                  //  the size of A
4817    int degf;
4818    ideal g;
4819    list polys;
4820    int sizepolys;
4821    list newpoly;
4822    def R=basering;
4823    //intvec hv=hilb(SI,1);
4824    for (k=1;k<=size(indsets);k++)
4825    {
4826      v=indsets[k];
4827      for (j=1;j<=nvars(R);j++)
4828      {
4829        if (v[j]==1)
4830        {
4831          U=U+varstr(j)+",";
4832        }
4833        else
4834        {
4835          A=A+varstr(j)+",";
4836          a++;
4837        }
4838      }
4839
4840      U[size(U)]=")";           // we compute the extractor of I (w.r.t. U)
4841      execute("ring RAU=("+charstr(basering)+"),("+A+U+",(dp("+string(a)+"),dp);");
4842      ideal I=imap(R,SI);
4843      //I=std(I,hv);            // the standard basis in (R[U])[A]
4844      I=std(I);            // the standard basis in (R[U])[A]
4845      A[size(A)]=")";
4846      execute("ring Rloc=("+charstr(basering)+","+U+",("+A+",dp;");
4847      ideal I=imap(RAU,I);
4848      //"std in lokalisierung:"+newline,I;
4849      ideal h;
4850      for(j=ncols(I);j>=1;j--)
4851      {
4852        h[j]=leadcoef(I[j]);  // consider I in (R(U))[A]
4853      }
4854      setring R;
4855      g=imap(Rloc,h);
4856      kill RAU,Rloc;
4857      U="";
4858      A="";
4859      a=0;
4860      f=lcm(g);
4861      newpoly[1]=f;
4862      polys=polys+newpoly;
4863      newpoly=list();
4864    }
4865    f=polys[1];
4866    degf=deg(f);
4867    sizepolys=size(polys);
4868    for (k=2;k<=sizepolys;k++)
4869    {
4870      if (deg(polys[k])<degf)
4871      {
4872        f=polys[k];
4873        degf=deg(f);
4874      }
4875    }
4876  }
4877  else
4878  {
4879    f=1;
4880  }
4881  poly f0,h0; ideal SQ; ideal fac;
4882  if(f!=1)
4883  {
4884    SQ,f0,h0,fac=minsat(SI,f);
4885    return(SQ,std(SI+h0),fac);
4886             // the tripel
4887             // a standard basis of Q,
4888             // a standard basis of remaining component,
4889             // irreducible factors of
4890             // the "minimal divisor" of the extractor
4891             // as computed by the procedure minsat
4892  }
4893  else
4894  {
4895    return(SI,ideal(1),ideal(1));
4896  }
4897}
4898
4899/////////////////////////////////////////////////////
4900// proc minsat
4901// input:  a standard basis of an ideal I and a polynomial p
4902// output: a standard basis IS of the saturation of I w.r. to p,
4903// the maximal squarefree factor f0 of p,
4904// the "minimal divisor" f of f0 such that the saturation of
4905// I w.r. to f equals the saturation of I w.r. to f0 (which is IS),
4906// the irreducible factors of f
4907//////////////////////////////////////////////////////////
4908
4909
4910static proc minsat(ideal SI, poly p)
4911{
4912  ideal fac=factorize(p,1);       //the irreducible factors of p
4913  fac=sort(fac)[1];
4914  int i,k;
4915  poly f0=1;
4916  for(i=ncols(fac);i>=1;i--)
4917  {
4918    f0=f0*fac[i];
4919  }
4920  poly f=1;
4921  ideal iold;
4922  list quotM;
4923  quotM[1]=SI;
4924  quotM[2]=fac;
4925  quotM[3]=f0;
4926  // we deal seperately with the first quotient;
4927  // factors, which do not contribute to this one,
4928  // are omitted
4929  iold=quotM[1];
4930  quotM=minquot(quotM);
4931  fac=quotM[2];
4932  if(quotM[3]==1)
4933    {
4934      return(quotM[1],f0,f,fac);
4935    }
4936  while(special_ideals_equal(iold,quotM[1])==0)
4937    {
4938      f=f*quotM[3];
4939      iold=quotM[1];
4940      quotM=minquot(quotM);
4941    }
4942  return(quotM[1],f0,f,fac);           // the quadrupel ((I:p),f0,f, irr. factors of f)
4943}
4944
4945/////////////////////////////////////////////////////
4946// proc minsat_ppd
4947// input:  a standard basis of an ideal I and a polynomial p
4948// output: a standard basis IS of the saturation of I w.r. to p,
4949// the maximal squarefree factor f0 of p,
4950// the "minimal divisor" f of f0 such that the saturation of
4951// I w.r. to f equals the saturation of I w.r. to f0 (which is IS),
4952// the irreducible factors of f
4953//////////////////////////////////////////////////////////
4954
4955
4956static proc minsat_ppd(ideal SI, ideal fac)
4957{
4958  fac=sort(fac)[1];
4959  int i,k;
4960  poly f0=1;
4961  for(i=ncols(fac);i>=1;i--)
4962  {
4963    f0=f0*fac[i];
4964  }
4965  poly f=1;
4966  ideal iold;
4967  list quotM;
4968  quotM[1]=SI;
4969  quotM[2]=fac;
4970  quotM[3]=f0;
4971  // we deal seperately with the first quotient;
4972  // factors, which do not contribute to this one,
4973  // are omitted
4974  iold=quotM[1];
4975  quotM=minquot(quotM);
4976  fac=quotM[2];
4977  if(quotM[3]==1)
4978    {
4979      return(quotM[1],f0,f,fac);
4980    }
4981  while(special_ideals_equal(iold,quotM[1])==0)
4982  {
4983    f=f*quotM[3];
4984    iold=quotM[1];
4985    quotM=minquot(quotM);
4986    k++;
4987  }
4988  return(quotM[1],f0,f,fac);           // the quadrupel ((I:p),f0,f, irr. factors of f)
4989}
4990/////////////////////////////////////////////////////////////////
4991// proc minquot
4992// input: a list with 3 components: a standard basis
4993// of an ideal I, a set of irreducible polynomials, and
4994// there product f0
4995// output: a standard basis of the ideal (I:f0), the irreducible
4996// factors of the "minimal divisor" f of f0 with (I:f0) = (I:f),
4997// the "minimal divisor" f
4998/////////////////////////////////////////////////////////////////
4999
5000static proc minquot(list tsil)
5001{
5002   intvec op;
5003   int i,j,k,action;
5004   ideal verg;
5005   list l;
5006   poly g;
5007   ideal laedi=tsil[1];
5008   ideal fac=tsil[2];
5009   poly f=tsil[3];
5010
5011//std
5012//   ideal star=quotient(laedi,f);
5013//   star=std(star);
5014   op=option(get);
5015   option(returnSB);
5016   ideal star=quotient(laedi,f);
5017   option(set,op);
5018   if(special_ideals_equal(laedi,star)==1)
5019     {
5020       return(laedi,ideal(1),1);
5021     }
5022   action=1;
5023   while(action==1)
5024   {
5025      if(size(fac)==1)
5026      {
5027         action=0;
5028         break;
5029      }
5030      for(i=1;i<=size(fac);i++)
5031      {
5032        g=1;
5033         for(j=1;j<=size(fac);j++)
5034         {
5035            if(i!=j)
5036            {
5037               g=g*fac[j];
5038            }
5039         }
5040//std
5041//         verg=quotient(laedi,g);
5042//         verg=std(verg);
5043         op=option(get);
5044         option(returnSB);
5045         verg=quotient(laedi,g);
5046         option(set,op);
5047         if(special_ideals_equal(verg,star)==1)
5048         {
5049            f=g;
5050            fac[i]=0;
5051            fac=simplify(fac,2);
5052            break;
5053         }
5054         if(i==size(fac))
5055         {
5056            action=0;
5057         }
5058      }
5059   }
5060   l=star,fac,f;
5061   return(l);
5062}
5063/////////////////////////////////////////////////
5064// proc special_ideals_equal
5065// input: standard bases of ideal k1 and k2 such that
5066// k1 is contained in k2, or k2 is contained ink1
5067// output: 1, if k1 equals k2, 0 otherwise
5068//////////////////////////////////////////////////
5069
5070static proc special_ideals_equal( ideal k1, ideal k2)
5071{
5072   int j;
5073   if(size(k1)==size(k2))
5074   {
5075      for(j=1;j<=size(k1);j++)
5076      {
5077         if(leadexp(k1[j])!=leadexp(k2[j]))
5078         {
5079            return(0);
5080         }
5081      }
5082      return(1);
5083   }
5084   return(0);
5085}
5086
5087
5088///////////////////////////////////////////////////////////////////////////////
5089
5090static proc convList(list l)
5091{
5092   int i;
5093   list re,he;
5094   for(i=1;i<=size(l) div 2;i++)
5095   {
5096      he=l[2*i-1],l[2*i];
5097      re[i]=he;
5098   }
5099   return(re);
5100}
5101///////////////////////////////////////////////////////////////////////////////
5102
5103static proc reconvList(list l)
5104{
5105   int i;
5106   list re;
5107   for(i=1;i<=size(l);i++)
5108   {
5109      re[2*i-1]=l[i][1];
5110      re[2*i]=l[i][2];
5111   }
5112   return(re);
5113}
5114
5115///////////////////////////////////////////////////////////////////////////////
5116//
5117//     The main procedures
5118//
5119///////////////////////////////////////////////////////////////////////////////
5120
5121proc primdecGTZ(ideal i, list #)
5122"USAGE:   primdecGTZ(i); i ideal
5123RETURN:  a list pr of primary ideals and their associated primes:
5124@format
5125   pr[i][1]   the i-th primary component,
5126   pr[i][2]   the i-th prime component.
5127@end format
5128NOTE:    - Algorithm of Gianni/Trager/Zacharias.
5129         - Designed for characteristic 0, works also in char k > 0, if it
5130           terminates (may result in an infinite loop in small characteristic!)
5131         - For local orderings, the result is considered in the localization
5132           of the polynomial ring, not in the power series ring
5133         - For local and mixed orderings, the decomposition in the
5134           corresponding global ring is returned if the string 'global'
5135           is specified as second argument
5136EXAMPLE: example primdecGTZ; shows an example
5137"
5138{
5139   if(size(#)>0)
5140   {
5141      int keep_comp=1;
5142   }
5143   if(attrib(basering,"global")!=1)
5144   {
5145// algorithms only work in global case!
5146// pass to appropriate global ring
5147      def r=basering;
5148      def s=changeord(list(list("dp",1:nvars(basering))));
5149      setring s;
5150      ideal i=imap(r,i);
5151// decompose and go back
5152      list li=primdecGTZ(i);
5153      setring r;
5154      def li=imap(s,li);
5155// clean up
5156      if(!defined(keep_comp))
5157      {
5158         for(int k=size(li);k>=1;k--)
5159         {
5160            if(mindeg(std(lead(li[k][2]))[1])==0)
5161            {
5162// 1 contained in ideal, i.e. component does not meet origin in local ordering
5163               li=delete(li,k);
5164            }
5165         }
5166      }
5167      return(li);
5168   }
5169
5170   if(minpoly!=0)
5171   {
5172      return(algeDeco(i,0));
5173      ERROR(
5174      "// Not implemented yet for algebraic extensions.Simulate the ring extension by adding the minpoly to the ideal"
5175      );
5176   }
5177  return(convList(decomp(i)));
5178}
5179example
5180{ "EXAMPLE:";  echo = 2;
5181   ring  r = 0,(x,y,z),lp;
5182   poly  p = z2+1;
5183   poly  q = z3+2;
5184   ideal i = p*q^2,y-z2;
5185   list pr = primdecGTZ(i);
5186   pr;
5187}
5188///////////////////////////////////////////////////////////////////////////////
5189proc absPrimdecGTZ(ideal I, list #)
5190"USAGE:   absPrimdecGTZ(I); I ideal
5191ASSUME:  Ground field has characteristic 0.
5192RETURN:  a ring containing two lists: @code{absolute_primes}, the absolute
5193         prime components of I, and @code{primary_decomp}, the output of
5194         @code{primdecGTZ(I)}.
5195         The list absolute_primes has to be interpreted as follows:
5196         each entry describes a class of conjugated absolute primes,
5197@format
5198   absolute_primes[i][1]   the absolute prime component,
5199   absolute_primes[i][2]   the number of conjugates.
5200@end format
5201         The first entry of @code{absolute_primes[i][1]} is the minimal
5202         polynomial of a minimal finite field extension over which the
5203         absolute prime component is defined.
5204         For local orderings, the result is considered in the localization
5205         of the polynomial ring, not in the power series ring.
5206         For local and mixed orderings, the decomposition in the
5207         corresponding global ring is returned if the string 'global'
5208         is specified as second argument
5209NOTE:    Algorithm of Gianni/Trager/Zacharias combined with the
5210         @code{absFactorize} command.
5211SEE ALSO: primdecGTZ; absFactorize
5212EXAMPLE: example absPrimdecGTZ; shows an example
5213"
5214{
5215  if (char(basering) != 0)
5216  {
5217    ERROR("primdec.lib::absPrimdecGTZ is only implemented for "+
5218           +"characteristic 0");
5219  }
5220
5221  if(size(#)>0)
5222  {
5223     int keep_comp=1;
5224  }
5225
5226  if(attrib(basering,"global")!=1)
5227  {
5228// algorithm automatically passes to the global case
5229// hence prepare to go back to an appropriate new ring
5230      def r=basering;
5231      ideal max_of_r=maxideal(1);
5232      def s=changeord(list(list("dp",1:nvars(basering))));
5233      setring s;
5234      def I=imap(r,I);
5235      def S=absPrimdecGTZ(I);
5236      setring S;
5237      ring r1=char(basering),var(nvars(r)+1),dp;
5238      def rS=r+r1;
5239// move objects to appropriate ring and clean up
5240      setring rS;
5241      def max_of_r=imap(r,max_of_r);
5242      attrib(max_of_r,"isSB",1);
5243      def absolute_primes=imap(S,absolute_primes);
5244      def primary_decomp=imap(S,primary_decomp);
5245      if(!defined(keep_comp))
5246      {
5247         ideal tempid;
5248         for(int k=size(absolute_primes);k>=1;k--)
5249         {
5250            tempid=absolute_primes[k][1];
5251            tempid[1]=0;                  // ignore minimal polynomial
5252            if(size(reduce(lead(tempid),max_of_r))!=0)
5253            {
5254// 1 contained in ideal, i.e. component does not meet origin in local ordering
5255               absolute_primes=delete(absolute_primes,k);
5256            }
5257         }
5258         for(k=size(primary_decomp);k>=1;k--)
5259         {
5260            if(mindeg(std(lead(primary_decomp[k][2]))[1])==0)
5261            {
5262// 1 contained in ideal, i.e. component does not meet origin in local ordering
5263               primary_decomp=delete(primary_decomp,k);
5264            }
5265         }
5266         kill tempid;
5267      }
5268      export(primary_decomp);
5269      export(absolute_primes);
5270      return(rS);
5271  }
5272  if(minpoly!=0)
5273  {
5274    //return(algeDeco(i,0));
5275    ERROR(
5276      "// Not implemented yet for algebraic extensions.Simulate the ring extension by adding the minpoly to the ideal"
5277    );
5278  }
5279  def R=basering;
5280  int n=nvars(R);
5281  list L=decomp(I,3);
5282  string newvar=L[1][3];
5283  int k=find(newvar,",",find(newvar,",")+1);
5284  newvar=newvar[k+1..size(newvar)];
5285  list lR=ringlist(R);
5286  int i,de,ii;
5287  intvec vv=1:n;
5288  //for(i=1;i<=n;i++){vv[i]=1;}
5289
5290  list orst;
5291  orst[1]=list("dp",vv);
5292  orst[2]=list("dp",intvec(1));
5293  orst[3]=list("C",0);
5294  lR[3]=orst;
5295  lR[2][n+1] = newvar;
5296  def Rz = ring(lR);
5297  setring Rz;
5298  list L=imap(R,L);
5299  list absolute_primes,primary_decomp;
5300  ideal I,M,N,K;
5301  M=maxideal(1);
5302  N=maxideal(1);
5303  poly p,q,f,g;
5304  map phi,psi;
5305  string tvar;
5306  for(i=1;i<=size(L);i++)
5307  {
5308    tvar=L[i][4];
5309    ii=find(tvar,"+");
5310    while(ii)
5311    {
5312      tvar=tvar[ii+1..size(tvar)];
5313      ii=find(tvar,"+");
5314    }
5315    for(ii=1;ii<=nvars(basering);ii++)
5316    {
5317      if(tvar==string(var(ii))) break;
5318    }
5319    I=L[i][2];
5320    execute("K="+L[i][3]+";");
5321    p=K[1];
5322    q=K[2];
5323    execute("f="+L[i][4]+";");
5324    g=2*var(ii)-f;
5325    M[ii]=f;
5326    N[ii]=g;
5327    de=deg(p);
5328    psi=Rz,M;
5329    phi=Rz,N;
5330    I=phi(I),p,q;
5331    I=std(I);
5332    absolute_primes[i]=list(psi(I),de);
5333    primary_decomp[i]=list(L[i][1],L[i][2]);
5334  }
5335  export(primary_decomp);
5336  export(absolute_primes);
5337  setring R;
5338  dbprint( printlevel-voice+3,"
5339// 'absPrimdecGTZ' created a ring, in which two lists absolute_primes (the
5340// absolute prime components) and primary_decomp (the primary and prime
5341// components over the current basering) are stored.
5342// To access the list of absolute prime components, type (if the name S was
5343// assigned to the return value):
5344        setring S; absolute_primes; ");
5345
5346  return(Rz);
5347}
5348example
5349{ "EXAMPLE:";  echo = 2;
5350   ring  r = 0,(x,y,z),lp;
5351   poly  p = z2+1;
5352   poly  q = z3+2;
5353   ideal i = p*q^2,y-z2;
5354   def S = absPrimdecGTZ(i);
5355   setring S;
5356   absolute_primes;
5357}
5358
5359///////////////////////////////////////////////////////////////////////////////
5360
5361proc primdecSY(ideal i, list #)
5362"USAGE:   primdecSY(I, c); I ideal, c int (optional)
5363RETURN:  a list pr of primary ideals and their associated primes:
5364@format
5365   pr[i][1]   the i-th primary component,
5366   pr[i][2]   the i-th prime component.
5367@end format
5368NOTE:    Algorithm of Shimoyama/Yokoyama.
5369@format
5370   if c=0,  the given ordering of the variables is used,
5371   if c=1,  minAssChar tries to use an optimal ordering (default),
5372   if c=2,  minAssGTZ is used,
5373   if c=3,  minAssGTZ and facstd are used.
5374@end format
5375         For local orderings, the result is considered in the localization
5376         of the polynomial ring, not in the power series ring.
5377         For local and mixed orderings, the decomposition in the
5378         corresponding global ring is returned if the string 'global'
5379         is specified as third argument
5380EXAMPLE: example primdecSY; shows an example
5381"
5382{
5383   if(size(#)>1)
5384   {
5385      int keep_comp=1;
5386   }
5387   if(attrib(basering,"global")!=1)
5388   {
5389// algorithms only work in global case!
5390// pass to appropriate global ring
5391      def r=basering;
5392      def s=changeord(list(list("dp",1:nvars(basering))));
5393      setring s;
5394      ideal i=imap(r,i);
5395// decompose and go back
5396      list li=primdecSY(i);
5397      setring r;
5398      def li=imap(s,li);
5399// clean up
5400      if(!defined(keep_comp))
5401      {
5402         for(int k=size(li);k>=1;k--)
5403         {
5404            if(mindeg(std(lead(li[k][2]))[1])==0)
5405            {
5406// 1 contained in ideal, i.e. component does not meet origin in local ordering
5407               li=delete(li,k);
5408            }
5409         }
5410      }
5411      return(li);
5412   }
5413   i=simplify(i,2);
5414   if ((i[1]==0)||(i[1]==1))
5415   {
5416     list L=list(ideal(i[1]),ideal(i[1]));
5417     return(list(L));
5418   }
5419
5420   if(minpoly!=0)
5421   {
5422      return(algeDeco(i,1));
5423   }
5424   if (size(#)!=0)
5425   { return(prim_dec(i,#[1])); }
5426   else
5427   { return(prim_dec(i,1)); }
5428}
5429example
5430{ "EXAMPLE:";  echo = 2;
5431   ring  r = 0,(x,y,z),lp;
5432   poly  p = z2+1;
5433   poly  q = z3+2;
5434   ideal i = p*q^2,y-z2;
5435   list pr = primdecSY(i);
5436   pr;
5437}
5438///////////////////////////////////////////////////////////////////////////////
5439proc minAssGTZ(ideal i,list #)
5440"USAGE:    minAssGTZ(I[, l]); I ideal, l list (optional)
5441   @* Optional parameters in list l (can be entered in any order):
5442   @* 0, \"facstd\" -> uses facstd to first decompose the ideal (default)
5443   @* 1, \"noFacstd\" -> does not use facstd
5444   @* \"GTZ\" -> the original algorithm by Gianni, Trager and Zacharias is used
5445   @* \"SL\" -> GTZ algorithm with modificiations by Laplagne is used (default)
5446
5447RETURN:  a list, the minimal associated prime ideals of I.
5448NOTE:    - Designed for characteristic 0, works also in char k > 0 based
5449           on an algorithm of Yokoyama
5450         - For local orderings, the result is considered in the localization
5451           of the polynomial ring, not in the power series ring
5452         - For local and mixed orderings, the decomposition in the
5453           corresponding global ring is returned if the string 'global'
5454           is specified as second argument
5455EXAMPLE: example minAssGTZ; shows an example
5456"
5457{
5458   if(size(#)>0)
5459   {
5460      int keep_comp=1;
5461   }
5462
5463  if(attrib(basering,"global")!=1)
5464  {
5465  // algorithms only work in global case!
5466// pass to appropriate global ring
5467      def r=basering;
5468      def s=changeord(list(list("dp",1:nvars(basering))));
5469      setring s;
5470      ideal i=imap(r,i);
5471// decompose and go back
5472      list li=minAssGTZ(i);
5473      setring r;
5474      def li=imap(s,li);
5475// clean up
5476      if(!defined(keep_comp))
5477      {
5478         for(int k=size(li);k>=1;k--)
5479         {
5480            if(mindeg(std(lead(li[k]))[1])==0)
5481            {
5482// 1 contained in ideal, i.e. component does not meet origin in local ordering
5483               li=delete(li,k);
5484            }
5485         }
5486      }
5487      return(li);
5488  }
5489
5490  int j;
5491  string algorithm;
5492  string facstdOption;
5493  int useFac;
5494
5495  // Set input parameters
5496  algorithm = "SL";         // Default: SL algorithm
5497  facstdOption = "facstd";
5498  if(size(#) > 0)
5499  {
5500    int valid;
5501    for(j = 1; j <= size(#); j++)
5502    {
5503      valid = 0;
5504      if((typeof(#[j]) == "int") or (typeof(#[j]) == "number"))
5505      {
5506        if (#[j] == 1) {facstdOption = "noFacstd"; valid = 1;}    // If #[j] == 1, facstd is not used.
5507        if (#[j] == 0) {facstdOption = "facstd";   valid = 1;}    // If #[j] == 0, facstd is used.
5508      }
5509      if(typeof(#[j]) == "string")
5510      {
5511        if((#[j] == "GTZ") || (#[j] == "SL"))
5512        {
5513          algorithm = #[j];
5514          valid = 1;
5515        }
5516        if((#[j] == "noFacstd") || (#[j] == "facstd"))
5517        {
5518          facstdOption = #[j];
5519          valid = 1;
5520        }
5521      }
5522      if(valid == 0)
5523      {
5524        dbprint(1, "Warning! The following input parameter was not recognized:", #[j]);
5525      }
5526    }
5527  }
5528
5529  if(minpoly!=0)
5530  {
5531    return(algeDeco(i,2));
5532  }
5533
5534  list result = minAssPrimes(i, facstdOption, algorithm);
5535  return(result);
5536}
5537example
5538{ "EXAMPLE:";  echo = 2;
5539   ring  r = 0,(x,y,z),dp;
5540   poly  p = z2+1;
5541   poly  q = z3+2;
5542   ideal i = p*q^2,y-z2;
5543   list pr = minAssGTZ(i);
5544   pr;
5545}
5546
5547///////////////////////////////////////////////////////////////////////////////
5548proc minAssChar(ideal i, list #)
5549"USAGE:   minAssChar(I[,c]); i ideal, c int (optional).
5550RETURN:  list, the minimal associated prime ideals of i.
5551NOTE:    If c=0, the given ordering of the variables is used. @*
5552         Otherwise, the system tries to find an optimal ordering,
5553         which in some cases may considerably speed up the algorithm. @*
5554         For local orderings, the result is considered in the localization
5555         of the polynomial ring, not in the power series ring
5556         For local and mixed orderings, the decomposition in the
5557         corresponding global ring is returned if the string 'global'
5558         is specified as third argument
5559EXAMPLE: example minAssChar; shows an example
5560"
5561{
5562   if(size(#)>1)
5563   {
5564      int keep_comp=1;
5565   }
5566   if(attrib(basering,"global")!=1)
5567   {
5568// algorithms only work in global case!
5569// pass to appropriate global ring
5570      def r=basering;
5571      def s=changeord(list(list("dp",1:nvars(basering))));
5572      setring s;
5573      ideal i=imap(r,i);
5574// decompose and go back
5575      list li=minAssChar(i);
5576      setring r;
5577      def li=imap(s,li);
5578// clean up
5579      if(!defined(keep_comp))
5580      {
5581         for(int k=size(li);k>=1;k--)
5582         {
5583            if(mindeg(std(lead(li[k]))[1])==0)
5584            {
5585// 1 contained in ideal, i.e. component does not meet origin in local ordering
5586               li=delete(li,k);
5587            }
5588         }
5589      }
5590      return(li);
5591   }
5592   if (size(#)>0)
5593   { return(min_ass_prim_charsets(i,#[1])); }
5594   else
5595   { return(min_ass_prim_charsets(i,1)); }
5596}
5597example
5598{ "EXAMPLE:";  echo = 2;
5599   ring  r = 0,(x,y,z),dp;
5600   poly  p = z2+1;
5601   poly  q = z3+2;
5602   ideal i = p*q^2,y-z2;
5603   list pr = minAssChar(i);
5604   pr;
5605}
5606///////////////////////////////////////////////////////////////////////////////
5607proc equiRadical(ideal i)
5608"USAGE:   equiRadical(I); I ideal
5609RETURN:  ideal, intersection of associated primes of I of maximal dimension.
5610NOTE:    A combination of the algorithms of Krick/Logar (with modifications by Laplagne) and Kemper is used.
5611         Works also in positive characteristic (Kempers algorithm).
5612EXAMPLE: example equiRadical; shows an example
5613"
5614{
5615  if(attrib(basering,"global")!=1)
5616  {
5617     ERROR(
5618     "// Not implemented for this ordering, please change to global ordering."
5619     );
5620  }
5621  return(radical(i, 1));
5622}
5623example
5624{ "EXAMPLE:";  echo = 2;
5625   ring  r = 0,(x,y,z),dp;
5626   poly  p = z2+1;
5627   poly  q = z3+2;
5628   ideal i = p*q^2,y-z2;
5629   ideal pr= equiRadical(i);
5630   pr;
5631}
5632
5633///////////////////////////////////////////////////////////////////////////////
5634proc radical(ideal i, list #)
5635"USAGE: radical(I[, l]); I ideal, l list (optional)
5636 @*  Optional parameters in list l (can be entered in any order):
5637 @*  0, \"fullRad\" -> full radical is computed (default)
5638 @*  1, \"equiRad\" -> equiRadical is computed
5639 @*  \"KL\" -> Krick/Logar algorithm is used
5640 @*  \"SL\" -> modifications by Laplagne are used (default)
5641 @*  \"facstd\" -> uses facstd to first decompose the ideal (default for non homogeneous ideals)
5642 @*  \"noFacstd\" -> does not use facstd (default for homogeneous ideals)
5643RETURN:  ideal, the radical of I (or the equiradical if required in the input parameters)
5644NOTE:    A combination of the algorithms of Krick/Logar (with modifications by Laplagne) and Kemper is used.
5645         Works also in positive characteristic (Kempers algorithm).
5646EXAMPLE: example radical; shows an example
5647"
5648{
5649  dbprint(printlevel - voice, "Radical, version 2006.05.08");
5650  if(attrib(basering,"global")!=1)
5651  {
5652// algorithms only work in global case!
5653// pass to appropriate global ring
5654      def r=basering;
5655      def s=changeord(list(list("dp",1:nvars(basering))));
5656      setring s;
5657      ideal i=imap(r,i);
5658// compute radical and go back
5659      def j=radical(i);
5660      setring r;
5661      def j=imap(s,j);
5662      return(j);
5663  }
5664  if(size(i) == 0){return(ideal(0));}
5665  int j;
5666  def P0 = basering;
5667  list Pl=ringlist(P0);
5668  intvec dp_w;
5669  for(j=nvars(P0);j>0;j--) {dp_w[j]=1;}
5670  Pl[3]=list(list("dp",dp_w),list("C",0));
5671  def @P=ring(Pl);
5672  setring @P;
5673  ideal i=imap(P0,i);
5674
5675  int il;
5676  string algorithm;
5677  int useFac;
5678
5679  // Set input parameters
5680  algorithm = "SL";                                 // Default: SL algorithm
5681  il = 0;                                           // Default: Full radical (not only equiRadical)
5682  if (homog(i) == 1)
5683  {   // Default: facStd is used, except if the ideal is homogeneous.
5684    useFac = 0;
5685  }
5686  else
5687  {
5688    useFac = 1;
5689  }
5690  if(size(#) > 0)
5691  {
5692    int valid;
5693    for(j = 1; j <= size(#); j++)
5694    {
5695      valid = 0;
5696      if((typeof(#[j]) == "int") or (typeof(#[j]) == "number"))
5697      {
5698        il = #[j];          // If il == 1, equiRadical is computed
5699        valid = 1;
5700      }
5701      if(typeof(#[j]) == "string")
5702      {
5703        if(#[j] == "KL")
5704        {
5705          algorithm = "KL";
5706          valid = 1;
5707        }
5708        if(#[j] == "SL")
5709        {
5710          algorithm = "SL";
5711          valid = 1;
5712        }
5713        if(#[j] == "noFacstd")
5714        {
5715          useFac = 0;
5716          valid = 1;
5717        }
5718        if(#[j] == "facstd")
5719        {
5720          useFac = 1;
5721          valid = 1;
5722        }
5723        if(#[j] == "equiRad")
5724        {
5725          il = 1;
5726          valid = 1;
5727        }
5728        if(#[j] == "fullRad")
5729        {
5730          il = 0;
5731          valid = 1;
5732        }
5733      }
5734      if(valid == 0)
5735      {
5736        dbprint(1, "Warning! The following input parameter was not recognized:", #[j]);
5737      }
5738    }
5739  }
5740
5741  ideal rad = 1;
5742  intvec op = option(get);
5743  list qr = simplifyIdeal(i);
5744  map phi = @P, qr[2];
5745
5746  option(redSB);
5747  i = groebner(qr[1]);
5748  option(set, op);
5749  int di = dim(i);
5750
5751  if(di == 0)
5752  {
5753    i = zeroRad(i, qr[1]);
5754    option(redSB);
5755    i=interred(phi(i));
5756    option(set, op);
5757    setring(P0);
5758    i=imap(@P,i);
5759    return(i);
5760  }
5761
5762  option(redSB);
5763  list pr;
5764  if(useFac == 1)
5765  {
5766    pr = facstd(i);
5767  }
5768  else
5769  {
5770    pr = i;
5771  }
5772  option(set, op);
5773  int s = size(pr);
5774  if(useFac == 1)
5775  {
5776    dbprint(printlevel - voice, "Number of components returned by facstd: ", s);
5777  }
5778  for(j = 1; j <= s; j++)
5779  {
5780    attrib(pr[s + 1 - j], "isSB", 1);
5781    if((size(reduce(rad, pr[s + 1 - j], 1)) != 0) && ((dim(pr[s + 1 - j]) == di) || !il))
5782    {
5783      // SL Debug messages
5784      dbprint(printlevel-voice, "We shall compute the radical of ", pr[s + 1 - j]);
5785      dbprint(printlevel-voice, "The dimension is: ", dim(pr[s+1-j]));
5786
5787      if(algorithm == "KL")
5788      {
5789        rad = intersect(rad, radicalKL(pr[s + 1 - j], rad, il));
5790      }
5791      if(algorithm == "SL")
5792      {
5793        rad = intersect(rad, radicalSL(pr[s + 1 - j], il));
5794      }
5795    }
5796    else
5797    {
5798      // SL Debug
5799      dbprint(printlevel-voice, "The radical of this component is not needed.");
5800      dbprint(printlevel-voice, "size(reduce(rad, pr[s + 1 - j], 1))",
5801              size(reduce(rad, pr[s + 1 - j], 1)));
5802      dbprint(printlevel-voice, "dim(pr[s + 1 - j])", dim(pr[s + 1 - j]));
5803      dbprint(printlevel-voice, "il", il);
5804    }
5805  }
5806  rad=interred(phi(rad));
5807  setring(P0);
5808  i=imap(@P,rad);
5809  return(i);
5810}
5811example
5812{ "EXAMPLE:";  echo = 2;
5813   ring  r = 0,(x,y,z),dp;
5814   poly  p = z2+1;
5815   poly  q = z3+2;
5816   ideal i = p*q^2,y-z2;
5817   ideal pr = radical(i);
5818   pr;
5819}
5820
5821///////////////////////////////////////////////////////////////////////////////
5822//
5823// Computes the radical of I using KL algorithm.
5824// The only difference with the previous implementation of KL algorithm is
5825// that now it uses block dp instead of lp ordering for the reduction to the
5826// zerodimensional case.
5827// The reduction step has been moved to the new routine radicalReduction, so that it can be
5828// used also by radicalSL procedure.
5829//
5830static proc radicalKL(ideal I, ideal ser, list #)
5831{
5832// ideal I     The ideal for which the radical is computed
5833// ideal ser   Used to reduce components already obtained
5834// list #      If #[1] = 1, equiradical is computed.
5835
5836  // I needs to be a Groebner basis.
5837  if (attrib(I, "isSB") != 1)
5838  {
5839    I = groebner(I);
5840  }
5841
5842  ideal rad;                                // The radical
5843  int allIndep = 1;                // All max independent sets are used
5844
5845  list result = radicalReduction(I, ser, allIndep, #);
5846  int done = result[3];
5847  rad = result[1];
5848  if (done == 0)
5849  {
5850    rad = intersect(rad, radicalKL(result[2], ideal(1), #));
5851  }
5852  return(rad);
5853}
5854
5855
5856///////////////////////////////////////////////////////////////////////////////
5857//
5858// Computes the radical of I via Laplagne algorithm, using zerodimensional radical in
5859// the zero dimensional case.
5860// For the reduction to the zerodimensional case, it uses the procedure
5861// radical, with some modifications to avoid the recursion.
5862//
5863static proc radicalSL(ideal I, list #)
5864// Input = I, ideal
5865//         #, list. If #[1] = 1, then computes only the equiradical.
5866// Output = (P, primaryDec) where P = rad(I) and primaryDec is the list of the radicals
5867// obtained in intermediate steps.
5868{
5869  ideal rad = 1;
5870  ideal equiRad = 1;
5871  list primes;
5872  int k;                        // Counter
5873  int il;                 // If il = 1, only the equiradical is required.
5874  int iDim;                // The dimension of I
5875  int stop = 0;   // Checks if the radical has been obtained
5876
5877  if (attrib(I, "isSB") != 1)
5878  {
5879    I = groebner(I);
5880  }
5881  iDim = dim(I);
5882
5883  // Checks if only equiradical is required
5884  if (size(#) > 0)
5885  {
5886    il = #[1];
5887  }
5888
5889  while(stop == 0)
5890  {
5891    dbprint (printlevel-voice, "// We call radLoopR to find new prime ideals.");
5892    primes = radicalSLIteration(I, rad);                         // A list of primes or intersections of primes, not included in P
5893    dbprint (printlevel - voice, "// Output of Iteration Step:");
5894    dbprint (printlevel - voice, primes);
5895    if (size(primes) > 0)
5896    {
5897      dbprint (printlevel - voice, "// We intersect P with the ideal just obtained.");
5898      for(k = 1; k <= size(primes); k++)
5899      {
5900        rad = intersect(rad, primes[k]);
5901        if (il == 1)
5902        {
5903          if (attrib(primes[k], "isSB") != 1)
5904          {
5905            primes[k] = groebner(primes[k]);
5906          }
5907          if (iDim == dim(primes[k]))
5908          {
5909            equiRad = intersect(equiRad, primes[k]);
5910          }
5911        }
5912      }
5913    }
5914    else
5915    {
5916      stop = 1;
5917    }
5918  }
5919  if (il == 0)
5920  {
5921    return(rad);
5922  }
5923  else
5924  {
5925    return(equiRad);
5926  }
5927}
5928
5929//////////////////////////////////////////////////////////////////////////
5930// Based on radicalKL.
5931// It contains all of old version of proc radicalKL except the recursion call.
5932//
5933// Output:
5934// #1 -> output ideal, the part of the radical that has been computed
5935// #2 -> complementary ideal, the part of the ideal I whose radical remains to be computed
5936//       = (I, h) in KL algorithm
5937//       This is not used in the new algorithm. It is part of KL algorithm
5938// #3 -> done, 1: output = radical, there is no need to continue
5939//                   0: radical = output \cap \sqrt{complementary ideal}
5940//       This is not used in the new algorithm. It is part of KL algorithm
5941
5942static proc radicalReduction(ideal I, ideal ser, int allIndep, list #)
5943{
5944// allMaximal      1 -> Indicates that the reduction to the zerodim case
5945//                    must be done for all indep set of the leading terms ideal
5946//                 0 -> Otherwise
5947// ideal ser       Only for radicalKL. (Same as in radicalKL)
5948// list #          Only for radicalKL (If #[1] = 1,
5949//                    only equiradical is required.
5950//                    It is used to set the value of done.)
5951
5952  attrib(I, "isSB", 1);   // I needs to be a reduced standard basis
5953  list indep, fett;
5954  intvec @w, @hilb, op;
5955  int @wr, @n, @m, lauf, di;
5956  ideal fac, @h, collectrad, lsau;
5957  poly @q;
5958  string @va, quotring;
5959
5960  def @P = basering;
5961  int jdim = dim(I);               // Computes the dimension of I
5962  int  homo = homog(I);            // Finds out if I is homogeneous
5963  ideal rad = ideal(1);            // The unit ideal
5964  ideal te = ser;
5965  if(size(#) > 0)
5966  {
5967    @wr = #[1];
5968  }
5969  if(homo == 1)
5970  {
5971    for(@n = 1; @n <= nvars(basering); @n++)
5972    {
5973      @w[@n] = ord(var(@n));
5974    }
5975    @hilb = hilb(I, 1, @w);
5976  }
5977
5978  // SL 2006.04.11 1 Debug messages
5979  dbprint(printlevel-voice, "//Computes the radical of the ideal:", I);
5980  // SL 2006.04.11 2 Debug messages
5981
5982  //---------------------------------------------------------------------------
5983  //j is the ring
5984  //---------------------------------------------------------------------------
5985
5986  if (jdim==-1)
5987  {
5988    return(ideal(1), ideal(1), 1);
5989  }
5990
5991  //---------------------------------------------------------------------------
5992  //the zero-dimensional case
5993  //---------------------------------------------------------------------------
5994
5995  if (jdim==0)
5996  {
5997    return(zeroRad(I), ideal(1), 1);
5998  }
5999
6000  //-------------------------------------------------------------------------
6001  //search for a maximal independent set indep,i.e.
6002  //look for subring such that the intersection with the ideal is zero
6003  //j intersected with K[var(indep[3]+1),...,var(nvar)] is zero,
6004  //indep[1] is the new varstring, indep[2] the string for the block-ordering
6005  //-------------------------------------------------------------------------
6006
6007  // SL 2006-04-24 1   If allIndep = 0, then it only computes one maximal
6008  //                     independent set.
6009  //                     This looks better for the new algorithm but not for KL
6010  //                     algorithm
6011  list parameters = allIndep;
6012  indep = newMaxIndependSetDp(I, parameters);
6013  // SL 2006-04-24 2
6014
6015  for(@m = 1; @m <= size(indep); @m++)
6016  {
6017    if((indep[@m][1] == varstr(basering)) && (@m == 1))
6018    //this is the good case, nothing to do, just to have the same notations
6019    //change the ring
6020    {
6021      execute("ring gnir1 = ("+charstr(basering)+"),("+varstr(basering)+"),("
6022                              +ordstr(basering)+");");
6023      ideal @j = fetch(@P, I);
6024      attrib(@j, "isSB", 1);
6025    }
6026    else
6027    {
6028      @va = string(maxideal(1));
6029
6030      execute("ring gnir1 = (" + charstr(basering) + "), (" + indep[@m][1] + "),("
6031                              + indep[@m][2] + ");");
6032      execute("map phi = @P," + @va + ";");
6033      if(homo == 1)
6034      {
6035        ideal @j = std(phi(I), @hilb, @w);
6036      }
6037      else
6038      {
6039        ideal @j = groebner(phi(I));
6040      }
6041    }
6042    if((deg(@j[1]) == 0) || (dim(@j) < jdim))
6043    {
6044      setring @P;
6045      break;
6046    }
6047    for (lauf = 1; lauf <= size(@j); lauf++)
6048    {
6049      fett[lauf] = size(@j[lauf]);
6050    }
6051    //------------------------------------------------------------------------
6052    // We have now the following situation:
6053    // j intersected with K[var(nnp+1),..,var(nva)] is zero so we may pass
6054    // to this quotientring, j is there still a standardbasis, the
6055    // leading coefficients of the polynomials there (polynomials in
6056    // K[var(nnp+1),..,var(nva)]) are collected in the list h,
6057    // we need their LCM, gh, because of the following:
6058    // let (j:gh^n)=(j:gh^infinity) then j*K(var(nnp+1),..,var(nva))[..rest..]
6059    // intersected with K[var(1),...,var(nva)] is (j:gh^n)
6060    // on the other hand j = ((j, gh^n) intersected with (j : gh^n))
6061
6062    //------------------------------------------------------------------------
6063    // The arrangement for the quotientring K(var(nnp+1),..,var(nva))[..rest..]
6064    // and the map phi:K[var(1),...,var(nva)] ----->
6065    // K(var(nnpr+1),..,var(nva))[..the rest..]
6066    //------------------------------------------------------------------------
6067    quotring = prepareQuotientRingDp(nvars(basering) - indep[@m][3]);
6068    //------------------------------------------------------------------------
6069    // We pass to the quotientring   K(var(nnp+1),..,var(nva))[..the rest..]
6070    //------------------------------------------------------------------------
6071
6072    execute(quotring);
6073
6074    // @j considered in the quotientring
6075    ideal @j = imap(gnir1, @j);
6076
6077    kill gnir1;
6078
6079    // j is a standardbasis in the quotientring but usually not minimal
6080    // here it becomes minimal
6081
6082    @j = clearSB(@j, fett);
6083
6084    // We need later LCM(h[1],...) = gh for saturation
6085    ideal @h;
6086    if(deg(@j[1]) > 0)
6087    {
6088      for(@n = 1; @n <= size(@j); @n++)
6089      {
6090        @h[@n] = leadcoef(@j[@n]);
6091      }
6092      op = option(get);
6093      option(redSB);
6094      @j = std(@j);  //to obtain a reduced standardbasis
6095      option(set, op);
6096
6097      // SL 1 Debug messages
6098      dbprint(printlevel - voice, "zero_rad", basering, @j, dim(groebner(@j)));
6099      ideal zero_rad = zeroRad(@j);
6100      dbprint(printlevel - voice, "zero_rad passed");
6101      // SL 2
6102    }
6103    else
6104    {
6105      ideal zero_rad = ideal(1);
6106    }
6107
6108    // We need the intersection of the ideals in the list quprimary with the
6109    // polynomialring, i.e. let q=(f1,...,fr) in the quotientring such an ideal
6110    // but fi polynomials, then the intersection of q with the polynomialring
6111    // is the saturation of the ideal generated by f1,...,fr with respect to
6112    // h which is the lcm of the leading coefficients of the fi considered in
6113    // the quotientring: this is coded in saturn
6114
6115    zero_rad = std(zero_rad);
6116
6117    ideal hpl;
6118
6119    for(@n = 1; @n <= size(zero_rad); @n++)
6120    {
6121      hpl = hpl, leadcoef(zero_rad[@n]);
6122    }
6123
6124    //------------------------------------------------------------------------
6125    // We leave  the quotientring   K(var(nnp+1),..,var(nva))[..the rest..]
6126    // back to the polynomialring
6127    //------------------------------------------------------------------------
6128    setring @P;
6129
6130    collectrad = imap(quring, zero_rad);
6131    lsau = simplify(imap(quring, hpl), 2);
6132    @h = imap(quring, @h);
6133
6134    kill quring;
6135
6136    // Here the intersection with the polynomialring
6137    // mentioned above is really computed
6138
6139    collectrad = sat2(collectrad, lsau)[1];
6140    if(deg(@h[1])>=0)
6141    {
6142      fac = ideal(0);
6143      for(lauf = 1; lauf <= ncols(@h); lauf++)
6144      {
6145        if(deg(@h[lauf]) > 0)
6146        {
6147          fac = fac + factorize(@h[lauf], 1);
6148        }
6149      }
6150      fac = simplify(fac, 6);
6151      @q = 1;
6152      for(lauf = 1; lauf <= size(fac); lauf++)
6153      {
6154        @q = @q * fac[lauf];
6155      }
6156      op = option(get);
6157      option(returnSB);
6158      option(redSB);
6159      I = quotient(I + ideal(@q), rad);
6160      attrib(I, "isSB", 1);
6161      option(set, op);
6162    }
6163    if((deg(rad[1]) > 0) && (deg(collectrad[1]) > 0))
6164    {
6165      rad = intersect(rad, collectrad);
6166      te = intersect(te, collectrad);
6167      te = simplify(reduce(te, I, 1), 2);
6168    }
6169    else
6170    {
6171      if(deg(collectrad[1]) > 0)
6172      {
6173        rad = collectrad;
6174        te = intersect(te, collectrad);
6175        te = simplify(reduce(te, I, 1), 2);
6176      }
6177    }
6178
6179    if((dim(I) < jdim)||(size(te) == 0))
6180    {
6181      break;
6182    }
6183    if(homo==1)
6184    {
6185      @hilb = hilb(I, 1, @w);
6186    }
6187  }
6188
6189  // SL 2006.04.11 1 Debug messages
6190  dbprint (printlevel-voice, "// Part of the Radical already computed:", rad);
6191  dbprint (printlevel-voice, "// Dimension:", dim(groebner(rad)));
6192  // SL 2006.04.11 2 Debug messages
6193
6194  // SL 2006.04.21 1    New variable "done".
6195  //                      It tells if the radical is already computed or
6196  //                      if it still has to be computed the radical of the new ideal I
6197  int done;
6198  if(((@wr == 1) && (dim(I)<jdim)) || (deg(I[1])==0) || (size(te) == 0))
6199  {
6200    done = 1;
6201  }
6202  else
6203  {
6204    done = 0;
6205  }
6206  // SL 2006.04.21 2
6207
6208  // SL 2006.04.21 1     See details of the output at the beginning of this proc.
6209  list result = rad, I, done;
6210  return(result);
6211  // SL 2006.04.21 2
6212}
6213
6214///////////////////////////////////////////////////////////////////////////////
6215// Given an ideal I and an ideal P (intersection of some minimal prime ideals
6216// associated to I), it calculates the intersection of new minimal prime ideals
6217// associated to I which where not used to calculate P.
6218// This version uses ZD Radical in the zerodimensional case.
6219static proc radicalSLIteration (ideal I, ideal P);
6220// Input: I, ideal. The ideal from which new prime components will be obtained.
6221//        P, ideal. Intersection of some prime ideals of I.
6222// Output: ideal. Intersection of some primes of I different from the ones in P.
6223{
6224  int k = 1;                     // Counter
6225  int good  = 0;                 // Checks if an element of P is in rad(I)
6226
6227  dbprint (printlevel-voice, "// We search for an element in P - sqrt(I).");
6228  while ((k <= size(P)) and (good == 0))
6229  {
6230    dbprint (printlevel-voice, "// We try with:", P[k]);
6231    good = 1 - rad_con(P[k], I);
6232    k++;
6233  }
6234  k--;
6235  if (good == 0)
6236  {
6237    dbprint (printlevel-voice, "// No element was found, P = sqrt(I).");
6238    list emptyList = list();
6239    return (emptyList);
6240  }
6241  dbprint(printlevel - voice, "// That one was good!");
6242  dbprint(printlevel - voice, "// We saturate I with respect to this element.");
6243  if (P[k] != 1)
6244  {
6245    intvec oo=option(get);
6246    option(redSB);
6247    ideal J = sat(I, P[k])[1];
6248    option(set,oo);
6249
6250  }
6251  else
6252  {
6253    dbprint(printlevel - voice, "// The polynomial is 1, the saturation in not actually computed.");
6254    ideal J = I;
6255  }
6256
6257  // We now call proc radicalNew;
6258  dbprint(printlevel - voice, "// We do the reduction to the zerodimensional case, via radical.");
6259  dbprint(printlevel - voice, "// The ideal is ", J);
6260  dbprint(printlevel - voice, "// The dimension is ", dim(groebner(J)));
6261
6262  int allMaximal = 0;   // Compute the zerodim reduction for only one indep set.
6263  ideal re = 1;         // No reduction is need,
6264                        //    there are not redundant components.
6265  list emptyList = list();   // Look for primes of any dimension,
6266                             //   not only of max dimension.
6267  list result = radicalReduction(J, re, allMaximal, emptyList);
6268
6269  return(result[1]);
6270}
6271
6272///////////////////////////////////////////////////////////////////////////////////
6273// Based on maxIndependSet
6274// Added list # as parameter
6275// If the first element of # is 0, the output is only 1 max indep set.
6276// If no list is specified or #[1] = 1, the output is all the max indep set of the
6277// leading terms ideal. This is the original output of maxIndependSet
6278
6279// The ordering given in the output has been changed to block dp instead of lp.
6280
6281proc newMaxIndependSetDp(ideal j, list #)
6282"USAGE:   newMaxIndependentSetDp(I); I ideal (returns all maximal independent sets of the corresponding leading terms ideal)
6283          newMaxIndependentSetDp(I, 0); I ideal (returns only one maximal independent set)
6284RETURN:  list = #1. new varstring with the maximal independent set at the end,
6285                #2. ordstring with the corresponding dp block ordering,
6286                #3. the number of independent variables
6287NOTE:
6288EXAMPLE: example newMaxIndependentSetDp; shows an example
6289"
6290{
6291  int n, k, di;
6292  list resu, hilf;
6293  string var1, var2;
6294  list v = indepSet(j, 0);
6295
6296  // SL 2006.04.21 1 Lines modified to use only one independent Set
6297  int allMaximal;
6298  if (size(#) > 0)
6299  {
6300    allMaximal = #[1];
6301  }
6302  else
6303  {
6304    allMaximal = 1;
6305  }
6306
6307  int nMax;
6308  if (allMaximal == 1)
6309  {
6310    nMax = size(v);
6311  }
6312  else
6313  {
6314    nMax = 1;
6315  }
6316
6317  for(n = 1; n <= nMax; n++)
6318  // SL 2006.04.21 2
6319  {
6320    di = 0;
6321    var1 = "";
6322    var2 = "";
6323    for(k = 1; k <= size(v[n]); k++)
6324    {
6325     if(v[n][k] != 0)
6326      {
6327        di++;
6328        var2 = var2 + "var(" + string(k) + "), ";
6329      }
6330      else
6331      {
6332        var1 = var1 + "var(" + string(k) + "), ";
6333      }
6334    }
6335    if(di > 0)
6336    {
6337      var1 = var1 + var2;
6338      var1 = var1[1..size(var1) - 2];                         // The "- 2" removes the trailer comma
6339      hilf[1] = var1;
6340      // SL 2006.21.04 1 The order is now block dp instead of lp
6341      hilf[2] = "dp(" + string(nvars(basering) - di) + "), dp(" + string(di) + ")";
6342      // SL 2006.21.04 2
6343      hilf[3] = di;
6344      resu[n] = hilf;
6345    }
6346    else
6347    {
6348      resu[n] = varstr(basering), ordstr(basering), 0;
6349    }
6350  }
6351  return(resu);
6352}
6353example
6354{ "EXAMPLE:"; echo = 2;
6355   ring s1 = (0, x, y), (a, b, c, d, e, f, g), lp;
6356   ideal i = ea - fbg, fa + be, ec - fdg, fc + de;
6357   i = std(i);
6358   list l = newMaxIndependSetDp(i);
6359   l;
6360   i = i, g;
6361   l = newMaxIndependSetDp(i);
6362   l;
6363
6364   ring s = 0, (x, y, z), lp;
6365   ideal i = z, yx;
6366   list l = newMaxIndependSetDp(i);
6367   l;
6368}
6369
6370
6371///////////////////////////////////////////////////////////////////////////////
6372// based on prepareQuotientring
6373// The order returned is now (C, dp) instead of (C, lp)
6374
6375static proc prepareQuotientRingDp (int nnp)
6376"USAGE:   prepareQuotientRingDp(nnp); nnp int
6377RETURN:  string = to define Kvar(nnp+1),...,var(nvars)[..rest ]
6378NOTE:
6379EXAMPLE: example prepareQuotientRingDp; shows an example
6380"
6381{
6382  ideal @ih,@jh;
6383  int npar=npars(basering);
6384  int @n;
6385
6386  string quotring= "ring quring = ("+charstr(basering);
6387  for(@n = nnp + 1; @n <= nvars(basering); @n++)
6388  {
6389     quotring = quotring + ", var(" + string(@n) + ")";
6390     @ih = @ih + var(@n);
6391  }
6392
6393  quotring = quotring+"),(var(1)";
6394  @jh = @jh + var(1);
6395  for(@n = 2; @n <= nnp; @n++)
6396  {
6397    quotring = quotring + ", var(" + string(@n) + ")";
6398    @jh = @jh + var(@n);
6399  }
6400  // SL 2006-04-21 1 The order returned is now (C, dp) instead of (C, lp)
6401  quotring = quotring + "), (C, dp);";
6402  // SL 2006-04-21 2
6403
6404  return(quotring);
6405}
6406example
6407{ "EXAMPLE:"; echo = 2;
6408   ring s1=(0,x),(a,b,c,d,e,f,g),lp;
6409   def @Q=basering;
6410   list l= prepareQuotientRingDp(3);
6411   l;
6412   execute(l[1]);
6413   execute(l[2]);
6414   basering;
6415   phi;
6416   setring @Q;
6417
6418}
6419
6420///////////////////////////////////////////////////////////////////////////////
6421proc prepareAss(ideal i)
6422"USAGE:   prepareAss(I); I ideal
6423RETURN:  list, the radicals of the maximal dimensional components of I.
6424NOTE:    Uses algorithm of Eisenbud/Huneke/Vasconcelos.
6425EXAMPLE: example prepareAss; shows an example
6426"
6427{
6428  if(attrib(basering,"global")!=1)
6429  {
6430      ERROR(
6431      "// Not implemented for this ordering, please change to global ordering."
6432      );
6433  }
6434  ideal j=std(i);
6435  int cod=nvars(basering)-dim(j);
6436  int e;
6437  list er;
6438  ideal ann;
6439  if(homog(i)==1)
6440  {
6441     list re=sres(j,0);                   //the resolution
6442     re=minres(re);                       //minimized resolution
6443  }
6444  else
6445  {
6446    list re=mres(i,0);
6447  }
6448  for(e=cod;e<=nvars(basering);e++)
6449  {
6450     ann=AnnExt_R(e,re);
6451
6452     if(nvars(basering)-dim(std(ann))==e)
6453     {
6454        er[size(er)+1]=equiRadical(ann);
6455     }
6456  }
6457  return(er);
6458}
6459example
6460{ "EXAMPLE:";  echo = 2;
6461   ring  r = 0,(x,y,z),dp;
6462   poly  p = z2+1;
6463   poly  q = z3+2;
6464   ideal i = p*q^2,y-z2;
6465   list pr = prepareAss(i);
6466   pr;
6467}
6468///////////////////////////////////////////////////////////////////////////////
6469proc equidimMaxEHV(ideal i)
6470"USAGE:  equidimMaxEHV(I); I ideal
6471RETURN:  ideal, the equidimensional component (of maximal dimension) of I.
6472NOTE:    Uses algorithm of Eisenbud, Huneke and Vasconcelos.
6473EXAMPLE: example equidimMaxEHV; shows an example
6474"
6475{
6476  if(attrib(basering,"global")!=1)
6477  {
6478      ERROR(
6479      "// Not implemented for this ordering, please change to global ordering."
6480      );
6481  }
6482  ideal j=groebner(i);
6483  int cod=nvars(basering)-dim(j);
6484  int e;
6485  ideal ann;
6486  if(homog(i)==1)
6487  {
6488     list re=sres(j,0);                   //the resolution
6489     re=minres(re);                       //minimized resolution
6490  }
6491  else
6492  {
6493    list re=mres(i,0);
6494  }
6495  ann=AnnExt_R(cod,re);
6496  return(ann);
6497}
6498example
6499{ "EXAMPLE:";  echo = 2;
6500   ring  r = 0,(x,y,z),dp;
6501   ideal i=intersect(ideal(z),ideal(x,y),ideal(x2,z2),ideal(x5,y5,z5));
6502   equidimMaxEHV(i);
6503}
6504
6505proc testPrimary(list pr, ideal k)
6506"USAGE:   testPrimary(pr,k); pr a list, k an ideal.
6507ASSUME:  pr is the result of primdecGTZ(k) or primdecSY(k).
6508RETURN:  int, 1 if the intersection of the ideals in pr is k, 0 if not
6509EXAMPLE: example testPrimary; shows an example
6510"
6511{
6512   int i;
6513   pr=reconvList(pr);
6514   ideal j=pr[1];
6515   for (i=2;i<=size(pr) div 2;i++)
6516   {
6517       j=intersect(j,pr[2*i-1]);
6518   }
6519   return(idealsEqual(j,k));
6520}
6521example
6522{ "EXAMPLE:";  echo = 2;
6523   ring  r = 32003,(x,y,z),dp;
6524   poly  p = z2+1;
6525   poly  q = z4+2;
6526   ideal i = p^2*q^3,(y-z3)^3,(x-yz+z4)^4;
6527   list pr = primdecGTZ(i);
6528   testPrimary(pr,i);
6529}
6530
6531///////////////////////////////////////////////////////////////////////////////
6532proc zerodec(ideal I)
6533"USAGE:   zerodec(I); I ideal
6534ASSUME:  I is zero-dimensional, the characteristic of the ground field is 0
6535RETURN:  list of primary ideals, the zero-dimensional decomposition of I
6536NOTE:    The algorithm (of Monico), works well only for a small total number
6537         of solutions (@code{vdim(std(I))} should be < 100) and without
6538         parameters. In practice, it works also in large characteristic p>0
6539         but may fail for small p.
6540@*       If printlevel > 0 (default = 0) additional information is displayed.
6541EXAMPLE: example zerodec; shows an example
6542"
6543{
6544  if(attrib(basering,"global")!=1)
6545  {
6546    ERROR(
6547    "// Not implemented for this ordering, please change to global ordering."
6548    );
6549  }
6550  def R=basering;
6551  poly q;
6552  int j,time;
6553  matrix m;
6554  list re;
6555  poly va=var(1);
6556  ideal J=groebner(I);
6557  ideal ba=kbase(J);
6558  int d=vdim(J);
6559  dbprint(printlevel-voice+2,"// multiplicity of ideal : "+ string(d));
6560//------ compute matrix of multiplication on R/I with generic element p -----
6561  int e=nvars(basering);
6562  poly p=randomLast(100)[e]+random(-50,50);     //the generic element
6563  matrix n[d][d];
6564  time = timer;
6565  for(j=2;j<=e;j++)
6566  {
6567    va=va*var(j);
6568  }
6569  for(j=1;j<=d;j++)
6570  {
6571    q=reduce(p*ba[j],J);
6572    m=coeffs(q,ba,va);
6573    n[j,1..d]=m[1..d,1];
6574  }
6575  dbprint(printlevel-voice+2,
6576    "// time for computing multiplication matrix (with generic element) : "+
6577    string(timer-time));
6578//---------------- compute characteristic polynomial of matrix --------------
6579  execute("ring P1=("+charstr(R)+"),T,dp;");
6580  matrix n=imap(R,n);
6581  time = timer;
6582  poly charpol=det(n-T*freemodule(d));
6583  dbprint(printlevel-voice+2,"// time for computing char poly: "+
6584         string(timer-time));
6585//------------------- factorize characteristic polynomial -------------------
6586//check first if constant term of charpoly is != 0 (which is true for
6587//sufficiently generic element)
6588  if(charpol[size(charpol)]!=0)
6589  {
6590    time = timer;
6591    list fac=factor(charpol);
6592    testFactor(fac,charpol);
6593    dbprint(printlevel-voice+2,"// time for factorizing char poly: "+
6594            string(timer-time));
6595    int f=size(fac[1]);
6596//--------------------------- the irreducible case --------------------------
6597    if(f==1)
6598    {
6599      setring R;
6600      re=I;
6601      return(re);
6602    }
6603//---------------------------- the reducible case ---------------------------
6604//if f_i are the irreducible factors of charpoly, mult=ri, then <I,g_i^ri>
6605//are the primary components where g_i = f_i(p). However, substituting p in
6606//f_i may result in a huge object although the final result may be small.
6607//Hence it is better to simultaneously reduce with I. For this we need a new
6608//ring.
6609    execute("ring P=("+charstr(R)+"),(T,"+varstr(R)+"),(dp(1),dp);");
6610    list rfac=imap(P1,fac);
6611    intvec ov=option(get);;
6612    option(redSB);
6613    list re1;
6614    ideal new = T-imap(R,p),imap(R,J);
6615    attrib(new, "isSB",1);    //we know that new is a standard basis
6616    for(j=1;j<=f;j++)
6617    {
6618      re1[j]=reduce(rfac[1][j]^rfac[2][j],new);
6619    }
6620    setring R;
6621    re = imap(P,re1);
6622    for(j=1;j<=f;j++)
6623    {
6624      J=I,re[j];
6625      re[j]=interred(J);
6626    }
6627    option(set,ov);
6628    return(re);
6629  }
6630  else
6631//------------------- choice of generic element failed -------------------
6632  {
6633    dbprint(printlevel-voice+2,"// try new generic element!");
6634    setring R;
6635    return(zerodec(I));
6636  }
6637}
6638example
6639{ "EXAMPLE:";  echo = 2;
6640   ring r  = 0,(x,y),dp;
6641   ideal i = x2-2,y2-2;
6642   list pr = zerodec(i);
6643   pr;
6644}
6645///////////////////////////////////////////////////////////////////////////////
6646static proc newDecompStep(ideal i, list #)
6647"USAGE:  newDecompStep(i); i ideal  (for primary decomposition)
6648         newDecompStep(i,1);        (for the associated primes of dimension of i)
6649         newDecompStep(i,2);        (for the minimal associated primes)
6650         newDecompStep(i,3);        (for the absolute primary decomposition (not tested!))
6651         "oneIndep";        (for using only one max indep set)
6652         "intersect";        (returns alse the intersection of the components founded)
6653
6654RETURN:  list = list of primary ideals and their associated primes
6655         (at even positions in the list)
6656         (resp. a list of the minimal associated primes)
6657NOTE:    Algorithm of Gianni/Trager/Zacharias
6658EXAMPLE: example newDecompStep; shows an example
6659"
6660{
6661  intvec op,@vv;
6662  def  @P = basering;
6663  list primary,indep,ltras;
6664  intvec @vh,isat,@w;
6665  int @wr,@k,@n,@m,@n1,@n2,@n3,homo,seri,keepdi,abspri,ab,nn;
6666  ideal peek=i;
6667  ideal ser,tras;
6668  list data;
6669  list result;
6670  intvec @hilb;
6671  int isS=(attrib(i,"isSB")==1);
6672
6673  // Debug
6674  dbprint(printlevel - voice, "newDecompStep, v2.0");
6675
6676  string indepOption = "allIndep";
6677  string intersectOption = "noIntersect";
6678
6679  if(size(#)>0)
6680  {
6681    int count = 1;
6682    if(typeof(#[count]) == "string")
6683    {
6684      if ((#[count] == "oneIndep") or (#[count] == "allIndep"))
6685      {
6686        indepOption = #[count];
6687        count++;
6688      }
6689    }
6690    if(typeof(#[count]) == "string")
6691    {
6692      if ((#[count] == "intersect") or (#[count] == "noIntersect"))
6693      {
6694        intersectOption = #[count];
6695        count++;
6696      }
6697    }
6698    if((typeof(#[count]) == "int") or (typeof(#[count]) == "number"))
6699    {
6700      if ((#[count]==1)||(#[count]==2)||(#[count]==3))
6701      {
6702        @wr=#[count];
6703        if(@wr==3){abspri = 1; @wr = 0;}
6704        count++;
6705      }
6706    }
6707    if(size(#)>count)
6708    {
6709      seri=1;
6710      peek=#[count + 1];
6711      ser=#[count + 2];
6712    }
6713  }
6714  if(abspri)
6715  {
6716    list absprimary,abskeep,absprimarytmp,abskeeptmp;
6717  }
6718  homo=homog(i);
6719  if(homo==1)
6720  {
6721    if(attrib(i,"isSB")!=1)
6722    {
6723      //ltras=mstd(i);
6724      tras=groebner(i);
6725      ltras=tras,tras;
6726      attrib(ltras[1],"isSB",1);
6727    }
6728    else
6729    {
6730      ltras=i,i;
6731      attrib(ltras[1],"isSB",1);
6732    }
6733    tras = ltras[1];
6734    attrib(tras,"isSB",1);
6735    if(dim(tras)==0)
6736    {
6737      primary[1]=ltras[2];
6738      primary[2]=maxideal(1);
6739      if(@wr>0)
6740      {
6741        list l;
6742        l[2]=maxideal(1);
6743        l[1]=maxideal(1);
6744        if (intersectOption == "intersect")
6745        {
6746          return(list(l, maxideal(1)));
6747        }
6748        else
6749        {
6750          return(l);
6751        }
6752      }
6753      if (intersectOption == "intersect")
6754      {
6755        return(list(primary, primary[1]));
6756      }
6757      else
6758      {
6759        return(primary);
6760      }
6761    }
6762    for(@n=1;@n<=nvars(basering);@n++)
6763    {
6764      @w[@n]=ord(var(@n));
6765    }
6766    @hilb=hilb(tras,1,@w);
6767    intvec keephilb=@hilb;
6768  }
6769
6770  //----------------------------------------------------------------
6771  //i is the zero-ideal
6772  //----------------------------------------------------------------
6773
6774  if(size(i)==0)
6775  {
6776    primary=i,i;
6777    if (intersectOption == "intersect")
6778    {
6779      return(list(primary, i));
6780    }
6781    else
6782    {
6783      return(primary);
6784    }
6785  }
6786
6787  //----------------------------------------------------------------
6788  //pass to the lexicographical ordering and compute a standardbasis
6789  //----------------------------------------------------------------
6790
6791  int lp=islp();
6792
6793  execute("ring gnir = ("+charstr(basering)+"),("+varstr(basering)+"),(C,lp);");
6794  op=option(get);
6795  option(redSB);
6796
6797  ideal ser=fetch(@P,ser);
6798  if(homo==1)
6799  {
6800    if(!lp)
6801    {
6802      ideal @j=std(fetch(@P,i),@hilb,@w);
6803    }
6804    else
6805    {
6806      ideal @j=fetch(@P,tras);
6807      attrib(@j,"isSB",1);
6808    }
6809  }
6810  else
6811  {
6812    if(lp&&isS)
6813    {
6814      ideal @j=fetch(@P,i);
6815      attrib(@j,"isSB",1);
6816    }
6817    else
6818    {
6819      ideal @j=groebner(fetch(@P,i));
6820    }
6821  }
6822  option(set,op);
6823  if(seri==1)
6824  {
6825    ideal peek=fetch(@P,peek);
6826    attrib(peek,"isSB",1);
6827  }
6828  else
6829  {
6830    ideal peek=@j;
6831  }
6832  if((size(ser)==0)&&(!abspri))
6833  {
6834    ideal fried;
6835    @n=size(@j);
6836    for(@k=1;@k<=@n;@k++)
6837    {
6838      if(deg(lead(@j[@k]))==1)
6839      {
6840        fried[size(fried)+1]=@j[@k];
6841        @j[@k]=0;
6842      }
6843    }
6844    if(size(fried)==nvars(basering))
6845    {
6846      setring @P;
6847      primary[1]=i;
6848      primary[2]=i;
6849      if (intersectOption == "intersect")
6850      {
6851        return(list(primary, i));
6852      }
6853      else
6854      {
6855        return(primary);
6856      }
6857    }
6858    if(size(fried)>0)
6859    {
6860      string newva;
6861      string newma;
6862      for(@k=1;@k<=nvars(basering);@k++)
6863      {
6864        @n1=0;
6865        for(@n=1;@n<=size(fried);@n++)
6866        {
6867          if(leadmonom(fried[@n])==var(@k))
6868          {
6869            @n1=1;
6870            break;
6871          }
6872        }
6873        if(@n1==0)
6874        {
6875          newva=newva+string(var(@k))+",";
6876          newma=newma+string(var(@k))+",";
6877        }
6878        else
6879        {
6880          newma=newma+string(0)+",";
6881        }
6882      }
6883      newva[size(newva)]=")";
6884      newma[size(newma)]=";";
6885      execute("ring @deirf=("+charstr(gnir)+"),("+newva+",lp;");
6886      execute("map @kappa=gnir,"+newma);
6887      ideal @j= @kappa(@j);
6888      @j=simplify(@j, 2);
6889      attrib(@j,"isSB",1);
6890      result = newDecompStep(@j, indepOption, intersectOption, @wr);
6891      if (intersectOption == "intersect")
6892      {
6893       list pr = result[1];
6894       ideal intersection = result[2];
6895      }
6896      else
6897      {
6898        list pr = result;
6899      }
6900
6901      setring gnir;
6902      list pr=imap(@deirf,pr);
6903      for(@k=1;@k<=size(pr);@k++)
6904      {
6905        @j=pr[@k]+fried;
6906        pr[@k]=@j;
6907      }
6908      if (intersectOption == "intersect")
6909      {
6910        ideal intersection = imap(@deirf, intersection);
6911        @j = intersection + fried;
6912        intersection = @j;
6913      }
6914      setring @P;
6915      if (intersectOption == "intersect")
6916      {
6917        return(list(imap(gnir,pr), imap(gnir,intersection)));
6918      }
6919      else
6920      {
6921        return(imap(gnir,pr));
6922      }
6923    }
6924  }
6925  //----------------------------------------------------------------
6926  //j is the ring
6927  //----------------------------------------------------------------
6928
6929  if (dim(@j)==-1)
6930  {
6931    setring @P;
6932    primary=ideal(1),ideal(1);
6933    if (intersectOption == "intersect")
6934    {
6935      return(list(primary, ideal(1)));
6936    }
6937    else
6938    {
6939      return(primary);
6940    }
6941  }
6942
6943  //----------------------------------------------------------------
6944  //  the case of one variable
6945  //----------------------------------------------------------------
6946
6947  if(nvars(basering)==1)
6948  {
6949    list fac=factor(@j[1]);
6950    list gprimary;
6951    poly generator;
6952    ideal gIntersection;
6953    for(@k=1;@k<=size(fac[1]);@k++)
6954    {
6955      if(@wr==0)
6956      {
6957        gprimary[2*@k-1]=ideal(fac[1][@k]^fac[2][@k]);
6958        gprimary[2*@k]=ideal(fac[1][@k]);
6959      }
6960      else
6961      {
6962        gprimary[2*@k-1]=ideal(fac[1][@k]);
6963        gprimary[2*@k]=ideal(fac[1][@k]);
6964      }
6965      if (intersectOption == "intersect")
6966      {
6967        generator = generator * fac[1][@k];
6968      }
6969    }
6970    if (intersectOption == "intersect")
6971    {
6972      gIntersection = generator;
6973    }
6974    setring @P;
6975    primary=fetch(gnir,gprimary);
6976    if (intersectOption == "intersect")
6977    {
6978      ideal intersection = fetch(gnir,gIntersection);
6979    }
6980
6981//HIER
6982    if(abspri)
6983    {
6984      list resu,tempo;
6985      string absotto;
6986      for(ab=1;ab<=size(primary) div 2;ab++)
6987      {
6988        absotto= absFactorize(primary[2*ab][1],77);
6989        tempo=primary[2*ab-1],primary[2*ab],absotto,string(var(nvars(basering)));
6990        resu[ab]=tempo;
6991      }
6992      primary=resu;
6993      intersection = 1;
6994      for(ab=1;ab<=size(primary);ab++)
6995      {
6996        intersection = intersect(intersection, primary[ab][2]);
6997      }
6998    }
6999    if (intersectOption == "intersect")
7000    {
7001      return(list(primary, intersection));
7002    }
7003    else
7004    {
7005      return(primary);
7006    }
7007  }
7008
7009 //------------------------------------------------------------------
7010 //the zero-dimensional case
7011 //------------------------------------------------------------------
7012  if (dim(@j)==0)
7013  {
7014    op=option(get);
7015    option(redSB);
7016    list gprimary= newZero_decomp(@j,ser,@wr);
7017
7018    setring @P;
7019    primary=fetch(gnir,gprimary);
7020
7021    if(size(ser)>0)
7022    {
7023      primary=cleanPrimary(primary);
7024    }
7025//HIER
7026    if(abspri)
7027    {
7028      list resu,tempo;
7029      string absotto;
7030      for(ab=1;ab<=size(primary) div 2;ab++)
7031      {
7032        absotto= absFactorize(primary[2*ab][1],77);
7033        tempo=primary[2*ab-1],primary[2*ab],absotto,string(var(nvars(basering)));
7034        resu[ab]=tempo;
7035      }
7036      primary=resu;
7037    }
7038    option(set,op);
7039    if (intersectOption == "intersect")
7040    {
7041      return(list(primary, fetch(gnir,@j)));
7042    }
7043    else
7044    {
7045      return(primary);
7046    }
7047  }
7048
7049  poly @gs,@gh,@p;
7050  string @va,quotring;
7051  list quprimary,htprimary,collectprimary,lsau,lnew,allindep,restindep;
7052  ideal @h;
7053  int jdim=dim(@j);
7054  list fett;
7055  int lauf,di,newtest;
7056  //------------------------------------------------------------------
7057  //search for a maximal independent set indep,i.e.
7058  //look for subring such that the intersection with the ideal is zero
7059  //j intersected with K[var(indep[3]+1),...,var(nvar] is zero,
7060  //indep[1] is the new varstring and indep[2] the string for block-ordering
7061  //------------------------------------------------------------------
7062  if(@wr!=1)
7063  {
7064    allindep = newMaxIndependSetLp(@j, indepOption);
7065    for(@m=1;@m<=size(allindep);@m++)
7066    {
7067      if(allindep[@m][3]==jdim)
7068      {
7069        di++;
7070        indep[di]=allindep[@m];
7071      }
7072      else
7073      {
7074        lauf++;
7075        restindep[lauf]=allindep[@m];
7076      }
7077    }
7078  }
7079  else
7080  {
7081    indep = newMaxIndependSetLp(@j, indepOption);
7082  }
7083
7084  ideal jkeep=@j;
7085  if(ordstr(@P)[1]=="w")
7086  {
7087    execute("ring @Phelp=("+charstr(gnir)+"),("+varstr(gnir)+"),("+ordstr(@P)+");");
7088  }
7089  else
7090  {
7091    execute( "ring @Phelp=("+charstr(gnir)+"),("+varstr(gnir)+"),(C,dp);");
7092  }
7093
7094  if(homo==1)
7095  {
7096    if((ordstr(@P)[3]=="d")||(ordstr(@P)[1]=="d")||(ordstr(@P)[1]=="w")
7097       ||(ordstr(@P)[3]=="w"))
7098    {
7099      ideal jwork=imap(@P,tras);
7100      attrib(jwork,"isSB",1);
7101    }
7102    else
7103    {
7104      ideal jwork=std(imap(gnir,@j),@hilb,@w);
7105    }
7106  }
7107  else
7108  {
7109    ideal jwork=groebner(imap(gnir,@j));
7110  }
7111  list hquprimary;
7112  poly @p,@q;
7113  ideal @h,fac,ser;
7114//Aenderung================
7115  ideal @Ptest=1;
7116//=========================
7117  di=dim(jwork);
7118  keepdi=di;
7119
7120  ser = 1;
7121
7122  setring gnir;
7123  for(@m=1; @m<=size(indep); @m++)
7124  {
7125    data[1] = indep[@m];
7126    result = newReduction(@j, ser, @hilb, @w, jdim, abspri, @wr, data);
7127    quprimary = quprimary + result[1];
7128    if(abspri)
7129    {
7130      absprimary = absprimary + result[2];
7131      abskeep = abskeep + result[3];
7132    }
7133    @h = result[5];
7134    ser = result[4];
7135    if(size(@h)>0)
7136    {
7137      //---------------------------------------------------------------
7138      //we change to @Phelp to have the ordering dp for saturation
7139      //---------------------------------------------------------------
7140
7141      setring @Phelp;
7142      @h=imap(gnir,@h);
7143//Aenderung==================================
7144      if(defined(@LL)){kill @LL;}
7145      list @LL=minSat(jwork,@h);
7146      @Ptest=intersect(@Ptest,@LL[1]);
7147      ser = intersect(ser, @LL[1]);
7148//===========================================
7149
7150      if(@wr!=1)
7151      {
7152//Aenderung==================================
7153        @q=@LL[2];
7154//===========================================
7155        //@q=minSat(jwork,@h)[2];
7156      }
7157      else
7158      {
7159        fac=ideal(0);
7160        for(lauf=1;lauf<=ncols(@h);lauf++)
7161        {
7162          if(deg(@h[lauf])>0)
7163          {
7164            fac=fac+factorize(@h[lauf],1);
7165          }
7166        }
7167        fac=simplify(fac,6);
7168        @q=1;
7169        for(lauf=1;lauf<=size(fac);lauf++)
7170        {
7171          @q=@q*fac[lauf];
7172        }
7173      }
7174      jwork = std(jwork,@q);
7175      keepdi = dim(jwork);
7176      if(keepdi < di)
7177      {
7178        setring gnir;
7179        @j = imap(@Phelp, jwork);
7180        ser = imap(@Phelp, ser);
7181        break;
7182      }
7183      if(homo == 1)
7184      {
7185        @hilb = hilb(jwork, 1, @w);
7186      }
7187
7188      setring gnir;
7189      ser = imap(@Phelp, ser);
7190      @j = imap(@Phelp, jwork);
7191    }
7192  }
7193
7194  if((size(quprimary)==0)&&(@wr==1))
7195  {
7196     @j=ideal(1);
7197     quprimary[1]=ideal(1);
7198     quprimary[2]=ideal(1);
7199  }
7200  if((size(quprimary)==0))
7201  {
7202    keepdi = di - 1;
7203    quprimary[1]=ideal(1);
7204    quprimary[2]=ideal(1);
7205  }
7206  //---------------------------------------------------------------
7207  //notice that j=sat(j,gh) intersected with (j,gh^n)
7208  //we finished with sat(j,gh) and have to start with (j,gh^n)
7209  //---------------------------------------------------------------
7210  if((deg(@j[1])!=0)&&(@wr!=1))
7211  {
7212     if(size(quprimary)>0)
7213     {
7214        setring @Phelp;
7215        ser=imap(gnir,ser);
7216
7217        hquprimary=imap(gnir,quprimary);
7218        if(@wr==0)
7219        {
7220//Aenderung====================================================
7221//HIER STATT DURCHSCHNITT SATURIEREN!
7222           ideal htest=@Ptest;
7223/*
7224           ideal htest=hquprimary[1];
7225           for (@n1=2;@n1<=size(hquprimary) div 2;@n1++)
7226           {
7227              htest=intersect(htest,hquprimary[2*@n1-1]);
7228           }
7229*/
7230//=============================================================
7231        }
7232        else
7233        {
7234           ideal htest=hquprimary[2];
7235
7236           for (@n1=2;@n1<=size(hquprimary) div 2;@n1++)
7237           {
7238              htest=intersect(htest,hquprimary[2*@n1]);
7239           }
7240        }
7241
7242        if(size(ser)>0)
7243        {
7244           ser=intersect(htest,ser);
7245        }
7246        else
7247        {
7248          ser=htest;
7249        }
7250        setring gnir;
7251        ser=imap(@Phelp,ser);
7252     }
7253     if(size(reduce(ser,peek,1))!=0)
7254     {
7255        for(@m=1;@m<=size(restindep);@m++)
7256        {
7257         // if(restindep[@m][3]>=keepdi)
7258         // {
7259           isat=0;
7260           @n2=0;
7261
7262           if(restindep[@m][1]==varstr(basering))
7263           //the good case, nothing to do, just to have the same notations
7264           //change the ring
7265           {
7266              execute("ring gnir1 = ("+charstr(basering)+"),("+
7267                varstr(basering)+"),("+ordstr(basering)+");");
7268              ideal @j=fetch(gnir,jkeep);
7269              attrib(@j,"isSB",1);
7270           }
7271           else
7272           {
7273              @va=string(maxideal(1));
7274              execute("ring gnir1 = ("+charstr(basering)+"),("+
7275                      restindep[@m][1]+"),(" +restindep[@m][2]+");");
7276              execute("map phi=gnir,"+@va+";");
7277              op=option(get);
7278              option(redSB);
7279              if(homo==1)
7280              {
7281                 ideal @j=std(phi(jkeep),keephilb,@w);
7282              }
7283              else
7284              {
7285                ideal @j=groebner(phi(jkeep));
7286              }
7287              ideal ser=phi(ser);
7288              option(set,op);
7289           }
7290
7291           for (lauf=1;lauf<=size(@j);lauf++)
7292           {
7293              fett[lauf]=size(@j[lauf]);
7294           }
7295           //------------------------------------------------------------------
7296           //we have now the following situation:
7297           //j intersected with K[var(nnp+1),..,var(nva)] is zero so we may
7298           //pass to this quotientring, j is their still a standardbasis, the
7299           //leading coefficients of the polynomials  there (polynomials in
7300           //K[var(nnp+1),..,var(nva)]) are collected in the list h,
7301           //we need their ggt, gh, because of the following:
7302           //let (j:gh^n)=(j:gh^infinity) then
7303           //j*K(var(nnp+1),..,var(nva))[..the rest..]
7304           //intersected with K[var(1),...,var(nva)] is (j:gh^n)
7305           //on the other hand j=(j,gh^n) intersected with (j:gh^n)
7306
7307           //------------------------------------------------------------------
7308
7309           //the arrangement for the quotientring
7310           // K(var(nnp+1),..,var(nva))[..the rest..]
7311           //and the map phi:K[var(1),...,var(nva)] ---->
7312           //--->K(var(nnpr+1),..,var(nva))[..the rest..]
7313           //------------------------------------------------------------------
7314
7315           quotring=prepareQuotientring(nvars(basering)-restindep[@m][3]);
7316
7317           //------------------------------------------------------------------
7318           //we pass to the quotientring  K(var(nnp+1),..,var(nva))[..rest..]
7319           //------------------------------------------------------------------
7320
7321           execute(quotring);
7322
7323           // @j considered in the quotientring
7324           ideal @j=imap(gnir1,@j);
7325           ideal ser=imap(gnir1,ser);
7326
7327           kill gnir1;
7328
7329           //j is a standardbasis in the quotientring but usually not minimal
7330           //here it becomes minimal
7331           @j=clearSB(@j,fett);
7332           attrib(@j,"isSB",1);
7333
7334           //we need later ggt(h[1],...)=gh for saturation
7335           ideal @h;
7336
7337           for(@n=1;@n<=size(@j);@n++)
7338           {
7339              @h[@n]=leadcoef(@j[@n]);
7340           }
7341           //the primary decomposition of j*K(var(nnp+1),..,var(nva))[..rest..]
7342
7343           op=option(get);
7344           option(redSB);
7345           list uprimary= newZero_decomp(@j,ser,@wr);
7346//HIER
7347           if(abspri)
7348           {
7349              ideal II;
7350              ideal jmap;
7351              map sigma;
7352              nn=nvars(basering);
7353              map invsigma=basering,maxideal(1);
7354              for(ab=1;ab<=size(uprimary) div 2;ab++)
7355              {
7356                 II=uprimary[2*ab];
7357                 attrib(II,"isSB",1);
7358                 if(deg(II[1])!=vdim(II))
7359                 {
7360                    jmap=randomLast(50);
7361                    sigma=basering,jmap;
7362                    jmap[nn]=2*var(nn)-jmap[nn];
7363                    invsigma=basering,jmap;
7364                    II=groebner(sigma(II));
7365                  }
7366                  absprimarytmp[ab]= absFactorize(II[1],77);
7367                  II=var(nn);
7368                  abskeeptmp[ab]=string(invsigma(II));
7369                  invsigma=basering,maxideal(1);
7370              }
7371           }
7372           option(set,op);
7373
7374           //we need the intersection of the ideals in the list quprimary with
7375           //the polynomialring, i.e. let q=(f1,...,fr) in the quotientring
7376           //such an ideal but fi polynomials, then the intersection of q with
7377           //the polynomialring is the saturation of the ideal generated by
7378           //f1,...,fr with respect toh which is the lcm of the leading
7379           //coefficients of the fi considered in the quotientring:
7380           //this is coded in saturn
7381
7382           list saturn;
7383           ideal hpl;
7384
7385           for(@n=1;@n<=size(uprimary);@n++)
7386           {
7387              hpl=0;
7388              for(@n1=1;@n1<=size(uprimary[@n]);@n1++)
7389              {
7390                 hpl=hpl,leadcoef(uprimary[@n][@n1]);
7391              }
7392              saturn[@n]=hpl;
7393           }
7394           //------------------------------------------------------------------
7395           //we leave  the quotientring   K(var(nnp+1),..,var(nva))[..rest..]
7396           //back to the polynomialring
7397           //------------------------------------------------------------------
7398           setring gnir;
7399           collectprimary=imap(quring,uprimary);
7400           lsau=imap(quring,saturn);
7401           @h=imap(quring,@h);
7402
7403           kill quring;
7404
7405
7406           @n2=size(quprimary);
7407//================NEU=========================================
7408           if(deg(quprimary[1][1])<=0){ @n2=0; }
7409//============================================================
7410
7411           @n3=@n2;
7412
7413           for(@n1=1;@n1<=size(collectprimary) div 2;@n1++)
7414           {
7415              if(deg(collectprimary[2*@n1][1])>0)
7416              {
7417                 @n2++;
7418                 quprimary[@n2]=collectprimary[2*@n1-1];
7419                 lnew[@n2]=lsau[2*@n1-1];
7420                 @n2++;
7421                 lnew[@n2]=lsau[2*@n1];
7422                 quprimary[@n2]=collectprimary[2*@n1];
7423                 if(abspri)
7424                 {
7425                   absprimary[@n2 div 2]=absprimarytmp[@n1];
7426                   abskeep[@n2 div 2]=abskeeptmp[@n1];
7427                 }
7428              }
7429           }
7430
7431
7432           //here the intersection with the polynomialring
7433           //mentioned above is really computed
7434
7435           for(@n=@n3 div 2+1;@n<=@n2 div 2;@n++)
7436           {
7437              if(specialIdealsEqual(quprimary[2*@n-1],quprimary[2*@n]))
7438              {
7439                 quprimary[2*@n-1]=sat2(quprimary[2*@n-1],lnew[2*@n-1])[1];
7440                 quprimary[2*@n]=quprimary[2*@n-1];
7441              }
7442              else
7443              {
7444                 if(@wr==0)
7445                 {
7446                    quprimary[2*@n-1]=sat2(quprimary[2*@n-1],lnew[2*@n-1])[1];
7447                 }
7448                 quprimary[2*@n]=sat2(quprimary[2*@n],lnew[2*@n])[1];
7449              }
7450           }
7451           if(@n2>=@n3+2)
7452           {
7453              setring @Phelp;
7454              ser=imap(gnir,ser);
7455              hquprimary=imap(gnir,quprimary);
7456              for(@n=@n3 div 2+1;@n<=@n2 div 2;@n++)
7457              {
7458                if(@wr==0)
7459                {
7460                   ser=intersect(ser,hquprimary[2*@n-1]);
7461                }
7462                else
7463                {
7464                   ser=intersect(ser,hquprimary[2*@n]);
7465                }
7466              }
7467              setring gnir;
7468              ser=imap(@Phelp,ser);
7469           }
7470
7471         // }
7472        }
7473//HIER
7474        if(abspri)
7475        {
7476          list resu,tempo;
7477          for(ab=1;ab<=size(quprimary) div 2;ab++)
7478          {
7479             if (deg(quprimary[2*ab][1])!=0)
7480             {
7481               tempo=quprimary[2*ab-1],quprimary[2*ab],
7482                         absprimary[ab],abskeep[ab];
7483               resu[ab]=tempo;
7484             }
7485          }
7486          quprimary=resu;
7487          @wr=3;
7488        }
7489        if(size(reduce(ser,peek,1))!=0)
7490        {
7491           if(@wr>0)
7492           {
7493              // The following line was dropped to avoid the recursion step:
7494              //htprimary=newDecompStep(@j,@wr,peek,ser);
7495              htprimary = list();
7496           }
7497           else
7498           {
7499              // The following line was dropped to avoid the recursion step:
7500              //htprimary=newDecompStep(@j,peek,ser);
7501              htprimary = list();
7502           }
7503           // here we collect now both results primary(sat(j,gh))
7504           // and primary(j,gh^n)
7505           @n=size(quprimary);
7506           if (deg(quprimary[1][1])<=0) { @n=0; }
7507           for (@k=1;@k<=size(htprimary);@k++)
7508           {
7509              quprimary[@n+@k]=htprimary[@k];
7510           }
7511        }
7512     }
7513   }
7514   else
7515   {
7516      if(abspri)
7517      {
7518        list resu,tempo;
7519        for(ab=1;ab<=size(quprimary) div 2;ab++)
7520        {
7521           tempo=quprimary[2*ab-1],quprimary[2*ab],
7522                   absprimary[ab],abskeep[ab];
7523           resu[ab]=tempo;
7524        }
7525        quprimary=resu;
7526      }
7527   }
7528  //---------------------------------------------------------------------------
7529  //back to the ring we started with
7530  //the final result: primary
7531  //---------------------------------------------------------------------------
7532
7533  setring @P;
7534  primary=imap(gnir,quprimary);
7535
7536  if (intersectOption == "intersect")
7537  {
7538     return(list(primary, imap(gnir, ser)));
7539  }
7540  else
7541  {
7542    return(primary);
7543  }
7544}
7545example
7546{ "EXAMPLE:"; echo = 2;
7547   ring  r = 32003,(x,y,z),lp;
7548   poly  p = z2+1;
7549   poly  q = z4+2;
7550   ideal i = p^2*q^3,(y-z3)^3,(x-yz+z4)^4;
7551   list pr= newDecompStep(i);
7552   pr;
7553   testPrimary( pr, i);
7554}
7555
7556// This was part of proc decomp.
7557// In proc newDecompStep, used for the computation of the minimal associated primes,
7558// this part was separated as a soubrutine to make the code more clear.
7559// Also, since the reduction is performed twice in proc newDecompStep, it should use both times this routine.
7560// This is not yet implemented, since the reduction is not exactly the same and some changes should be made.
7561static proc newReduction(ideal @j, ideal ser, intvec @hilb, intvec @w, int jdim, int abspri, int @wr, list data)
7562{
7563   string @va;
7564   string quotring;
7565   intvec op;
7566   intvec @vv;
7567   def gnir = basering;
7568   ideal isat=0;
7569   int @n;
7570   int @n1 = 0;
7571   int @n2 = 0;
7572   int @n3 = 0;
7573   int homo = homog(@j);
7574   int lauf;
7575   int @k;
7576   list fett;
7577   int keepdi;
7578   list collectprimary;
7579   list lsau;
7580   list lnew;
7581   ideal @h;
7582
7583   list indepInfo = data[1];
7584   list quprimary = list();
7585
7586   //if(abspri)
7587   //{
7588     int ab;
7589     list absprimarytmp,abskeeptmp;
7590     list absprimary, abskeep;
7591   //}
7592   // Debug
7593   dbprint(printlevel - voice, "newReduction, v2.0");
7594
7595   if((indepInfo[1]==varstr(basering)))  // &&(@m==1)
7596   //this is the good case, nothing to do, just to have the same notations
7597   //change the ring
7598   {
7599     execute("ring gnir1 = ("+charstr(basering)+"),("+varstr(basering)+"),("
7600                              +ordstr(basering)+");");
7601     ideal @j = fetch(gnir, @j);
7602     attrib(@j,"isSB",1);
7603     ideal ser = fetch(gnir, ser);
7604   }
7605   else
7606   {
7607     @va=string(maxideal(1));
7608//Aenderung==============
7609     //if(@m==1)
7610     //{
7611     //  @j=fetch(@P,i);
7612     //}
7613//=======================
7614     execute("ring gnir1 = ("+charstr(basering)+"),("+indepInfo[1]+"),("
7615                              +indepInfo[2]+");");
7616     execute("map phi=gnir,"+@va+";");
7617     op=option(get);
7618     option(redSB);
7619     if(homo==1)
7620     {
7621       ideal @j=std(phi(@j),@hilb,@w);
7622     }
7623     else
7624     {
7625       ideal @j=groebner(phi(@j));
7626     }
7627     ideal ser=phi(ser);
7628
7629     option(set,op);
7630   }
7631   if((deg(@j[1])==0)||(dim(@j)<jdim))
7632   {
7633     setring gnir;
7634     break;
7635   }
7636   for (lauf=1;lauf<=size(@j);lauf++)
7637   {
7638     fett[lauf]=size(@j[lauf]);
7639   }
7640   //------------------------------------------------------------------------
7641   //we have now the following situation:
7642   //j intersected with K[var(nnp+1),..,var(nva)] is zero so we may pass
7643   //to this quotientring, j is their still a standardbasis, the
7644   //leading coefficients of the polynomials  there (polynomials in
7645   //K[var(nnp+1),..,var(nva)]) are collected in the list h,
7646   //we need their ggt, gh, because of the following: let
7647   //(j:gh^n)=(j:gh^infinity) then j*K(var(nnp+1),..,var(nva))[..the rest..]
7648   //intersected with K[var(1),...,var(nva)] is (j:gh^n)
7649   //on the other hand j=(j,gh^n) intersected with (j:gh^n)
7650
7651   //------------------------------------------------------------------------
7652
7653   //arrangement for quotientring K(var(nnp+1),..,var(nva))[..the rest..] and
7654   //map phi:K[var(1),...,var(nva)] --->K(var(nnpr+1),..,var(nva))[..rest..]
7655   //------------------------------------------------------------------------
7656
7657   quotring=prepareQuotientring(nvars(basering)-indepInfo[3]);
7658
7659   //---------------------------------------------------------------------
7660   //we pass to the quotientring   K(var(nnp+1),..,var(nva))[..the rest..]
7661   //---------------------------------------------------------------------
7662
7663   ideal @jj=lead(@j);               //!! vorn vereinbaren
7664   execute(quotring);
7665
7666   ideal @jj=imap(gnir1,@jj);
7667   @vv=clearSBNeu(@jj,fett);  //!! vorn vereinbaren
7668   setring gnir1;
7669   @k=size(@j);
7670   for (lauf=1;lauf<=@k;lauf++)
7671   {
7672     if(@vv[lauf]==1)
7673     {
7674       @j[lauf]=0;
7675     }
7676   }
7677   @j=simplify(@j,2);
7678   setring quring;
7679   // @j considered in the quotientring
7680   ideal @j=imap(gnir1,@j);
7681
7682   ideal ser=imap(gnir1,ser);
7683
7684   kill gnir1;
7685
7686   //j is a standardbasis in the quotientring but usually not minimal
7687   //here it becomes minimal
7688
7689   attrib(@j,"isSB",1);
7690
7691   //we need later ggt(h[1],...)=gh for saturation
7692   ideal @h;
7693   if(deg(@j[1])>0)
7694   {
7695     for(@n=1;@n<=size(@j);@n++)
7696     {
7697       @h[@n]=leadcoef(@j[@n]);
7698     }
7699     //the primary decomposition of j*K(var(nnp+1),..,var(nva))[..the rest..]
7700     op=option(get);
7701     option(redSB);
7702
7703     int zeroMinAss = @wr;
7704     if (@wr == 2) {zeroMinAss = 1;}
7705     list uprimary= newZero_decomp(@j, ser, zeroMinAss);
7706
7707//HIER
7708     if(abspri)
7709     {
7710       ideal II;
7711       ideal jmap;
7712       map sigma;
7713       nn=nvars(basering);
7714       map invsigma=basering,maxideal(1);
7715       for(ab=1;ab<=size(uprimary) div 2;ab++)
7716       {
7717         II=uprimary[2*ab];
7718         attrib(II,"isSB",1);
7719         if(deg(II[1])!=vdim(II))
7720         {
7721           jmap=randomLast(50);
7722           sigma=basering,jmap;
7723           jmap[nn]=2*var(nn)-jmap[nn];
7724           invsigma=basering,jmap;
7725           II=groebner(sigma(II));
7726         }
7727         absprimarytmp[ab]= absFactorize(II[1],77);
7728         II=var(nn);
7729         abskeeptmp[ab]=string(invsigma(II));
7730         invsigma=basering,maxideal(1);
7731       }
7732     }
7733     option(set,op);
7734   }
7735   else
7736   {
7737     list uprimary;
7738     uprimary[1]=ideal(1);
7739     uprimary[2]=ideal(1);
7740   }
7741   //we need the intersection of the ideals in the list quprimary with the
7742   //polynomialring, i.e. let q=(f1,...,fr) in the quotientring such an ideal
7743   //but fi polynomials, then the intersection of q with the polynomialring
7744   //is the saturation of the ideal generated by f1,...,fr with respect to
7745   //h which is the lcm of the leading coefficients of the fi considered in
7746   //in the quotientring: this is coded in saturn
7747
7748   list saturn;
7749   ideal hpl;
7750
7751   for(@n=1;@n<=size(uprimary);@n++)
7752   {
7753     uprimary[@n]=interred(uprimary[@n]); // temporary fix
7754     hpl=0;
7755     for(@n1=1;@n1<=size(uprimary[@n]);@n1++)
7756     {
7757       hpl=hpl,leadcoef(uprimary[@n][@n1]);
7758     }
7759     saturn[@n]=hpl;
7760   }
7761
7762   //--------------------------------------------------------------------
7763   //we leave  the quotientring   K(var(nnp+1),..,var(nva))[..the rest..]
7764   //back to the polynomialring
7765   //---------------------------------------------------------------------
7766   setring gnir;
7767
7768   collectprimary=imap(quring,uprimary);
7769   lsau=imap(quring,saturn);
7770   @h=imap(quring,@h);
7771
7772   kill quring;
7773
7774   @n2=size(quprimary);
7775   @n3=@n2;
7776
7777   for(@n1=1;@n1<=size(collectprimary) div 2;@n1++)
7778   {
7779     if(deg(collectprimary[2*@n1][1])>0)
7780     {
7781       @n2++;
7782       quprimary[@n2]=collectprimary[2*@n1-1];
7783       lnew[@n2]=lsau[2*@n1-1];
7784       @n2++;
7785       lnew[@n2]=lsau[2*@n1];
7786       quprimary[@n2]=collectprimary[2*@n1];
7787       if(abspri)
7788       {
7789         absprimary[@n2 div 2]=absprimarytmp[@n1];
7790         abskeep[@n2 div 2]=abskeeptmp[@n1];
7791       }
7792     }
7793   }
7794
7795   //here the intersection with the polynomialring
7796   //mentioned above is really computed
7797   for(@n=@n3 div 2+1;@n<=@n2 div 2;@n++)
7798   {
7799     if(specialIdealsEqual(quprimary[2*@n-1],quprimary[2*@n]))
7800     {
7801       quprimary[2*@n-1]=sat2(quprimary[2*@n-1],lnew[2*@n-1])[1];
7802       quprimary[2*@n]=quprimary[2*@n-1];
7803     }
7804     else
7805     {
7806       if(@wr==0)
7807       {
7808         quprimary[2*@n-1]=sat2(quprimary[2*@n-1],lnew[2*@n-1])[1];
7809       }
7810       quprimary[2*@n]=sat2(quprimary[2*@n],lnew[2*@n])[1];
7811     }
7812   }
7813
7814   return(quprimary, absprimary, abskeep, ser, @h);
7815}
7816
7817
7818////////////////////////////////////////////////////////////////////////////
7819
7820
7821
7822
7823///////////////////////////////////////////////////////////////////////////////
7824// Based on minAssGTZ
7825
7826proc minAss(ideal i,list #)
7827"USAGE:   minAss(I[, l]); i ideal, l list (optional) of parameters, same as minAssGTZ
7828RETURN:  a list, the minimal associated prime ideals of I.
7829NOTE:    Designed for characteristic 0, works also in char k > 0 based
7830         on an algorithm of Yokoyama
7831EXAMPLE: example minAss; shows an example
7832"
7833{
7834  return(minAssGTZ(i,#));
7835}
7836example
7837{ "EXAMPLE:";  echo = 2;
7838   ring  r = 0, (x, y, z), dp;
7839   poly  p = z2 + 1;
7840   poly  q = z3 + 2;
7841   ideal i = p * q^2, y - z2;
7842   list pr = minAss(i);
7843   pr;
7844}
7845
7846
7847///////////////////////////////////////////////////////////////////////////////
7848//
7849// Computes the minimal associated primes of I via Laplagne algorithm,
7850// using primary decomposition in the zero dimensional case.
7851// For reduction to the zerodimensional case, it uses the procedure
7852// decomp, with some modifications to avoid the recursion.
7853//
7854
7855static proc minAssSL(ideal I)
7856// Input = I, ideal
7857// Output = primaryDec where primaryDec is the list of the minimal
7858// associated primes and the primary components corresponding to these primes.
7859{
7860  ideal P = 1;
7861  list pd = list();
7862  int k;
7863  int stop = 0;
7864  list primaryDec = list();
7865
7866  while (stop == 0)
7867  {
7868    // Debug
7869    dbprint(printlevel - voice, "// We call minAssSLIteration to find new prime ideals!");
7870    pd = minAssSLIteration(I, P);
7871    // Debug
7872    dbprint(printlevel - voice, "// Output of minAssSLIteration:");
7873    dbprint(printlevel - voice, pd);
7874    if (size(pd[1]) > 0)
7875    {
7876      primaryDec = primaryDec + pd[1];
7877      // Debug
7878      dbprint(printlevel - voice, "// We intersect the prime ideals obtained.");
7879      P = intersect(P, pd[2]);
7880      // Debug
7881      dbprint(printlevel - voice, "// Intersection finished.");
7882    }
7883    else
7884    {
7885      stop = 1;
7886    }
7887  }
7888
7889  // Returns only the primary components, not the radical.
7890  return(primaryDec);
7891}
7892
7893///////////////////////////////////////////////////////////////////////////////
7894// Given an ideal I and an ideal P (intersection of some minimal prime ideals
7895// associated to I), it calculates new minimal prime ideals associated to I
7896// which were not used to calculate P.
7897// This version uses Primary Decomposition in the zerodimensional case.
7898static proc minAssSLIteration(ideal I, ideal P);
7899{
7900  int k = 1;
7901  int good  = 0;
7902  list primaryDec = list();
7903  // Debug
7904  dbprint (printlevel-voice, "// We search for an element in P - sqrt(I).");
7905  while ((k <= size(P)) and (good == 0))
7906  {
7907    good = 1 - rad_con(P[k], I);
7908    k++;
7909  }
7910  k--;
7911  if (good == 0)
7912  {
7913    // Debug
7914    dbprint (printlevel - voice, "// No element was found, P = sqrt(I).");
7915    return (list(primaryDec, ideal(0)));
7916  }
7917  // Debug
7918  dbprint (printlevel - voice, "// We found h = ", P[k]);
7919  dbprint (printlevel - voice, "// We calculate the saturation of I with respect to the element just founded.");
7920  ideal J = sat(I, P[k])[1];
7921
7922  // Uses decomp from primdec, modified to avoid the recursion.
7923  // Debug
7924  dbprint(printlevel - voice, "// We do the reduction to the zerodimensional case, via decomp.");
7925
7926  primaryDec = newDecompStep(J, "oneIndep", "intersect", 2);
7927  // Debug
7928  dbprint(printlevel - voice, "// Proc decomp has found", size(primaryDec) div 2, "new primary components.");
7929
7930  return(primaryDec);
7931}
7932
7933
7934
7935///////////////////////////////////////////////////////////////////////////////////
7936// Based on maxIndependSet
7937// Added list # as parameter
7938// If the first element of # is 0, the output is only 1 max indep set.
7939// If no list is specified or #[1] = 1, the output is all the max indep set of the
7940// leading terms ideal. This is the original output of maxIndependSet
7941
7942proc newMaxIndependSetLp(ideal j, list #)
7943"USAGE:   newMaxIndependentSetLp(i); i ideal (returns all maximal independent sets of the corresponding leading terms ideal)
7944          newMaxIndependentSetLp(i, 0); i ideal (returns only one maximal independent set)
7945RETURN:  list = #1. new varstring with the maximal independent set at the end,
7946                #2. ordstring with the lp ordering,
7947                #3. the number of independent variables
7948NOTE:
7949EXAMPLE: example newMaxIndependentSetLp; shows an example
7950"
7951{
7952  int n, k, di;
7953  list resu, hilf;
7954  string var1, var2;
7955  list v = indepSet(j, 0);
7956
7957  // SL 2006.04.21 1 Lines modified to use only one independent Set
7958  string indepOption;
7959  if (size(#) > 0)
7960  {
7961    indepOption = #[1];
7962  }
7963  else
7964  {
7965    indepOption = "allIndep";
7966  }
7967
7968  int nMax;
7969  if (indepOption == "allIndep")
7970  {
7971    nMax = size(v);
7972  }
7973  else
7974  {
7975    nMax = 1;
7976  }
7977
7978  for(n = 1; n <= nMax; n++)
7979  // SL 2006.04.21 2
7980  {
7981    di = 0;
7982    var1 = "";
7983    var2 = "";
7984    for(k = 1; k <= size(v[n]); k++)
7985    {
7986      if(v[n][k] != 0)
7987      {
7988        di++;
7989        var2 = var2 + "var(" + string(k) + "), ";
7990      }
7991      else
7992      {
7993        var1 = var1 + "var(" + string(k) + "), ";
7994      }
7995    }
7996    if(di > 0)
7997    {
7998      var1 = var1 + var2;
7999      var1 = var1[1..size(var1) - 2];       // The "- 2" removes the trailer comma
8000      hilf[1] = var1;
8001      // SL 2006.21.04 1 The order is now block dp instead of lp
8002      //hilf[2] = "dp(" + string(nvars(basering) - di) + "), dp(" + string(di) + ")";
8003      // SL 2006.21.04 2
8004      // For decomp, lp ordering is needed. Nothing is changed.
8005      hilf[2] = "lp";
8006      hilf[3] = di;
8007      resu[n] = hilf;
8008    }
8009    else
8010    {
8011      resu[n] = varstr(basering), ordstr(basering), 0;
8012    }
8013  }
8014  return(resu);
8015}
8016example
8017{ "EXAMPLE:"; echo = 2;
8018   ring s1 = (0, x, y), (a, b, c, d, e, f, g), lp;
8019   ideal i = ea - fbg, fa + be, ec - fdg, fc + de;
8020   i = std(i);
8021   list l = newMaxIndependSetLp(i);
8022   l;
8023   i = i, g;
8024   l = newMaxIndependSetLp(i);
8025   l;
8026
8027   ring s = 0, (x, y, z), lp;
8028   ideal i = z, yx;
8029   list l = newMaxIndependSetLp(i);
8030   l;
8031}
8032
8033
8034///////////////////////////////////////////////////////////////////////////////
8035
8036proc newZero_decomp (ideal j, ideal ser, int @wr, list #)
8037"USAGE:   newZero_decomp(j,ser,@wr); j,ser ideals, @wr=0 or 1
8038         (@wr=0 for primary decomposition, @wr=1 for computation of associated
8039         primes)
8040         if #[1] = "nest", then #[2] indicates the nest level (number of recursive calls)
8041         When the nest level is high it indicates that the computation is difficult,
8042         and different methods are applied.
8043RETURN:  list = list of primary ideals and their radicals (at even positions
8044         in the list) if the input is zero-dimensional and a standardbases
8045         with respect to lex-ordering
8046         If ser!=(0) and ser is contained in j or if j is not zero-dimen-
8047         sional then ideal(1),ideal(1) is returned
8048NOTE:    Algorithm of Gianni/Trager/Zacharias
8049EXAMPLE: example newZero_decomp; shows an example
8050"
8051{
8052  def   @P = basering;
8053  int uytrewq;
8054  int nva = nvars(basering);
8055  int @k,@s,@n,@k1,zz;
8056  list primary,lres0,lres1,act,@lh,@wh;
8057  map phi,psi,phi1,psi1;
8058  ideal jmap,jmap1,jmap2,helpprim,@qh,@qht,ser1;
8059  intvec @vh,@hilb;
8060  string @ri;
8061  poly @f;
8062
8063  // Debug
8064  dbprint(printlevel - voice, "proc newZero_decomp");
8065
8066  if (dim(j)>0)
8067  {
8068    primary[1]=ideal(1);
8069    primary[2]=ideal(1);
8070    return(primary);
8071  }
8072  j=interred(j);
8073
8074  attrib(j,"isSB",1);
8075
8076  int nestLevel = 0;
8077  if (size(#) > 0)
8078  {
8079    if (typeof(#[1]) == "string")
8080    {
8081      if (#[1] == "nest")
8082      {
8083        nestLevel = #[2];
8084      }
8085      # = list();
8086    }
8087  }
8088
8089  if(vdim(j)==deg(j[1]))
8090  {
8091    act=factor(j[1]);
8092    for(@k=1;@k<=size(act[1]);@k++)
8093    {
8094      @qh=j;
8095      if(@wr==0)
8096      {
8097        @qh[1]=act[1][@k]^act[2][@k];
8098      }
8099      else
8100      {
8101        @qh[1]=act[1][@k];
8102      }
8103      primary[2*@k-1]=interred(@qh);
8104      @qh=j;
8105      @qh[1]=act[1][@k];
8106      primary[2*@k]=interred(@qh);
8107      attrib( primary[2*@k-1],"isSB",1);
8108
8109      if((size(ser)>0)&&(size(reduce(ser,primary[2*@k-1],1))==0))
8110      {
8111        primary[2*@k-1]=ideal(1);
8112        primary[2*@k]=ideal(1);
8113      }
8114    }
8115    return(primary);
8116  }
8117
8118  if(homog(j)==1)
8119  {
8120    primary[1]=j;
8121    if((size(ser)>0)&&(size(reduce(ser,j,1))==0))
8122    {
8123      primary[1]=ideal(1);
8124      primary[2]=ideal(1);
8125      return(primary);
8126    }
8127    if(dim(j)==-1)
8128    {
8129      primary[1]=ideal(1);
8130      primary[2]=ideal(1);
8131    }
8132    else
8133    {
8134      primary[2]=maxideal(1);
8135    }
8136    return(primary);
8137  }
8138
8139//the first element in the standardbase is factorized
8140  if(deg(j[1])>0)
8141  {
8142    act=factor(j[1]);
8143    testFactor(act,j[1]);
8144  }
8145  else
8146  {
8147    primary[1]=ideal(1);
8148    primary[2]=ideal(1);
8149    return(primary);
8150  }
8151
8152//with the factors new ideals (hopefully the primary decomposition)
8153//are created
8154  if(size(act[1])>1)
8155  {
8156    if(size(#)>1)
8157    {
8158      primary[1]=ideal(1);
8159      primary[2]=ideal(1);
8160      primary[3]=ideal(1);
8161      primary[4]=ideal(1);
8162      return(primary);
8163    }
8164    for(@k=1;@k<=size(act[1]);@k++)
8165    {
8166      if(@wr==0)
8167      {
8168        primary[2*@k-1]=std(j,act[1][@k]^act[2][@k]);
8169      }
8170      else
8171      {
8172        primary[2*@k-1]=std(j,act[1][@k]);
8173      }
8174      if((act[2][@k]==1)&&(vdim(primary[2*@k-1])==deg(act[1][@k])))
8175      {
8176        primary[2*@k]   = primary[2*@k-1];
8177      }
8178      else
8179      {
8180        primary[2*@k]   = primaryTest(primary[2*@k-1],act[1][@k]);
8181      }
8182    }
8183  }
8184  else
8185  {
8186    primary[1]=j;
8187    if((size(#)>0)&&(act[2][1]>1))
8188    {
8189      act[2]=1;
8190      primary[1]=std(primary[1],act[1][1]);
8191    }
8192    if(@wr!=0)
8193    {
8194      primary[1]=std(j,act[1][1]);
8195    }
8196    if((act[2][1]==1)&&(vdim(primary[1])==deg(act[1][1])))
8197    {
8198      primary[2]=primary[1];
8199    }
8200    else
8201    {
8202      primary[2]=primaryTest(primary[1],act[1][1]);
8203    }
8204  }
8205
8206  if(size(#)==0)
8207  {
8208    primary=splitPrimary(primary,ser,@wr,act);
8209  }
8210
8211  if((voice>=6)&&(char(basering)<=181))
8212  {
8213    primary=splitCharp(primary);
8214  }
8215
8216  if((@wr==2)&&(npars(basering)>0)&&(voice>=6)&&(char(basering)>0))
8217  {
8218  //the prime decomposition of Yokoyama in characteristic p
8219    list ke,ek;
8220    @k=0;
8221    while(@k<size(primary) div 2)
8222    {
8223      @k++;
8224      if(size(primary[2*@k])==0)
8225      {
8226        ek=insepDecomp(primary[2*@k-1]);
8227        primary=delete(primary,2*@k);
8228        primary=delete(primary,2*@k-1);
8229        @k--;
8230      }
8231      ke=ke+ek;
8232    }
8233    for(@k=1;@k<=size(ke);@k++)
8234    {
8235      primary[size(primary)+1]=ke[@k];
8236      primary[size(primary)+1]=ke[@k];
8237    }
8238  }
8239
8240  if(nestLevel > 1){primary=extF(primary);}
8241
8242//test whether all ideals in the decomposition are primary and
8243//in general position
8244//if not after a random coordinate transformation of the last
8245//variable the corresponding ideal is decomposed again.
8246  if((npars(basering)>0)&&(nestLevel > 1))
8247  {
8248    poly randp;
8249    for(zz=1;zz<nvars(basering);zz++)
8250    {
8251      randp=randp
8252              +(random(0,5)*par(1)^2+random(0,5)*par(1)+random(0,5))*var(zz);
8253    }
8254    randp=randp+var(nvars(basering));
8255  }
8256  @k=0;
8257  while(@k<(size(primary) div 2))
8258  {
8259    @k++;
8260    if (size(primary[2*@k])==0)
8261    {
8262      for(zz=1;zz<size(primary[2*@k-1])-1;zz++)
8263      {
8264        attrib(primary[2*@k-1],"isSB",1);
8265        if(vdim(primary[2*@k-1])==deg(primary[2*@k-1][zz]))
8266        {
8267          primary[2*@k]=primary[2*@k-1];
8268        }
8269      }
8270    }
8271  }
8272
8273  @k=0;
8274  ideal keep;
8275  while(@k<(size(primary) div 2))
8276  {
8277    @k++;
8278    if (size(primary[2*@k])==0)
8279    {
8280      jmap=randomLast(100);
8281      jmap1=maxideal(1);
8282      jmap2=maxideal(1);
8283      @qht=primary[2*@k-1];
8284      if((npars(basering)>0)&&(nestLevel > 1))
8285      {
8286        jmap[size(jmap)]=randp;
8287      }
8288
8289      for(@n=2;@n<=size(primary[2*@k-1]);@n++)
8290      {
8291        if(deg(lead(primary[2*@k-1][@n]))==1)
8292        {
8293          for(zz=1;zz<=nva;zz++)
8294          {
8295            if(lead(primary[2*@k-1][@n])/var(zz)!=0)
8296            {
8297              jmap1[zz]=-1/leadcoef(primary[2*@k-1][@n])*primary[2*@k-1][@n]
8298                   +2/leadcoef(primary[2*@k-1][@n])*lead(primary[2*@k-1][@n]);
8299              jmap2[zz]=primary[2*@k-1][@n];
8300              @qht[@n]=var(zz);
8301            }
8302          }
8303          jmap[nva]=subst(jmap[nva],lead(primary[2*@k-1][@n]),0);
8304        }
8305      }
8306      if(size(subst(jmap[nva],var(1),0)-var(nva))!=0)
8307      {
8308        // jmap[nva]=subst(jmap[nva],var(1),0);
8309        //hier geaendert +untersuchen!!!!!!!!!!!!!!
8310      }
8311      phi1=@P,jmap1;
8312      phi=@P,jmap;
8313      for(@n=1;@n<=nva;@n++)
8314      {
8315        jmap[@n]=-(jmap[@n]-2*var(@n));
8316      }
8317      psi=@P,jmap;
8318      psi1=@P,jmap2;
8319      @qh=phi(@qht);
8320
8321//=================== the new part ============================
8322
8323      if (npars(basering)>1) { @qh=groebner(@qh,"par2var"); }
8324      else                   { @qh=groebner(@qh); }
8325
8326//=============================================================
8327//       if(npars(@P)>0)
8328//       {
8329//          @ri= "ring @Phelp ="
8330//                  +string(char(@P))+",
8331//                   ("+varstr(@P)+","+parstr(@P)+",@t),(C,dp);";
8332//       }
8333//       else
8334//       {
8335//          @ri= "ring @Phelp ="
8336//                  +string(char(@P))+",("+varstr(@P)+",@t),(C,dp);";
8337//       }
8338//       execute(@ri);
8339//       ideal @qh=homog(imap(@P,@qht),@t);
8340//
8341//       ideal @qh1=std(@qh);
8342//       @hilb=hilb(@qh1,1);
8343//       @ri= "ring @Phelp1 ="
8344//                  +string(char(@P))+",("+varstr(@Phelp)+"),(C,lp);";
8345//       execute(@ri);
8346//       ideal @qh=homog(imap(@P,@qh),@t);
8347//       kill @Phelp;
8348//       @qh=std(@qh,@hilb);
8349//       @qh=subst(@qh,@t,1);
8350//       setring @P;
8351//       @qh=imap(@Phelp1,@qh);
8352//       kill @Phelp1;
8353//       @qh=clearSB(@qh);
8354//       attrib(@qh,"isSB",1);
8355//=============================================================
8356
8357      ser1=phi1(ser);
8358      @lh=newZero_decomp (@qh,phi(ser1),@wr, list("nest", nestLevel + 1));
8359
8360      kill lres0;
8361      list lres0;
8362      if(size(@lh)==2)
8363      {
8364        helpprim=@lh[2];
8365        lres0[1]=primary[2*@k-1];
8366        ser1=psi(helpprim);
8367        lres0[2]=psi1(ser1);
8368        if(size(reduce(lres0[2],lres0[1],1))==0)
8369        {
8370          primary[2*@k]=primary[2*@k-1];
8371          continue;
8372        }
8373      }
8374      else
8375      {
8376        lres1=psi(@lh);
8377        lres0=psi1(lres1);
8378      }
8379
8380//=================== the new part ============================
8381
8382      primary=delete(primary,2*@k-1);
8383      primary=delete(primary,2*@k-1);
8384      @k--;
8385      if(size(lres0)==2)
8386      {
8387        if (npars(basering)>1) { lres0[2]=groebner(lres0[2],"par2var"); }
8388        else                   { lres0[2]=groebner(lres0[2]); }
8389      }
8390      else
8391      {
8392        for(@n=1;@n<=size(lres0) div 2;@n++)
8393        {
8394          if(specialIdealsEqual(lres0[2*@n-1],lres0[2*@n])==1)
8395          {
8396            lres0[2*@n-1]=groebner(lres0[2*@n-1]);
8397            lres0[2*@n]=lres0[2*@n-1];
8398            attrib(lres0[2*@n],"isSB",1);
8399          }
8400          else
8401          {
8402            lres0[2*@n-1]=groebner(lres0[2*@n-1]);
8403            lres0[2*@n]=groebner(lres0[2*@n]);
8404          }
8405        }
8406      }
8407      primary=primary+lres0;
8408
8409//=============================================================
8410//       if(npars(@P)>0)
8411//       {
8412//          @ri= "ring @Phelp ="
8413//                  +string(char(@P))+",
8414//                   ("+varstr(@P)+","+parstr(@P)+",@t),(C,dp);";
8415//       }
8416//       else
8417//       {
8418//          @ri= "ring @Phelp ="
8419//                  +string(char(@P))+",("+varstr(@P)+",@t),(C,dp);";
8420//       }
8421//       execute(@ri);
8422//       list @lvec;
8423//       list @lr=imap(@P,lres0);
8424//       ideal @lr1;
8425//
8426//       if(size(@lr)==2)
8427//       {
8428//          @lr[2]=homog(@lr[2],@t);
8429//          @lr1=std(@lr[2]);
8430//          @lvec[2]=hilb(@lr1,1);
8431//       }
8432//       else
8433//       {
8434//          for(@n=1;@n<=size(@lr) div 2;@n++)
8435//          {
8436//             if(specialIdealsEqual(@lr[2*@n-1],@lr[2*@n])==1)
8437//             {
8438//                @lr[2*@n-1]=homog(@lr[2*@n-1],@t);
8439//                @lr1=std(@lr[2*@n-1]);
8440//                @lvec[2*@n-1]=hilb(@lr1,1);
8441//                @lvec[2*@n]=@lvec[2*@n-1];
8442//             }
8443//             else
8444//             {
8445//                @lr[2*@n-1]=homog(@lr[2*@n-1],@t);
8446//                @lr1=std(@lr[2*@n-1]);
8447//                @lvec[2*@n-1]=hilb(@lr1,1);
8448//                @lr[2*@n]=homog(@lr[2*@n],@t);
8449//                @lr1=std(@lr[2*@n]);
8450//                @lvec[2*@n]=hilb(@lr1,1);
8451//
8452//             }
8453//         }
8454//       }
8455//       @ri= "ring @Phelp1 ="
8456//                  +string(char(@P))+",("+varstr(@Phelp)+"),(C,lp);";
8457//       execute(@ri);
8458//       list @lr=imap(@Phelp,@lr);
8459//
8460//       kill @Phelp;
8461//       if(size(@lr)==2)
8462//      {
8463//          @lr[2]=std(@lr[2],@lvec[2]);
8464//          @lr[2]=subst(@lr[2],@t,1);
8465//
8466//       }
8467//       else
8468//       {
8469//          for(@n=1;@n<=size(@lr) div 2;@n++)
8470//          {
8471//             if(specialIdealsEqual(@lr[2*@n-1],@lr[2*@n])==1)
8472//             {
8473//                @lr[2*@n-1]=std(@lr[2*@n-1],@lvec[2*@n-1]);
8474//                @lr[2*@n-1]=subst(@lr[2*@n-1],@t,1);
8475//                @lr[2*@n]=@lr[2*@n-1];
8476//                attrib(@lr[2*@n],"isSB",1);
8477//             }
8478//             else
8479//             {
8480//                @lr[2*@n-1]=std(@lr[2*@n-1],@lvec[2*@n-1]);
8481//                @lr[2*@n-1]=subst(@lr[2*@n-1],@t,1);
8482//                @lr[2*@n]=std(@lr[2*@n],@lvec[2*@n]);
8483//                @lr[2*@n]=subst(@lr[2*@n],@t,1);
8484//             }
8485//          }
8486//       }
8487//       kill @lvec;
8488//       setring @P;
8489//       lres0=imap(@Phelp1,@lr);
8490//       kill @Phelp1;
8491//       for(@n=1;@n<=size(lres0);@n++)
8492//       {
8493//          lres0[@n]=clearSB(lres0[@n]);
8494//          attrib(lres0[@n],"isSB",1);
8495//       }
8496//
8497//       primary[2*@k-1]=lres0[1];
8498//       primary[2*@k]=lres0[2];
8499//       @s=size(primary) div 2;
8500//       for(@n=1;@n<=size(lres0) div 2-1;@n++)
8501//       {
8502//         primary[2*@s+2*@n-1]=lres0[2*@n+1];
8503//         primary[2*@s+2*@n]=lres0[2*@n+2];
8504//       }
8505//       @k--;
8506//=============================================================
8507    }
8508  }
8509  return(primary);
8510}
8511example
8512{ "EXAMPLE:"; echo = 2;
8513   ring  r = 0,(x,y,z),lp;
8514   poly  p = z2+1;
8515   poly  q = z4+2;
8516   ideal i = p^2*q^3,(y-z3)^3,(x-yz+z4)^4;
8517   i=std(i);
8518   list  pr= newZero_decomp(i,ideal(0),0);
8519   pr;
8520}
8521///////////////////////////////////////////////////////////////////////////////
8522
8523////////////////////////////////////////////////////////////////////////////
8524/*
8525//Beispiele Wenk-Dipl (in ~/Texfiles/Diplom/Wenk/Examples/)
8526//Zeiten: Singular/Singular/Singular -r123456789 -v :wilde13 (PentiumPro200)
8527//Singular for HPUX-9 version 1-3-8  (2000060214)  Jun  2 2000 15:31:26
8528//(wilde13)
8529
8530//1. vdim=20, 3  Komponenten
8531//zerodec-time:2(1)  (matrix:1 charpoly:0 factor:1)
8532//primdecGTZ-time: 1(0)
8533ring rs= 0,(a,b,c),dp;
8534poly f1= a^2*b*c + a*b^2*c + a*b*c^2 + a*b*c + a*b + a*c + b*c;
8535poly f2= a^2*b^2*c + a*b^2*c^2 + a^2*b*c + a*b*c + b*c + a + c;
8536poly f3= a^2*b^2*c^2 + a^2*b^2*c + a*b^2*c + a*b*c + a*c + c + 1;
8537ideal gls=f1,f2,f3;
8538int time=timer;
8539printlevel =1;
8540time=timer; list pr1=zerodec(gls); timer-time;size(pr1);
8541time=timer; list pr =primdecGTZ(gls); timer-time;size(pr);
8542time=timer; ideal ra =radical(gls); timer-time;size(pr);
8543
8544//2.cyclic5  vdim=70, 20 Komponenten
8545//zerodec-time:36(28)  (matrix:1(0) charpoly:18(19) factor:17(9)
8546//primdecGTZ-time: 28(5)
8547//radical : 0
8548ring rs= 0,(a,b,c,d,e),dp;
8549poly f0= a + b + c + d + e + 1;
8550poly f1= a + b + c + d + e;
8551poly f2= a*b + b*c + c*d + a*e + d*e;
8552poly f3= a*b*c + b*c*d + a*b*e + a*d*e + c*d*e;
8553poly f4= a*b*c*d + a*b*c*e + a*b*d*e + a*c*d*e + b*c*d*e;
8554poly f5= a*b*c*d*e - 1;
8555ideal gls= f1,f2,f3,f4,f5;
8556
8557//3. random vdim=40, 1 Komponente
8558//zerodec-time:126(304)  (matrix:1 charpoly:115(298) factor:10(5))
8559//primdecGTZ-time:17 (11)
8560ring rs=0,(x,y,z),dp;
8561poly f1=2*x^2 + 4*x + 3*y^2 + 7*x*z + 9*y*z + 5*z^2;
8562poly f2=7*x^3 + 8*x*y + 12*y^2 + 18*x*z + 3*y^4*z + 10*z^3 + 12;
8563poly f3=3*x^4 + 1*x*y*z + 6*y^3 + 3*x*z^2 + 2*y*z^2 + 4*z^2 + 5;
8564ideal gls=f1,f2,f3;
8565
8566//4. introduction into resultants, sturmfels, vdim=28, 1 Komponente
8567//zerodec-time:4  (matrix:0 charpoly:0 factor:4)
8568//primdecGTZ-time:1
8569ring rs=0,(x,y),dp;
8570poly f1= x4+y4-1;
8571poly f2= x5y2-4x3y3+x2y5-1;
8572ideal gls=f1,f2;
8573
8574//5. 3 quadratic equations with random coeffs, vdim=8, 1 Komponente
8575//zerodec-time:0(0)  (matrix:0 charpoly:0 factor:0)
8576//primdecGTZ-time:1(0)
8577ring rs=0,(x,y,z),dp;
8578poly f1=2*x^2 + 4*x*y + 3*y^2 + 7*x*z + 9*y*z + 5*z^2 + 2;
8579poly f2=7*x^2 + 8*x*y + 12*y^2 + 18*x*z + 3*y*z + 10*z^2 + 12;
8580poly f3=3*x^2 + 1*x*y + 6*y^2 + 3*x*z + 2*y*z + 4*z^2 + 5;
8581ideal gls=f1,f2,f3;
8582
8583//6. 3 polys    vdim=24, 1 Komponente
8584// run("ex14",2);
8585//zerodec-time:5(4)  (matrix:0 charpoly:3(3) factor:2(1))
8586//primdecGTZ-time:4 (2)
8587ring rs=0,(x1,x2,x3,x4),dp;
8588poly f1=16*x1^2 + 3*x2^2 + 5*x3^4 - 1 - 4*x4 + x4^3;
8589poly f2=5*x1^3 + 3*x2^2 + 4*x3^2*x4 + 2*x1*x4 - 1 + x4 + 4*x1 + x2 + x3 + x4;
8590poly f3=-4*x1^2 + x2^2 + x3^2 - 3 + x4^2 + 4*x1 + x2 + x3 + x4;
8591poly f4=-4*x1 + x2 + x3 + x4;
8592ideal gls=f1,f2,f3,f4;
8593
8594//7. ex43, PoSSo, caprasse   vdim=56, 16 Komponenten
8595//zerodec-time:23(15)  (matrix:0 charpoly:16(13) factor:3(2))
8596//primdecGTZ-time:3 (2)
8597ring rs= 0,(y,z,x,t),dp;
8598ideal gls=y^2*z+2*y*x*t-z-2*x,
85994*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,
86002*y*z*t+x*t^2-2*z-x,
8601-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;
8602
8603//8. Arnborg-System, n=6 (II),    vdim=156, 90 Komponenten
8604//zerodec-time (char32003):127(45)(matrix:2(0) charpoly:106(37) factor:16(7))
8605//primdecGTZ-time(char32003) :81 (18)
8606//ring rs= 0,(a,b,c,d,x,f),dp;
8607ring rs= 32003,(a,b,c,d,x,f),dp;
8608ideal gls=a+b+c+d+x+f, ab+bc+cd+dx+xf+af, abc+bcd+cdx+d*xf+axf+abf,
8609abcd+bcdx+cd*xf+ad*xf+abxf+abcf, abcdx+bcd*xf+acd*xf+abd*xf+abcxf+abcdf,
8610abcd*xf-1;
8611
8612//9. ex42, PoSSo, Methan6_1, vdim=27, 2 Komponenten
8613//zerodec-time:610  (matrix:10 charpoly:557 factor:26)
8614//primdecGTZ-time: 118
8615//zerodec-time(char32003):2
8616//primdecGTZ-time(char32003):4
8617//ring rs= 0,(x1,x2,x3,x4,x5,x6,x7,x8,x9,x10),dp;
8618ring rs= 32003,(x1,x2,x3,x4,x5,x6,x7,x8,x9,x10),dp;
8619ideal gls=64*x2*x7-10*x1*x8+10*x7*x9+11*x7*x10-320000*x1,
8620-32*x2*x7-5*x2*x8-5*x2*x10+160000*x1-5000*x2,
8621-x3*x8+x6*x8+x9*x10+210*x6+1300000,
8622-x4*x8+700000,
8623x10^2-2*x5,
8624-x6*x8+x7*x9-210*x6,
8625-64*x2*x7-10*x7*x9-11*x7*x10+320000*x1-16*x7+7000000,
8626-10*x1*x8-10*x2*x8-10*x3*x8-10*x4*x8-10*x6*x8+10*x2*x10+11*x7*x10
8627    +20000*x2+14*x5,
8628x4*x8-x7*x9-x9*x10-410*x9,
862910*x2*x8+10*x3*x8+10*x6*x8+10*x7*x9-10*x2*x10-11*x7*x10-10*x9*x10
8630    -10*x10^2+1400*x6-4200*x10;
8631
8632//10. ex33, walk-s7, Diplomarbeit von Tim, vdim=114
8633//zerfaellt in unterschiedlich viele Komponenten in versch. Charkteristiken:
8634//char32003:30, char0:3(2xdeg1,1xdeg112!), char181:4(2xdeg1,1xdeg28,1xdeg84)
8635//char 0: zerodec-time:10075 (ca 3h) (matrix:3 charpoly:9367, factor:680
8636//        + 24 sec fuer Normalform (anstatt einsetzen), total [29623k])
8637//        primdecGTZ-time: 214
8638//char 32003:zerodec-time:197(68) (matrix:2(1) charpoly:173(60) factor:15(6))
8639//        primdecGTZ-time:14 (5)
8640//char 181:zerodec-time:(87) (matrix:(1) charpoly:(58) factor:(25))
8641//        primdecGTZ-time:(2)
8642//in char181 stimmen Ergebnisse von zerodec und primdecGTZ ueberein (gecheckt)
8643
8644//ring rs= 0,(a,b,c,d,e,f,g),dp;
8645ring rs= 32003,(a,b,c,d,e,f,g),dp;
8646poly f1= 2gb + 2fc + 2ed + a2 + a;
8647poly f2= 2gc + 2fd + e2 + 2ba + b;
8648poly f3= 2gd + 2fe + 2ca + c + b2;
8649poly f4= 2ge + f2 + 2da + d + 2cb;
8650poly f5= 2fg + 2ea + e + 2db + c2;
8651poly f6= g2 + 2fa + f + 2eb + 2dc;
8652poly f7= 2ga + g + 2fb + 2ec + d2;
8653ideal gls= f1,f2,f3,f4,f5,f6,f7;
8654
8655~/Singular/Singular/Singular -r123456789 -v
8656LIB"./primdec.lib";
8657timer=1;
8658int time=timer;
8659printlevel =1;
8660option(prot,mem);
8661time=timer; list pr1=zerodec(gls); timer-time;
8662
8663time=timer; list pr =primdecGTZ(gls); timer-time;
8664time=timer; list pr =primdecSY(gls); timer-time;
8665time=timer; ideal ra =radical(gls); timer-time;size(pr);
8666LIB"all.lib";
8667
8668ring R=0,(a,b,c,d,e,f),dp;
8669ideal I=cyclic(6);
8670minAssGTZ(I);
8671
8672
8673ring S=(2,a,b),(x,y),lp;
8674ideal I=x8-b,y4+a;
8675minAssGTZ(I);
8676
8677ring S1=2,(x,y,a,b),lp;
8678ideal I=x8-b,y4+a;
8679minAssGTZ(I);
8680
8681
8682ring S2=(2,z),(x,y),dp;
8683minpoly=z2+z+1;
8684ideal I=y3+y+1,x4+x+1;
8685primdecGTZ(I);
8686minAssGTZ(I);
8687
8688ring S3=2,(x,y,z),dp;
8689ideal I=y3+y+1,x4+x+1,z2+z+1;
8690primdecGTZ(I);
8691minAssGTZ(I);
8692
8693
8694ring R1=2,(x,y,z),lp;
8695ideal I=y6+y5+y3+y2+1,x4+x+1,z2+z+1;
8696primdecGTZ(I);
8697minAssGTZ(I);
8698
8699
8700ring R2=(2,z),(x,y),lp;
8701minpoly=z3+z+1;
8702ideal I=y2+y+(z2+z+1),x4+x+1;
8703primdecGTZ(I);
8704minAssGTZ(I);
8705
8706*/
Note: See TracBrowser for help on using the repository browser.