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

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