source: git/Singular/LIB/primdec.lib @ 3c4dcc

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