source: git/Singular/LIB/primdec.lib @ 7475b3f

spielwiese
Last change on this file since 7475b3f was 7475b3f, checked in by Gert-Martin Greuel <greuel@…>, 23 years ago
* GMG: proc lcmP entfernt, da lcm in poly.lib dasselbe tut und lcmP duch * lcm ersetzt, wo es verwendet wird git-svn-id: file:///usr/local/Singular/svn/trunk@4999 2c84dea3-7e68-4137-9b89-c4e89433aadc
  • Property mode set to 100644
File size: 119.4 KB
Line 
1///////////////////////////////////////////////////////////////////////////////
2version="$Id: primdec.lib,v 1.82 2000-12-31 02:02:05 greuel Exp $";
3category="Commutative Algebra";
4info="
5LIBRARY: primdec.lib   Primary Decomposition and Radical of Ideals
6AUTHORS:  Gerhard Pfister, email: pfister@mathematik.uni-kl.de (GTZ)
7          Wolfram Decker, email: decker@math.uni-sb.de         (SY)
8          Hans Schoenemann, email: hannes@mathematik.uni-kl.de (SY)
9
10OVERVIEW:
11 Algorithms for primary decomposition based on the ideas of
12 Gianni,Trager,Zacharias was written by Gerhard Pfister.                       
13 Algorithms for primary decomposition based on the ideas of
14 Shimoyama/Yokoyama was written by Wolfram Decker and Hans Schoenemann.   
15 These procedures are implemented to be used in characteristic 0.
16 @*They also work in positive characteristic >> 0.
17 @*In small characteristic and for algebraic extensions, primdecGTZ,
18 minAssGTZ, radical and equiRadical may not terminate and primdecSY and
19 minAssChar may not give a complete decomposition.
20
21PROCEDURES:
22 primdecGTZ(I);    complete primary decomposition via Gianni,Trager,Zacharias
23 primdecSY(I...);  complete primary decomposition via Shimoyama-Yokoyama
24 minAssGTZ(I);     the minimal associated primes via Gianni,Trager,Zacharias
25 minAssChar(I...); the minimal associated primes using characteristic sets
26 testPrimary(L,k); tests the result of the primary decomposition
27 radical(I);       computes the radical of the ideal I
28 equiRadical(I);   the radical of the equidimensional part of the ideal I
29 prepareAss(I);    list of radicals of the equidimensional components of I
30 equidim(I);       weak equidimensional decomposition of I
31 equidimMax(I);    equidimensional locus of I
32 equidimMaxEHV(I); equidimensional locus of I via Eisenbud,Huneke,Vasconcelos
33 zerodec(I);       zerodimensional decomposition via Monico
34";
35
36LIB "general.lib";
37LIB "elim.lib";
38LIB "poly.lib";
39LIB "random.lib";
40LIB "inout.lib";
41LIB "matrix.lib";
42///////////////////////////////////////////////////////////////////////////////
43//
44//                      Gianni/Trager/Zacharias
45//
46///////////////////////////////////////////////////////////////////////////////
47
48proc sat1 (ideal id, poly p)
49"USAGE:   sat1(id,j);  id ideal, j polynomial
50RETURN:  saturation of id with respect to j (= union_(k=1...) of id:j^k)
51NOTE:    result is a std basis in the basering
52EXAMPLE: example sat; shows an example
53"
54{
55   int @k;
56   ideal inew=std(id);
57   ideal iold;
58   option(returnSB);
59   while(specialIdealsEqual(iold,inew)==0 )
60   {
61      iold=inew;
62      inew=quotient(iold,p);
63      @k++;
64   }
65   @k--;
66   option(noreturnSB);
67   list L =inew,p^@k;
68   return (L);
69}
70
71///////////////////////////////////////////////////////////////////////////////
72
73proc sat2 (ideal id, ideal h)
74"USAGE:   sat2(id,j);  id ideal, j polynomial
75RETURN:  saturation of id with respect to j (= union_(k=1...) of id:j^k)
76NOTE:    result is a std basis in the basering
77EXAMPLE: example sat2; shows an example
78"
79{
80   int @k,@i;
81   def @P= basering;
82   if(ordstr(basering)[1,2]!="dp")
83   {
84      execute("ring @Phelp=("+charstr(@P)+"),("+varstr(@P)+"),(C,dp);");
85      ideal inew=std(imap(@P,id));
86      ideal  @h=imap(@P,h);
87   }
88   else
89   {
90      ideal @h=h;
91      ideal inew=std(id);
92   }
93   ideal fac;
94
95   for(@i=1;@i<=ncols(@h);@i++)
96   {
97     if(deg(@h[@i])>0)
98     {
99        fac=fac+factorize(@h[@i],1);
100     }
101   }
102   fac=simplify(fac,4);
103   poly @f=1;
104   if(deg(fac[1])>0)
105   {
106      ideal iold;
107
108      for(@i=1;@i<=size(fac);@i++)
109      {
110        @f=@f*fac[@i];
111      }
112      option(returnSB);
113      while(specialIdealsEqual(iold,inew)==0 )
114      {
115         iold=inew;
116         if(deg(iold[size(iold)])!=1)
117         {
118            inew=quotient(iold,@f);
119         }
120         else
121         {
122            inew=iold;
123         }
124         @k++;
125      }
126      option(noreturnSB);
127      @k--;
128   }
129
130   if(ordstr(@P)[1,2]!="dp")
131   {
132      setring @P;
133      ideal inew=std(imap(@Phelp,inew));
134      poly @f=imap(@Phelp,@f);
135   }
136   list L =inew,@f^@k;
137   return (L);
138}
139
140///////////////////////////////////////////////////////////////////////////////
141
142proc minSat(ideal inew, ideal h)
143{
144   int i,k;
145   poly f=1;
146   ideal iold,fac;
147   list quotM,l;
148
149   for(i=1;i<=ncols(h);i++)
150   {
151      if(deg(h[i])>0)
152      {
153         fac=fac+factorize(h[i],1);
154      }
155   }
156   fac=simplify(fac,4);
157   if(size(fac)==0)
158   {
159      l=inew,1;
160      return(l);
161   }
162   fac=sort(fac)[1];
163   for(i=1;i<=size(fac);i++)
164   {
165      f=f*fac[i];
166   }
167   quotM[1]=inew;
168   quotM[2]=fac;
169   quotM[3]=f;
170   f=1;
171   option(returnSB);
172   while(specialIdealsEqual(iold,quotM[1])==0)
173   {
174      if(k>0)
175      {
176         f=f*quotM[3];
177      }
178      iold=quotM[1];
179      quotM=quotMin(quotM);
180      k++;
181   }
182   option(noreturnSB);
183   l=quotM[1],f;
184   return(l);
185}
186
187proc quotMin(list tsil)
188{
189   int i,j,k,action;
190   ideal verg;
191   list l;
192   poly g;
193
194   ideal laedi=tsil[1];
195   ideal fac=tsil[2];
196   poly f=tsil[3];
197
198   ideal star=quotient(laedi,f);
199
200   if(specialIdealsEqual(star,laedi))
201   {
202      l=star,fac,f;
203      return(l);     
204   }
205 
206   action=1;
207
208   while(action==1)
209   {
210      if(size(fac)==1)
211      {
212         action=0;
213         break;
214      }
215      for(i=1;i<=size(fac);i++)
216      {
217        g=1;
218        verg=laedi;
219
220         for(j=1;j<=size(fac);j++)
221         {
222            if(i!=j)
223            {
224               g=g*fac[j];
225            }
226         }
227
228         verg=quotient(laedi,g);
229
230         if(specialIdealsEqual(verg,star)==1)
231         {
232            f=g;
233            fac[i]=0;
234            fac=simplify(fac,2);
235            break;
236         }
237         if(i==size(fac))
238         {
239            action=0;
240         }
241      }
242   }
243   l=star,fac,f;
244   return(l);
245}
246
247///////////////////////////////////////////////////////////////////////////////
248
249proc testFactor(list act,poly p)
250{
251  poly keep=p;
252
253   int i;
254   poly q=act[1][1]^act[2][1];
255   for(i=2;i<=size(act[1]);i++)
256   {
257      q=q*act[1][i]^act[2][i];
258   }
259   q=1/leadcoef(q)*q;
260   p=1/leadcoef(p)*p;
261   if(p-q!=0)
262   {
263      "ERROR IN FACTOR";
264      basering;
265
266      act;
267      keep;
268      pause();
269
270      p;
271      q;
272      pause();
273   }
274}
275///////////////////////////////////////////////////////////////////////////////
276
277proc factor(poly p)
278"USAGE:   factor(p) p poly
279RETURN:  list=;
280NOTE:
281EXAMPLE: example factor; shows an example
282"
283{
284
285  ideal @i;
286  list @l;
287  intvec @v,@w;
288  int @j,@k,@n;
289
290  if(deg(p)<=1)
291  {
292     @i=ideal(p);
293     @v=1;
294     @l[1]=@i;
295     @l[2]=@v;
296     return(@l);
297  }
298  if (size(p)==1)
299  {
300     @w=leadexp(p);
301     for(@j=1;@j<=nvars(basering);@j++)
302     {
303        if(@w[@j]!=0)
304        {
305           @k++;
306           @v[@k]=@w[@j];
307           @i=@i+ideal(var(@j));
308        }
309     }
310     @l[1]=@i;
311     @l[2]=@v;
312     return(@l);
313  }
314  //  @l=factorize(p,2);
315  @l=factorize(p);
316  // if(npars(basering)>0)
317  // {
318     for(@j=1;@j<=size(@l[1]);@j++)
319     {
320        if(deg(@l[1][@j])==0)
321        {
322           @n++;
323        }
324     }
325     if(@n>0)
326     {
327        if(@n==size(@l[1]))
328        {
329           @l[1]=ideal(1);
330           @v=1;
331           @l[2]=@v;
332        }
333        else
334        {
335           @k=0;
336           int pleh;
337           for(@j=1;@j<=size(@l[1]);@j++)
338           {
339              if(deg(@l[1][@j])!=0)
340              {
341                 @k++;
342                 @i=@i+ideal(@l[1][@j]);
343                 if(size(@i)==pleh)
344                 {
345                   "//factorization error";
346                   @l;
347                    @k--;
348                    @v[@k]=@v[@k]+@l[2][@j];
349                 }
350                 else
351                 {
352                    pleh++;
353                    @v[@k]=@l[2][@j];
354                 }
355              }
356           }
357           @l[1]=@i;
358           @l[2]=@v;
359        }
360     }
361     // }
362  return(@l);
363}
364example
365{ "EXAMPLE:"; echo = 2;
366   ring  r = 0,(x,y,z),lp;
367   poly  p = (x+y)^2*(y-z)^3;
368   list  l = factor(p);
369   l;
370   ring r1 =(0,b,d,f,g),(a,c,e),lp;
371   poly p  =(1*d)*e^2+(1*d*f^2*g);
372   list  l = factor(p);
373   l;
374   ring r2 =(0,b,f,g),(a,c,e,d),lp;
375   poly p  =(1*d)*e^2+(1*d*f^2*g);
376   list  l = factor(p);
377   l;
378
379}
380
381
382
383///////////////////////////////////////////////////////////////////////////////
384
385proc idealsEqual( ideal k, ideal j)
386{
387   return(stdIdealsEqual(std(k),std(j)));
388}
389
390proc specialIdealsEqual( ideal k1, ideal k2)
391{
392   int j;
393
394   if(size(k1)==size(k2))
395   {
396      for(j=1;j<=size(k1);j++)
397      {
398         if(leadexp(k1[j])!=leadexp(k2[j]))
399         {
400            return(0);
401         }
402      }
403      return(1);
404   }
405   return(0);
406}
407
408proc stdIdealsEqual( ideal k1, ideal k2)
409{
410   int j;
411
412   if(size(k1)==size(k2))
413   {
414      for(j=1;j<=size(k1);j++)
415      {
416         if(leadexp(k1[j])!=leadexp(k2[j]))
417         {
418            return(0);
419         }
420      }
421      attrib(k2,"isSB",1);
422      if(size(reduce(k1,k2,1))==0)
423      {
424         return(1);
425      }
426   }
427   return(0);
428}
429///////////////////////////////////////////////////////////////////////////////
430
431
432proc primaryTest (ideal i, poly p)
433{
434   int m=1;
435   int n=nvars(basering);
436   int e,f;
437   poly t;
438   ideal h;
439   list act;
440
441   ideal prm=p;
442   attrib(prm,"isSB",1);
443
444   while (n>1)
445   {
446      n=n-1;
447      m=m+1;
448
449      //search for i[m] which has a power of var(n) as leading term
450      if (n==1)
451      {
452         m=size(i);
453      }
454      else
455      {
456        while (lead(i[m])/var(n-1)==0)
457        {
458          m=m+1;
459        }
460        m=m-1;
461      }
462      //check whether i[m] =(c*var(n)+h)^e modulo prm for some
463      //h in K[var(n+1),...,var(nvars(basering))], c in K
464      //if not (0) is returned, else var(n)+h is added to prm
465
466      e=deg(lead(i[m]));
467      if(char(basering)!=0)
468      {
469         f=1;
470         if(e mod char(basering)==0)
471         {
472           if ( voice >=15 )
473           {
474              "// WARNING: The characteristic is perhaps too small to use";
475              "// the algorithm of Gianni/Trager/Zacharias.";
476              "// This may result in an infinte loop";
477              "// loop in primaryTest, voice:",voice;"";
478           }
479           while(e mod char(basering)==0)
480           {
481              f=f*char(basering);
482              e=e/char(basering); 
483           }
484       
485         }
486         t=leadcoef(i[m])*e*var(n)^f+(i[m]-lead(i[m]))/var(n)^((e-1)*f);
487         i[m]=poly(e)^e*leadcoef(i[m])^(e-1)*i[m];
488         if (reduce(i[m]-t^e,prm,1) !=0)
489         {
490           return(ideal(0));
491         }
492         if(f>1)
493         {       
494            act=factorize(t);
495            if(size(act[1])>2)
496            {
497              return(ideal(0));   
498            }
499            if(deg(act[1][2])>1)
500            {
501              return(ideal(0));   
502            }
503            t=act[1][2];
504         }
505      }
506      else
507      {
508         t=leadcoef(i[m])*e*var(n)+(i[m]-lead(i[m]))/var(n)^(e-1);
509         i[m]=poly(e)^e*leadcoef(i[m])^(e-1)*i[m];
510         if (reduce(i[m]-t^e,prm,1) !=0)
511         {
512           return(ideal(0));
513         }
514      }
515
516      h=interred(t);
517      t=h[1];
518
519      prm = prm,t;
520      attrib(prm,"isSB",1);
521   }
522   return(prm);
523}
524
525
526///////////////////////////////////////////////////////////////////////////////
527proc splitPrimary(list l,ideal ser,int @wr,list sact)
528{
529   int i,j,k,s,r,w;
530   list keepresult,act,keepprime;
531   poly @f;
532   int sl=size(l);
533   for(i=1;i<=sl/2;i++)
534   {
535      if(sact[2][i]>1)
536      {
537         keepprime[i]=l[2*i-1]+ideal(sact[1][i]);
538      }
539      else
540      {
541         keepprime[i]=l[2*i-1];
542      }
543  }
544   i=0;
545   while(i<size(l)/2)
546   {
547      i++;
548      if((size(ser)>0)&&(size(reduce(ser,l[2*i-1],1))==0))
549      {
550         l[2*i-1]=ideal(1);
551         l[2*i]=ideal(1);
552         continue;
553      }
554
555      if(size(l[2*i])==0)
556      {
557         if(homog(l[2*i-1])==1)
558         {
559            l[2*i]=maxideal(1);
560            continue;
561         }
562         j=0;
563         if(i<=sl/2)
564         {
565            j=1;
566         }
567         while(j<size(l[2*i-1]))
568         {
569            j++;
570            act=factor(l[2*i-1][j]);
571            r=size(act[1]);
572            attrib(l[2*i-1],"isSB",1);
573            if((r==1)&&(vdim(l[2*i-1])==deg(l[2*i-1][j])))
574            {
575              l[2*i]=std(l[2*i-1],act[1][1]);
576              break;
577            }
578            if((r==1)&&(act[2][1]>1))
579            {
580               keepprime[i]=interred(keepprime[i]+ideal(act[1][1]));
581               if(homog(keepprime[i])==1)
582               {
583                  l[2*i]=maxideal(1);
584                  break;
585               }
586            }
587            if(gcdTest(act[1])==1)
588            {
589               for(k=2;k<=r;k++)
590               {
591                  keepprime[size(l)/2+k-1]=interred(keepprime[i]+ideal(act[1][k]));
592               }
593               keepprime[i]=interred(keepprime[i]+ideal(act[1][1]));
594               for(k=1;k<=r;k++)
595               {
596                  if(@wr==0)
597                  {
598                     keepresult[k]=std(l[2*i-1],act[1][k]^act[2][k]);
599                  }
600                  else
601                  {
602                     keepresult[k]=std(l[2*i-1],act[1][k]);
603                  }
604               }
605               l[2*i-1]=keepresult[1];
606               if(vdim(keepresult[1])==deg(act[1][1]))
607               {
608                  l[2*i]=keepresult[1];
609               }
610               if((homog(keepresult[1])==1)||(homog(keepprime[i])==1))
611               {
612                  l[2*i]=maxideal(1);
613               }
614               s=size(l)-2;
615               for(k=2;k<=r;k++)
616               {
617                  l[s+2*k-1]=keepresult[k];
618                  keepprime[s/2+k]=interred(keepresult[k]+ideal(act[1][k]));
619                  if(vdim(keepresult[k])==deg(act[1][k]))
620                  {
621                     l[s+2*k]=keepresult[k];
622                  }
623                  else
624                  {
625                     l[s+2*k]=ideal(0);
626                  }
627                  if((homog(keepresult[k])==1)||(homog(keepprime[s/2+k])==1))
628                  {
629                    l[s+2*k]=maxideal(1);
630                  }
631               }
632               i--;
633               break;
634            }
635            if(r>=2)
636            {
637               s=size(l);
638               @f=act[1][1];
639               act=sat1(l[2*i-1],act[1][1]);
640               if(deg(act[1][1])>0)
641               {
642                  l[s+1]=std(l[2*i-1],act[2]);
643                  if(homog(l[s+1])==1)
644                  {
645                     l[s+2]=maxideal(1);
646                  }
647                  else
648                  {
649                     l[s+2]=ideal(0);
650                  }
651                  keepprime[s/2+1]=interred(keepprime[i]+ideal(@f));
652                  if(homog(keepprime[s/2+1])==1)
653                  {
654                     l[s+2]=maxideal(1);
655                  }
656                  keepprime[i]=act[1];
657                  l[2*i-1]=act[1];
658                  attrib(l[2*i-1],"isSB",1);
659                  if(homog(l[2*i-1])==1)
660                  {
661                     l[2*i]=maxideal(1);
662                  }
663
664                  i--;
665                  break;
666               }
667            }
668         }
669      }
670   }
671   if(sl==size(l))
672   {
673      return(l);
674   }
675   for(i=1;i<=size(l)/2;i++)
676   {
677     attrib(l[2*i-1],"isSB",1);
678
679     if((size(ser)>0)&&(size(reduce(ser,l[2*i-1],1))==0)&&(deg(l[2*i-1][1])>0))
680     {
681       "Achtung in split";
682
683         l[2*i-1]=ideal(1);
684         l[2*i]=ideal(1);
685     }
686     if((size(l[2*i])==0)&&(specialIdealsEqual(keepprime[i],l[2*i-1])!=1))
687      {
688         keepprime[i]=std(keepprime[i]);
689         if(homog(keepprime[i])==1)
690         {
691             l[2*i]=maxideal(1);
692         }
693         else
694         {
695            act=zero_decomp(keepprime[i],ideal(0),@wr,1);
696            if(size(act)==2)
697            {
698               l[2*i]=act[2];
699            }
700         }
701      }
702   }
703   return(l);
704}
705example
706{ "EXAMPLE:"; echo=2;
707   ring  r = 32003,(x,y,z),lp;
708   ideal i1=x*(x+1),yz,(z+1)*(z-1);
709   ideal i2=xy,yz,(x-2)*(x+3);
710   list l=i1,ideal(0),i2,ideal(0),i2,ideal(1);
711   list l1=splitPrimary(l,ideal(0),0);
712   l1;
713}
714///////////////////////////////////////////////////////////////////////////////
715proc splitCharp(list l)
716{
717  if((char(basering)==0)||(npars(basering)>0))
718  {
719     return(l);
720  }
721  def P=basering;
722  int i,j,k,m,q,d;
723  int n=nvars(basering);
724  ideal s,t,u,sact;
725  poly ni;
726  string minp,gnir,va;
727  list sa,keep;
728  for(i=1;i<=size(l)/2;i++)
729  {
730    if(size(l[2*i])==0)
731    {
732       if(deg(l[2*i-1][1])==vdim(l[2*i-1]))
733       {
734          l[2*i]=l[2*i-1];
735       }
736    }
737  }
738  for(i=1;i<=size(l)/2;i++)
739  {
740    if(size(l[2*i])==0)
741    {
742      s=factorize(l[2*i-1][1],1);
743      t=l[2*i-1];
744      m=size(t);
745      ni=s[1];
746      if(deg(ni)>1)
747      {
748        va=varstr(P);
749        j=size(va);
750        while(va[j]!=","){j--;}
751        va=va[1..j-1];
752        gnir="ring RL=("+string(char(P))+","+string(var(n))+"),("+va+"),dp;";
753        execute(gnir);
754        minpoly=leadcoef(imap(P,ni));
755        ideal act;
756        ideal t=imap(P,t);
757        for(k=2;k<=m;k++)
758        {
759           act=factorize(t[k],1);
760           if(size(act)>1)
761           {
762
763             break;
764           }
765        }
766        setring P;
767        sact=imap(RL,act);
768        kill RL;
769        if(size(sact)>1)
770        {
771           sa=sat1(l[2*i-1],sact[1]);
772           keep[size(keep)+1]=std(l[2*i-1],sa[2]);
773           l[2*i-1]=std(sa[1]);
774           l[2*i]=primaryTest(sa[1],sa[1][1]);
775        }
776      }
777    }
778  }
779  if(size(keep)>0)
780  {
781    for(i=1;i<=size(keep);i++)
782    {
783       l[size(l)+1]=keep[i];
784       l[size(l)+1]=primaryTest(keep[i],keep[i][1]);
785    }
786  }
787  return(l);
788}
789
790///////////////////////////////////////////////////////////////////////////////
791
792proc zero_decomp (ideal j,ideal ser,int @wr,list #)
793"USAGE:   zero_decomp(j,ser,@wr); j,ser ideals, @wr=0 or 1
794         (@wr=0 for primary decomposition, @wr=1 for computaion of associated
795         primes)
796RETURN:  list = list of primary ideals and their radicals (at even positions
797         in the list) if the input is zero-dimensional and a standardbases
798         with respect to lex-ordering
799         If ser!=(0) and ser is contained in j or if j is not zero-dimen-
800         sional then ideal(1),ideal(1) is returned
801NOTE:    Algorithm of Gianni, Traeger, Zacharias
802EXAMPLE: example zero_decomp; shows an example
803"
804{
805  def   @P = basering;
806  int uytrewq;
807  int nva = nvars(basering);
808  int @k,@s,@n,@k1,zz;
809  list primary,lres0,lres1,act,@lh,@wh;
810  map phi,psi,phi1,psi1;
811  ideal jmap,jmap1,jmap2,helpprim,@qh,@qht,ser1;
812  intvec @vh,@hilb;
813  string @ri;
814  poly @f;
815  if (dim(j)>0)
816  {
817     primary[1]=ideal(1);
818     primary[2]=ideal(1);
819     return(primary);
820  }
821  j=interred(j);
822
823  attrib(j,"isSB",1);
824  if(vdim(j)==deg(j[1]))
825  {
826     act=factor(j[1]);
827     for(@k=1;@k<=size(act[1]);@k++)
828     {
829       @qh=j;
830       if(@wr==0)
831       {
832          @qh[1]=act[1][@k]^act[2][@k];
833       }
834       else
835       {
836          @qh[1]=act[1][@k];
837       }
838       primary[2*@k-1]=interred(@qh);
839       @qh=j;
840       @qh[1]=act[1][@k];
841       primary[2*@k]=interred(@qh);
842       attrib( primary[2*@k-1],"isSB",1);
843
844       if((size(ser)>0)&&(size(reduce(ser,primary[2*@k-1],1))==0))
845       {
846          primary[2*@k-1]=ideal(1);
847          primary[2*@k]=ideal(1);
848       }
849     }
850     return(primary);
851  }
852
853  if(homog(j)==1)
854  {
855     primary[1]=j;
856     if((size(ser)>0)&&(size(reduce(ser,j,1))==0))
857     {
858          primary[1]=ideal(1);
859          primary[2]=ideal(1);
860          return(primary);
861     }
862     if(dim(j)==-1)
863     {
864        primary[1]=ideal(1);
865        primary[2]=ideal(1);
866     }
867     else
868     {
869        primary[2]=maxideal(1);
870     }
871     return(primary);
872  }
873
874//the first element in the standardbase is factorized
875  if(deg(j[1])>0)
876  {
877    act=factor(j[1]);
878    testFactor(act,j[1]);
879  }
880  else
881  {
882     primary[1]=ideal(1);
883     primary[2]=ideal(1);
884     return(primary);
885  }
886
887//with the factors new ideals (hopefully the primary decomposition)
888//are created
889
890  if(size(act[1])>1)
891  {
892     if(size(#)>1)
893     {
894        primary[1]=ideal(1);
895        primary[2]=ideal(1);
896        primary[3]=ideal(1);
897        primary[4]=ideal(1);
898        return(primary);
899     }
900     for(@k=1;@k<=size(act[1]);@k++)
901     {
902        if(@wr==0)
903        {
904           primary[2*@k-1]=std(j,act[1][@k]^act[2][@k]);
905        }
906        else
907        {
908           primary[2*@k-1]=std(j,act[1][@k]);
909        }
910        if((act[2][@k]==1)&&(vdim(primary[2*@k-1])==deg(act[1][@k])))
911        {
912           primary[2*@k]   = primary[2*@k-1];
913        }
914        else
915        {
916           primary[2*@k]   = primaryTest(primary[2*@k-1],act[1][@k]);
917        }
918     }
919  }
920  else
921  {
922     primary[1]=j;
923     if((size(#)>0)&&(act[2][1]>1))
924     {
925        act[2]=1;
926        primary[1]=std(primary[1],act[1][1]);
927     }
928
929     if((act[2][1]==1)&&(vdim(primary[1])==deg(act[1][1])))
930     {
931        primary[2]=primary[1];
932     }
933     else
934     {
935        primary[2]=primaryTest(primary[1],act[1][1]);
936     }
937  }
938  if(size(#)==0)
939  {
940     primary=splitPrimary(primary,ser,@wr,act);
941  }
942  primary=splitCharp(primary);
943//test whether all ideals in the decomposition are primary and
944//in general position
945//if not after a random coordinate transformation of the last
946//variable the corresponding ideal is decomposed again.
947
948  @k=0;
949  while(@k<(size(primary)/2))
950  {
951    @k++;
952    if (size(primary[2*@k])==0)
953    {
954       for(zz=1;zz<size(primary[2*@k-1])-1;zz++)
955       {
956          if(vdim(primary[2*@k-1])==deg(primary[2*@k-1][zz]))
957          {
958             primary[2*@k]=primary[2*@k-1];
959          }
960       }
961    }
962  }
963
964  @k=0;
965  ideal keep;
966  while(@k<(size(primary)/2))
967  {
968    @k++;
969    if (size(primary[2*@k])==0)
970    {
971
972       jmap=randomLast(100);
973       jmap1=maxideal(1);
974       jmap2=maxideal(1);
975       @qht=primary[2*@k-1];
976
977       for(@n=2;@n<=size(primary[2*@k-1]);@n++)
978       {
979          if(deg(lead(primary[2*@k-1][@n]))==1)
980          {
981             for(zz=1;zz<=nva;zz++)
982             {
983                if(lead(primary[2*@k-1][@n])/var(zz)!=0)
984                {
985                   jmap1[zz]=-1/leadcoef(primary[2*@k-1][@n])*primary[2*@k-1][@n]
986                   +2/leadcoef(primary[2*@k-1][@n])*lead(primary[2*@k-1][@n]);
987                    jmap2[zz]=primary[2*@k-1][@n];
988                    @qht[@n]=var(zz);
989
990                }
991             }
992             jmap[nva]=subst(jmap[nva],lead(primary[2*@k-1][@n]),0);
993          }
994       }
995       if(size(subst(jmap[nva],var(1),0)-var(nva))!=0)
996       {
997         // jmap[nva]=subst(jmap[nva],var(1),0);
998         //hier geaendert +untersuchen!!!!!!!!!!!!!!
999       }
1000       phi1=@P,jmap1;
1001       phi=@P,jmap;
1002       for(@n=1;@n<=nva;@n++)
1003       {
1004          jmap[@n]=-(jmap[@n]-2*var(@n));
1005       }
1006       psi=@P,jmap;
1007       psi1=@P,jmap2;
1008       @qh=phi(@qht);
1009       if(npars(@P)>0)
1010       {
1011          @ri= "ring @Phelp ="
1012                  +string(char(@P))+",
1013                   ("+varstr(@P)+","+parstr(@P)+",@t),(C,dp);";
1014       }
1015       else
1016       {
1017          @ri= "ring @Phelp ="
1018                  +string(char(@P))+",("+varstr(@P)+",@t),(C,dp);";
1019       }
1020       execute(@ri);
1021       ideal @qh=homog(imap(@P,@qht),@t);
1022
1023       ideal @qh1=std(@qh);
1024       @hilb=hilb(@qh1,1);
1025       @ri= "ring @Phelp1 ="
1026                  +string(char(@P))+",("+varstr(@Phelp)+"),(C,lp);";
1027       execute(@ri);
1028       ideal @qh=homog(imap(@P,@qh),@t);
1029       kill @Phelp;
1030       @qh=std(@qh,@hilb);
1031       @qh=subst(@qh,@t,1);
1032       setring @P;
1033       @qh=imap(@Phelp1,@qh);
1034       kill @Phelp1;
1035       @qh=clearSB(@qh);
1036       attrib(@qh,"isSB",1);
1037       ser1=phi1(ser);
1038       @lh=zero_decomp (@qh,phi(ser1),@wr);
1039//       @lh=zero_decomp (@qh,psi(ser),@wr);
1040
1041       kill lres0;
1042       list lres0;
1043       if(size(@lh)==2)
1044       {
1045          helpprim=@lh[2];
1046          lres0[1]=primary[2*@k-1];
1047          ser1=psi(helpprim);
1048          lres0[2]=psi1(ser1);
1049          if(size(reduce(lres0[2],lres0[1],1))==0)
1050          {
1051             primary[2*@k]=primary[2*@k-1];
1052             continue;
1053          }
1054       }
1055       else
1056       {
1057          //act=factor(@qh[1]);
1058          //if(2*size(act[1])==size(@lh))
1059          //{
1060
1061         //   for(@n=1;@n<=size(act[1]);@n++)
1062         //    {
1063         //       @f=act[1][@n]^act[2][@n];
1064         //       ser1=psi(@f);
1065         //       lres0[2*@n-1]=interred(primary[2*@k-1]+psi1(ser1));
1066         //       helpprim=@lh[2*@n];
1067         //      ser1=psi(helpprim);
1068         //       lres0[2*@n]=psi1(ser1);
1069         //    }
1070         // }
1071         // else
1072         // {
1073             lres1=psi(@lh);
1074             lres0=psi1(lres1);
1075         //}
1076       }
1077       if(npars(@P)>0)
1078       {
1079          @ri= "ring @Phelp ="
1080                  +string(char(@P))+",
1081                   ("+varstr(@P)+","+parstr(@P)+",@t),(C,dp);";
1082       }
1083       else
1084       {
1085          @ri= "ring @Phelp ="
1086                  +string(char(@P))+",("+varstr(@P)+",@t),(C,dp);";
1087       }
1088       execute(@ri);
1089       list @lvec;
1090       list @lr=imap(@P,lres0);
1091       ideal @lr1;
1092
1093       if(size(@lr)==2)
1094       {
1095          @lr[2]=homog(@lr[2],@t);
1096          @lr1=std(@lr[2]);
1097          @lvec[2]=hilb(@lr1,1);
1098       }
1099       else
1100       {
1101          for(@n=1;@n<=size(@lr)/2;@n++)
1102          {
1103             if(specialIdealsEqual(@lr[2*@n-1],@lr[2*@n])==1)
1104             {
1105                @lr[2*@n-1]=homog(@lr[2*@n-1],@t);
1106                @lr1=std(@lr[2*@n-1]);
1107                @lvec[2*@n-1]=hilb(@lr1,1);
1108                @lvec[2*@n]=@lvec[2*@n-1];
1109             }
1110             else
1111             {
1112                @lr[2*@n-1]=homog(@lr[2*@n-1],@t);
1113                @lr1=std(@lr[2*@n-1]);
1114                @lvec[2*@n-1]=hilb(@lr1,1);
1115                @lr[2*@n]=homog(@lr[2*@n],@t);
1116                @lr1=std(@lr[2*@n]);
1117                @lvec[2*@n]=hilb(@lr1,1);
1118
1119             }
1120         }
1121       }
1122       @ri= "ring @Phelp1 ="
1123                  +string(char(@P))+",("+varstr(@Phelp)+"),(C,lp);";
1124       execute(@ri);
1125       list @lr=imap(@Phelp,@lr);
1126
1127       kill @Phelp;
1128       if(size(@lr)==2)
1129       {
1130          @lr[2]=std(@lr[2],@lvec[2]);
1131          @lr[2]=subst(@lr[2],@t,1);
1132
1133       }
1134       else
1135       {
1136          for(@n=1;@n<=size(@lr)/2;@n++)
1137          {
1138             if(specialIdealsEqual(@lr[2*@n-1],@lr[2*@n])==1)
1139             {
1140                @lr[2*@n-1]=std(@lr[2*@n-1],@lvec[2*@n-1]);
1141                @lr[2*@n-1]=subst(@lr[2*@n-1],@t,1);
1142                @lr[2*@n]=@lr[2*@n-1];
1143                attrib(@lr[2*@n],"isSB",1);
1144             }
1145             else
1146             {
1147                @lr[2*@n-1]=std(@lr[2*@n-1],@lvec[2*@n-1]);
1148                @lr[2*@n-1]=subst(@lr[2*@n-1],@t,1);
1149                @lr[2*@n]=std(@lr[2*@n],@lvec[2*@n]);
1150                @lr[2*@n]=subst(@lr[2*@n],@t,1);
1151             }
1152          }
1153       }
1154       kill @lvec;
1155       setring @P;
1156       lres0=imap(@Phelp1,@lr);
1157       kill @Phelp1;
1158       for(@n=1;@n<=size(lres0);@n++)
1159       {
1160          lres0[@n]=clearSB(lres0[@n]);
1161          attrib(lres0[@n],"isSB",1);
1162       }
1163
1164       primary[2*@k-1]=lres0[1];
1165       primary[2*@k]=lres0[2];
1166       @s=size(primary)/2;
1167       for(@n=1;@n<=size(lres0)/2-1;@n++)
1168       {
1169         primary[2*@s+2*@n-1]=lres0[2*@n+1];
1170         primary[2*@s+2*@n]=lres0[2*@n+2];
1171       }
1172       @k--;
1173     }
1174  }
1175  return(primary);
1176}
1177example
1178{ "EXAMPLE:"; echo = 2;
1179   ring  r = 0,(x,y,z),lp;
1180   poly  p = z2+1;
1181   poly  q = z4+2;
1182   ideal i = p^2*q^3,(y-z3)^3,(x-yz+z4)^4;
1183   i=std(i);
1184   list  pr= zero_decomp(i,ideal(0),0);
1185   pr;
1186}
1187
1188///////////////////////////////////////////////////////////////////////////////
1189
1190proc ggt (ideal i)
1191"USAGE:   ggt(i); i list of polynomials
1192RETURN:  poly = ggt(i[1],...,i[size(i)])
1193NOTE:
1194EXAMPLE: example ggt; shows an example
1195"
1196{
1197  int k;
1198  poly p=i[1];
1199  if(deg(p)==0)
1200  {
1201    return(1);
1202  }
1203
1204
1205  for (k=2;k<=size(i);k++)
1206  {
1207     if(deg(i[k])==0)
1208     {
1209        return(1)
1210     }
1211     p=GCD(p,i[k]);
1212     if(deg(p)==0)
1213     {
1214        return(1);
1215     }
1216  }
1217  return(p);
1218}
1219example
1220{ "EXAMPLE:"; echo = 2;
1221   ring  r = 0,(x,y,z),lp;
1222   poly  p = (x+y)*(y+z);
1223   poly  q = (z4+2)*(y+z);
1224   ideal l=p,q;
1225   poly  pr= ggt(l);
1226   pr;
1227}
1228///////////////////////////////////////////////////////////////////////////////
1229proc gcdTest(ideal act)
1230{
1231  int i,j;
1232  if(size(act)<=1)
1233  {
1234     return(0);
1235  }
1236  for (i=1;i<=size(act)-1;i++)
1237  {
1238     for(j=i+1;j<=size(act);j++)
1239     {
1240        if(deg(std(ideal(act[i],act[j]))[1])>0)
1241        {
1242           return(0);
1243        }
1244     }
1245  }
1246  return(1);
1247}
1248
1249///////////////////////////////////////////////////////////////////////////////
1250proc coeffLcm(ideal h)
1251{
1252   string @pa=parstr(basering);
1253   if(size(@pa)==0)
1254   {
1255      return(lcm(h));
1256   }
1257   def bsr= basering;
1258   string @id=string(h);
1259   execute("ring @r=0,("+@pa+","+varstr(bsr)+"),(C,dp);");
1260   execute ("ideal @i="+@id+";");
1261   poly @p=lcm(@i);
1262   string @ps=string(@p);
1263   setring bsr;
1264   execute ("poly @p="+@ps+";");
1265   return(@p);
1266}
1267example
1268{
1269   "EXAMPLE:"; echo = 2;
1270   ring  r =( 0,a,b),(x,y,z),lp;
1271   poly  p = (a+b)*(y-z);
1272   poly  q = (a+b)*(y+z);
1273   ideal l=p,q;
1274   poly  pr= coeffLcm(l);
1275   pr;
1276}
1277///////////////////////////////////////////////////////////////////////////////
1278
1279proc clearSB (ideal i,list #)
1280"USAGE:   clearSB(i); i ideal which is SB ordered by monomial ordering
1281RETURN:  ideal = minimal SB
1282NOTE:
1283EXAMPLE: example clearSB; shows an example
1284"
1285{
1286  int k,j;
1287  poly m;
1288  int c=size(i);
1289
1290  if(size(#)==0)
1291  {
1292    for(j=1;j<c;j++)
1293    {
1294      if(deg(i[j])==0)
1295      {
1296        i=ideal(1);
1297        return(i);
1298      }
1299      if(deg(i[j])>0)
1300      {
1301        m=lead(i[j]);
1302        for(k=j+1;k<=c;k++)
1303        {
1304           if(size(lead(i[k])/m)>0)
1305           {
1306             i[k]=0;
1307           }
1308        }
1309      }
1310    }
1311  }
1312  else
1313  {
1314    j=0;
1315    while(j<c-1)
1316    {
1317      j++;
1318      if(deg(i[j])==0)
1319      {
1320        i=ideal(1);
1321        return(i);
1322      }
1323      if(deg(i[j])>0)
1324      {
1325        m=lead(i[j]);
1326        for(k=j+1;k<=c;k++)
1327        {
1328           if(size(lead(i[k])/m)>0)
1329           {
1330             if((leadexp(m)!=leadexp(i[k]))||(#[j]<=#[k]))
1331             {
1332                i[k]=0;
1333             }
1334             else
1335             {
1336                i[j]=0;
1337                break;
1338             }
1339           }
1340        }
1341      }
1342    }
1343  }
1344  return(simplify(i,2));
1345}
1346example
1347{ "EXAMPLE:"; echo = 2;
1348   ring  r = (0,a,b),(x,y,z),dp;
1349   ideal i=ax2+y,a2x+y,bx;
1350   list l=1,2,1;
1351   ideal j=clearSB(i,l);
1352   j;
1353}
1354
1355///////////////////////////////////////////////////////////////////////////////
1356
1357proc independSet (ideal j)
1358"USAGE:   independentSet(i); i ideal
1359RETURN:  list = new varstring with the independent set at the end,
1360                ordstring with the corresponding block ordering,
1361                the integer where the independent set starts in the varstring
1362NOTE:
1363EXAMPLE: example independentSet; shows an example
1364"
1365{
1366   int n,k,di;
1367   list resu,hilf;
1368   string var1,var2;
1369   list v=indepSet(j,1);
1370
1371   for(n=1;n<=size(v);n++)
1372   {
1373      di=0;
1374      var1="";
1375      var2="";
1376      for(k=1;k<=size(v[n]);k++)
1377      {
1378         if(v[n][k]!=0)
1379         {
1380            di++;
1381            var2=var2+"var("+string(k)+"),";
1382         }
1383         else
1384         {
1385            var1=var1+"var("+string(k)+"),";
1386         }
1387      }
1388      if(di>0)
1389      {
1390         var1=var1+var2;
1391         var1=var1[1..size(var1)-1];
1392         hilf[1]=var1;
1393         hilf[2]="lp";
1394         //"lp("+string(nvars(basering)-di)+"),dp("+string(di)+")";
1395         hilf[3]=di;
1396         resu[n]=hilf;
1397      }
1398      else
1399      {
1400         resu[n]=varstr(basering),ordstr(basering),0;
1401      }
1402   }
1403   return(resu);
1404}
1405example
1406{ "EXAMPLE:"; echo = 2;
1407   ring s1=(0,x,y),(a,b,c,d,e,f,g),lp;
1408   ideal i=ea-fbg,fa+be,ec-fdg,fc+de;
1409   i=std(i);
1410   list  l=independSet(i);
1411   l;
1412   i=i,g;
1413   l=independSet(i);
1414   l;
1415
1416   ring s=0,(x,y,z),lp;
1417   ideal i=z,yx;
1418   list l=independSet(i);
1419   l;
1420
1421
1422}
1423///////////////////////////////////////////////////////////////////////////////
1424
1425proc maxIndependSet (ideal j)
1426"USAGE:   maxIndependentSet(i); i ideal
1427RETURN:  list = new varstring with the maximal independent set at the end,
1428                ordstring with the corresponding block ordering,
1429                the integer where the independent set starts in the varstring
1430NOTE:
1431EXAMPLE: example maxIndependentSet; shows an example
1432"
1433{
1434   int n,k,di;
1435   list resu,hilf;
1436   string var1,var2;
1437   list v=indepSet(j,0);
1438
1439   for(n=1;n<=size(v);n++)
1440   {
1441      di=0;
1442      var1="";
1443      var2="";
1444      for(k=1;k<=size(v[n]);k++)
1445      {
1446         if(v[n][k]!=0)
1447         {
1448            di++;
1449            var2=var2+"var("+string(k)+"),";
1450         }
1451         else
1452         {
1453            var1=var1+"var("+string(k)+"),";
1454         }
1455      }
1456      if(di>0)
1457      {
1458         var1=var1+var2;
1459         var1=var1[1..size(var1)-1];
1460         hilf[1]=var1;
1461         hilf[2]="lp";
1462         hilf[3]=di;
1463         resu[n]=hilf;
1464      }
1465      else
1466      {
1467         resu[n]=varstr(basering),ordstr(basering),0;
1468      }
1469   }
1470   return(resu);
1471}
1472example
1473{ "EXAMPLE:"; echo = 2;
1474   ring s1=(0,x,y),(a,b,c,d,e,f,g),lp;
1475   ideal i=ea-fbg,fa+be,ec-fdg,fc+de;
1476   i=std(i);
1477   list  l=maxIndependSet(i);
1478   l;
1479   i=i,g;
1480   l=maxIndependSet(i);
1481   l;
1482
1483   ring s=0,(x,y,z),lp;
1484   ideal i=z,yx;
1485   list l=maxIndependSet(i);
1486   l;
1487
1488
1489}
1490
1491///////////////////////////////////////////////////////////////////////////////
1492
1493proc prepareQuotientring (int nnp)
1494"USAGE:   prepareQuotientring(nnp); nnp int
1495RETURN:  string = to define Kvar(nnp+1),...,var(nvars)[..rest ]
1496NOTE:
1497EXAMPLE: example independentSet; shows an example
1498"
1499{
1500  ideal @ih,@jh;
1501  int npar=npars(basering);
1502  int @n;
1503
1504  string quotring= "ring quring = ("+charstr(basering);
1505  for(@n=nnp+1;@n<=nvars(basering);@n++)
1506  {
1507     quotring=quotring+",var("+string(@n)+")";
1508     @ih=@ih+var(@n);
1509  }
1510
1511  quotring=quotring+"),(var(1)";
1512  @jh=@jh+var(1);
1513  for(@n=2;@n<=nnp;@n++)
1514  {
1515    quotring=quotring+",var("+string(@n)+")";
1516    @jh=@jh+var(@n);
1517  }
1518  quotring=quotring+"),(C,lp);";
1519
1520  return(quotring);
1521
1522}
1523example
1524{ "EXAMPLE:"; echo = 2;
1525   ring s1=(0,x),(a,b,c,d,e,f,g),lp;
1526   def @Q=basering;
1527   list l= prepareQuotientring(3);
1528   l;
1529   execute(l[1]);
1530   execute(l[2]);
1531   basering;
1532   phi;
1533   setring @Q;
1534
1535}
1536
1537///////////////////////////////////////////////////////////////////////////////
1538
1539proc projdim(list l)
1540{
1541   int i=size(l)+1;
1542
1543   while(i>2)
1544   {
1545      i--;
1546      if((size(l[i])>0)&&(deg(l[i][1])>0))
1547      {
1548         return(i);
1549      }
1550   }
1551}
1552
1553///////////////////////////////////////////////////////////////////////////////
1554proc cleanPrimary(list l)
1555{
1556   int i,j;
1557   list lh;
1558   for(i=1;i<=size(l)/2;i++)
1559   {
1560      if(deg(l[2*i-1][1])>0)
1561      {
1562         j++;
1563         lh[j]=l[2*i-1];
1564         j++;
1565         lh[j]=l[2*i];
1566      }
1567   }
1568   return(lh);
1569}
1570///////////////////////////////////////////////////////////////////////////////
1571
1572proc minAssPrimes(ideal i, list #)
1573"USAGE:   minAssPrimes(i); i ideal
1574         minAssPrimes(i,1); i ideal  (to use also the factorizing Groebner)
1575RETURN:  list = the minimal associated prime ideals of i
1576EXAMPLE: example minAssPrimes; shows an example
1577"
1578{
1579   def @P=basering;
1580   list qr=simplifyIdeal(i);
1581   map phi=@P,qr[2];
1582   i=qr[1];
1583
1584   execute ("ring gnir = ("+charstr(basering)+"),("+varstr(basering)+"),("
1585             +ordstr(basering)+");");
1586
1587
1588   ideal i=fetch(@P,i);
1589   if(size(#)==0)
1590   {
1591      int @wr;
1592      list tluser,@res;
1593      list primary=decomp(i,2);
1594
1595      @res[1]=primary;
1596
1597      tluser=union(@res);
1598      setring @P;
1599      list @res=imap(gnir,tluser);
1600      return(phi(@res));
1601   }
1602   list @res,empty;
1603   ideal ser;
1604   option(redSB);
1605   list @pr=facstd(i);
1606   if(size(@pr)==1)
1607   {
1608      attrib(@pr[1],"isSB",1);
1609      if((dim(@pr[1])==0)&&(homog(@pr[1])==1))
1610      {
1611         setring @P;
1612         list @res=maxideal(1);
1613         return(phi(@res));
1614      }
1615      if(dim(@pr[1])>1)
1616      {
1617         setring @P;
1618        // kill gnir;
1619         execute ("ring gnir1 = ("+charstr(basering)+"),
1620                              ("+varstr(basering)+"),(C,lp);");
1621         ideal i=fetch(@P,i);
1622         list @pr=facstd(i);
1623        // ideal ser;
1624         setring gnir;
1625         @pr=fetch(gnir1,@pr);
1626         kill gnir1;
1627      }
1628   }
1629    option(noredSB);
1630   int j,k,odim,ndim,count;
1631   attrib(@pr[1],"isSB",1);
1632   if(#[1]==77)
1633   {
1634     odim=dim(@pr[1]);
1635     count=1;
1636     intvec pos;
1637     pos[size(@pr)]=0;
1638     for(j=2;j<=size(@pr);j++)
1639     {
1640        attrib(@pr[j],"isSB",1);
1641        ndim=dim(@pr[j]);
1642        if(ndim>odim)
1643        {
1644           for(k=count;k<=j-1;k++)
1645           {
1646              pos[k]=1;
1647           }
1648           count=j;
1649           odim=ndim;
1650        }
1651        if(ndim<odim)
1652        {
1653           pos[j]=1;
1654        }
1655     }
1656     for(j=1;j<=size(@pr);j++)
1657     {
1658        if(pos[j]!=1)
1659        {
1660            @res[j]=decomp(@pr[j],2);
1661        }
1662        else
1663        {
1664           @res[j]=empty;
1665        }
1666     }
1667   }
1668   else
1669   {
1670     ser=ideal(1);
1671     for(j=1;j<=size(@pr);j++)
1672     {
1673//@pr[j];
1674//pause();
1675        @res[j]=decomp(@pr[j],2);
1676//       @res[j]=decomp(@pr[j],2,@pr[j],ser);
1677//       for(k=1;k<=size(@res[j]);k++)
1678//       {
1679//          ser=intersect(ser,@res[j][k]);
1680//       }
1681     }
1682   }
1683
1684   @res=union(@res);
1685   setring @P;
1686   list @res=imap(gnir,@res);
1687   return(phi(@res));
1688}
1689example
1690{ "EXAMPLE:"; echo = 2;
1691   ring  r = 32003,(x,y,z),lp;
1692   poly  p = z2+1;
1693   poly  q = z4+2;
1694   ideal i = p^2*q^3,(y-z3)^3,(x-yz+z4)^4;
1695   list pr= minAssPrimes(i);  pr;
1696
1697   minAssPrimes(i,1);
1698}
1699
1700proc union(list li)
1701{
1702  int i,j,k;
1703
1704  def P=basering;
1705
1706  execute("ring ir = ("+charstr(basering)+"),("+varstr(basering)+"),(C,lp);");
1707  list l=fetch(P,li);
1708  list @erg;
1709
1710  for(k=1;k<=size(l);k++)
1711  {
1712     for(j=1;j<=size(l[k])/2;j++)
1713     {
1714        if(deg(l[k][2*j][1])!=0)
1715        {
1716           i++;
1717           @erg[i]=l[k][2*j];
1718        }
1719     }
1720  }
1721
1722  list @wos;
1723  i=0;
1724  ideal i1,i2;
1725  while(i<size(@erg)-1)
1726  {
1727     i++;
1728     k=i+1;
1729     i1=lead(@erg[i]);
1730      attrib(i1,"isSB",1);
1731      attrib(@erg[i],"isSB",1);
1732
1733     while(k<=size(@erg))
1734     {
1735        if(deg(@erg[i][1])==0)
1736        {
1737           break;
1738        }
1739        i2=lead(@erg[k]);
1740        attrib(@erg[k],"isSB",1);
1741        attrib(i2,"isSB",1);
1742
1743        if(size(reduce(i1,i2,1))==0)
1744        {
1745           if(size(reduce(@erg[i],@erg[k],1))==0)
1746           {
1747              @erg[k]=ideal(1);
1748              i2=ideal(1);
1749           }
1750        }
1751        if(size(reduce(i2,i1,1))==0)
1752        {
1753           if(size(reduce(@erg[k],@erg[i],1))==0)
1754           {
1755              break;
1756           }
1757        }
1758        k++;
1759        if(k>size(@erg))
1760        {
1761           @wos[size(@wos)+1]=@erg[i];
1762        }
1763     }
1764  }
1765  if(deg(@erg[size(@erg)][1])!=0)
1766  {
1767     @wos[size(@wos)+1]=@erg[size(@erg)];
1768  }
1769  setring P;
1770  list @ser=fetch(ir,@wos);
1771  return(@ser);
1772}
1773///////////////////////////////////////////////////////////////////////////////
1774proc radicalOld(ideal i)
1775{
1776   list pr=minAssPrimes(i,1);
1777   int j;
1778   ideal k=pr[1];
1779   for(j=2;j<=size(pr);j++)
1780   {
1781      k=intersect(k,pr[j]);
1782   }
1783   return(k);
1784}
1785///////////////////////////////////////////////////////////////////////////////
1786proc equidim(ideal i,list #)
1787"USAGE:  equidim(i) or equidim(i,1) ; i ideal
1788         equidim(i,1) uses the algorithm of Eisenbud, Hunecke and Vasconcelos         
1789 RETURN: list = list of equidimensional ideals a1,...,as such that
1790         i is the intersection of a1,...,as. as is the equidimensional
1791         locus of i, ai are the lower dimensional equidimensional loci
1792         with (perhaps) modified embedded components,i.e. an embedded
1793         component q (primary ideal) of i can be replaced in the decompo-
1794         sition by a primary ideal q1 with the same radical as q
1795 EXAMPLE:example equidim; shows an example
1796"
1797{
1798  def  P = basering;
1799  list eq;
1800  intvec w;
1801  int n,m;
1802  int g=size(i);
1803  int a=attrib(i,"isSB");
1804  int homo=homog(i);
1805  if(size(#)!=0)
1806  {
1807     m=1;
1808  }
1809
1810  if(((homo==1)||(a==1))&&(find(ordstr(basering),"l")==0)
1811                                &&(find(ordstr(basering),"s")==0))
1812  {
1813     execute("ring gnir = ("+charstr(basering)+"),("+varstr(basering)+"),("
1814                              +ordstr(basering)+");");
1815     ideal i=imap(P,i);
1816     ideal j=i;
1817     if(a==1)
1818     {
1819       attrib(j,"isSB",1);
1820     }
1821     else
1822     {
1823       j=groebner(i);
1824     }
1825  }
1826  else
1827  {
1828     execute("ring gnir = ("+charstr(basering)+"),("+varstr(basering)+"),dp;");
1829     ideal i=imap(P,i);
1830     ideal j=groebner(i);
1831  } 
1832  if(homo==1)
1833  {
1834     for(n=1;n<=nvars(basering);n++)
1835     {
1836        w[n]=ord(var(n));
1837     }
1838     intvec hil=hilb(j,1,w);
1839  }
1840
1841  if ((dim(j)==-1)||(size(j)==0)||(nvars(basering)==1)
1842                  ||(dim(j)==0)||(dim(j)+g==nvars(basering)))
1843  {
1844    setring P;
1845    eq[1]=i;
1846    return(eq);
1847  }
1848
1849  if(m==0)
1850  {
1851     ideal k=equidimMax(j);
1852  }
1853  else
1854  {
1855     ideal k=equidimMaxEHV(j);
1856  }
1857  if(size(reduce(k,j,1))==0)
1858  {
1859    setring P;
1860    eq[1]=i;
1861    kill gnir;
1862    return(eq);
1863  }
1864  option(returnSB); 
1865  j=quotient(j,k);
1866  option(noreturnSB);
1867
1868  list equi=equidim(j); 
1869  if(deg(equi[size(equi)][1])<=0)
1870  {
1871      equi[size(equi)]=k;
1872  }
1873  else
1874  {
1875    equi[size(equi)+1]=k;
1876  }
1877  setring P;
1878  eq=imap(gnir,equi);
1879  kill gnir;
1880  return(eq);
1881}
1882example
1883{ "EXAMPLE:"; echo = 2;
1884   ring  r = 32003,(x,y,z),dp;
1885   ideal i=intersect(ideal(z),ideal(x,y),ideal(x2,z2),ideal(x5,y5,z5));
1886   equidim(i);
1887}
1888
1889///////////////////////////////////////////////////////////////////////////////
1890proc equidimMax(ideal i)
1891"USAGE:  equidimMax(i); i ideal           
1892 RETURN:  ideal = ideal of equidimensional locus
1893 EXAMPLE: example equidimMax; shows an example
1894"
1895{
1896  def  P = basering;
1897  ideal eq;
1898  intvec w;
1899  int n;
1900  int g=size(i);
1901  int a=attrib(i,"isSB");
1902  int homo=homog(i);
1903   
1904  if(((homo==1)||(a==1))&&(find(ordstr(basering),"l")==0)
1905                                &&(find(ordstr(basering),"s")==0))
1906  {
1907     execute("ring gnir = ("+charstr(basering)+"),("+varstr(basering)+"),("
1908                              +ordstr(basering)+");");
1909     ideal i=imap(P,i);
1910     ideal j=i;
1911     if(a==1)
1912     {
1913       attrib(j,"isSB",1);
1914     }
1915     else
1916     {
1917       j=groebner(i);
1918     }
1919  }
1920  else
1921  {
1922     execute("ring gnir = ("+charstr(basering)+"),("+varstr(basering)+"),dp;");
1923     ideal i=imap(P,i);
1924     ideal j=groebner(i);
1925  }
1926  list indep;
1927  ideal equ,equi;
1928  if(homo==1)
1929  {
1930     for(n=1;n<=nvars(basering);n++)
1931     {
1932        w[n]=ord(var(n));
1933     }
1934     intvec hil=hilb(j,1,w);
1935  }
1936  if ((dim(j)==-1)||(size(j)==0)||(nvars(basering)==1)
1937                  ||(dim(j)==0)||(dim(j)+g==nvars(basering)))
1938  {
1939    setring P;
1940    return(i);
1941  }
1942
1943  indep=maxIndependSet(j);
1944
1945  execute("ring gnir1 = ("+charstr(basering)+"),("+indep[1][1]+"),("
1946                              +indep[1][2]+");");
1947  if(homo==1)
1948  {
1949     ideal j=std(imap(gnir,j),hil,w);
1950  }
1951  else
1952  {
1953     ideal j=groebner(imap(gnir,j));
1954  }
1955  string quotring=prepareQuotientring(nvars(basering)-indep[1][3]);
1956  execute(quotring);
1957  ideal j=imap(gnir1,j);
1958  kill gnir1;
1959  j=clearSB(j);
1960  ideal h;
1961  for(n=1;n<=size(j);n++)
1962  {
1963     h[n]=leadcoef(j[n]);
1964  }
1965  setring gnir;
1966  ideal h=imap(quring,h);
1967  kill quring;
1968
1969  list l=minSat(j,h);
1970 
1971  if(deg(l[2])>0)
1972  {
1973    equ=l[1];
1974    attrib(equ,"isSB",1);
1975    j=std(j,l[2]);
1976
1977    if(dim(equ)==dim(j))
1978    {
1979      equi=equidimMax(j);
1980      equ=interred(intersect(equ,equi));
1981    }
1982  }
1983  else
1984  {
1985    equ=i;
1986  }
1987
1988  setring P;
1989  eq=imap(gnir,equ);
1990  kill gnir;
1991  return(eq);
1992}
1993example
1994{ "EXAMPLE:"; echo = 2;
1995   ring  r = 32003,(x,y,z),dp;
1996   ideal i=intersect(ideal(z),ideal(x,y),ideal(x2,z2),ideal(x5,y5,z5));
1997   equidimMax(i);
1998}
1999
2000///////////////////////////////////////////////////////////////////////////////
2001proc decomp(ideal i,list #)
2002"USAGE:   decomp(i); i ideal  (for primary decomposition)   (resp.
2003         decomp(i,1);        (for the minimal associated primes) )
2004RETURN:  list = list of primary ideals and their associated primes
2005         (at even positions in the list)
2006         (resp. a list of the minimal associated primes)
2007NOTE:    Algorithm of Gianni, Traeger, Zacharias
2008EXAMPLE: example decomp; shows an example
2009"
2010{
2011  def  @P = basering;
2012  list primary,indep,ltras;
2013  intvec @vh,isat,@w;
2014  int @wr,@k,@n,@m,@n1,@n2,@n3,homo,seri,keepdi;
2015  ideal peek=i;
2016  ideal ser,tras;
2017
2018  if(size(#)>0)
2019  {
2020     if((#[1]==1)||(#[1]==2))
2021     {
2022        @wr=#[1];
2023        if(size(#)>1)
2024        {
2025          seri=1;
2026          peek=#[2];
2027          ser=#[3];
2028        }
2029      }
2030      else
2031      {
2032        seri=1;
2033        peek=#[1];
2034        ser=#[2];
2035      }
2036  }
2037
2038  homo=homog(i);
2039  if(homo==1)
2040  {
2041    if(attrib(i,"isSB")!=1)
2042    {
2043      ltras=mstd(i);
2044      attrib(ltras[1],"isSB",1);
2045    }
2046    else
2047    {
2048      ltras=i,i;
2049    }
2050    tras=ltras[1];
2051    if(dim(tras)==0)
2052    {
2053        primary[1]=ltras[2];
2054        primary[2]=maxideal(1);
2055        if(@wr>0)
2056        {
2057           list l;
2058           l[1]=maxideal(1);
2059           l[2]=maxideal(1);
2060           return(l);
2061        }
2062        return(primary);
2063     }
2064     for(@n=1;@n<=nvars(basering);@n++)
2065     {
2066        @w[@n]=ord(var(@n));
2067     }
2068     intvec @hilb=hilb(tras,1,@w);
2069     intvec keephilb=@hilb;
2070  }
2071
2072  //----------------------------------------------------------------
2073  //i is the zero-ideal
2074  //----------------------------------------------------------------
2075
2076  if(size(i)==0)
2077  {
2078     primary=i,i;
2079     return(primary);
2080  }
2081
2082  //----------------------------------------------------------------
2083  //pass to the lexicographical ordering and compute a standardbasis
2084  //----------------------------------------------------------------
2085
2086  execute("ring gnir = ("+charstr(basering)+"),("+varstr(basering)+"),(C,lp);");
2087  option(redSB);
2088
2089  ideal ser=fetch(@P,ser);
2090
2091  if(homo==1)
2092  {
2093     if((ordstr(@P)[1]!="(C,lp)")&&(ordstr(@P)[3]!="(C,lp)"))
2094     {
2095       ideal @j=std(fetch(@P,i),@hilb,@w);
2096     }
2097     else
2098     {
2099        ideal @j=fetch(@P,tras);
2100        attrib(@j,"isSB",1);
2101     }
2102  }
2103  else
2104  {
2105     ideal @j=groebner(fetch(@P,i));
2106  }
2107  option(noredSB);
2108  if(seri==1)
2109  {
2110    ideal peek=fetch(@P,peek);
2111    attrib(peek,"isSB",1);
2112  }
2113  else
2114  {
2115    ideal peek=@j;
2116  }
2117  if(size(ser)==0)
2118  {
2119    ideal fried;
2120    @n=size(@j);
2121    for(@k=1;@k<=@n;@k++)
2122    {
2123      if(deg(lead(@j[@k]))==1)
2124      {
2125        fried[size(fried)+1]=@j[@k];
2126        @j[@k]=0;
2127      }
2128    }
2129    if(size(fried)==nvars(basering))
2130    {
2131       setring @P;
2132       primary[1]=i;
2133       primary[2]=i;
2134       return(primary);
2135    }
2136    if(size(fried)>0)
2137    {
2138       string newva;
2139       string newma;
2140       for(@k=1;@k<=nvars(basering);@k++)
2141       {
2142          @n1=0;
2143          for(@n=1;@n<=size(fried);@n++)
2144          {
2145             if(leadmonom(fried[@n])==var(@k))
2146             {
2147                @n1=1;
2148                break;
2149             }
2150          }
2151          if(@n1==0)
2152          {
2153            newva=newva+string(var(@k))+",";
2154            newma=newma+string(var(@k))+",";
2155          }
2156          else
2157          {
2158            newma=newma+string(0)+",";   
2159          }     
2160       }
2161       newva[size(newva)]=")";
2162       newma[size(newma)]=";";
2163       execute("ring @deirf=("+charstr(gnir)+"),("+newva+",lp;");
2164       execute("map @kappa=gnir,"+newma);
2165       ideal @j= @kappa(@j);
2166       @j=simplify(@j,2);
2167       attrib(@j,"isSB",1);
2168       list pr=decomp(@j);
2169       setring gnir;
2170       list pr=imap(@deirf,pr);
2171       for(@k=1;@k<=size(pr);@k++)
2172       {
2173         @j=pr[@k]+fried;
2174         pr[@k]=@j;
2175       }
2176       setring @P;
2177       return(imap(gnir,pr));
2178    }
2179  }
2180
2181  //----------------------------------------------------------------
2182  //j is the ring
2183  //----------------------------------------------------------------
2184
2185  if (dim(@j)==-1)
2186  {
2187    setring @P;
2188    primary=ideal(1),ideal(1);
2189    return(primary);
2190  }
2191
2192  //----------------------------------------------------------------
2193  //  the case of one variable
2194  //----------------------------------------------------------------
2195
2196  if(nvars(basering)==1)
2197  {
2198
2199     list fac=factor(@j[1]);
2200     list gprimary;
2201     for(@k=1;@k<=size(fac[1]);@k++)
2202     {
2203        if(@wr==0)
2204        {
2205           gprimary[2*@k-1]=ideal(fac[1][@k]^fac[2][@k]);
2206           gprimary[2*@k]=ideal(fac[1][@k]);
2207        }
2208        else
2209        {
2210           gprimary[2*@k-1]=ideal(fac[1][@k]);
2211           gprimary[2*@k]=ideal(fac[1][@k]);
2212        }
2213     }
2214     setring @P;
2215     primary=fetch(gnir,gprimary);
2216
2217     return(primary);
2218  }
2219
2220 //------------------------------------------------------------------
2221 //the zero-dimensional case
2222 //------------------------------------------------------------------
2223  if (dim(@j)==0)
2224  {
2225    option(redSB);
2226    list gprimary= zero_decomp(@j,ser,@wr);
2227    option(noredSB);
2228    setring @P;
2229    primary=fetch(gnir,gprimary);
2230    if(size(ser)>0)
2231    {
2232      primary=cleanPrimary(primary);
2233    }
2234    return(primary);
2235  }
2236
2237  poly @gs,@gh,@p;
2238  string @va,quotring;
2239  list quprimary,htprimary,collectprimary,lsau,lnew,allindep,restindep;
2240  ideal @h;
2241  int jdim=dim(@j);
2242  list fett;
2243  int lauf,di,newtest;
2244  //------------------------------------------------------------------
2245  //search for a maximal independent set indep,i.e.
2246  //look for subring such that the intersection with the ideal is zero
2247  //j intersected with K[var(indep[3]+1),...,var(nvar] is zero,
2248  //indep[1] is the new varstring and indep[2] the string for block-ordering
2249  //------------------------------------------------------------------
2250
2251  if(@wr!=1)
2252  {
2253     allindep=independSet(@j);
2254     for(@m=1;@m<=size(allindep);@m++)
2255     {
2256        if(allindep[@m][3]==jdim)
2257        {
2258           di++;
2259           indep[di]=allindep[@m];
2260        }
2261        else
2262        {
2263           lauf++;
2264           restindep[lauf]=allindep[@m];
2265        }
2266     }
2267   }
2268   else
2269   {
2270      indep=maxIndependSet(@j);
2271   }
2272
2273  ideal jkeep=@j;
2274  if(ordstr(@P)[1]=="w")
2275  {
2276     execute("ring @Phelp=("+charstr(gnir)+"),("+varstr(gnir)+"),("+ordstr(@P)+");");
2277  }
2278  else
2279  {
2280     execute( "ring @Phelp=("+charstr(gnir)+"),("+varstr(gnir)+"),(C,dp);");
2281  }
2282
2283  if(homo==1)
2284  {
2285    if((ordstr(@P)[3]=="d")||(ordstr(@P)[1]=="d")||(ordstr(@P)[1]=="w")
2286       ||(ordstr(@P)[3]=="w"))
2287    {
2288      ideal jwork=imap(@P,tras);
2289      attrib(jwork,"isSB",1);
2290    }
2291    else
2292    {
2293      ideal jwork=std(imap(gnir,@j),@hilb,@w);
2294    }
2295
2296  }
2297  else
2298  {
2299    ideal jwork=groebner(imap(gnir,@j));
2300  }
2301  list hquprimary;
2302  poly @p,@q;
2303  ideal @h,fac,ser;
2304  di=dim(jwork);
2305  keepdi=di;
2306
2307  setring gnir;
2308  for(@m=1;@m<=size(indep);@m++)
2309  {
2310     isat=0;
2311     @n2=0;
2312     option(redSB);
2313     if((indep[@m][1]==varstr(basering))&&(@m==1))
2314     //this is the good case, nothing to do, just to have the same notations
2315     //change the ring
2316     {
2317        execute("ring gnir1 = ("+charstr(basering)+"),("+varstr(basering)+"),("
2318                              +ordstr(basering)+");");
2319        ideal @j=fetch(gnir,@j);
2320        attrib(@j,"isSB",1);
2321        ideal ser=fetch(gnir,ser);
2322
2323     }
2324     else
2325     {
2326        @va=string(maxideal(1));
2327        execute("ring gnir1 = ("+charstr(basering)+"),("+indep[@m][1]+"),("
2328                              +indep[@m][2]+");");
2329        execute("map phi=gnir,"+@va+";");
2330        if(homo==1)
2331        {
2332           ideal @j=std(phi(@j),@hilb,@w);
2333        }
2334        else
2335        {
2336          ideal @j=groebner(phi(@j));
2337        }
2338        ideal ser=phi(ser);
2339
2340     }
2341     option(noredSB);
2342     if((deg(@j[1])==0)||(dim(@j)<jdim))
2343     {
2344       setring gnir;
2345       break;
2346     }
2347     for (lauf=1;lauf<=size(@j);lauf++)
2348     {
2349         fett[lauf]=size(@j[lauf]);
2350     }
2351     //------------------------------------------------------------------------
2352     //we have now the following situation:
2353     //j intersected with K[var(nnp+1),..,var(nva)] is zero so we may pass
2354     //to this quotientring, j is their still a standardbasis, the
2355     //leading coefficients of the polynomials  there (polynomials in
2356     //K[var(nnp+1),..,var(nva)]) are collected in the list h,
2357     //we need their ggt, gh, because of the following: let
2358     //(j:gh^n)=(j:gh^infinity) then j*K(var(nnp+1),..,var(nva))[..the rest..]
2359     //intersected with K[var(1),...,var(nva)] is (j:gh^n)
2360     //on the other hand j=(j,gh^n) intersected with (j:gh^n)
2361
2362     //------------------------------------------------------------------------
2363
2364     //arrangement for quotientring K(var(nnp+1),..,var(nva))[..the rest..] and
2365     //map phi:K[var(1),...,var(nva)] --->K(var(nnpr+1),..,var(nva))[..rest..]
2366     //------------------------------------------------------------------------
2367
2368     quotring=prepareQuotientring(nvars(basering)-indep[@m][3]);
2369
2370     //---------------------------------------------------------------------
2371     //we pass to the quotientring   K(var(nnp+1),..,var(nva))[..the rest..]
2372     //---------------------------------------------------------------------
2373
2374     execute(quotring);
2375
2376    // @j considered in the quotientring
2377     ideal @j=imap(gnir1,@j);
2378     ideal ser=imap(gnir1,ser);
2379
2380     kill gnir1;
2381
2382     //j is a standardbasis in the quotientring but usually not minimal
2383     //here it becomes minimal
2384
2385     @j=clearSB(@j,fett);
2386     attrib(@j,"isSB",1);
2387
2388     //we need later ggt(h[1],...)=gh for saturation
2389     ideal @h;
2390     if(deg(@j[1])>0)
2391     {
2392        for(@n=1;@n<=size(@j);@n++)
2393        {
2394           @h[@n]=leadcoef(@j[@n]);
2395        }
2396        //the primary decomposition of j*K(var(nnp+1),..,var(nva))[..the rest..]
2397        option(redSB);
2398        list uprimary= zero_decomp(@j,ser,@wr);
2399        option(noredSB);
2400     }
2401     else
2402     {
2403       list uprimary;
2404       uprimary[1]=ideal(1);
2405       uprimary[2]=ideal(1);
2406     }
2407     //we need the intersection of the ideals in the list quprimary with the
2408     //polynomialring, i.e. let q=(f1,...,fr) in the quotientring such an ideal
2409     //but fi polynomials, then the intersection of q with the polynomialring
2410     //is the saturation of the ideal generated by f1,...,fr with respect to
2411     //h which is the lcm of the leading coefficients of the fi considered in
2412     //in the quotientring: this is coded in saturn
2413
2414     list saturn;
2415     ideal hpl;
2416
2417     for(@n=1;@n<=size(uprimary);@n++)
2418     {
2419        uprimary[@n]=interred(uprimary[@n]); // temporary fix
2420        hpl=0;
2421        for(@n1=1;@n1<=size(uprimary[@n]);@n1++)
2422        {
2423           hpl=hpl,leadcoef(uprimary[@n][@n1]);
2424        }
2425        saturn[@n]=hpl;
2426     }
2427
2428     //--------------------------------------------------------------------
2429     //we leave  the quotientring   K(var(nnp+1),..,var(nva))[..the rest..]
2430     //back to the polynomialring
2431     //---------------------------------------------------------------------
2432     setring gnir;
2433
2434     collectprimary=imap(quring,uprimary);
2435     lsau=imap(quring,saturn);
2436     @h=imap(quring,@h);
2437
2438     kill quring;
2439
2440
2441     @n2=size(quprimary);
2442     @n3=@n2;
2443
2444     for(@n1=1;@n1<=size(collectprimary)/2;@n1++)
2445     {
2446        if(deg(collectprimary[2*@n1][1])>0)
2447        {
2448           @n2++;
2449           quprimary[@n2]=collectprimary[2*@n1-1];
2450           lnew[@n2]=lsau[2*@n1-1];
2451           @n2++;
2452           lnew[@n2]=lsau[2*@n1];
2453           quprimary[@n2]=collectprimary[2*@n1];
2454        }
2455     }
2456
2457     //here the intersection with the polynomialring
2458     //mentioned above is really computed
2459     for(@n=@n3/2+1;@n<=@n2/2;@n++)
2460     {
2461        if(specialIdealsEqual(quprimary[2*@n-1],quprimary[2*@n]))
2462        {
2463           quprimary[2*@n-1]=sat2(quprimary[2*@n-1],lnew[2*@n-1])[1];
2464           quprimary[2*@n]=quprimary[2*@n-1];
2465        }
2466        else
2467        {
2468           if(@wr==0)
2469           {
2470              quprimary[2*@n-1]=sat2(quprimary[2*@n-1],lnew[2*@n-1])[1];
2471           }
2472           quprimary[2*@n]=sat2(quprimary[2*@n],lnew[2*@n])[1];
2473        }
2474     }
2475
2476     if(size(@h)>0)
2477     {
2478           //---------------------------------------------------------------
2479           //we change to @Phelp to have the ordering dp for saturation
2480           //---------------------------------------------------------------
2481        setring @Phelp;
2482        @h=imap(gnir,@h);
2483        if(@wr!=1)
2484        {
2485          @q=minSat(jwork,@h)[2];
2486        }
2487        else
2488        {
2489            fac=ideal(0);
2490            for(lauf=1;lauf<=ncols(@h);lauf++)
2491           {
2492              if(deg(@h[lauf])>0)
2493              {
2494                 fac=fac+factorize(@h[lauf],1);
2495              }
2496           }
2497           fac=simplify(fac,4);
2498           @q=1;
2499           for(lauf=1;lauf<=size(fac);lauf++)
2500           {
2501             @q=@q*fac[lauf];
2502           }
2503        }
2504        jwork=std(jwork,@q);
2505        keepdi=dim(jwork);
2506        if(keepdi<di)
2507        {
2508           setring gnir;
2509           @j=imap(@Phelp,jwork);
2510           break;
2511        }
2512        if(homo==1)
2513        {
2514              @hilb=hilb(jwork,1,@w);
2515        }
2516
2517        setring gnir;
2518        @j=imap(@Phelp,jwork);
2519     }
2520  }
2521  if((size(quprimary)==0)&&(@wr>0))
2522  {
2523     @j=ideal(1);
2524     quprimary[1]=ideal(1);
2525     quprimary[2]=ideal(1);
2526  }
2527  if((size(quprimary)==0))
2528  {
2529    keepdi=di-1;
2530  }
2531  //---------------------------------------------------------------
2532  //notice that j=sat(j,gh) intersected with (j,gh^n)
2533  //we finished with sat(j,gh) and have to start with (j,gh^n)
2534  //---------------------------------------------------------------
2535  if((deg(@j[1])!=0)&&(@wr!=1))
2536  {
2537     if(size(quprimary)>0)
2538     {
2539        setring @Phelp;
2540        ser=imap(gnir,ser);
2541        hquprimary=imap(gnir,quprimary);
2542        if(@wr==0)
2543        {
2544           ideal htest=hquprimary[1];
2545           for (@n1=2;@n1<=size(hquprimary)/2;@n1++)
2546           {
2547              htest=intersect(htest,hquprimary[2*@n1-1]);
2548           }
2549        }
2550        else
2551        {
2552           ideal htest=hquprimary[2];
2553
2554           for (@n1=2;@n1<=size(hquprimary)/2;@n1++)
2555           {
2556              htest=intersect(htest,hquprimary[2*@n1]);
2557           }
2558        }
2559
2560        if(size(ser)>0)
2561        {
2562           ser=intersect(htest,ser);
2563        }
2564        else
2565        {
2566          ser=htest;
2567        }
2568        setring gnir;
2569        ser=imap(@Phelp,ser);
2570     }
2571     if(size(reduce(ser,peek,1))!=0)
2572     {
2573        for(@m=1;@m<=size(restindep);@m++)
2574        {
2575         // if(restindep[@m][3]>=keepdi)
2576         // {
2577           isat=0;
2578           @n2=0;
2579           option(redSB);
2580
2581           if(restindep[@m][1]==varstr(basering))
2582           //the good case, nothing to do, just to have the same notations
2583           //change the ring
2584           {
2585              execute("ring gnir1 = ("+charstr(basering)+"),("+
2586                varstr(basering)+"),("+ordstr(basering)+");");
2587              ideal @j=fetch(gnir,jkeep);
2588              attrib(@j,"isSB",1);
2589           }
2590           else
2591           {
2592              @va=string(maxideal(1));
2593              execute("ring gnir1 = ("+charstr(basering)+"),("+
2594                      restindep[@m][1]+"),(" +restindep[@m][2]+");");
2595              execute("map phi=gnir,"+@va+";");
2596              if(homo==1)
2597              {
2598                 ideal @j=std(phi(jkeep),keephilb,@w);
2599              }
2600              else
2601              {
2602                ideal @j=groebner(phi(jkeep));
2603              }
2604              ideal ser=phi(ser);
2605           }
2606           option(noredSB);
2607
2608           for (lauf=1;lauf<=size(@j);lauf++)
2609           {
2610              fett[lauf]=size(@j[lauf]);
2611           }
2612           //------------------------------------------------------------------
2613           //we have now the following situation:
2614           //j intersected with K[var(nnp+1),..,var(nva)] is zero so we may
2615           //pass to this quotientring, j is their still a standardbasis, the
2616           //leading coefficients of the polynomials  there (polynomials in
2617           //K[var(nnp+1),..,var(nva)]) are collected in the list h,
2618           //we need their ggt, gh, because of the following:
2619           //let (j:gh^n)=(j:gh^infinity) then
2620           //j*K(var(nnp+1),..,var(nva))[..the rest..]
2621           //intersected with K[var(1),...,var(nva)] is (j:gh^n)
2622           //on the other hand j=(j,gh^n) intersected with (j:gh^n)
2623
2624           //------------------------------------------------------------------
2625
2626           //the arrangement for the quotientring
2627           // K(var(nnp+1),..,var(nva))[..the rest..]
2628           //and the map phi:K[var(1),...,var(nva)] ---->
2629           //--->K(var(nnpr+1),..,var(nva))[..the rest..]
2630           //------------------------------------------------------------------
2631
2632           quotring=prepareQuotientring(nvars(basering)-restindep[@m][3]);
2633
2634           //------------------------------------------------------------------
2635           //we pass to the quotientring  K(var(nnp+1),..,var(nva))[..rest..]
2636           //------------------------------------------------------------------
2637
2638           execute(quotring);
2639
2640           // @j considered in the quotientring
2641           ideal @j=imap(gnir1,@j);
2642           ideal ser=imap(gnir1,ser);
2643
2644           kill gnir1;
2645
2646           //j is a standardbasis in the quotientring but usually not minimal
2647           //here it becomes minimal
2648           @j=clearSB(@j,fett);
2649           attrib(@j,"isSB",1);
2650
2651           //we need later ggt(h[1],...)=gh for saturation
2652           ideal @h;
2653
2654           for(@n=1;@n<=size(@j);@n++)
2655           {
2656              @h[@n]=leadcoef(@j[@n]);
2657           }
2658           //the primary decomposition of j*K(var(nnp+1),..,var(nva))[..rest..]
2659
2660           option(redSB);
2661           list uprimary= zero_decomp(@j,ser,@wr);
2662           option(noredSB);
2663
2664
2665           //we need the intersection of the ideals in the list quprimary with
2666           //the polynomialring, i.e. let q=(f1,...,fr) in the quotientring
2667           //such an ideal but fi polynomials, then the intersection of q with
2668           //the polynomialring is the saturation of the ideal generated by
2669           //f1,...,fr with respect toh which is the lcm of the leading
2670           //coefficients of the fi considered in the quotientring:
2671           //this is coded in saturn
2672
2673           list saturn;
2674           ideal hpl;
2675
2676           for(@n=1;@n<=size(uprimary);@n++)
2677           {
2678              hpl=0;
2679              for(@n1=1;@n1<=size(uprimary[@n]);@n1++)
2680              {
2681                 hpl=hpl,leadcoef(uprimary[@n][@n1]);
2682              }
2683               saturn[@n]=hpl;
2684           }
2685           //------------------------------------------------------------------
2686           //we leave  the quotientring   K(var(nnp+1),..,var(nva))[..rest..]
2687           //back to the polynomialring
2688           //------------------------------------------------------------------
2689           setring gnir;
2690
2691           collectprimary=imap(quring,uprimary);
2692           lsau=imap(quring,saturn);
2693           @h=imap(quring,@h);
2694
2695           kill quring;
2696
2697
2698           @n2=size(quprimary);
2699           @n3=@n2;
2700
2701           for(@n1=1;@n1<=size(collectprimary)/2;@n1++)
2702           {
2703              if(deg(collectprimary[2*@n1][1])>0)
2704              {
2705                 @n2++;
2706                 quprimary[@n2]=collectprimary[2*@n1-1];
2707                 lnew[@n2]=lsau[2*@n1-1];
2708                 @n2++;
2709                 lnew[@n2]=lsau[2*@n1];
2710                 quprimary[@n2]=collectprimary[2*@n1];
2711              }
2712           }
2713
2714
2715           //here the intersection with the polynomialring
2716           //mentioned above is really computed
2717
2718           for(@n=@n3/2+1;@n<=@n2/2;@n++)
2719           {
2720              if(specialIdealsEqual(quprimary[2*@n-1],quprimary[2*@n]))
2721              {
2722                 quprimary[2*@n-1]=sat2(quprimary[2*@n-1],lnew[2*@n-1])[1];
2723                 quprimary[2*@n]=quprimary[2*@n-1];
2724              }
2725              else
2726              {
2727                 if(@wr==0)
2728                 {
2729                    quprimary[2*@n-1]=sat2(quprimary[2*@n-1],lnew[2*@n-1])[1];
2730                 }
2731                 quprimary[2*@n]=sat2(quprimary[2*@n],lnew[2*@n])[1];
2732              }
2733           }
2734           if(@n2>=@n3+2)
2735           {
2736              setring @Phelp;
2737              ser=imap(gnir,ser);
2738              hquprimary=imap(gnir,quprimary);
2739              for(@n=@n3/2+1;@n<=@n2/2;@n++)
2740              {
2741                if(@wr==0)
2742                {
2743                   ser=intersect(ser,hquprimary[2*@n-1]);
2744                }
2745                else
2746                {
2747                   ser=intersect(ser,hquprimary[2*@n]);
2748                }
2749              }
2750              setring gnir;
2751              ser=imap(@Phelp,ser);
2752           }
2753
2754         // }
2755        }
2756        if(size(reduce(ser,peek,1))!=0)
2757        {
2758           if(@wr>0)
2759           {
2760              htprimary=decomp(@j,@wr,peek,ser);
2761           }
2762           else
2763           {
2764              htprimary=decomp(@j,peek,ser);
2765           }
2766           // here we collect now both results primary(sat(j,gh))
2767           // and primary(j,gh^n)
2768           @n=size(quprimary);
2769           for (@k=1;@k<=size(htprimary);@k++)
2770           {
2771              quprimary[@n+@k]=htprimary[@k];
2772           }
2773        }
2774     }
2775
2776   }
2777  //---------------------------------------------------------------------------
2778  //back to the ring we started with
2779  //the final result: primary
2780  //---------------------------------------------------------------------------
2781
2782  setring @P;
2783  primary=imap(gnir,quprimary);
2784  return(primary);
2785}
2786
2787
2788example
2789{ "EXAMPLE:"; echo = 2;
2790   ring  r = 32003,(x,y,z),lp;
2791   poly  p = z2+1;
2792   poly  q = z4+2;
2793   ideal i = p^2*q^3,(y-z3)^3,(x-yz+z4)^4;
2794   list pr= decomp(i);
2795   pr;
2796   testPrimary( pr, i);
2797}
2798
2799///////////////////////////////////////////////////////////////////////////////
2800proc radicalKL (list m,ideal ser,list #)
2801{
2802   ideal i=m[2];
2803  //--------------------------------------------------------------------------
2804  //i is the zero-ideal
2805  //-------------------------------------------------------------------------
2806
2807   if(size(i)==0)
2808   {
2809      return(ideal(0));
2810   }
2811
2812   def  @P = basering;
2813   list indep,allindep,restindep,fett,@mu;
2814   intvec @vh,isat;
2815   int @wr,@k,@n,@m,@n1,@n2,@n3,lauf,di;
2816   ideal @j,@j1,fac,@h,collectrad,htrad,lsau;
2817   ideal rad=ideal(1);
2818   ideal te=ser;
2819
2820   poly @p,@q;
2821   string @va,quotring;
2822   int  homo=homog(i);
2823   if((find(ordstr(basering),"w")!=0)||(find(ordstr(basering),"W")!=0)||(find(ordstr(basering),"a")!=0))
2824   {
2825      homo=0;
2826   }
2827   if(size(#)>0)
2828   {
2829      @wr=#[1];
2830   }
2831   @j=m[1];
2832   @j1=m[2];
2833   int jdim=dim(@j);
2834   if(size(reduce(ser,@j,1))==0)
2835   {
2836      return(ser);
2837   }
2838   if(homo==1)
2839   {
2840      if(jdim==0)
2841      {
2842         option(noredSB);
2843         return(maxideal(1));
2844      }
2845      intvec @hilb=hilb(@j,1);
2846   }
2847
2848
2849  //---------------------------------------------------------------------------
2850  //j is the ring
2851  //---------------------------------------------------------------------------
2852
2853   if (jdim==-1)
2854   {
2855      option(noredSB);
2856      return(ideal(0));
2857   }
2858
2859  //---------------------------------------------------------------------------
2860  //  the case of one variable
2861  //---------------------------------------------------------------------------
2862
2863   if(nvars(basering)==1)
2864   {
2865      fac=factorize(@j[1],1);
2866      @p=1;
2867      for(@k=1;@k<=size(fac);@k++)
2868      {
2869         @p=@p*fac[@k];
2870      }
2871      option(noredSB);
2872
2873      return(ideal(@p));
2874   }
2875  //---------------------------------------------------------------------------
2876  //the case of a complete intersection
2877  //---------------------------------------------------------------------------
2878    if(jdim+size(@j1)==nvars(basering))
2879    {
2880      // ideal jac=minor(jacob(@j1),size(@j1));
2881      // return(quotient(@j1,jac));
2882    }
2883
2884  //---------------------------------------------------------------------------
2885  //the zero-dimensional case
2886  //---------------------------------------------------------------------------
2887
2888   if (jdim==0)
2889   {
2890      if((npars(basering)>0)&&(char(basering)>0)&&(char(basering)<=181))
2891      {
2892         "        !  Warning  !  ";
2893         "    The field is not perfect.";
2894         "    The result may be wrong.";
2895      }
2896      @j1=finduni(@j);
2897      for(@k=1;@k<=size(@j1);@k++)
2898      {
2899         fac=factorize(cleardenom(@j1[@k]),1);
2900         @p=fac[1];
2901         for(@n=2;@n<=size(fac);@n++)
2902         {
2903            @p=@p*fac[@n];
2904         }
2905         @j=@j,@p;
2906      }
2907      @j=std(@j);
2908      option(noredSB);
2909      return(@j);
2910   }
2911
2912   //-------------------------------------------------------------------------
2913   //search for a maximal independent set indep,i.e.
2914   //look for subring such that the intersection with the ideal is zero
2915   //j intersected with K[var(indep[3]+1),...,var(nvar] is zero,
2916   //indep[1] is the new varstring, indep[2] the string for the block-ordering
2917   //-------------------------------------------------------------------------
2918
2919   indep=maxIndependSet(@j);
2920
2921   di=dim(@j);
2922
2923   for(@m=1;@m<=size(indep);@m++)
2924   {
2925      if((indep[@m][1]==varstr(basering))&&(@m==1))
2926      //this is the good case, nothing to do, just to have the same notations
2927      //change the ring
2928      {
2929        execute("ring gnir1 = ("+charstr(basering)+"),("+varstr(basering)+"),("
2930                              +ordstr(basering)+");");
2931         ideal @j=fetch(@P,@j);
2932         attrib(@j,"isSB",1);
2933      }
2934      else
2935      {
2936         @va=string(maxideal(1));
2937         execute("ring gnir1 = ("+charstr(basering)+"),("+indep[@m][1]+"),("
2938                              +indep[@m][2]+");");
2939         execute("map phi=@P,"+@va+";");
2940         if(homo==1)
2941         {
2942            ideal @j=std(phi(@j),@hilb);
2943         }
2944         else
2945         {
2946           ideal @j=groebner(phi(@j));
2947         }
2948      }
2949      if((deg(@j[1])==0)||(dim(@j)<jdim))
2950      {
2951         setring @P;
2952         break;
2953      }
2954      for (lauf=1;lauf<=size(@j);lauf++)
2955      {
2956         fett[lauf]=size(@j[lauf]);
2957      }
2958     //------------------------------------------------------------------------
2959     //we have now the following situation:
2960     //j intersected with K[var(nnp+1),..,var(nva)] is zero so we may pass
2961     //to this quotientring, j is their still a standardbasis, the
2962     //leading coefficients of the polynomials  there (polynomials in
2963     //K[var(nnp+1),..,var(nva)]) are collected in the list h,
2964     //we need their ggt, gh, because of the following:
2965     //let (j:gh^n)=(j:gh^infinity) then j*K(var(nnp+1),..,var(nva))[..rest..]
2966     //intersected with K[var(1),...,var(nva)] is (j:gh^n)
2967     //on the other hand j=(j,gh^n) intersected with (j:gh^n)
2968
2969     //------------------------------------------------------------------------
2970
2971     //the arrangement for the quotientring K(var(nnp+1),..,var(nva))[..rest..]
2972     //and the map phi:K[var(1),...,var(nva)] ----->
2973     //K(var(nnpr+1),..,var(nva))[..the rest..]
2974     //------------------------------------------------------------------------
2975      quotring=prepareQuotientring(nvars(basering)-indep[@m][3]);
2976
2977     //------------------------------------------------------------------------
2978     //we pass to the quotientring   K(var(nnp+1),..,var(nva))[..the rest..]
2979     //------------------------------------------------------------------------
2980
2981      execute(quotring);
2982
2983    // @j considered in the quotientring
2984      ideal @j=imap(gnir1,@j);
2985
2986      kill gnir1;
2987
2988     //j is a standardbasis in the quotientring but usually not minimal
2989     //here it becomes minimal
2990
2991      @j=clearSB(@j,fett);
2992      attrib(@j,"isSB",1);
2993
2994     //we need later ggt(h[1],...)=gh for saturation
2995      ideal @h;
2996      if(deg(@j[1])>0)
2997      {
2998         for(@n=1;@n<=size(@j);@n++)
2999         {
3000            @h[@n]=leadcoef(@j[@n]);
3001         }
3002        //the primary decomposition of j*K(var(nnp+1),..,var(nva))[..rest..]
3003         option(redSB);
3004
3005         @j=interred(@j);
3006
3007         attrib(@j,"isSB",1);
3008         list  @mo=@j,@j;
3009         ideal zero_rad= radicalKL(@mo,ideal(1));
3010      }
3011      else
3012      {
3013         ideal zero_rad=ideal(1);
3014      }
3015
3016     //we need the intersection of the ideals in the list quprimary with the
3017     //polynomialring, i.e. let q=(f1,...,fr) in the quotientring such an ideal
3018     //but fi polynomials, then the intersection of q with the polynomialring
3019     //is the saturation of the ideal generated by f1,...,fr with respect to
3020     //h which is the lcm of the leading coefficients of the fi considered in
3021     //the quotientring: this is coded in saturn
3022
3023      ideal hpl;
3024
3025      for(@n=1;@n<=size(zero_rad);@n++)
3026      {
3027         hpl=hpl,leadcoef(zero_rad[@n]);
3028      }
3029
3030     //------------------------------------------------------------------------
3031     //we leave  the quotientring   K(var(nnp+1),..,var(nva))[..the rest..]
3032     //back to the polynomialring
3033     //------------------------------------------------------------------------
3034      setring @P;
3035
3036      collectrad=imap(quring,zero_rad);
3037      lsau=simplify(imap(quring,hpl),2);
3038      @h=imap(quring,@h);
3039
3040      kill quring;
3041
3042
3043     //here the intersection with the polynomialring
3044     //mentioned above is really computed
3045
3046      collectrad=sat2(collectrad,lsau)[1];
3047
3048      if(deg(@h[1])>=0)
3049      {
3050         fac=ideal(0);
3051         for(lauf=1;lauf<=ncols(@h);lauf++)
3052         {
3053            if(deg(@h[lauf])>0)
3054            {
3055                fac=fac+factorize(@h[lauf],1);
3056            }
3057         }
3058         fac=simplify(fac,4);
3059         @q=1;
3060         for(lauf=1;lauf<=size(fac);lauf++)
3061         {
3062            @q=@q*fac[lauf];
3063         }
3064
3065
3066         @mu=mstd(quotient(@j+ideal(@q),rad));
3067         @j=@mu[1];
3068         attrib(@j,"isSB",1);
3069
3070      }
3071      if((deg(rad[1])>0)&&(deg(collectrad[1])>0))
3072      {
3073         rad=intersect(rad,collectrad);
3074      }
3075      else
3076      {
3077         if(deg(collectrad[1])>0)
3078         {
3079            rad=collectrad;
3080         }
3081      }
3082
3083      te=simplify(reduce(te*rad,@j),2);
3084
3085      if((dim(@j)<di)||(size(te)==0))
3086      {
3087         break;
3088      }
3089      if(homo==1)
3090      {
3091         @hilb=hilb(@j,1);
3092      }
3093   }
3094
3095   if(((@wr==1)&&(dim(@j)<di))||(deg(@j[1])==0)||(size(te)==0))
3096   {
3097      return(rad);
3098   }
3099  // rad=intersect(rad,radicalKL(@mu,rad,@wr));
3100   rad=intersect(rad,radicalKL(@mu,ideal(1),@wr));
3101
3102
3103   option(noredSB);
3104   return(rad);
3105}
3106
3107///////////////////////////////////////////////////////////////////////////////
3108
3109proc radicalEHV(ideal i,ideal re,list #)
3110{
3111   ideal J,I,I0,radI0,L,radI1,I2,radI2;
3112   int l,il;
3113   if(size(#)>0)
3114   {
3115      il=#[1];
3116   }
3117
3118   option(redSB);
3119   list m=mstd(i);
3120        I=m[2];
3121   option(noredSB);
3122   if(size(reduce(re,m[1],1))==0)
3123   {
3124      return(re);
3125   }
3126   int cod=nvars(basering)-dim(m[1]);
3127   if((nvars(basering)<=5)&&(size(m[2])<=5)
3128       &&((char(basering)==0)||(char(basering)>181)))
3129   {
3130      if(cod==size(m[2]))
3131      {
3132        J=minor(jacob(I),cod);
3133        return(quotient(I,J));
3134      }
3135
3136      for(l=1;l<=cod;l++)
3137      {
3138         I0[l]=I[l];
3139      }
3140      if(dim(std(I0))+cod==nvars(basering))
3141      {
3142         J=minor(jacob(I0),cod);
3143         radI0=quotient(I0,J);
3144         L=quotient(radI0,I);
3145         radI1=quotient(radI0,L);
3146
3147         if(size(reduce(radI1,m[1],1))==0)
3148         {
3149            return(I);
3150         }
3151         if(il==1)
3152         {
3153
3154            return(radI1);
3155         }
3156
3157         I2=sat(I,radI1)[1];
3158
3159         if(deg(I2[1])<=0)
3160         {
3161            return(radI1);
3162         }
3163         return(intersect(radI1,radicalEHV(I2,re,il)));
3164      }
3165   }
3166   return(radicalKL(m,re,il));
3167}
3168///////////////////////////////////////////////////////////////////////////////
3169
3170proc Ann(module M)
3171{
3172  M=prune(M);  //to obtain a small embedding
3173  ideal ann=quotient1(M,freemodule(nrows(M)));
3174  return(ann);
3175}
3176///////////////////////////////////////////////////////////////////////////////
3177
3178//computes the equidimensional part of the ideal i of codimension e
3179proc int_ass_primary_e(ideal i, int e)
3180{
3181  if(homog(i)!=1)
3182  {
3183     i=std(i);
3184  }
3185  list re=sres(i,0);                   //the resolution
3186  re=minres(re);                       //minimized resolution
3187  ideal ann=AnnExt_R(e,re);
3188  if(nvars(basering)-dim(std(ann))!=e)
3189  {
3190    return(ideal(1));
3191  }
3192  return(ann);
3193}
3194
3195///////////////////////////////////////////////////////////////////////////////
3196
3197//computes the annihilator of Ext^n(R/i,R) with given resolution re
3198//n is not necessarily the number of variables
3199proc AnnExt_R(int n,list re)
3200{
3201  if(n<nvars(basering))
3202  {
3203     matrix f=transpose(re[n+1]);      //Hom(_,R)
3204     module k=nres(f,2)[2];            //the kernel
3205     matrix g=transpose(re[n]);        //the image of Hom(_,R)
3206
3207     ideal ann=quotient1(g,k);           //the anihilator
3208  }
3209  else
3210  {
3211     ideal ann=Ann(transpose(re[n]));
3212  }
3213  return(ann);
3214}
3215///////////////////////////////////////////////////////////////////////////////
3216
3217proc analyze(list pr)
3218{
3219   int ii,jj;
3220   for(ii=1;ii<=size(pr)/2;ii++)
3221   {
3222      dim(std(pr[2*ii]));
3223      idealsEqual(pr[2*ii-1],pr[2*ii]);
3224      "===========================";
3225   }
3226
3227   for(ii=size(pr)/2;ii>1;ii--)
3228   {
3229      for(jj=1;jj<ii;jj++)
3230      {
3231         if(size(reduce(pr[2*jj],std(pr[2*ii],1)))==0)
3232         {
3233            "eingebette Komponente";
3234            jj;
3235            ii;
3236         }
3237      }
3238   }
3239}
3240
3241///////////////////////////////////////////////////////////////////////////////
3242//
3243//                  Shimoyama-Yokoyama
3244//
3245///////////////////////////////////////////////////////////////////////////////
3246
3247proc simplifyIdeal(ideal i)
3248{
3249  def r=basering;
3250
3251  int j,k;
3252  map phi;
3253  poly p;
3254
3255  ideal iwork=i;
3256  ideal imap1=maxideal(1);
3257  ideal imap2=maxideal(1);
3258
3259
3260  for(j=1;j<=nvars(basering);j++)
3261  {
3262    for(k=1;k<=size(i);k++)
3263    {
3264      if(deg(iwork[k]/var(j))==0)
3265      {
3266        p=-1/leadcoef(iwork[k]/var(j))*iwork[k];
3267        imap1[j]=p+2*var(j);
3268        phi=r,imap1;
3269        iwork=phi(iwork);
3270        iwork=subst(iwork,var(j),0);
3271        iwork[k]=var(j);
3272        imap1=maxideal(1);
3273        imap2[j]=-p;
3274        break;
3275      }
3276    }
3277  }
3278  return(iwork,imap2);
3279}
3280
3281
3282///////////////////////////////////////////////////////
3283// ini_mod
3284// input: a polynomial p
3285// output: the initial term of p as needed
3286// in the context of characteristic sets
3287//////////////////////////////////////////////////////
3288
3289proc ini_mod(poly p)
3290{
3291  if (p==0)
3292  {
3293    return(0);
3294  }
3295  int n; matrix m;
3296  for( n=nvars(basering); n>0; n=n-1)
3297  {
3298    m=coef(p,var(n));
3299    if(m[1,1]!=1)
3300    {
3301      p=m[2,1];
3302      break;
3303    }
3304  }
3305  if(deg(p)==0)
3306  {
3307    p=0;
3308  }
3309  return(p);
3310}
3311///////////////////////////////////////////////////////
3312// min_ass_prim_charsets
3313// input: generators of an ideal PS and an integer cho
3314// If cho=0, the given ordering of the variables is used.
3315// Otherwise, the system tries to find an "optimal ordering",
3316// which in some cases may considerably speed up the algorithm
3317// output: the minimal associated primes of PS
3318// algorithm: via characteriostic sets
3319//////////////////////////////////////////////////////
3320
3321
3322proc min_ass_prim_charsets (ideal PS, int cho)
3323{
3324  if((cho<0) and (cho>1))
3325    {
3326      "ERROR: <int> must be 0 or 1"
3327      return();
3328    }
3329  if(system("version")>933)
3330  {
3331    option(notWarnSB);
3332  }
3333  if(cho==0)
3334  {
3335    return(min_ass_prim_charsets0(PS));
3336  }
3337  else
3338  {
3339     return(min_ass_prim_charsets1(PS));
3340  }
3341}
3342///////////////////////////////////////////////////////
3343// min_ass_prim_charsets0
3344// input: generators of an ideal PS
3345// output: the minimal associated primes of PS
3346// algorithm: via characteristic sets
3347// the given ordering of the variables is used
3348//////////////////////////////////////////////////////
3349
3350
3351proc min_ass_prim_charsets0 (ideal PS)
3352{
3353
3354  matrix m=char_series(PS);  // We compute an irreducible
3355                             // characteristic series
3356  int i,j,k;
3357  list PSI;
3358  list PHI;  // the ideals given by the characteristic series
3359  for(i=nrows(m);i>=1; i--)
3360  {
3361     PHI[i]=ideal(m[i,1..ncols(m)]);
3362  }
3363  // We compute the radical of each ideal in PHI
3364  ideal I,JS,II;
3365  int sizeJS, sizeII;
3366  for(i=size(PHI);i>=1; i--)
3367  {
3368     I=0;
3369     for(j=size(PHI[i]);j>0;j=j-1)
3370     {
3371       I=I+ini_mod(PHI[i][j]);
3372     }
3373     JS=std(PHI[i]);
3374     sizeJS=size(JS);
3375     for(j=size(I);j>0;j=j-1)
3376     {
3377       II=0;
3378       sizeII=0;
3379       k=0;
3380       while(k<=sizeII)                  // successive saturation
3381       {
3382         option(returnSB);
3383         II=quotient(JS,I[j]);
3384         option(noreturnSB);
3385  //std
3386  //         II=std(II);
3387         sizeII=size(II);
3388         if(sizeII==sizeJS)
3389         {
3390            for(k=1;k<=sizeII;k++)
3391            {
3392              if(leadexp(II[k])!=leadexp(JS[k])) break;
3393            }
3394         }
3395         JS=II;
3396         sizeJS=sizeII;
3397       }
3398    }
3399    PSI=insert(PSI,JS);
3400  }
3401  int sizePSI=size(PSI);
3402  // We eliminate redundant ideals
3403  for(i=1;i<sizePSI;i++)
3404  {
3405    for(j=i+1;j<=sizePSI;j++)
3406    {
3407      if(size(PSI[i])!=0)
3408      {
3409        if(size(PSI[j])!=0)
3410        {
3411          if(size(NF(PSI[i],PSI[j],1))==0)
3412          {
3413            PSI[j]=ideal(0);
3414          }
3415          else
3416          {
3417            if(size(NF(PSI[j],PSI[i],1))==0)
3418            {
3419              PSI[i]=ideal(0);
3420            }
3421          }
3422        }
3423      }
3424    }
3425  }
3426  for(i=sizePSI;i>=1;i--)
3427  {
3428    if(size(PSI[i])==0)
3429    {
3430      PSI=delete(PSI,i);
3431    }
3432  }
3433  return (PSI);
3434}
3435
3436///////////////////////////////////////////////////////
3437// min_ass_prim_charsets1
3438// input: generators of an ideal PS
3439// output: the minimal associated primes of PS
3440// algorithm: via characteristic sets
3441// input: generators of an ideal PS and an integer i
3442// The system tries to find an "optimal ordering" of
3443// the variables
3444//////////////////////////////////////////////////////
3445
3446
3447proc min_ass_prim_charsets1 (ideal PS)
3448{
3449  def oldring=basering;
3450  string n=system("neworder",PS);
3451  execute("ring r=("+charstr(oldring)+"),("+n+"),dp;");
3452  ideal PS=imap(oldring,PS);
3453  matrix m=char_series(PS);  // We compute an irreducible
3454                             // characteristic series
3455  int i,j,k;
3456  ideal I;
3457  list PSI;
3458  list PHI;    // the ideals given by the characteristic series
3459  list ITPHI;  // their initial terms
3460  for(i=nrows(m);i>=1; i--)
3461  {
3462     PHI[i]=ideal(m[i,1..ncols(m)]);
3463     I=0;
3464     for(j=size(PHI[i]);j>0;j=j-1)
3465     {
3466       I=I,ini_mod(PHI[i][j]);
3467     }
3468      I=I[2..ncols(I)];
3469      ITPHI[i]=I;
3470  }
3471  setring oldring;
3472  matrix m=imap(r,m);
3473  list PHI=imap(r,PHI);
3474  list ITPHI=imap(r,ITPHI);
3475  // We compute the radical of each ideal in PHI
3476  ideal I,JS,II;
3477  int sizeJS, sizeII;
3478  for(i=size(PHI);i>=1; i--)
3479  {
3480     I=0;
3481     for(j=size(PHI[i]);j>0;j=j-1)
3482     {
3483       I=I+ITPHI[i][j];
3484     }
3485     JS=std(PHI[i]);
3486     sizeJS=size(JS);
3487     for(j=size(I);j>0;j=j-1)
3488     {
3489       II=0;
3490       sizeII=0;
3491       k=0;
3492       while(k<=sizeII)                  // successive iteration
3493       {
3494         option(returnSB);
3495         II=quotient(JS,I[j]);
3496         option(noreturnSB);
3497//std
3498//         II=std(II);
3499         sizeII=size(II);
3500         if(sizeII==sizeJS)
3501         {
3502            for(k=1;k<=sizeII;k++)
3503            {
3504              if(leadexp(II[k])!=leadexp(JS[k])) break;
3505            }
3506         }
3507         JS=II;
3508         sizeJS=sizeII;
3509       }
3510    }
3511    PSI=insert(PSI,JS);
3512  }
3513  int sizePSI=size(PSI);
3514  // We eliminate redundant ideals
3515  for(i=1;i<sizePSI;i++)
3516  {
3517    for(j=i+1;j<=sizePSI;j++)
3518    {
3519      if(size(PSI[i])!=0)
3520      {
3521        if(size(PSI[j])!=0)
3522        {
3523          if(size(NF(PSI[i],PSI[j],1))==0)
3524          {
3525            PSI[j]=ideal(0);
3526          }
3527          else
3528          {
3529            if(size(NF(PSI[j],PSI[i],1))==0)
3530            {
3531              PSI[i]=ideal(0);
3532            }
3533          }
3534        }
3535      }
3536    }
3537  }
3538  for(i=sizePSI;i>=1;i--)
3539  {
3540    if(size(PSI[i])==0)
3541    {
3542      PSI=delete(PSI,i);
3543    }
3544  }
3545  return (PSI);
3546}
3547
3548
3549/////////////////////////////////////////////////////
3550// proc prim_dec
3551// input:  generators of an ideal I and an integer choose
3552// If choose=0, min_ass_prim_charsets with the given
3553// ordering of the variables is used.
3554// If choose=1, min_ass_prim_charsets with the "optimized"
3555// ordering of the variables is used.
3556// If choose=2, minAssPrimes from primdec.lib is used
3557// If choose=3, minAssPrimes+factorizing Buchberger from primdec.lib is used
3558// output: a primary decomposition of I, i.e., a list
3559// of pairs consisting of a standard basis of a primary component
3560// of I and a standard basis of the corresponding associated prime.
3561// To compute the minimal associated primes of a given ideal
3562// min_ass_prim_l is called, i.e., the minimal associated primes
3563// are computed via characteristic sets.
3564// In the homogeneous case, the performance of the procedure
3565// will be improved if I is already given by a minimal set of
3566// generators. Apply minbase if necessary.
3567//////////////////////////////////////////////////////////
3568
3569
3570proc prim_dec(ideal I, int choose)
3571{
3572   if((choose<0) or (choose>3))
3573   {
3574     "ERROR: <int> must be 0 or 1 or 2 or 3";
3575      return();
3576   }
3577   if(system("version")>933)
3578   {
3579      option(notWarnSB);
3580   }
3581  ideal H=1; // The intersection of the primary components
3582  list U;    // the leaves of the decomposition tree, i.e.,
3583             // pairs consisting of a primary component of I
3584             // and the corresponding associated prime
3585  list W;    // the non-leaf vertices in the decomposition tree.
3586             // every entry has 6 components:
3587                // 1- the vertex itself , i.e., a standard bais of the
3588                //    given ideal I (type 1), or a standard basis of a
3589                //    pseudo-primary component arising from
3590                //    pseudo-primary decomposition (type 2), or a
3591                //    standard basis of a remaining component arising from
3592                //    pseudo-primary decomposition or extraction (type 3)
3593                // 2- the type of the vertex as indicated above
3594                // 3- the weighted_tree_depth of the vertex
3595                // 4- the tester of the vertex
3596                // 5- a standard basis of the associated prime
3597                //    of a vertex of type 2, or 0 otherwise
3598                // 6- a list of pairs consisting of a standard
3599                //    basis of a minimal associated prime ideal
3600                //    of the father of the vertex and the
3601                //    irreducible factors of the "minimal
3602                //    divisor" of the seperator or extractor
3603                //    corresponding to the prime ideal
3604                //    as computed by the procedure minsat,
3605                //    if the vertex is of type 3, or
3606                //    the empty list otherwise
3607  ideal SI=std(I);
3608  if(SI[1]==1)  // primdecSY(ideal(1))
3609  {
3610    return(list());
3611  }
3612  int ncolsSI=ncols(SI);
3613  int ncolsH=1;
3614  W[1]=list(I,1,0,poly(1),ideal(0),list()); // The root of the tree
3615  int weighted_tree_depth;
3616  int i,j;
3617  int check;
3618  list V;  // current vertex
3619  list VV; // new vertex
3620  list QQ;
3621  list WI;
3622  ideal Qi,SQ,SRest,fac;
3623  poly tester;
3624
3625  while(1)
3626  {
3627    i=1;
3628    while(1)
3629    {
3630      while(i<=size(W)) // find vertex V of smallest weighted tree-depth
3631      {
3632        if (W[i][3]<=weighted_tree_depth) break;
3633        i++;
3634      }
3635      if (i<=size(W)) break;
3636      i=1;
3637      weighted_tree_depth++;
3638    }
3639    V=W[i];
3640    W=delete(W,i); // delete V from W
3641
3642    // now proceed by type of vertex V
3643
3644    if (V[2]==2)  // extraction needed
3645    {
3646      SQ,SRest,fac=extraction(V[1],V[5]);
3647                        // standard basis of primary component,
3648                        // standard basis of remaining component,
3649                        // irreducible factors of
3650                        // the "minimal divisor" of the extractor
3651                        // as computed by the procedure minsat,
3652      check=0;
3653      for(j=1;j<=ncolsH;j++)
3654      {
3655        if (NF(H[j],SQ,1)!=0) // Q is not redundant
3656        {
3657          check=1;
3658          break;
3659        }
3660      }
3661      if(check==1)             // Q is not redundant
3662      {
3663        QQ=list();
3664        QQ[1]=list(SQ,V[5]);  // primary component, associated prime,
3665                              // i.e., standard bases thereof
3666        U=U+QQ;
3667        H=intersect(H,SQ);
3668        H=std(H);
3669        ncolsH=ncols(H);
3670        check=0;
3671        if(ncolsH==ncolsSI)
3672        {
3673          for(j=1;j<=ncolsSI;j++)
3674          {
3675            if(leadexp(H[j])!=leadexp(SI[j]))
3676            {
3677              check=1;
3678              break;
3679            }
3680          }
3681        }
3682        else
3683        {
3684          check=1;
3685        }
3686        if(check==0) // H==I => U is a primary decomposition
3687        {
3688          return(U);
3689        }
3690      }
3691      if (SRest[1]!=1)        // the remaining component is not
3692                              // the whole ring
3693      {
3694        if (rad_con(V[4],SRest)==0) // the new vertex is not the
3695                                    // root of a redundant subtree
3696        {
3697          VV[1]=SRest;     // remaining component
3698          VV[2]=3;         // pseudoprimdec_special
3699          VV[3]=V[3]+1;    // weighted depth
3700          VV[4]=V[4];      // the tester did not change
3701          VV[5]=ideal(0);
3702          VV[6]=list(list(V[5],fac));
3703          W=insert(W,VV,size(W));
3704        }
3705      }
3706    }
3707    else
3708    {
3709      if (V[2]==3) // pseudo_prim_dec_special is needed
3710      {
3711        QQ,SRest=pseudo_prim_dec_special_charsets(V[1],V[6],choose);
3712                         // QQ = quadruples:
3713                         // standard basis of pseudo-primary component,
3714                         // standard basis of corresponding prime,
3715                         // seperator, irreducible factors of
3716                         // the "minimal divisor" of the seperator
3717                         // as computed by the procedure minsat,
3718                         // SRest=standard basis of remaining component
3719      }
3720      else     // V is the root, pseudo_prim_dec is needed
3721      {
3722        QQ,SRest=pseudo_prim_dec_charsets(I,SI,choose);
3723                         // QQ = quadruples:
3724                         // standard basis of pseudo-primary component,
3725                         // standard basis of corresponding prime,
3726                         // seperator, irreducible factors of
3727                         // the "minimal divisor" of the seperator
3728                         // as computed by the procedure minsat,
3729                         // SRest=standard basis of remaining component
3730
3731      }
3732      //check
3733      for(i=size(QQ);i>=1;i--)
3734      //for(i=1;i<=size(QQ);i++)
3735      {
3736        tester=QQ[i][3]*V[4];
3737        Qi=QQ[i][2];
3738        if(NF(tester,Qi,1)!=0)  // the new vertex is not the
3739                                // root of a redundant subtree
3740        {
3741          VV[1]=QQ[i][1];
3742          VV[2]=2;
3743          VV[3]=V[3]+1;
3744          VV[4]=tester;      // the new tester as computed above
3745          VV[5]=Qi;          // QQ[i][2];
3746          VV[6]=list();
3747          W=insert(W,VV,size(W));
3748        }
3749      }
3750      if (SRest[1]!=1)        // the remaining component is not
3751                              // the whole ring
3752      {
3753        if (rad_con(V[4],SRest)==0) // the vertex is not the root
3754                                    // of a redundant subtree
3755        {
3756          VV[1]=SRest;
3757          VV[2]=3;
3758          VV[3]=V[3]+2;
3759          VV[4]=V[4];      // the tester did not change
3760          VV[5]=ideal(0);
3761          WI=list();
3762          for(i=1;i<=size(QQ);i++)
3763          {
3764            WI=insert(WI,list(QQ[i][2],QQ[i][4]));
3765          }
3766          VV[6]=WI;
3767          W=insert(W,VV,size(W));
3768        }
3769      }
3770    }
3771  }
3772}
3773
3774//////////////////////////////////////////////////////////////////////////
3775// proc pseudo_prim_dec_charsets
3776// input: Generators of an arbitrary ideal I, a standard basis SI of I,
3777// and an integer choo
3778// If choo=0, min_ass_prim_charsets with the given
3779// ordering of the variables is used.
3780// If choo=1, min_ass_prim_charsets with the "optimized"
3781// ordering of the variables is used.
3782// If choo=2, minAssPrimes from primdec.lib is used
3783// If choo=3, minAssPrimes+factorizing Buchberger from primdec.lib is used
3784// output: a pseudo primary decomposition of I, i.e., a list
3785// of pseudo primary components together with a standard basis of the
3786// remaining component. Each pseudo primary component is
3787// represented by a quadrupel: A standard basis of the component,
3788// a standard basis of the corresponding associated prime, the
3789// seperator of the component, and the irreducible factors of the
3790// "minimal divisor" of the seperator as computed by the procedure minsat,
3791// calls  proc pseudo_prim_dec_i
3792//////////////////////////////////////////////////////////////////////////
3793
3794
3795proc pseudo_prim_dec_charsets (ideal I, ideal SI, int choo)
3796{
3797  list L;          // The list of minimal associated primes,
3798                   // each one given by a standard basis
3799  if((choo==0) or (choo==1))
3800    {
3801       L=min_ass_prim_charsets(I,choo);
3802    }
3803  else
3804    {
3805      if(choo==2)
3806      {
3807        L=minAssPrimes(I);
3808      }
3809      else
3810      {
3811        L=minAssPrimes(I,1);
3812      }
3813      for(int i=size(L);i>=1;i=i-1)
3814        {
3815          L[i]=std(L[i]);
3816        }
3817    }
3818  return (pseudo_prim_dec_i(SI,L));
3819}
3820
3821////////////////////////////////////////////////////////////////
3822// proc pseudo_prim_dec_special_charsets
3823// input: a standard basis of an ideal I whose radical is the
3824// intersection of the radicals of ideals generated by one prime ideal
3825// P_i together with one polynomial f_i, the list V6 must be the list of
3826// pairs (standard basis of P_i, irreducible factors of f_i),
3827// and an integer choo
3828// If choo=0, min_ass_prim_charsets with the given
3829// ordering of the variables is used.
3830// If choo=1, min_ass_prim_charsets with the "optimized"
3831// ordering of the variables is used.
3832// If choo=2, minAssPrimes from primdec.lib is used
3833// If choo=3, minAssPrimes+factorizing Buchberger from primdec.lib is used
3834// output: a pseudo primary decomposition of I, i.e., a list
3835// of pseudo primary components together with a standard basis of the
3836// remaining component. Each pseudo primary component is
3837// represented by a quadrupel: A standard basis of the component,
3838// a standard basis of the corresponding associated prime, the
3839// seperator of the component, and the irreducible factors of the
3840// "minimal divisor" of the seperator as computed by the procedure minsat,
3841// calls  proc pseudo_prim_dec_i
3842////////////////////////////////////////////////////////////////
3843
3844
3845proc pseudo_prim_dec_special_charsets (ideal SI,list V6, int choo)
3846{
3847  int i,j,l;
3848  list m;
3849  list L;
3850  int sizeL;
3851  ideal P,SP; ideal fac;
3852  int dimSP;
3853  for(l=size(V6);l>=1;l--)   // creates a list of associated primes
3854                             // of I, possibly redundant
3855  {
3856    P=V6[l][1];
3857    fac=V6[l][2];
3858    for(i=ncols(fac);i>=1;i--)
3859    {
3860      SP=P+fac[i];
3861      SP=std(SP);
3862      if(SP[1]!=1)
3863      {
3864        if((choo==0) or (choo==1))
3865        {
3866          m=min_ass_prim_charsets(SP,choo);  // a list of SB
3867        }
3868        else
3869        {
3870          if(choo==2)
3871          {
3872            m=minAssPrimes(SP);
3873          }
3874          else
3875          {
3876            m=minAssPrimes(SP,1);
3877          }
3878          for(j=size(m);j>=1;j=j-1)
3879            {
3880              m[j]=std(m[j]);
3881            }
3882        }
3883        dimSP=dim(SP);
3884        for(j=size(m);j>=1; j--)
3885        {
3886          if(dim(m[j])==dimSP)
3887          {
3888            L=insert(L,m[j],size(L));
3889          }
3890        }
3891      }
3892    }
3893  }
3894  sizeL=size(L);
3895  for(i=1;i<sizeL;i++)     // get rid of redundant primes
3896  {
3897    for(j=i+1;j<=sizeL;j++)
3898    {
3899      if(size(L[i])!=0)
3900      {
3901        if(size(L[j])!=0)
3902        {
3903          if(size(NF(L[i],L[j],1))==0)
3904          {
3905            L[j]=ideal(0);
3906          }
3907          else
3908          {
3909            if(size(NF(L[j],L[i],1))==0)
3910            {
3911              L[i]=ideal(0);
3912            }
3913          }
3914        }
3915      }
3916    }
3917  }
3918  for(i=sizeL;i>=1;i--)
3919  {
3920    if(size(L[i])==0)
3921    {
3922      L=delete(L,i);
3923    }
3924  }
3925  return (pseudo_prim_dec_i(SI,L));
3926}
3927
3928
3929////////////////////////////////////////////////////////////////
3930// proc pseudo_prim_dec_i
3931// input: A standard basis of an arbitrary ideal I, and standard bases
3932// of the minimal associated primes of I
3933// output: a pseudo primary decomposition of I, i.e., a list
3934// of pseudo primary components together with a standard basis of the
3935// remaining component. Each pseudo primary component is
3936// represented by a quadrupel: A standard basis of the component Q_i,
3937// a standard basis of the corresponding associated prime P_i, the
3938// seperator of the component, and the irreducible factors of the
3939// "minimal divisor" of the seperator as computed by the procedure minsat,
3940////////////////////////////////////////////////////////////////
3941
3942
3943proc pseudo_prim_dec_i (ideal SI, list L)
3944{
3945  list Q;
3946  if (size(L)==1)               // one minimal associated prime only
3947                                // the ideal is already pseudo primary
3948  {
3949    Q=SI,L[1],1;
3950    list QQ;
3951    QQ[1]=Q;
3952    return (QQ,ideal(1));
3953  }
3954
3955  poly f0,f,g;
3956  ideal fac;
3957  int i,j,k,l;
3958  ideal SQi;
3959  ideal I'=SI;
3960  list QP;
3961  int sizeL=size(L);
3962  for(i=1;i<=sizeL;i++)
3963  {
3964    fac=0;
3965    for(j=1;j<=sizeL;j++)           // compute the seperator sep_i
3966                                    // of the i-th component
3967    {
3968      if (i!=j)                       // search g not in L[i], but L[j]
3969      {
3970        for(k=1;k<=ncols(L[j]);k++)
3971        {
3972          if(NF(L[j][k],L[i],1)!=0)
3973          {
3974            break;
3975          }
3976        }
3977        fac=fac+L[j][k];
3978      }
3979    }
3980    // delete superfluous polynomials
3981    fac=simplify(fac,8);
3982    // saturation
3983    SQi,f0,f,fac=minsat_ppd(SI,fac);
3984    I'=I',f;
3985    QP=SQi,L[i],f0,fac;
3986             // the quadrupel:
3987             // a standard basis of Q_i,
3988             // a standard basis of P_i,
3989             // sep_i,
3990             // irreducible factors of
3991             // the "minimal divisor" of the seperator
3992             //  as computed by the procedure minsat,
3993    Q[i]=QP;
3994  }
3995  I'=std(I');
3996  return (Q, I');
3997                   // I' = remaining component
3998}
3999
4000
4001////////////////////////////////////////////////////////////////
4002// proc extraction
4003// input: A standard basis of a pseudo primary ideal I, and a standard
4004// basis of the unique minimal associated prime P of I
4005// output: an extraction of I, i.e., a standard basis of the primary
4006// component Q of I with associated prime P, a standard basis of the
4007// remaining component, and the irreducible factors of the
4008// "minimal divisor" of the extractor as computed by the procedure minsat
4009////////////////////////////////////////////////////////////////
4010
4011
4012proc extraction (ideal SI, ideal SP)
4013{
4014  list indsets=indepSet(SP,0);
4015  poly f;
4016  if(size(indsets)!=0)      //check, whether dim P != 0
4017  {
4018    intvec v;               // a maximal independent set of variables
4019                            // modulo P
4020    string U;               // the independent variables
4021    string A;               // the dependent variables
4022    int j,k;
4023    int a;                  //  the size of A
4024    int degf;
4025    ideal g;
4026    list polys;
4027    int sizepolys;
4028    list newpoly;
4029    def R=basering;
4030    //intvec hv=hilb(SI,1);
4031    for (k=1;k<=size(indsets);k++)
4032    {
4033      v=indsets[k];
4034      for (j=1;j<=nvars(R);j++)
4035      {
4036        if (v[j]==1)
4037        {
4038          U=U+varstr(j)+",";
4039        }
4040        else
4041        {
4042          A=A+varstr(j)+",";
4043          a++;
4044        }
4045      }
4046
4047      U[size(U)]=")";           // we compute the extractor of I (w.r.t. U)
4048      execute("ring RAU="+charstr(basering)+",("+A+U+",(dp("+string(a)+"),dp);");
4049      ideal I=imap(R,SI);
4050      //I=std(I,hv);            // the standard basis in (R[U])[A]
4051      I=std(I);            // the standard basis in (R[U])[A]
4052      A[size(A)]=")";
4053      execute("ring Rloc=("+charstr(basering)+","+U+",("+A+",dp;");
4054      ideal I=imap(RAU,I);
4055      //"std in lokalisierung:"+newline,I;
4056      ideal h;
4057      for(j=ncols(I);j>=1;j--)
4058      {
4059        h[j]=leadcoef(I[j]);  // consider I in (R(U))[A]
4060      }
4061      setring R;
4062      g=imap(Rloc,h);
4063      kill RAU,Rloc;
4064      U="";
4065      A="";
4066      a=0;
4067      f=lcm(g);
4068      newpoly[1]=f;
4069      polys=polys+newpoly;
4070      newpoly=list();
4071    }
4072    f=polys[1];
4073    degf=deg(f);
4074    sizepolys=size(polys);
4075    for (k=2;k<=sizepolys;k++)
4076    {
4077      if (deg(polys[k])<degf)
4078      {
4079        f=polys[k];
4080        degf=deg(f);
4081      }
4082    }
4083  }
4084  else
4085  {
4086    f=1;
4087  }
4088  poly f0,h0; ideal SQ; ideal fac;
4089  if(f!=1)
4090  {
4091    SQ,f0,h0,fac=minsat(SI,f);
4092    return(SQ,std(SI+h0),fac);
4093             // the tripel
4094             // a standard basis of Q,
4095             // a standard basis of remaining component,
4096             // irreducible factors of
4097             // the "minimal divisor" of the extractor
4098             // as computed by the procedure minsat
4099  }
4100  else
4101  {
4102    return(SI,ideal(1),ideal(1));
4103  }
4104}
4105
4106/////////////////////////////////////////////////////
4107// proc minsat
4108// input:  a standard basis of an ideal I and a polynomial p
4109// output: a standard basis IS of the saturation of I w.r. to p,
4110// the maximal squarefree factor f0 of p,
4111// the "minimal divisor" f of f0 such that the saturation of
4112// I w.r. to f equals the saturation of I w.r. to f0 (which is IS),
4113// the irreducible factors of f
4114//////////////////////////////////////////////////////////
4115
4116
4117proc minsat(ideal SI, poly p)
4118{
4119  ideal fac=factorize(p,1);       //the irreducible factors of p
4120  fac=sort(fac)[1];
4121  int i,k;
4122  poly f0=1;
4123  for(i=ncols(fac);i>=1;i--)
4124  {
4125    f0=f0*fac[i];
4126  }
4127  poly f=1;
4128  ideal iold;
4129  list quotM;
4130  quotM[1]=SI;
4131  quotM[2]=fac;
4132  quotM[3]=f0;
4133  // we deal seperately with the first quotient;
4134  // factors, which do not contribute to this one,
4135  // are omitted
4136  iold=quotM[1];
4137  quotM=minquot(quotM);
4138  fac=quotM[2];
4139  if(quotM[3]==1)
4140    {
4141      return(quotM[1],f0,f,fac);
4142    }
4143  while(special_ideals_equal(iold,quotM[1])==0)
4144    {
4145      f=f*quotM[3];
4146      iold=quotM[1];
4147      quotM=minquot(quotM);
4148    }
4149  return(quotM[1],f0,f,fac);           // the quadrupel ((I:p),f0,f, irr. factors of f)
4150}
4151
4152/////////////////////////////////////////////////////
4153// proc minsat_ppd
4154// input:  a standard basis of an ideal I and a polynomial p
4155// output: a standard basis IS of the saturation of I w.r. to p,
4156// the maximal squarefree factor f0 of p,
4157// the "minimal divisor" f of f0 such that the saturation of
4158// I w.r. to f equals the saturation of I w.r. to f0 (which is IS),
4159// the irreducible factors of f
4160//////////////////////////////////////////////////////////
4161
4162
4163proc minsat_ppd(ideal SI, ideal fac)
4164{
4165  fac=sort(fac)[1];
4166  int i,k;
4167  poly f0=1;
4168  for(i=ncols(fac);i>=1;i--)
4169  {
4170    f0=f0*fac[i];
4171  }
4172  poly f=1;
4173  ideal iold;
4174  list quotM;
4175  quotM[1]=SI;
4176  quotM[2]=fac;
4177  quotM[3]=f0;
4178  // we deal seperately with the first quotient;
4179  // factors, which do not contribute to this one,
4180  // are omitted
4181  iold=quotM[1];
4182  quotM=minquot(quotM);
4183  fac=quotM[2];
4184  if(quotM[3]==1)
4185    {
4186      return(quotM[1],f0,f,fac);
4187    }
4188  while(special_ideals_equal(iold,quotM[1])==0)
4189  {
4190    f=f*quotM[3];
4191    iold=quotM[1];
4192    quotM=minquot(quotM);
4193    k++;
4194  }
4195  return(quotM[1],f0,f,fac);           // the quadrupel ((I:p),f0,f, irr. factors of f)
4196}
4197/////////////////////////////////////////////////////////////////
4198// proc minquot
4199// input: a list with 3 components: a standard basis
4200// of an ideal I, a set of irreducible polynomials, and
4201// there product f0
4202// output: a standard basis of the ideal (I:f0), the irreducible
4203// factors of the "minimal divisor" f of f0 with (I:f0) = (I:f),
4204// the "minimal divisor" f
4205/////////////////////////////////////////////////////////////////
4206
4207proc minquot(list tsil)
4208{
4209   int i,j,k,action;
4210   ideal verg;
4211   list l;
4212   poly g;
4213   ideal laedi=tsil[1];
4214   ideal fac=tsil[2];
4215   poly f=tsil[3];
4216
4217//std
4218//   ideal star=quotient(laedi,f);
4219//   star=std(star);
4220   option(returnSB);
4221   ideal star=quotient(laedi,f);
4222   option(noreturnSB);
4223   if(special_ideals_equal(laedi,star)==1)
4224     {
4225       return(laedi,ideal(1),1);
4226     }
4227   action=1;
4228   while(action==1)
4229   {
4230      if(size(fac)==1)
4231      {
4232         action=0;
4233         break;
4234      }
4235      for(i=1;i<=size(fac);i++)
4236      {
4237        g=1;
4238         for(j=1;j<=size(fac);j++)
4239         {
4240            if(i!=j)
4241            {
4242               g=g*fac[j];
4243            }
4244         }
4245//std
4246//         verg=quotient(laedi,g);
4247//         verg=std(verg);
4248         option(returnSB);
4249         verg=quotient(laedi,g);
4250         option(noreturnSB);
4251         if(special_ideals_equal(verg,star)==1)
4252         {
4253            f=g;
4254            fac[i]=0;
4255            fac=simplify(fac,2);
4256            break;
4257         }
4258         if(i==size(fac))
4259         {
4260            action=0;
4261         }
4262      }
4263   }
4264   l=star,fac,f;
4265   return(l);
4266}
4267/////////////////////////////////////////////////
4268// proc special_ideals_equal
4269// input: standard bases of ideal k1 and k2 such that
4270// k1 is contained in k2, or k2 is contained ink1
4271// output: 1, if k1 equals k2, 0 otherwise
4272//////////////////////////////////////////////////
4273
4274proc special_ideals_equal( ideal k1, ideal k2)
4275{
4276   int j;
4277   if(size(k1)==size(k2))
4278   {
4279      for(j=1;j<=size(k1);j++)
4280      {
4281         if(leadexp(k1[j])!=leadexp(k2[j]))
4282         {
4283            return(0);
4284         }
4285      }
4286      return(1);
4287   }
4288   return(0);
4289}
4290
4291
4292///////////////////////////////////////////////////////////////////////////////
4293
4294proc convList(list l)
4295{
4296   int i;
4297   list re,he;
4298   for(i=1;i<=size(l)/2;i++)
4299   {
4300      he=l[2*i-1],l[2*i];
4301      re[i]=he;
4302   }
4303   return(re);
4304}
4305///////////////////////////////////////////////////////////////////////////////
4306
4307proc reconvList(list l)
4308{
4309   int i;
4310   list re;
4311   for(i=1;i<=size(l);i++)
4312   {
4313      re[2*i-1]=l[i][1];
4314      re[2*i]=l[i][2];
4315   }
4316   return(re);
4317}
4318
4319///////////////////////////////////////////////////////////////////////////////
4320//
4321//     The main procedures
4322//
4323///////////////////////////////////////////////////////////////////////////////
4324
4325proc primdecGTZ(ideal i)
4326"USAGE:   primdecGTZ(i); i ideal
4327RETURN:  a list, say pr, of primary ideals and their associated primes
4328         pr[i][1], resp. pr[i][2] is the i-th primary resp. prime component
4329NOTE:    Algorithm of Gianni, Traeger, Zacharias
4330         designed for characteristic 0, works also in char k > 0, if it
4331         terminates (may result in an infinite loop in small characteristic!)
4332EXAMPLE: example primdecGTZ; shows an example
4333"
4334{
4335   return(convList(decomp(i)));
4336}
4337example
4338{ "EXAMPLE:";  echo = 2;
4339   ring  r = 32003,(x,y,z),lp;
4340   poly  p = z2+1;
4341   poly  q = z4+2;
4342   ideal i = p^2*q^3,(y-z3)^3,(x-yz+z4)^4;
4343   list pr = primdecGTZ(i);
4344   pr;
4345}
4346///////////////////////////////////////////////////////////////////////////////
4347
4348proc primdecSY(ideal i, list #))
4349"USAGE:   primdecSY(i); i ideal, c int
4350         if c=0, the given ordering of the variables is used.
4351         if c=1, minAssChar tries to use an optimal ordering,
4352         if c=2, minAssGTZ is used
4353         if c=3, minAssGTZ and facstd is used
4354RETURN:  a list, say pr, of primary ideals and their associated primes
4355         pr[i][1], resp. pr[i][2] is the i-th primary resp. prime component
4356NOTE:    Algorithm of Shimoyama-Yokoyama
4357         implemented for characteristic 0, works also in char k > 0,
4358         the result may be not completely decomposed in small characteristic
4359EXAMPLE: example primdecSY; shows an example
4360"
4361{
4362   if (size(#)==1)
4363   { return(prim_dec(i,#[1])); }
4364   else
4365   { return(prim_dec(i,1)); }
4366}
4367example
4368{ "EXAMPLE:";  echo = 2;
4369   ring  r = 32003,(x,y,z),lp;
4370   poly  p = z2+1;
4371   poly  q = z4+2;
4372   ideal i = p^2*q^3,(y-z3)^3,(x-yz+z4)^4;
4373   list pr = primdecSY(i);
4374   pr;
4375}
4376///////////////////////////////////////////////////////////////////////////////
4377proc minAssGTZ(ideal i)
4378"USAGE:   minAssGTZ(i); i ideal
4379RETURN:  list = the minimal associated prime ideals of i
4380NOTE:    designed for characteristic 0, works also in char k > 0 if it
4381         terminates, may result in an infinite loop in small characteristic
4382EXAMPLE: example minAssGTZ; shows an example
4383"
4384{
4385   return(minAssPrimes(i,1));
4386}
4387example
4388{ "EXAMPLE:";  echo = 2;
4389   ring  r = 32003,(x,y,z),dp;
4390   poly  p = z2+1;
4391   poly  q = z4+2;
4392   ideal i = p^2*q^3,(y-z3)^3,(x-yz+z4)^4;
4393   list pr= minAssGTZ(i);
4394   pr;
4395}
4396
4397///////////////////////////////////////////////////////////////////////////////
4398proc minAssChar(ideal i, list #)
4399"USAGE:   minAssChar(i[,c]); i ideal,
4400         if c=0, the given ordering of the variables is used.
4401         Otherwise, the system tries to find an optimal ordering,
4402         which in some cases may considerably speed up the algorithm
4403RETURN:  list = the minimal associated prime ideals of i
4404NOTE:    implemented for characteristic 0, works also in char k >> 0,
4405         the result may be not compltely decomposed in small characteristic
4406EXAMPLE: example minAssChar; shows an example
4407"
4408{
4409  if (size(#)==1)
4410  { return(min_ass_prim_charsets(i,#[1])); }
4411  else
4412  { return(min_ass_prim_charsets(i,1)); }
4413}
4414example
4415{ "EXAMPLE:";  echo = 2;
4416   ring  r = 32003,(x,y,z),dp;
4417   poly  p = z2+1;
4418   poly  q = z4+2;
4419   ideal i = p^2*q^3,(y-z3)^3,(x-yz+z4)^4;
4420   list pr= minAssChar(i);
4421   pr;
4422}
4423///////////////////////////////////////////////////////////////////////////////
4424proc equiRadical(ideal i)
4425"USAGE:   equiRadical(i); i ideal
4426RETURN:  ideal, intersection of associated primes of i of maximal  dimension
4427NOTE:    designed for characteristic 0, works also in char k > 0 if it
4428         terminates, may result in an infinite loop in small characteristic
4429EXAMPLE: example equiRadical; shows an example
4430"
4431{
4432   return(radical(i,1));
4433}
4434example
4435{ "EXAMPLE:";  echo = 2;
4436   ring  r = 32003,(x,y,z),dp;
4437   poly  p = z2+1;
4438   poly  q = z4+2;
4439   ideal i = p^2*q^3,(y-z3)^3,(x-yz+z4)^4;
4440   ideal pr= equiRadical(i);
4441   pr;
4442}
4443///////////////////////////////////////////////////////////////////////////////
4444proc radical(ideal i,list #)
4445"USAGE:   radical(i); i ideal
4446RETURN:  ideal = the radical of i
4447NOTE:    a combination of the algorithms of Krick/Logar and
4448         Eisenbud/Huneke/Vasconcelos
4449         designed for characteristic 0, works also in char k > 0 if it
4450         terminates, may result in an infinite loop in small characteristic
4451EXAMPLE: example radical; shows an example
4452"
4453{
4454   def @P=basering;
4455   int j,il;
4456   if(size(#)>0)
4457   {
4458     il=#[1];
4459   }
4460   ideal re=1;
4461   option(redSB);
4462   list qr=simplifyIdeal(i);
4463
4464   map phi=@P,qr[2];
4465   i=qr[1];
4466
4467   list pr=facstd(i);
4468   if(size(pr)==1)
4469   {
4470      attrib(pr[1],"isSB",1);
4471      if((dim(pr[1])==0)&&(homog(pr[1])==1))
4472      {
4473         ideal @res=maxideal(1);
4474         return(phi(@res));
4475      }
4476      if(dim(pr[1])>1)
4477      {
4478         execute("ring gnir = ("+charstr(basering)+"),
4479                              ("+varstr(basering)+"),(C,lp);");
4480         ideal i=fetch(@P,i);
4481         list @pr=facstd(i);
4482         setring @P;
4483         pr=fetch(gnir,@pr);
4484      }
4485   }
4486   option(noredSB);
4487   int s=size(pr);
4488   if(s==1)
4489   {
4490     i=radicalEHV(pr[1],ideal(1),il);
4491     return(phi(i));
4492   }
4493   intvec pos;
4494   pos[s]=0;
4495   if(il==1)
4496   {
4497     int ndim,k;
4498     attrib(pr[1],"isSB",1);
4499     int odim=dim(pr[1]);
4500     int count=1;
4501
4502     for(j=2;j<=s;j++)
4503     {
4504        attrib(pr[j],"isSB",1);
4505        ndim=dim(pr[j]);
4506        if(ndim>odim)
4507        {
4508           for(k=count;k<=j-1;k++)
4509           {
4510              pos[k]=1;
4511           }
4512           count=j;
4513           odim=ndim;
4514        }
4515        if(ndim<odim)
4516        {
4517           pos[j]=1;
4518        }
4519     }
4520   }
4521   for(j=1;j<=s;j++)
4522   {
4523      if(pos[s+1-j]==0)
4524      {
4525         re=intersect(re,radicalEHV(pr[s+1-j],re,il));
4526      }
4527   }
4528   re=interred(re);
4529   return(phi(re));
4530}
4531example
4532{ "EXAMPLE:";  echo = 2;
4533   ring  r = 32003,(x,y,z),dp;
4534   poly  p = z2+1;
4535   poly  q = z4+2;
4536   ideal i = p^2*q^3,(y-z3)^3,(x-yz+z4)^4;
4537   ideal pr= radical(i);
4538   pr;
4539}
4540///////////////////////////////////////////////////////////////////////////////
4541proc prepareAss(ideal i)
4542"USAGE:   prepareAss(i); i ideal
4543RETURN:  list = the radicals of the maximal dimensional components of i
4544NOTE:    uses algorithm of Eisenbud, Huneke and Vasconcelos
4545EXAMPLE: example prepareAss; shows an example
4546"
4547{
4548  ideal j=std(i);
4549  int cod=nvars(basering)-dim(j);
4550  int e;
4551  list er;
4552  ideal ann;
4553  if(homog(i)==1)
4554  {
4555     list re=sres(j,0);                   //the resolution
4556     re=minres(re);                       //minimized resolution
4557  }
4558  else
4559  {
4560    list re=mres(i,0);
4561  }
4562  for(e=cod;e<=nvars(basering);e++)
4563  {
4564     ann=AnnExt_R(e,re);
4565
4566     if(nvars(basering)-dim(std(ann))==e)
4567     {
4568        er[size(er)+1]=equiRadical(ann);
4569     }
4570  }
4571  return(er);
4572}
4573example
4574{ "EXAMPLE:";  echo = 2;
4575   ring  r = 32003,(x,y,z),dp;
4576   poly  p = z2+1;
4577   poly  q = z4+2;
4578   ideal i = p^2*q^3,(y-z3)^3,(x-yz+z4)^4;
4579   list pr= prepareAss(i);
4580   pr;
4581}
4582///////////////////////////////////////////////////////////////////////////////
4583proc equidimMaxEHV(ideal i)
4584"USAGE:  equidimMaxEHV(i); i ideal
4585RETURN:  ideal = equidimensional componente of i
4586NOTE:    uses algorithm of Eisenbud, Huneke and Vasconcelos
4587EXAMPLE: example equidimMaxEHV; shows an example
4588"
4589{
4590  ideal j=groebner(i);
4591  int cod=nvars(basering)-dim(j);
4592  int e;
4593  ideal ann;
4594  if(homog(i)==1)
4595  {
4596     list re=sres(j,0);                   //the resolution
4597     re=minres(re);                       //minimized resolution
4598  }
4599  else
4600  {
4601    list re=mres(i,0);
4602  }
4603  ann=AnnExt_R(cod,re);
4604  return(ann);
4605}
4606example
4607{ "EXAMPLE:";  echo = 2;
4608   ring  r = 32003,(x,y,z),dp;
4609   ideal i=intersect(ideal(z),ideal(x,y),ideal(x2,z2),ideal(x5,y5,z5));
4610   equidimMaxEHV(i);
4611}
4612
4613proc testPrimary(list pr, ideal k)
4614"USAGE:   testPrimary(pr,k); pr a list, result of primdecGTZ(k) or primdecSY(k)
4615RETURN:  int, 1 if intersection of the primary ideals in pr is k, 0 if not
4616EXAMPLE: example testPrimary; shows an example
4617"
4618{
4619   int i;
4620   pr=reconvList(pr);
4621   ideal j=pr[1];
4622   for (i=2;i<=size(pr)/2;i++)
4623   {
4624       j=intersect(j,pr[2*i-1]);
4625   }
4626   return(idealsEqual(j,k));
4627}
4628example
4629{ "EXAMPLE:";  echo = 2;
4630   ring  r = 32003,(x,y,z),dp;
4631   poly  p = z2+1;
4632   poly  q = z4+2;
4633   ideal i = p^2*q^3,(y-z3)^3,(x-yz+z4)^4;
4634   list pr = primdecGTZ(i);
4635   testPrimary(pr,i);
4636}
4637
4638///////////////////////////////////////////////////////////////////////////////
4639proc zerodec(ideal I)
4640"USAGE:   zerodec(I); I ideal
4641RETURN:  a list of primary ideals, the zero-dimensional decomposition of I
4642ASSUME:  I is zero-dimensional, the characterisitic of the ground field is 0
4643NOTE:    the algorithm (of C. Monico), works well only for small total
4644         number of solutions (i.e. vdim(std(I)) should be < 100)
4645         and without parameters. In practice, it works also in big
4646         characteristic p>0 but may fail for small p.
4647         If printlevel > 0 (default = 0) additional information is displayed
4648EXAMPLE: example zerodec; shows an example
4649"
4650{
4651   def R=basering;
4652   poly q;
4653   int j,time;
4654   matrix m;
4655   list re;
4656   poly va=var(1);
4657   ideal J=groebner(I);
4658   ideal ba=kbase(J);
4659   int d=vdim(J);
4660   dbprint(printlevel-voice+2,"// multiplicity of ideal : "+ string(d));
4661//------ compute matrix of multiplication on R/I with generic element p -----
4662   int e=nvars(basering);
4663   poly p=randomLast(100)[e]+random(-50,50);     //the generic element
4664   matrix n[d][d];
4665   time = timer;
4666   for(j=2;j<=e;j++)
4667   {
4668      va=va*var(j);
4669   }
4670   for(j=1;j<=d;j++)
4671   {
4672      q=reduce(p*ba[j],J);
4673      m=coeffs(q,ba,va);
4674      n[j,1..d]=m[1..d,1];
4675   }
4676   dbprint(printlevel-voice+2,
4677      "// time for computing multiplication matrix (with generic element) : "+
4678      string(timer-time));
4679//---------------- compute characteristic polynomial of matrix --------------
4680   execute("ring P1=("+charstr(R)+"),T,dp;");
4681   matrix n=imap(R,n);
4682   time = timer;
4683   poly charpol=det(n-T*freemodule(d));
4684   dbprint(printlevel-voice+2,"// time for computing char poly: "+
4685           string(timer-time));
4686//------------------- factorize characteristic polynomial -------------------
4687//check first if constant term of charpoly is != 0 (which is true for
4688//sufficiently generic element)
4689   if(charpol[size(charpol)]!=0)
4690   {
4691     time = timer;
4692     list fac=factor(charpol);
4693     testFactor(fac,charpol);
4694     dbprint(printlevel-voice+2,"// time for factorizing char poly: "+
4695             string(timer-time));
4696     int f=size(fac[1]);
4697//--------------------------- the irreducible case --------------------------
4698     if(f==1)
4699     {
4700       setring R;
4701       re=I;
4702       return(re);
4703     }
4704//---------------------------- the reducible case ---------------------------
4705//if f_i are the irreducible factors of charpoly, mult=ri, then <I,g_i^ri>
4706//are the primary components where g_i = f_i(p). However, substituting p in
4707//f_i may result in a huge object although the final result may be small.
4708//Hence it is better to simultaneously reduce with I. For this we need a new
4709//ring.
4710     execute("ring P=("+charstr(R)+"),(T,"+varstr(R)+"),(dp(1),dp);");
4711     list rfac=imap(P1,fac);
4712     intvec ov=option(get);;
4713     option(redSB);
4714     list re1;
4715     ideal new = T-imap(R,p),imap(R,J);
4716     attrib(new, "isSB",1);    //we know that new is a standard basis
4717     for(j=1;j<=f;j++)
4718     {
4719        re1[j]=reduce(rfac[1][j]^rfac[2][j],new);
4720     }
4721     setring R;
4722     re = imap(P,re1);
4723     for(j=1;j<=f;j++)
4724     {
4725        J=I,re[j];
4726        re[j]=interred(J);
4727     }
4728     option(set,ov);
4729     return(re);
4730  }
4731  else
4732//------------------- choice of generic element failed -------------------
4733  {
4734     dbprint(printlevel-voice+2,"// try new generic element!");
4735     setring R;
4736     return(zerodec(I));
4737  }
4738}
4739example
4740{ "EXAMPLE:";  echo = 2;
4741   ring r=0,(x,y),dp;
4742   ideal i=x2-2,y2-2;
4743   list pr=zerodec(i);
4744   pr;
4745}
4746////////////////////////////////////////////////////////////////////////////
4747/*
4748//Beispiele Wenk-Dipl (in ~/Texfiles/Diplom/Wenk/Examples/)
4749//Zeiten: Singular/Singular/Singular -r123456789 -v :wilde13 (PentiumPro200)
4750//Singular for HPUX-9 version 1-3-8  (2000060214)  Jun  2 2000 15:31:26
4751//(wilde13)
4752
4753//1. vdim=20, 3  Komponenten
4754//zerodec-time:2(1)  (matrix:1 charpoly:0 factor:1)
4755//primdecGTZ-time: 1(0)
4756ring rs= 0,(a,b,c),dp;
4757poly f1= a^2*b*c + a*b^2*c + a*b*c^2 + a*b*c + a*b + a*c + b*c;
4758poly f2= a^2*b^2*c + a*b^2*c^2 + a^2*b*c + a*b*c + b*c + a + c;
4759poly f3= a^2*b^2*c^2 + a^2*b^2*c + a*b^2*c + a*b*c + a*c + c + 1;
4760ideal gls=f1,f2,f3;
4761int time=timer;
4762printlevel =1;
4763time=timer; list pr1=zerodec(gls); timer-time;size(pr1);
4764time=timer; list pr =primdecGTZ(gls); timer-time;size(pr);
4765
4766//2.cyclic5  vdim=70, 20 Komponenten
4767//zerodec-time:36(28)  (matrix:1(0) charpoly:18(19) factor:17(9)
4768//primdecGTZ-time: 28(5)
4769ring rs= 0,(a,b,c,d,e),dp;
4770poly f0= a + b + c + d + e + 1;
4771poly f1= a + b + c + d + e;
4772poly f2= a*b + b*c + c*d + a*e + d*e;
4773poly f3= a*b*c + b*c*d + a*b*e + a*d*e + c*d*e;
4774poly f4= a*b*c*d + a*b*c*e + a*b*d*e + a*c*d*e + b*c*d*e;
4775poly f5= a*b*c*d*e - 1;
4776ideal gls= f1,f2,f3,f4,f5;
4777
4778//3. random vdim=40, 1 Komponente
4779//zerodec-time:126(304)  (matrix:1 charpoly:115(298) factor:10(5))
4780//primdecGTZ-time:17 (11)
4781ring rs=0,(x,y,z),dp;
4782poly f1=2*x^2 + 4*x + 3*y^2 + 7*x*z + 9*y*z + 5*z^2;
4783poly f2=7*x^3 + 8*x*y + 12*y^2 + 18*x*z + 3*y^4*z + 10*z^3 + 12;
4784poly f3=3*x^4 + 1*x*y*z + 6*y^3 + 3*x*z^2 + 2*y*z^2 + 4*z^2 + 5;
4785ideal gls=f1,f2,f3;
4786
4787//4. introduction into resultants, sturmfels, vdim=28, 1 Komponente
4788//zerodec-time:4  (matrix:0 charpoly:0 factor:4)
4789//primdecGTZ-time:1
4790ring rs=0,(x,y),dp;
4791poly f1= x4+y4-1;
4792poly f2= x5y2-4x3y3+x2y5-1;
4793ideal gls=f1,f2;
4794
4795//5. 3 quadratic equations with random coeffs, vdim=8, 1 Komponente
4796//zerodec-time:0(0)  (matrix:0 charpoly:0 factor:0)
4797//primdecGTZ-time:1(0)
4798ring rs=0,(x,y,z),dp;
4799poly f1=2*x^2 + 4*x*y + 3*y^2 + 7*x*z + 9*y*z + 5*z^2 + 2;
4800poly f2=7*x^2 + 8*x*y + 12*y^2 + 18*x*z + 3*y*z + 10*z^2 + 12;
4801poly f3=3*x^2 + 1*x*y + 6*y^2 + 3*x*z + 2*y*z + 4*z^2 + 5;
4802ideal gls=f1,f2,f3;
4803
4804//6. 3 polys    vdim=24, 1 Komponente
4805// run("ex14",2);
4806//zerodec-time:5(4)  (matrix:0 charpoly:3(3) factor:2(1))
4807//primdecGTZ-time:4 (2)
4808ring rs=0,(x1,x2,x3,x4),dp;
4809poly f1=16*x1^2 + 3*x2^2 + 5*x3^4 - 1 - 4*x4 + x4^3;
4810poly f2=5*x1^3 + 3*x2^2 + 4*x3^2*x4 + 2*x1*x4 - 1 + x4 + 4*x1 + x2 + x3 + x4;
4811poly f3=-4*x1^2 + x2^2 + x3^2 - 3 + x4^2 + 4*x1 + x2 + x3 + x4;
4812poly f4=-4*x1 + x2 + x3 + x4;
4813ideal gls=f1,f2,f3,f4;
4814
4815//7. ex43, PoSSo, caprasse   vdim=56, 16 Komponenten
4816//zerodec-time:23(15)  (matrix:0 charpoly:16(13) factor:3(2))
4817//primdecGTZ-time:3 (2)
4818ring rs= 0,(y,z,x,t),dp;
4819ideal gls=y^2*z+2*y*x*t-z-2*x,
48204*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,
48212*y*z*t+x*t^2-2*z-x,
4822-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;
4823
4824//8. Arnborg-System, n=6 (II),    vdim=156, 90 Komponenten
4825//zerodec-time (char32003):127(45)(matrix:2(0) charpoly:106(37) factor:16(7))
4826//primdecGTZ-time(char32003) :81 (18)
4827//ring rs= 0,(a,b,c,d,x,f),dp;
4828ring rs= 32003,(a,b,c,d,x,f),dp;
4829ideal gls=a+b+c+d+x+f, ab+bc+cd+dx+xf+af, abc+bcd+cdx+d*xf+axf+abf,
4830abcd+bcdx+cd*xf+ad*xf+abxf+abcf, abcdx+bcd*xf+acd*xf+abd*xf+abcxf+abcdf,
4831abcd*xf-1;
4832
4833//9. ex42, PoSSo, Methan6_1, vdim=27, 2 Komponenten
4834//zerodec-time:610  (matrix:10 charpoly:557 factor:26)
4835//primdecGTZ-time: 118
4836//zerodec-time(char32003):2
4837//primdecGTZ-time(char32003):4
4838//ring rs= 0,(x1,x2,x3,x4,x5,x6,x7,x8,x9,x10),dp;
4839ring rs= 32003,(x1,x2,x3,x4,x5,x6,x7,x8,x9,x10),dp;
4840ideal gls=64*x2*x7-10*x1*x8+10*x7*x9+11*x7*x10-320000*x1,
4841-32*x2*x7-5*x2*x8-5*x2*x10+160000*x1-5000*x2,
4842-x3*x8+x6*x8+x9*x10+210*x6+1300000,
4843-x4*x8+700000,
4844x10^2-2*x5,
4845-x6*x8+x7*x9-210*x6,
4846-64*x2*x7-10*x7*x9-11*x7*x10+320000*x1-16*x7+7000000,
4847-10*x1*x8-10*x2*x8-10*x3*x8-10*x4*x8-10*x6*x8+10*x2*x10+11*x7*x10
4848    +20000*x2+14*x5,
4849x4*x8-x7*x9-x9*x10-410*x9,
485010*x2*x8+10*x3*x8+10*x6*x8+10*x7*x9-10*x2*x10-11*x7*x10-10*x9*x10
4851    -10*x10^2+1400*x6-4200*x10;
4852
4853//10. ex33, walk-s7, Diplomarbeit von Tim, vdim=114
4854//zerfaellt in unterschiedlich viele Komponenten in versch. Charkteristiken:
4855//char32003:30, char0:3(2xdeg1,1xdeg112!), char181:4(2xdeg1,1xdeg28,1xdeg84)
4856//char 0: zerodec-time:10075 (ca 3h) (matrix:3 charpoly:9367, factor:680
4857//        + 24 sec fuer Normalform (anstatt einsetzen), total [29623k])
4858//        primdecGTZ-time: 214
4859//char 32003:zerodec-time:197(68) (matrix:2(1) charpoly:173(60) factor:15(6))
4860//        primdecGTZ-time:14 (5)
4861//char 181:zerodec-time:(87) (matrix:(1) charpoly:(58) factor:(25))
4862//        primdecGTZ-time:(2)
4863//in char181 stimmen Ergebnisse von zerodec und primdecGTZ ueberein (gecheckt)
4864
4865//ring rs= 0,(a,b,c,d,e,f,g),dp;
4866ring rs= 32003,(a,b,c,d,e,f,g),dp;
4867poly f1= 2gb + 2fc + 2ed + a2 + a;
4868poly f2= 2gc + 2fd + e2 + 2ba + b;
4869poly f3= 2gd + 2fe + 2ca + c + b2;
4870poly f4= 2ge + f2 + 2da + d + 2cb;
4871poly f5= 2fg + 2ea + e + 2db + c2;
4872poly f6= g2 + 2fa + f + 2eb + 2dc;
4873poly f7= 2ga + g + 2fb + 2ec + d2;
4874ideal gls= f1,f2,f3,f4,f5,f6,f7;
4875
4876~/Singular/Singular/Singular -r123456789 -v
4877LIB"./primdec.lib";
4878timer=1;
4879int time=timer;
4880printlevel =1;
4881option(prot,mem);
4882time=timer; list pr1=zerodec(gls); timer-time;
4883
4884time=timer; list pr =primdecGTZ(gls); timer-time;
4885time=timer; list pr =primdecSY(gls); timer-time;
4886*/
4887
4888
4889
Note: See TracBrowser for help on using the repository browser.