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

fieker-DuValspielwiese
Last change on this file since dc5e5b was 24f458, checked in by Hans Schönemann <hannes@…>, 20 years ago
*hannes: from 2-0 git-svn-id: file:///usr/local/Singular/svn/trunk@7036 2c84dea3-7e68-4137-9b89-c4e89433aadc
  • Property mode set to 100644
File size: 134.9 KB
Line 
1///////////////////////////////////////////////////////////////////////////////
2version="$Id: primdec.lib,v 1.102 2004-02-12 09:54:06 Singular 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   list qr=simplifyIdeal(i);
1848   map phi=@P,qr[2];
1849   i=qr[1];
1850
1851   execute ("ring gnir = ("+charstr(basering)+"),("+varstr(basering)+"),("
1852             +ordstr(basering)+");");
1853
1854
1855   ideal i=fetch(@P,i);
1856   if(size(#)==0)
1857   {
1858      int @wr;
1859      list tluser,@res;
1860      list primary=decomp(i,2);
1861
1862      @res[1]=primary;
1863
1864      tluser=union(@res);
1865      setring @P;
1866      list @res=imap(gnir,tluser);
1867      return(phi(@res));
1868   }
1869   list @res,empty;
1870   ideal ser;
1871   option(redSB);
1872   list @pr=facstd(i);
1873   if(size(@pr)==1)
1874   {
1875      attrib(@pr[1],"isSB",1);
1876      if((dim(@pr[1])==0)&&(homog(@pr[1])==1))
1877      {
1878         setring @P;
1879         list @res=maxideal(1);
1880         return(phi(@res));
1881      }
1882      if(dim(@pr[1])>1)
1883      {
1884         setring @P;
1885        // kill gnir;
1886         execute ("ring gnir1 = ("+charstr(basering)+"),
1887                              ("+varstr(basering)+"),(C,lp);");
1888         ideal i=fetch(@P,i);
1889         list @pr=facstd(i);
1890        // ideal ser;
1891         setring gnir;
1892         @pr=fetch(gnir1,@pr);
1893         kill gnir1;
1894      }
1895   }
1896    option(noredSB);
1897   int j,k,odim,ndim,count;
1898   attrib(@pr[1],"isSB",1);
1899   if(#[1]==77)
1900   {
1901     odim=dim(@pr[1]);
1902     count=1;
1903     intvec pos;
1904     pos[size(@pr)]=0;
1905     for(j=2;j<=size(@pr);j++)
1906     {
1907        attrib(@pr[j],"isSB",1);
1908        ndim=dim(@pr[j]);
1909        if(ndim>odim)
1910        {
1911           for(k=count;k<=j-1;k++)
1912           {
1913              pos[k]=1;
1914           }
1915           count=j;
1916           odim=ndim;
1917        }
1918        if(ndim<odim)
1919        {
1920           pos[j]=1;
1921        }
1922     }
1923     for(j=1;j<=size(@pr);j++)
1924     {
1925        if(pos[j]!=1)
1926        {
1927            @res[j]=decomp(@pr[j],2);
1928        }
1929        else
1930        {
1931           @res[j]=empty;
1932        }
1933     }
1934   }
1935   else
1936   {
1937     ser=ideal(1);
1938     for(j=1;j<=size(@pr);j++)
1939     {
1940//@pr[j];
1941//pause();
1942        @res[j]=decomp(@pr[j],2);
1943//       @res[j]=decomp(@pr[j],2,@pr[j],ser);
1944//       for(k=1;k<=size(@res[j]);k++)
1945//       {
1946//          ser=intersect(ser,@res[j][k]);
1947//       }
1948     }
1949   }
1950
1951   @res=union(@res);
1952   setring @P;
1953   list @res=imap(gnir,@res);
1954   return(phi(@res));
1955}
1956example
1957{ "EXAMPLE:"; echo = 2;
1958   ring  r = 32003,(x,y,z),lp;
1959   poly  p = z2+1;
1960   poly  q = z4+2;
1961   ideal i = p^2*q^3,(y-z3)^3,(x-yz+z4)^4;
1962   list pr= minAssPrimes(i);  pr;
1963
1964   minAssPrimes(i,1);
1965}
1966
1967static proc primT(ideal i)
1968{
1969   //assumes that all generators of i are irreducible
1970   //i is standard basis
1971
1972   attrib(i,"isSB",1);
1973   int j=size(i);
1974   int k;
1975   while(j>0)
1976   {
1977     if(deg(i[j])>1){break;}
1978     j--;
1979   }
1980   if(j==0){return(1);}
1981   if(deg(i[j])==vdim(i)){return(1);}
1982   return(0);
1983}
1984
1985
1986static proc minAssPrimes(ideal i, list #)
1987"USAGE:   minAssPrimes(i); i ideal
1988         minAssPrimes(i,1); i ideal  (to use also the factorizing Groebner)
1989RETURN:  list = the minimal associated prime ideals of i
1990EXAMPLE: example minAssPrimes; shows an example
1991"
1992{
1993   def P=basering;
1994   list q=simplifyIdeal(i);
1995   list re=maxideal(1);
1996   int j,a,k;
1997   intvec op=option(get);
1998   map phi=P,q[2];
1999
2000   if(npars(P)==0){option(redSB);}
2001
2002   i=std(q[1]);
2003   if(dim(i)==-1){re=ideal(1);return(re);}
2004   if((dim(i)==0)&&(npars(P)==0))
2005   {
2006      int di=vdim(i);
2007      execute ("ring gnir=("+charstr(P)+"),("+varstr(P)+"),lp;");
2008      ideal J=interred(imap(P,i));
2009      attrib(J,"isSB",1);
2010      if(vdim(J)!=di)
2011      {
2012         J=fglm(P,i);
2013      }
2014      list pr=triangMH(J,2);
2015      list qr,re;
2016
2017      for(k=1;k<=size(pr);k++)
2018      {
2019         if(primT(pr[k]))
2020         {
2021            re[size(re)+1]=pr[k];
2022         }
2023         else
2024         {
2025            attrib(pr[k],"isSB",1);
2026            qr=decomp(pr[k],2);
2027            for(j=1;j<=size(qr)/2;j++)
2028            {
2029               re[size(re)+1]=qr[2*j];
2030            }
2031         }
2032      }
2033      setring P;
2034      re=imap(gnir,re);
2035      option(set,op);
2036      return(phi(re));
2037   }
2038
2039   if((size(#)==0)||(dim(i)==0))
2040   {
2041      re[1]=decomp(i,2);
2042      re=union(re);
2043      option(set,op);
2044      return(phi(re));
2045   }
2046
2047   q=facstd(i);
2048
2049   if((size(q)==1)&&(dim(i)>1))
2050   {
2051      execute ("ring gnir=("+charstr(P)+"),("+varstr(P)+"),lp;");
2052
2053      list p=facstd(fetch(P,i));
2054      if(size(p)>1)
2055      {
2056         a=1;
2057         setring P;
2058         q=fetch(gnir,p);
2059      }
2060      else
2061      {
2062         setring P;
2063      }
2064      kill gnir;
2065   }
2066
2067   option(set,op);
2068   for(j=1;j<=size(q);j++)
2069   {
2070      if(a==0){attrib(q[j],"isSB",1);}
2071      re[j]=decomp(q[j],2);
2072   }
2073   re=union(re);
2074   return(phi(re));
2075}
2076example
2077{ "EXAMPLE:"; echo = 2;
2078   ring  r = 32003,(x,y,z),lp;
2079   poly  p = z2+1;
2080   poly  q = z4+2;
2081   ideal i = p^2*q^3,(y-z3)^3,(x-yz+z4)^4;
2082   list pr= minAssPrimes(i);  pr;
2083
2084   minAssPrimes(i,1);
2085}
2086
2087static proc union(list li)
2088{
2089  int i,j,k;
2090
2091  def P=basering;
2092
2093  execute("ring ir = ("+charstr(basering)+"),("+varstr(basering)+"),(C,lp);");
2094  list l=fetch(P,li);
2095  list @erg;
2096
2097  for(k=1;k<=size(l);k++)
2098  {
2099     for(j=1;j<=size(l[k])/2;j++)
2100     {
2101        if(deg(l[k][2*j][1])!=0)
2102        {
2103           i++;
2104           @erg[i]=l[k][2*j];
2105        }
2106     }
2107  }
2108
2109  list @wos;
2110  i=0;
2111  ideal i1,i2;
2112  while(i<size(@erg)-1)
2113  {
2114     i++;
2115     k=i+1;
2116     i1=lead(@erg[i]);
2117      attrib(i1,"isSB",1);
2118      attrib(@erg[i],"isSB",1);
2119
2120     while(k<=size(@erg))
2121     {
2122        if(deg(@erg[i][1])==0)
2123        {
2124           break;
2125        }
2126        i2=lead(@erg[k]);
2127        attrib(@erg[k],"isSB",1);
2128        attrib(i2,"isSB",1);
2129
2130        if(size(reduce(i1,i2,1))==0)
2131        {
2132           if(size(reduce(@erg[i],@erg[k],1))==0)
2133           {
2134              @erg[k]=ideal(1);
2135              i2=ideal(1);
2136           }
2137        }
2138        if(size(reduce(i2,i1,1))==0)
2139        {
2140           if(size(reduce(@erg[k],@erg[i],1))==0)
2141           {
2142              break;
2143           }
2144        }
2145        k++;
2146        if(k>size(@erg))
2147        {
2148           @wos[size(@wos)+1]=@erg[i];
2149        }
2150     }
2151  }
2152  if(deg(@erg[size(@erg)][1])!=0)
2153  {
2154     @wos[size(@wos)+1]=@erg[size(@erg)];
2155  }
2156  setring P;
2157  list @ser=fetch(ir,@wos);
2158  return(@ser);
2159}
2160///////////////////////////////////////////////////////////////////////////////
2161proc equidim(ideal i,list #)
2162"USAGE:  equidim(i) or equidim(i,1) ; i ideal
2163RETURN: list of equidimensional ideals a[1],...,a[s] with:
2164        - a[s] the equidimensional locus of i, i.e. the intersection
2165          of the primary ideals of dimension of i
2166        - a[1],...,a[s-1] the lower dimensional equidimensional loci.
2167NOTE:    An embedded component q (primary ideal) of i can be replaced in the
2168         decomposition by a primary ideal q1 with the same radical as q. @*
2169         @code{equidim(i,1)} uses the algorithm of Eisenbud/Huneke/Vasconcelos.
2170
2171EXAMPLE:example equidim; shows an example
2172"
2173{
2174  if(ord_test(basering)!=1)
2175  {
2176      ERROR(
2177      "// Not implemented for this ordering, please change to global ordering."
2178      );
2179  }
2180  intvec op ;
2181  def  P = basering;
2182  list eq;
2183  intvec w;
2184  int n,m;
2185  int g=size(i);
2186  int a=attrib(i,"isSB");
2187  int homo=homog(i);
2188  if(size(#)!=0)
2189  {
2190     m=1;
2191  }
2192
2193  if(((homo==1)||(a==1))&&(find(ordstr(basering),"l")==0)
2194                                &&(find(ordstr(basering),"s")==0))
2195  {
2196     execute("ring gnir = ("+charstr(basering)+"),("+varstr(basering)+"),("
2197                              +ordstr(basering)+");");
2198     ideal i=imap(P,i);
2199     ideal j=i;
2200     if(a==1)
2201     {
2202       attrib(j,"isSB",1);
2203     }
2204     else
2205     {
2206       j=groebner(i);
2207     }
2208  }
2209  else
2210  {
2211     execute("ring gnir = ("+charstr(basering)+"),("+varstr(basering)+"),dp;");
2212     ideal i=imap(P,i);
2213     ideal j=groebner(i);
2214  }
2215  if(homo==1)
2216  {
2217     for(n=1;n<=nvars(basering);n++)
2218     {
2219        w[n]=ord(var(n));
2220     }
2221     intvec hil=hilb(j,1,w);
2222  }
2223
2224  if ((dim(j)==-1)||(size(j)==0)||(nvars(basering)==1)
2225                  ||(dim(j)==0)||(dim(j)+g==nvars(basering)))
2226  {
2227    setring P;
2228    eq[1]=i;
2229    return(eq);
2230  }
2231
2232  if(m==0)
2233  {
2234     ideal k=equidimMax(j);
2235  }
2236  else
2237  {
2238     ideal k=equidimMaxEHV(j);
2239  }
2240  if(size(reduce(k,j,1))==0)
2241  {
2242    setring P;
2243    eq[1]=i;
2244    kill gnir;
2245    return(eq);
2246  }
2247  op=option(get);
2248  option(returnSB);
2249  j=quotient(j,k);
2250  option(set,op);
2251
2252  list equi=equidim(j);
2253  if(deg(equi[size(equi)][1])<=0)
2254  {
2255      equi[size(equi)]=k;
2256  }
2257  else
2258  {
2259    equi[size(equi)+1]=k;
2260  }
2261  setring P;
2262  eq=imap(gnir,equi);
2263  kill gnir;
2264  return(eq);
2265}
2266example
2267{ "EXAMPLE:"; echo = 2;
2268   ring  r = 32003,(x,y,z),dp;
2269   ideal i = intersect(ideal(z),ideal(x,y),ideal(x2,z2),ideal(x5,y5,z5));
2270   equidim(i);
2271}
2272
2273///////////////////////////////////////////////////////////////////////////////
2274proc equidimMax(ideal i)
2275"USAGE:  equidimMax(i); i ideal
2276RETURN:  ideal of equidimensional locus (of maximal dimension) of i.
2277EXAMPLE: example equidimMax; shows an example
2278"
2279{
2280  if(ord_test(basering)!=1)
2281  {
2282      ERROR(
2283      "// Not implemented for this ordering, please change to global ordering."
2284      );
2285  }
2286  def  P = basering;
2287  ideal eq;
2288  intvec w;
2289  int n;
2290  int g=size(i);
2291  int a=attrib(i,"isSB");
2292  int homo=homog(i);
2293
2294  if(((homo==1)||(a==1))&&(find(ordstr(basering),"l")==0)
2295                                &&(find(ordstr(basering),"s")==0))
2296  {
2297     execute("ring gnir = ("+charstr(basering)+"),("+varstr(basering)+"),("
2298                              +ordstr(basering)+");");
2299     ideal i=imap(P,i);
2300     ideal j=i;
2301     if(a==1)
2302     {
2303       attrib(j,"isSB",1);
2304     }
2305     else
2306     {
2307       j=groebner(i);
2308     }
2309  }
2310  else
2311  {
2312     execute("ring gnir = ("+charstr(basering)+"),("+varstr(basering)+"),dp;");
2313     ideal i=imap(P,i);
2314     ideal j=groebner(i);
2315  }
2316  list indep;
2317  ideal equ,equi;
2318  if(homo==1)
2319  {
2320     for(n=1;n<=nvars(basering);n++)
2321     {
2322        w[n]=ord(var(n));
2323     }
2324     intvec hil=hilb(j,1,w);
2325  }
2326  if ((dim(j)==-1)||(size(j)==0)||(nvars(basering)==1)
2327                  ||(dim(j)==0)||(dim(j)+g==nvars(basering)))
2328  {
2329    setring P;
2330    return(i);
2331  }
2332
2333  indep=maxIndependSet(j);
2334
2335  execute("ring gnir1 = ("+charstr(basering)+"),("+indep[1][1]+"),("
2336                              +indep[1][2]+");");
2337  if(homo==1)
2338  {
2339     ideal j=std(imap(gnir,j),hil,w);
2340  }
2341  else
2342  {
2343     ideal j=groebner(imap(gnir,j));
2344  }
2345  string quotring=prepareQuotientring(nvars(basering)-indep[1][3]);
2346  execute(quotring);
2347  ideal j=imap(gnir1,j);
2348  kill gnir1;
2349  j=clearSB(j);
2350  ideal h;
2351  for(n=1;n<=size(j);n++)
2352  {
2353     h[n]=leadcoef(j[n]);
2354  }
2355  setring gnir;
2356  ideal h=imap(quring,h);
2357  kill quring;
2358
2359  list l=minSat(j,h);
2360
2361  if(deg(l[2])>0)
2362  {
2363    equ=l[1];
2364    attrib(equ,"isSB",1);
2365    j=std(j,l[2]);
2366
2367    if(dim(equ)==dim(j))
2368    {
2369      equi=equidimMax(j);
2370      equ=interred(intersect(equ,equi));
2371    }
2372  }
2373  else
2374  {
2375    equ=i;
2376  }
2377
2378  setring P;
2379  eq=imap(gnir,equ);
2380  kill gnir;
2381  return(eq);
2382}
2383example
2384{ "EXAMPLE:"; echo = 2;
2385   ring  r = 32003,(x,y,z),dp;
2386   ideal i = intersect(ideal(z),ideal(x,y),ideal(x2,z2),ideal(x5,y5,z5));
2387   equidimMax(i);
2388}
2389///////////////////////////////////////////////////////////////////////////////
2390static proc islp()
2391{
2392   string s=ordstr(basering);
2393   int n=find(s,"lp");
2394   if(!n){return(0);}
2395   int k=find(s,",");
2396   string t=s[k+1..size(s)];
2397   int l=find(t,",");
2398   t=s[1..k-1];
2399   int m=find(t,",");
2400   if(l+m){return(0);}
2401   return(1);
2402}
2403///////////////////////////////////////////////////////////////////////////////
2404
2405proc algeDeco(ideal i, int w)
2406{
2407//reduces primery decomposition over algebraic extensions to
2408//the other cases
2409   def R=basering;
2410   int n=nvars(R);
2411   string mp="poly p="+string(minpoly)+";";
2412   string gnir="ring RH="+string(char(R))+",("+varstr(R)+","+string(par(1))
2413                +"),dp;";
2414   execute(gnir);
2415   execute(mp);
2416   ideal i=imap(R,i);
2417         i=i,p;
2418   list pr;
2419   int j;
2420
2421   if(w==0)
2422   {
2423      pr=decomp(i);
2424   }
2425   if(w==1)
2426   {
2427      pr=prim_dec(i,1);
2428      pr=reconvList(pr);
2429   }
2430   if(w==2)
2431   {
2432      pr=minAssPrimes(i);
2433   }
2434
2435   gnir="ring RS="+string(char(R))+",("+varstr(RH)
2436                +"),(dp("+string(n)+"),lp);";
2437   execute(gnir);
2438   list pr=imap(RH,pr);
2439   ideal K;
2440   for(j=1;j<=size(pr);j++)
2441   {
2442      K=groebner(pr[j]);
2443      K=K[2..size(K)];
2444      pr[j]=K;
2445   }
2446   setring R;
2447   list pr=imap(RS,pr);
2448      list re;
2449   if(w==2)
2450   {
2451      re=pr;
2452   }
2453   else
2454   {
2455      re=convList(pr);
2456   }
2457   return(re);
2458}
2459
2460///////////////////////////////////////////////////////////////////////////////
2461static proc decomp(ideal i,list #)
2462"USAGE:  decomp(i); i ideal  (for primary decomposition)   (resp.
2463         decomp(i,1);        (for the associated primes of dimension of i) )
2464         decomp(i,2);        (for the minimal associated primes) )
2465RETURN:  list = list of primary ideals and their associated primes
2466         (at even positions in the list)
2467         (resp. a list of the minimal associated primes)
2468NOTE:    Algorithm of Gianni/Trager/Zacharias
2469EXAMPLE: example decomp; shows an example
2470"
2471{
2472  intvec op;
2473  def  @P = basering;
2474  list primary,indep,ltras;
2475  intvec @vh,isat,@w;
2476  int @wr,@k,@n,@m,@n1,@n2,@n3,homo,seri,keepdi;
2477  ideal peek=i;
2478  ideal ser,tras;
2479  int isS=(attrib(i,"isSB")==1);
2480
2481  if(size(#)>0)
2482  {
2483     if((#[1]==1)||(#[1]==2))
2484     {
2485        @wr=#[1];
2486        if(size(#)>1)
2487        {
2488          seri=1;
2489          peek=#[2];
2490          ser=#[3];
2491        }
2492      }
2493      else
2494      {
2495        seri=1;
2496        peek=#[1];
2497        ser=#[2];
2498      }
2499  }
2500
2501  homo=homog(i);
2502  if(homo==1)
2503  {
2504    if(attrib(i,"isSB")!=1)
2505    {
2506      ltras=mstd(i);
2507      attrib(ltras[1],"isSB",1);
2508    }
2509    else
2510    {
2511      ltras=i,i;
2512      attrib(ltras[1],"isSB",1);
2513    }
2514    tras=ltras[1];
2515    attrib(tras,"isSB",1);
2516    if(dim(tras)==0)
2517    {
2518        primary[1]=ltras[2];
2519        primary[2]=maxideal(1);
2520        if(@wr>0)
2521        {
2522           list l;
2523           l[1]=maxideal(1);
2524           l[2]=maxideal(1);
2525           return(l);
2526        }
2527        return(primary);
2528     }
2529     for(@n=1;@n<=nvars(basering);@n++)
2530     {
2531        @w[@n]=ord(var(@n));
2532     }
2533     intvec @hilb=hilb(tras,1,@w);
2534     intvec keephilb=@hilb;
2535  }
2536
2537  //----------------------------------------------------------------
2538  //i is the zero-ideal
2539  //----------------------------------------------------------------
2540
2541  if(size(i)==0)
2542  {
2543     primary=i,i;
2544     return(primary);
2545  }
2546
2547  //----------------------------------------------------------------
2548  //pass to the lexicographical ordering and compute a standardbasis
2549  //----------------------------------------------------------------
2550
2551  int lp=islp();
2552
2553  execute("ring gnir = ("+charstr(basering)+"),("+varstr(basering)+"),(C,lp);");
2554  op=option(get);
2555  option(redSB);
2556
2557  ideal ser=fetch(@P,ser);
2558
2559  if(homo==1)
2560  {
2561     if(!lp)
2562     {
2563       ideal @j=std(fetch(@P,i),@hilb,@w);
2564     }
2565     else
2566     {
2567        ideal @j=fetch(@P,tras);
2568        attrib(@j,"isSB",1);
2569     }
2570  }
2571  else
2572  {
2573      if(lp&&isS)
2574      {
2575        ideal @j=fetch(@P,i);
2576        attrib(@j,"isSB",1);
2577      }
2578      else
2579      {
2580        ideal @j=groebner(fetch(@P,i));
2581      }
2582  }
2583  option(set,op);
2584  if(seri==1)
2585  {
2586    ideal peek=fetch(@P,peek);
2587    attrib(peek,"isSB",1);
2588  }
2589  else
2590  {
2591    ideal peek=@j;
2592  }
2593  if(size(ser)==0)
2594  {
2595    ideal fried;
2596    @n=size(@j);
2597    for(@k=1;@k<=@n;@k++)
2598    {
2599      if(deg(lead(@j[@k]))==1)
2600      {
2601        fried[size(fried)+1]=@j[@k];
2602        @j[@k]=0;
2603      }
2604    }
2605    if(size(fried)==nvars(basering))
2606    {
2607       setring @P;
2608       primary[1]=i;
2609       primary[2]=i;
2610       return(primary);
2611    }
2612    if(size(fried)>0)
2613    {
2614       string newva;
2615       string newma;
2616       for(@k=1;@k<=nvars(basering);@k++)
2617       {
2618          @n1=0;
2619          for(@n=1;@n<=size(fried);@n++)
2620          {
2621             if(leadmonom(fried[@n])==var(@k))
2622             {
2623                @n1=1;
2624                break;
2625             }
2626          }
2627          if(@n1==0)
2628          {
2629            newva=newva+string(var(@k))+",";
2630            newma=newma+string(var(@k))+",";
2631          }
2632          else
2633          {
2634            newma=newma+string(0)+",";
2635          }
2636       }
2637       newva[size(newva)]=")";
2638       newma[size(newma)]=";";
2639       execute("ring @deirf=("+charstr(gnir)+"),("+newva+",lp;");
2640       execute("map @kappa=gnir,"+newma);
2641       ideal @j= @kappa(@j);
2642       @j=simplify(@j,2);
2643       attrib(@j,"isSB",1);
2644       list pr=decomp(@j);
2645       setring gnir;
2646       list pr=imap(@deirf,pr);
2647       for(@k=1;@k<=size(pr);@k++)
2648       {
2649         @j=pr[@k]+fried;
2650         pr[@k]=@j;
2651       }
2652       setring @P;
2653       return(imap(gnir,pr));
2654    }
2655  }
2656  //----------------------------------------------------------------
2657  //j is the ring
2658  //----------------------------------------------------------------
2659
2660  if (dim(@j)==-1)
2661  {
2662    setring @P;
2663    primary=ideal(1),ideal(1);
2664    return(primary);
2665  }
2666
2667  //----------------------------------------------------------------
2668  //  the case of one variable
2669  //----------------------------------------------------------------
2670
2671  if(nvars(basering)==1)
2672  {
2673
2674     list fac=factor(@j[1]);
2675     list gprimary;
2676     for(@k=1;@k<=size(fac[1]);@k++)
2677     {
2678        if(@wr==0)
2679        {
2680           gprimary[2*@k-1]=ideal(fac[1][@k]^fac[2][@k]);
2681           gprimary[2*@k]=ideal(fac[1][@k]);
2682        }
2683        else
2684        {
2685           gprimary[2*@k-1]=ideal(fac[1][@k]);
2686           gprimary[2*@k]=ideal(fac[1][@k]);
2687        }
2688     }
2689     setring @P;
2690     primary=fetch(gnir,gprimary);
2691
2692     return(primary);
2693  }
2694
2695 //------------------------------------------------------------------
2696 //the zero-dimensional case
2697 //------------------------------------------------------------------
2698  if (dim(@j)==0)
2699  {
2700    op=option(get);
2701    option(redSB);
2702
2703    list gprimary= zero_decomp(@j,ser,@wr);
2704    option(set,op);
2705    setring @P;
2706    primary=fetch(gnir,gprimary);
2707    if(size(ser)>0)
2708    {
2709      primary=cleanPrimary(primary);
2710    }
2711    return(primary);
2712  }
2713
2714  poly @gs,@gh,@p;
2715  string @va,quotring;
2716  list quprimary,htprimary,collectprimary,lsau,lnew,allindep,restindep;
2717  ideal @h;
2718  int jdim=dim(@j);
2719  list fett;
2720  int lauf,di,newtest;
2721  //------------------------------------------------------------------
2722  //search for a maximal independent set indep,i.e.
2723  //look for subring such that the intersection with the ideal is zero
2724  //j intersected with K[var(indep[3]+1),...,var(nvar] is zero,
2725  //indep[1] is the new varstring and indep[2] the string for block-ordering
2726  //------------------------------------------------------------------
2727  if(@wr!=1)
2728  {
2729     allindep=independSet(@j);
2730     for(@m=1;@m<=size(allindep);@m++)
2731     {
2732        if(allindep[@m][3]==jdim)
2733        {
2734           di++;
2735           indep[di]=allindep[@m];
2736        }
2737        else
2738        {
2739           lauf++;
2740           restindep[lauf]=allindep[@m];
2741        }
2742     }
2743   }
2744   else
2745   {
2746      indep=maxIndependSet(@j);
2747   }
2748
2749  ideal jkeep=@j;
2750  if(ordstr(@P)[1]=="w")
2751  {
2752     execute("ring @Phelp=("+charstr(gnir)+"),("+varstr(gnir)+"),("+ordstr(@P)+");");
2753  }
2754  else
2755  {
2756     execute( "ring @Phelp=("+charstr(gnir)+"),("+varstr(gnir)+"),(C,dp);");
2757  }
2758
2759  if(homo==1)
2760  {
2761    if((ordstr(@P)[3]=="d")||(ordstr(@P)[1]=="d")||(ordstr(@P)[1]=="w")
2762       ||(ordstr(@P)[3]=="w"))
2763    {
2764      ideal jwork=imap(@P,tras);
2765      attrib(jwork,"isSB",1);
2766    }
2767    else
2768    {
2769      ideal jwork=std(imap(gnir,@j),@hilb,@w);
2770    }
2771
2772  }
2773  else
2774  {
2775    ideal jwork=groebner(imap(gnir,@j));
2776  }
2777  list hquprimary;
2778  poly @p,@q;
2779  ideal @h,fac,ser;
2780  di=dim(jwork);
2781  keepdi=di;
2782
2783  setring gnir;
2784  for(@m=1;@m<=size(indep);@m++)
2785  {
2786     isat=0;
2787     @n2=0;
2788     if((indep[@m][1]==varstr(basering))&&(@m==1))
2789     //this is the good case, nothing to do, just to have the same notations
2790     //change the ring
2791     {
2792        execute("ring gnir1 = ("+charstr(basering)+"),("+varstr(basering)+"),("
2793                              +ordstr(basering)+");");
2794        ideal @j=fetch(gnir,@j);
2795        attrib(@j,"isSB",1);
2796        ideal ser=fetch(gnir,ser);
2797
2798     }
2799     else
2800     {
2801        @va=string(maxideal(1));
2802        execute("ring gnir1 = ("+charstr(basering)+"),("+indep[@m][1]+"),("
2803                              +indep[@m][2]+");");
2804        execute("map phi=gnir,"+@va+";");
2805        op=option(get);
2806        option(redSB);
2807        if(homo==1)
2808        {
2809           ideal @j=std(phi(@j),@hilb,@w);
2810        }
2811        else
2812        {
2813          ideal @j=groebner(phi(@j));
2814        }
2815        ideal ser=phi(ser);
2816
2817        option(set,op);
2818     }
2819     if((deg(@j[1])==0)||(dim(@j)<jdim))
2820     {
2821       setring gnir;
2822       break;
2823     }
2824     for (lauf=1;lauf<=size(@j);lauf++)
2825     {
2826         fett[lauf]=size(@j[lauf]);
2827     }
2828     //------------------------------------------------------------------------
2829     //we have now the following situation:
2830     //j intersected with K[var(nnp+1),..,var(nva)] is zero so we may pass
2831     //to this quotientring, j is their still a standardbasis, the
2832     //leading coefficients of the polynomials  there (polynomials in
2833     //K[var(nnp+1),..,var(nva)]) are collected in the list h,
2834     //we need their ggt, gh, because of the following: let
2835     //(j:gh^n)=(j:gh^infinity) then j*K(var(nnp+1),..,var(nva))[..the rest..]
2836     //intersected with K[var(1),...,var(nva)] is (j:gh^n)
2837     //on the other hand j=(j,gh^n) intersected with (j:gh^n)
2838
2839     //------------------------------------------------------------------------
2840
2841     //arrangement for quotientring K(var(nnp+1),..,var(nva))[..the rest..] and
2842     //map phi:K[var(1),...,var(nva)] --->K(var(nnpr+1),..,var(nva))[..rest..]
2843     //------------------------------------------------------------------------
2844
2845     quotring=prepareQuotientring(nvars(basering)-indep[@m][3]);
2846
2847     //---------------------------------------------------------------------
2848     //we pass to the quotientring   K(var(nnp+1),..,var(nva))[..the rest..]
2849     //---------------------------------------------------------------------
2850
2851     execute(quotring);
2852
2853    // @j considered in the quotientring
2854     ideal @j=imap(gnir1,@j);
2855     ideal ser=imap(gnir1,ser);
2856
2857     kill gnir1;
2858
2859     //j is a standardbasis in the quotientring but usually not minimal
2860     //here it becomes minimal
2861
2862     @j=clearSB(@j,fett);
2863     attrib(@j,"isSB",1);
2864
2865     //we need later ggt(h[1],...)=gh for saturation
2866     ideal @h;
2867     if(deg(@j[1])>0)
2868     {
2869        for(@n=1;@n<=size(@j);@n++)
2870        {
2871           @h[@n]=leadcoef(@j[@n]);
2872        }
2873        //the primary decomposition of j*K(var(nnp+1),..,var(nva))[..the rest..]
2874        op=option(get);
2875        option(redSB);
2876
2877        list uprimary= zero_decomp(@j,ser,@wr);
2878        option(set,op);
2879     }
2880     else
2881     {
2882       list uprimary;
2883       uprimary[1]=ideal(1);
2884       uprimary[2]=ideal(1);
2885     }
2886     //we need the intersection of the ideals in the list quprimary with the
2887     //polynomialring, i.e. let q=(f1,...,fr) in the quotientring such an ideal
2888     //but fi polynomials, then the intersection of q with the polynomialring
2889     //is the saturation of the ideal generated by f1,...,fr with respect to
2890     //h which is the lcm of the leading coefficients of the fi considered in
2891     //in the quotientring: this is coded in saturn
2892
2893     list saturn;
2894     ideal hpl;
2895
2896     for(@n=1;@n<=size(uprimary);@n++)
2897     {
2898        uprimary[@n]=interred(uprimary[@n]); // temporary fix
2899        hpl=0;
2900        for(@n1=1;@n1<=size(uprimary[@n]);@n1++)
2901        {
2902           hpl=hpl,leadcoef(uprimary[@n][@n1]);
2903        }
2904        saturn[@n]=hpl;
2905     }
2906
2907     //--------------------------------------------------------------------
2908     //we leave  the quotientring   K(var(nnp+1),..,var(nva))[..the rest..]
2909     //back to the polynomialring
2910     //---------------------------------------------------------------------
2911     setring gnir;
2912
2913     collectprimary=imap(quring,uprimary);
2914     lsau=imap(quring,saturn);
2915     @h=imap(quring,@h);
2916
2917     kill quring;
2918
2919     @n2=size(quprimary);
2920     @n3=@n2;
2921
2922     for(@n1=1;@n1<=size(collectprimary)/2;@n1++)
2923     {
2924        if(deg(collectprimary[2*@n1][1])>0)
2925        {
2926           @n2++;
2927           quprimary[@n2]=collectprimary[2*@n1-1];
2928           lnew[@n2]=lsau[2*@n1-1];
2929           @n2++;
2930           lnew[@n2]=lsau[2*@n1];
2931           quprimary[@n2]=collectprimary[2*@n1];
2932        }
2933     }
2934
2935     //here the intersection with the polynomialring
2936     //mentioned above is really computed
2937     for(@n=@n3/2+1;@n<=@n2/2;@n++)
2938     {
2939        if(specialIdealsEqual(quprimary[2*@n-1],quprimary[2*@n]))
2940        {
2941           quprimary[2*@n-1]=sat2(quprimary[2*@n-1],lnew[2*@n-1])[1];
2942           quprimary[2*@n]=quprimary[2*@n-1];
2943        }
2944        else
2945        {
2946           if(@wr==0)
2947           {
2948              quprimary[2*@n-1]=sat2(quprimary[2*@n-1],lnew[2*@n-1])[1];
2949           }
2950           quprimary[2*@n]=sat2(quprimary[2*@n],lnew[2*@n])[1];
2951        }
2952     }
2953
2954     if(size(@h)>0)
2955     {
2956           //---------------------------------------------------------------
2957           //we change to @Phelp to have the ordering dp for saturation
2958           //---------------------------------------------------------------
2959        setring @Phelp;
2960        @h=imap(gnir,@h);
2961        if(@wr!=1)
2962        {
2963          @q=minSat(jwork,@h)[2];
2964        }
2965        else
2966        {
2967            fac=ideal(0);
2968            for(lauf=1;lauf<=ncols(@h);lauf++)
2969           {
2970              if(deg(@h[lauf])>0)
2971              {
2972                 fac=fac+factorize(@h[lauf],1);
2973              }
2974           }
2975           fac=simplify(fac,4);
2976           @q=1;
2977           for(lauf=1;lauf<=size(fac);lauf++)
2978           {
2979             @q=@q*fac[lauf];
2980           }
2981        }
2982        jwork=std(jwork,@q);
2983        keepdi=dim(jwork);
2984        if(keepdi<di)
2985        {
2986           setring gnir;
2987           @j=imap(@Phelp,jwork);
2988           break;
2989        }
2990        if(homo==1)
2991        {
2992              @hilb=hilb(jwork,1,@w);
2993        }
2994
2995        setring gnir;
2996        @j=imap(@Phelp,jwork);
2997     }
2998  }
2999
3000  if((size(quprimary)==0)&&(@wr==1))
3001  {
3002     @j=ideal(1);
3003     quprimary[1]=ideal(1);
3004     quprimary[2]=ideal(1);
3005  }
3006  if((size(quprimary)==0))
3007  {
3008    keepdi=di-1;
3009  }
3010  //---------------------------------------------------------------
3011  //notice that j=sat(j,gh) intersected with (j,gh^n)
3012  //we finished with sat(j,gh) and have to start with (j,gh^n)
3013  //---------------------------------------------------------------
3014  if((deg(@j[1])!=0)&&(@wr!=1))
3015  {
3016     if(size(quprimary)>0)
3017     {
3018        setring @Phelp;
3019        ser=imap(gnir,ser);
3020        hquprimary=imap(gnir,quprimary);
3021        if(@wr==0)
3022        {
3023           ideal htest=hquprimary[1];
3024           for (@n1=2;@n1<=size(hquprimary)/2;@n1++)
3025           {
3026              htest=intersect(htest,hquprimary[2*@n1-1]);
3027           }
3028        }
3029        else
3030        {
3031           ideal htest=hquprimary[2];
3032
3033           for (@n1=2;@n1<=size(hquprimary)/2;@n1++)
3034           {
3035              htest=intersect(htest,hquprimary[2*@n1]);
3036           }
3037        }
3038
3039        if(size(ser)>0)
3040        {
3041           ser=intersect(htest,ser);
3042        }
3043        else
3044        {
3045          ser=htest;
3046        }
3047        setring gnir;
3048        ser=imap(@Phelp,ser);
3049     }
3050     if(size(reduce(ser,peek,1))!=0)
3051     {
3052        for(@m=1;@m<=size(restindep);@m++)
3053        {
3054         // if(restindep[@m][3]>=keepdi)
3055         // {
3056           isat=0;
3057           @n2=0;
3058
3059           if(restindep[@m][1]==varstr(basering))
3060           //the good case, nothing to do, just to have the same notations
3061           //change the ring
3062           {
3063              execute("ring gnir1 = ("+charstr(basering)+"),("+
3064                varstr(basering)+"),("+ordstr(basering)+");");
3065              ideal @j=fetch(gnir,jkeep);
3066              attrib(@j,"isSB",1);
3067           }
3068           else
3069           {
3070              @va=string(maxideal(1));
3071              execute("ring gnir1 = ("+charstr(basering)+"),("+
3072                      restindep[@m][1]+"),(" +restindep[@m][2]+");");
3073              execute("map phi=gnir,"+@va+";");
3074              op=option(get);
3075              option(redSB);
3076              if(homo==1)
3077              {
3078                 ideal @j=std(phi(jkeep),keephilb,@w);
3079              }
3080              else
3081              {
3082                ideal @j=groebner(phi(jkeep));
3083              }
3084              ideal ser=phi(ser);
3085              option(set,op);
3086           }
3087
3088           for (lauf=1;lauf<=size(@j);lauf++)
3089           {
3090              fett[lauf]=size(@j[lauf]);
3091           }
3092           //------------------------------------------------------------------
3093           //we have now the following situation:
3094           //j intersected with K[var(nnp+1),..,var(nva)] is zero so we may
3095           //pass to this quotientring, j is their still a standardbasis, the
3096           //leading coefficients of the polynomials  there (polynomials in
3097           //K[var(nnp+1),..,var(nva)]) are collected in the list h,
3098           //we need their ggt, gh, because of the following:
3099           //let (j:gh^n)=(j:gh^infinity) then
3100           //j*K(var(nnp+1),..,var(nva))[..the rest..]
3101           //intersected with K[var(1),...,var(nva)] is (j:gh^n)
3102           //on the other hand j=(j,gh^n) intersected with (j:gh^n)
3103
3104           //------------------------------------------------------------------
3105
3106           //the arrangement for the quotientring
3107           // K(var(nnp+1),..,var(nva))[..the rest..]
3108           //and the map phi:K[var(1),...,var(nva)] ---->
3109           //--->K(var(nnpr+1),..,var(nva))[..the rest..]
3110           //------------------------------------------------------------------
3111
3112           quotring=prepareQuotientring(nvars(basering)-restindep[@m][3]);
3113
3114           //------------------------------------------------------------------
3115           //we pass to the quotientring  K(var(nnp+1),..,var(nva))[..rest..]
3116           //------------------------------------------------------------------
3117
3118           execute(quotring);
3119
3120           // @j considered in the quotientring
3121           ideal @j=imap(gnir1,@j);
3122           ideal ser=imap(gnir1,ser);
3123
3124           kill gnir1;
3125
3126           //j is a standardbasis in the quotientring but usually not minimal
3127           //here it becomes minimal
3128           @j=clearSB(@j,fett);
3129           attrib(@j,"isSB",1);
3130
3131           //we need later ggt(h[1],...)=gh for saturation
3132           ideal @h;
3133
3134           for(@n=1;@n<=size(@j);@n++)
3135           {
3136              @h[@n]=leadcoef(@j[@n]);
3137           }
3138           //the primary decomposition of j*K(var(nnp+1),..,var(nva))[..rest..]
3139
3140           op=option(get);
3141           option(redSB);
3142           list uprimary= zero_decomp(@j,ser,@wr);
3143           option(set,op);
3144
3145           //we need the intersection of the ideals in the list quprimary with
3146           //the polynomialring, i.e. let q=(f1,...,fr) in the quotientring
3147           //such an ideal but fi polynomials, then the intersection of q with
3148           //the polynomialring is the saturation of the ideal generated by
3149           //f1,...,fr with respect toh which is the lcm of the leading
3150           //coefficients of the fi considered in the quotientring:
3151           //this is coded in saturn
3152
3153           list saturn;
3154           ideal hpl;
3155
3156           for(@n=1;@n<=size(uprimary);@n++)
3157           {
3158              hpl=0;
3159              for(@n1=1;@n1<=size(uprimary[@n]);@n1++)
3160              {
3161                 hpl=hpl,leadcoef(uprimary[@n][@n1]);
3162              }
3163               saturn[@n]=hpl;
3164           }
3165           //------------------------------------------------------------------
3166           //we leave  the quotientring   K(var(nnp+1),..,var(nva))[..rest..]
3167           //back to the polynomialring
3168           //------------------------------------------------------------------
3169           setring gnir;
3170
3171           collectprimary=imap(quring,uprimary);
3172           lsau=imap(quring,saturn);
3173           @h=imap(quring,@h);
3174
3175           kill quring;
3176
3177
3178           @n2=size(quprimary);
3179           @n3=@n2;
3180
3181           for(@n1=1;@n1<=size(collectprimary)/2;@n1++)
3182           {
3183              if(deg(collectprimary[2*@n1][1])>0)
3184              {
3185                 @n2++;
3186                 quprimary[@n2]=collectprimary[2*@n1-1];
3187                 lnew[@n2]=lsau[2*@n1-1];
3188                 @n2++;
3189                 lnew[@n2]=lsau[2*@n1];
3190                 quprimary[@n2]=collectprimary[2*@n1];
3191              }
3192           }
3193
3194
3195           //here the intersection with the polynomialring
3196           //mentioned above is really computed
3197
3198           for(@n=@n3/2+1;@n<=@n2/2;@n++)
3199           {
3200              if(specialIdealsEqual(quprimary[2*@n-1],quprimary[2*@n]))
3201              {
3202                 quprimary[2*@n-1]=sat2(quprimary[2*@n-1],lnew[2*@n-1])[1];
3203                 quprimary[2*@n]=quprimary[2*@n-1];
3204              }
3205              else
3206              {
3207                 if(@wr==0)
3208                 {
3209                    quprimary[2*@n-1]=sat2(quprimary[2*@n-1],lnew[2*@n-1])[1];
3210                 }
3211                 quprimary[2*@n]=sat2(quprimary[2*@n],lnew[2*@n])[1];
3212              }
3213           }
3214           if(@n2>=@n3+2)
3215           {
3216              setring @Phelp;
3217              ser=imap(gnir,ser);
3218              hquprimary=imap(gnir,quprimary);
3219              for(@n=@n3/2+1;@n<=@n2/2;@n++)
3220              {
3221                if(@wr==0)
3222                {
3223                   ser=intersect(ser,hquprimary[2*@n-1]);
3224                }
3225                else
3226                {
3227                   ser=intersect(ser,hquprimary[2*@n]);
3228                }
3229              }
3230              setring gnir;
3231              ser=imap(@Phelp,ser);
3232           }
3233
3234         // }
3235        }
3236        if(size(reduce(ser,peek,1))!=0)
3237        {
3238           if(@wr>0)
3239           {
3240              htprimary=decomp(@j,@wr,peek,ser);
3241           }
3242           else
3243           {
3244              htprimary=decomp(@j,peek,ser);
3245           }
3246           // here we collect now both results primary(sat(j,gh))
3247           // and primary(j,gh^n)
3248           @n=size(quprimary);
3249           for (@k=1;@k<=size(htprimary);@k++)
3250           {
3251              quprimary[@n+@k]=htprimary[@k];
3252           }
3253        }
3254     }
3255
3256   }
3257  //---------------------------------------------------------------------------
3258  //back to the ring we started with
3259  //the final result: primary
3260  //---------------------------------------------------------------------------
3261
3262  setring @P;
3263  primary=imap(gnir,quprimary);
3264  return(primary);
3265}
3266
3267
3268example
3269{ "EXAMPLE:"; echo = 2;
3270   ring  r = 32003,(x,y,z),lp;
3271   poly  p = z2+1;
3272   poly  q = z4+2;
3273   ideal i = p^2*q^3,(y-z3)^3,(x-yz+z4)^4;
3274   list pr= decomp(i);
3275   pr;
3276   testPrimary( pr, i);
3277}
3278
3279///////////////////////////////////////////////////////////////////////////////
3280static proc powerCoeffs(poly f,int e)
3281//computes a polynomial with the same monomials as f but coefficients
3282//the p^e th power of the coefficients of f
3283{
3284   int i;
3285   poly g;
3286   int ex=char(basering)^e;
3287   for(i=1;i<=size(f);i++)
3288   {
3289      g=g+leadcoef(f[i])^ex*leadmonom(f[i]);
3290   }
3291   return(g);
3292}
3293///////////////////////////////////////////////////////////////////////////////
3294
3295static proc sep(poly f,int i, list #)
3296"USAGE:  input: a polynomial f depending on the i-th variable and optional
3297         an integer k considering the polynomial f defined over Fp(t1,...,tm)
3298         as polynomial over Fp(t(1)^(p^-k),...,t(m)^(p^-k))
3299 RETURN: the separabel part of f as polynomial in Fp(t1,...,tm)
3300        and an integer k to indicate that f should be considerd
3301        as polynomial over Fp(t(1)^(p^-k),...,t(m)^(p^-k))
3302 EXAMPLE: example sep; shows an example
3303{
3304   def R=basering;
3305   int k;
3306   if(size(#)>0){k=#[1];}
3307
3308   poly h=gcd(f,diff(f,var(i)));
3309   poly g1=lift(h,f)[1][1];    //  f/h
3310   poly h1;
3311
3312   while(h!=h1)
3313   {
3314      h1=h;
3315      h=gcd(h,diff(h,var(i)));
3316   }
3317
3318   if(deg(h1)==0){return(list(g1,k));} //in characteristic 0 we return here
3319
3320   k++;
3321
3322   ideal ma=maxideal(1);
3323   ma[i]=var(i)^char(R);
3324   map phi=R,ma;
3325   ideal hh=h;    //this is technical because preimage works only for ideals
3326
3327   poly u=preimage(R,phi,hh)[1]; //h=u(x(i)^p)
3328
3329   list g2=sep(u,i,k);           //we consider u(t(1)^(p^-1),...,t(m)^(p^-1))
3330   g1=powerCoeffs(g1,g2[2]-k+1); //to have g1 over the same field as g2[1]
3331
3332   list g3=sep(g1*g2[1],i,g2[2]);
3333   return(g3);
3334}
3335example
3336{ "EXAMPLE:"; echo = 2;
3337   ring R=(5,t,s),(x,y,z),dp;
3338   poly f=(x^25-t*x^5+t)*(x^3+s);
3339   sep(f,1);
3340}
3341
3342///////////////////////////////////////////////////////////////////////////////
3343 proc zeroRad(ideal I,list #)
3344"USAGE:  zeroRad(I) , I a zero-dimensional ideal
3345 RETURN: the radical of I
3346 NOTE:  Algorithm of Kemper
3347 EXAMPLE: example zeroRad; shows an example
3348{
3349   if(homog(I)==1){return(maxideal(1));}
3350   //I needs to be a reduced standard basis
3351   def R=basering;
3352   int m=npars(R);
3353   int n=nvars(R);
3354   int p=char(R);
3355   int i,k;
3356   list l;
3357   intvec op=option(get);
3358
3359   option(redSB);
3360   ideal F=finduni(I);//F[i] generates I intersected with K[var(i)]
3361
3362   option(set,op);
3363   if(size(#)>0){I=#[1];}
3364
3365   for(i=1;i<=n;i++)
3366   {
3367      l[i]=sep(F[i],i);
3368      F[i]=l[i][1];
3369      if(l[i][2]>k){k=l[i][2];}  //computation of the maximal k
3370   }
3371
3372   if((k==0)||(m==0)){return(interred(I+F));}        //the separable case
3373
3374   for(i=1;i<=n;i++)             //consider all polynomials over
3375   {                             //Fp(t(1)^(p^-k),...,t(m)^(p^-k))
3376      F[i]=powerCoeffs(F[i],k-l[i][2]);
3377   }
3378
3379   string cR="ring @R="+string(p)+",("+parstr(R)+","+varstr(R)+"),dp;";
3380   execute(cR);
3381   ideal F=imap(R,F);
3382
3383   string nR="ring @S="+string(p)+",(y(1..m),"+varstr(R)+","+parstr(R)+"),dp;";
3384   execute(nR);
3385
3386   ideal G=fetch(@R,F);    //G[i](t(1)^(p^-k),...,t(m)^(p^-k),x(i))=sep(F[i])
3387
3388   ideal I=imap(R,I);
3389   ideal J=I+G;
3390   poly el=1;
3391   k=p^k;
3392   for(i=1;i<=m;i++)
3393   {
3394      J=J,var(i)^k-var(m+n+i);
3395      el=el*y(i);
3396   }
3397
3398   J=eliminate(J,el);
3399   setring R;
3400   ideal J=imap(@S,J);
3401   return(J);
3402}
3403example
3404{ "EXAMPLE:"; echo = 2;
3405   ring R=(5,t),(x,y),dp;
3406   ideal I=x^5-t,y^5-t;
3407   zeroRad(I);
3408}
3409
3410///////////////////////////////////////////////////////////////////////////////
3411static proc radicalKL (ideal i,ideal ser,list #)
3412{
3413   attrib(i,"isSB",1);   // i needs to be a reduced standard basis
3414   list indep,fett;
3415   intvec @w,@hilb,op;
3416   int @wr,@n,@m,lauf,di;
3417   ideal fac,@h,collectrad,lsau;
3418   poly @q;
3419   string @va,quotring;
3420
3421   def  @P = basering;
3422   int jdim=dim(i);
3423   int  homo=homog(i);
3424   ideal rad=ideal(1);
3425   ideal te=ser;
3426   if(size(#)>0)
3427   {
3428      @wr=#[1];
3429   }
3430   if(homo==1)
3431   {
3432      for(@n=1;@n<=nvars(basering);@n++)
3433      {
3434         @w[@n]=ord(var(@n));
3435      }
3436      @hilb=hilb(i,1,@w);
3437   }
3438
3439
3440  //---------------------------------------------------------------------------
3441  //j is the ring
3442  //---------------------------------------------------------------------------
3443
3444   if (jdim==-1)
3445   {
3446
3447      return(ideal(1));
3448   }
3449
3450  //---------------------------------------------------------------------------
3451  //the zero-dimensional case
3452  //---------------------------------------------------------------------------
3453
3454   if (jdim==0)
3455   {
3456      return(zeroRad(i));
3457   }
3458   //-------------------------------------------------------------------------
3459   //search for a maximal independent set indep,i.e.
3460   //look for subring such that the intersection with the ideal is zero
3461   //j intersected with K[var(indep[3]+1),...,var(nvar] is zero,
3462   //indep[1] is the new varstring, indep[2] the string for the block-ordering
3463   //-------------------------------------------------------------------------
3464
3465   indep=maxIndependSet(i);
3466
3467   for(@m=1;@m<=size(indep);@m++)
3468   {
3469      if((indep[@m][1]==varstr(basering))&&(@m==1))
3470      //this is the good case, nothing to do, just to have the same notations
3471      //change the ring
3472      {
3473        execute("ring gnir1 = ("+charstr(basering)+"),("+varstr(basering)+"),("
3474                              +ordstr(basering)+");");
3475         ideal @j=fetch(@P,i);
3476         attrib(@j,"isSB",1);
3477      }
3478      else
3479      {
3480         @va=string(maxideal(1));
3481         execute("ring gnir1 = ("+charstr(basering)+"),("+indep[@m][1]+"),("
3482                              +indep[@m][2]+");");
3483         execute("map phi=@P,"+@va+";");
3484         if(homo==1)
3485         {
3486            ideal @j=std(phi(i),@hilb,@w);
3487         }
3488         else
3489         {
3490           ideal @j=groebner(phi(i));
3491         }
3492      }
3493      if((deg(@j[1])==0)||(dim(@j)<jdim))
3494      {
3495         setring @P;
3496         break;
3497      }
3498      for (lauf=1;lauf<=size(@j);lauf++)
3499      {
3500         fett[lauf]=size(@j[lauf]);
3501      }
3502     //------------------------------------------------------------------------
3503     //we have now the following situation:
3504     //j intersected with K[var(nnp+1),..,var(nva)] is zero so we may pass
3505     //to this quotientring, j is their still a standardbasis, the
3506     //leading coefficients of the polynomials  there (polynomials in
3507     //K[var(nnp+1),..,var(nva)]) are collected in the list h,
3508     //we need their ggt, gh, because of the following:
3509     //let (j:gh^n)=(j:gh^infinity) then j*K(var(nnp+1),..,var(nva))[..rest..]
3510     //intersected with K[var(1),...,var(nva)] is (j:gh^n)
3511     //on the other hand j=(j,gh^n) intersected with (j:gh^n)
3512
3513     //------------------------------------------------------------------------
3514
3515     //the arrangement for the quotientring K(var(nnp+1),..,var(nva))[..rest..]
3516     //and the map phi:K[var(1),...,var(nva)] ----->
3517     //K(var(nnpr+1),..,var(nva))[..the rest..]
3518     //------------------------------------------------------------------------
3519      quotring=prepareQuotientring(nvars(basering)-indep[@m][3]);
3520
3521     //------------------------------------------------------------------------
3522     //we pass to the quotientring   K(var(nnp+1),..,var(nva))[..the rest..]
3523     //------------------------------------------------------------------------
3524
3525      execute(quotring);
3526
3527    // @j considered in the quotientring
3528      ideal @j=imap(gnir1,@j);
3529
3530      kill gnir1;
3531
3532     //j is a standardbasis in the quotientring but usually not minimal
3533     //here it becomes minimal
3534
3535      @j=clearSB(@j,fett);
3536
3537     //we need later ggt(h[1],...)=gh for saturation
3538      ideal @h;
3539      if(deg(@j[1])>0)
3540      {
3541         for(@n=1;@n<=size(@j);@n++)
3542         {
3543            @h[@n]=leadcoef(@j[@n]);
3544         }
3545         op=option(get);
3546         option(redSB);
3547         @j=interred(@j);  //to obtain a reduced standardbasis
3548         attrib(@j,"isSB",1);
3549         option(set,op);
3550
3551         ideal zero_rad= zeroRad(@j);
3552      }
3553      else
3554      {
3555         ideal zero_rad=ideal(1);
3556      }
3557
3558     //we need the intersection of the ideals in the list quprimary with the
3559     //polynomialring, i.e. let q=(f1,...,fr) in the quotientring such an ideal
3560     //but fi polynomials, then the intersection of q with the polynomialring
3561     //is the saturation of the ideal generated by f1,...,fr with respect to
3562     //h which is the lcm of the leading coefficients of the fi considered in
3563     //the quotientring: this is coded in saturn
3564
3565      zero_rad=std(zero_rad);
3566
3567      ideal hpl;
3568
3569      for(@n=1;@n<=size(zero_rad);@n++)
3570      {
3571         hpl=hpl,leadcoef(zero_rad[@n]);
3572      }
3573
3574     //------------------------------------------------------------------------
3575     //we leave  the quotientring   K(var(nnp+1),..,var(nva))[..the rest..]
3576     //back to the polynomialring
3577     //------------------------------------------------------------------------
3578      setring @P;
3579
3580      collectrad=imap(quring,zero_rad);
3581      lsau=simplify(imap(quring,hpl),2);
3582      @h=imap(quring,@h);
3583
3584      kill quring;
3585
3586
3587     //here the intersection with the polynomialring
3588     //mentioned above is really computed
3589
3590      collectrad=sat2(collectrad,lsau)[1];
3591      if(deg(@h[1])>=0)
3592      {
3593         fac=ideal(0);
3594         for(lauf=1;lauf<=ncols(@h);lauf++)
3595         {
3596            if(deg(@h[lauf])>0)
3597            {
3598                fac=fac+factorize(@h[lauf],1);
3599            }
3600         }
3601         fac=simplify(fac,4);
3602         @q=1;
3603         for(lauf=1;lauf<=size(fac);lauf++)
3604         {
3605            @q=@q*fac[lauf];
3606         }
3607         op=option(get);
3608         option(returnSB);
3609         option(redSB);
3610         i=quotient(i+ideal(@q),rad);
3611         attrib(i,"isSB",1);
3612         option(set,op);
3613
3614      }
3615      if((deg(rad[1])>0)&&(deg(collectrad[1])>0))
3616      {
3617         rad=intersect(rad,collectrad);
3618         te=intersect(te,collectrad);
3619         te=simplify(reduce(te,i,1),2);
3620      }
3621      else
3622      {
3623         if(deg(collectrad[1])>0)
3624         {
3625            rad=collectrad;
3626            te=intersect(te,collectrad);
3627            te=simplify(reduce(te,i,1),2);
3628         }
3629      }
3630
3631      if((dim(i)<jdim)||(size(te)==0))
3632      {
3633         break;
3634      }
3635      if(homo==1)
3636      {
3637         @hilb=hilb(i,1,@w);
3638      }
3639   }
3640   if(((@wr==1)&&(dim(i)<jdim))||(deg(i[1])==0)||(size(te)==0))
3641   {
3642      return(rad);
3643   }
3644   rad=intersect(rad,radicalKL(i,ideal(1),@wr));
3645   return(rad);
3646}
3647
3648///////////////////////////////////////////////////////////////////////////////
3649
3650proc radicalEHV(ideal i)
3651"USAGE:   radicalEHV(i); i ideal.
3652RETURN:  ideal, the radical of i.
3653NOTE:    Uses the algorithm of Eisenbud/Huneke/Vasconcelos, which
3654         reduces the computation to the complete intersection case,
3655         by taking, in the general case, a generic linear combination
3656         of the input.
3657         Works only in characteristic 0 or p large.
3658EXAMPLE: example radicalEHV; shows an example
3659"
3660{
3661   if(ord_test(basering)!=1)
3662   {
3663      ERROR(
3664      "// Not implemented for this ordering, please change to global ordering."
3665      );
3666   }
3667   if((char(basering)<100)&&(char(basering)!=0))
3668   {
3669      "WARNING: The characteristic is too small, the result may be wrong";
3670   }
3671   ideal J,I,I0,radI0,L,radI1,I2,radI2;
3672   int l,n;
3673   intvec op=option(get);
3674   matrix M;
3675
3676   option(redSB);
3677   list m=mstd(i);
3678        I=m[2];
3679   option(set,op);
3680
3681   int cod=nvars(basering)-dim(m[1]);
3682   //-------------------complete intersection case:----------------------
3683   if(cod==size(m[2]))
3684   {
3685     J=minor(jacob(I),cod);
3686     return(quotient(I,J));
3687   }
3688   //-----first codim elements of I are a complete intersection:---------
3689   for(l=1;l<=cod;l++)
3690   {
3691      I0[l]=I[l];
3692   }
3693   n=dim(std(I0))+cod-nvars(basering);
3694   //-----last codim elements of I are a complete intersection:----------
3695   if(n!=0)
3696   {
3697      for(l=1;l<=cod;l++)
3698      {
3699         I0[l]=I[size(I)-l+1];
3700      }
3701      n=dim(std(I0))+cod-nvars(basering);
3702   }
3703   //-----taking a generic linear combination of the input:--------------
3704   if(n!=0)
3705   {
3706      M=transpose(sparsetriag(size(m[2]),cod,95,1));
3707      I0=ideal(M*transpose(I));
3708      n=dim(std(I0))+cod-nvars(basering);
3709   }
3710   //-----taking a more generic linear combination of the input:---------
3711   if(n!=0)
3712   {
3713      M=transpose(sparsetriag(size(m[2]),cod,0,100));
3714      I0=ideal(M*transpose(I));
3715      n=dim(std(I0))+cod-nvars(basering);
3716   }
3717   if(n==0)
3718   {
3719      J=minor(jacob(I0),cod);
3720      radI0=quotient(I0,J);
3721      L=quotient(radI0,I);
3722      radI1=quotient(radI0,L);
3723
3724      if(size(reduce(radI1,m[1],1))==0)
3725      {
3726         return(I);
3727      }
3728
3729      I2=sat(I,radI1)[1];
3730
3731      if(deg(I2[1])<=0)
3732      {
3733         return(radI1);
3734      }
3735      return(intersect(radI1,radicalEHV(I2)));
3736   }
3737   //---------------------general case-------------------------------------
3738   return(radical(I));
3739}
3740example
3741{ "EXAMPLE:";  echo = 2;
3742   ring  r = 0,(x,y,z),dp;
3743   poly  p = z2+1;
3744   poly  q = z3+2;
3745   ideal i = p*q^2,y-z2;
3746   ideal pr= radicalEHV(i);
3747   pr;
3748}
3749
3750///////////////////////////////////////////////////////////////////////////////
3751
3752proc Ann(module M)
3753{
3754  M=prune(M);  //to obtain a small embedding
3755  ideal ann=quotient1(M,freemodule(nrows(M)));
3756  return(ann);
3757}
3758///////////////////////////////////////////////////////////////////////////////
3759
3760//computes the equidimensional part of the ideal i of codimension e
3761static proc int_ass_primary_e(ideal i, int e)
3762{
3763  if(homog(i)!=1)
3764  {
3765     i=std(i);
3766  }
3767  list re=sres(i,0);                   //the resolution
3768  re=minres(re);                       //minimized resolution
3769  ideal ann=AnnExt_R(e,re);
3770  if(nvars(basering)-dim(std(ann))!=e)
3771  {
3772    return(ideal(1));
3773  }
3774  return(ann);
3775}
3776
3777///////////////////////////////////////////////////////////////////////////////
3778
3779//computes the annihilator of Ext^n(R/i,R) with given resolution re
3780//n is not necessarily the number of variables
3781static proc AnnExt_R(int n,list re)
3782{
3783  if(n<nvars(basering))
3784  {
3785     matrix f=transpose(re[n+1]);      //Hom(_,R)
3786     module k=nres(f,2)[2];            //the kernel
3787     matrix g=transpose(re[n]);        //the image of Hom(_,R)
3788
3789     ideal ann=quotient1(g,k);           //the anihilator
3790  }
3791  else
3792  {
3793     ideal ann=Ann(transpose(re[n]));
3794  }
3795  return(ann);
3796}
3797///////////////////////////////////////////////////////////////////////////////
3798
3799static proc analyze(list pr)
3800{
3801   int ii,jj;
3802   for(ii=1;ii<=size(pr)/2;ii++)
3803   {
3804      dim(std(pr[2*ii]));
3805      idealsEqual(pr[2*ii-1],pr[2*ii]);
3806      "===========================";
3807   }
3808
3809   for(ii=size(pr)/2;ii>1;ii--)
3810   {
3811      for(jj=1;jj<ii;jj++)
3812      {
3813         if(size(reduce(pr[2*jj],std(pr[2*ii],1)))==0)
3814         {
3815            "eingebette Komponente";
3816            jj;
3817            ii;
3818         }
3819      }
3820   }
3821}
3822
3823///////////////////////////////////////////////////////////////////////////////
3824//
3825//                  Shimoyama-Yokoyama
3826//
3827///////////////////////////////////////////////////////////////////////////////
3828
3829static proc simplifyIdeal(ideal i)
3830{
3831  def r=basering;
3832
3833  int j,k;
3834  map phi;
3835  poly p;
3836
3837  ideal iwork=i;
3838  ideal imap1=maxideal(1);
3839  ideal imap2=maxideal(1);
3840
3841
3842  for(j=1;j<=nvars(basering);j++)
3843  {
3844    for(k=1;k<=size(i);k++)
3845    {
3846      if(deg(iwork[k]/var(j))==0)
3847      {
3848        p=-1/leadcoef(iwork[k]/var(j))*iwork[k];
3849        imap1[j]=p+2*var(j);
3850        phi=r,imap1;
3851        iwork=phi(iwork);
3852        iwork=subst(iwork,var(j),0);
3853        iwork[k]=var(j);
3854        imap1=maxideal(1);
3855        imap2[j]=-p;
3856        break;
3857      }
3858    }
3859  }
3860  return(iwork,imap2);
3861}
3862
3863
3864///////////////////////////////////////////////////////
3865// ini_mod
3866// input: a polynomial p
3867// output: the initial term of p as needed
3868// in the context of characteristic sets
3869//////////////////////////////////////////////////////
3870
3871static proc ini_mod(poly p)
3872{
3873  if (p==0)
3874  {
3875    return(0);
3876  }
3877  int n; matrix m;
3878  for( n=nvars(basering); n>0; n=n-1)
3879  {
3880    m=coef(p,var(n));
3881    if(m[1,1]!=1)
3882    {
3883      p=m[2,1];
3884      break;
3885    }
3886  }
3887  if(deg(p)==0)
3888  {
3889    p=0;
3890  }
3891  return(p);
3892}
3893///////////////////////////////////////////////////////
3894// min_ass_prim_charsets
3895// input: generators of an ideal PS and an integer cho
3896// If cho=0, the given ordering of the variables is used.
3897// Otherwise, the system tries to find an "optimal ordering",
3898// which in some cases may considerably speed up the algorithm
3899// output: the minimal associated primes of PS
3900// algorithm: via characteriostic sets
3901//////////////////////////////////////////////////////
3902
3903
3904static proc min_ass_prim_charsets (ideal PS, int cho)
3905{
3906  if((cho<0) and (cho>1))
3907    {
3908      "ERROR: <int> must be 0 or 1"
3909      return();
3910    }
3911  if(system("version")>933)
3912  {
3913    option(notWarnSB);
3914  }
3915  if(cho==0)
3916  {
3917    return(min_ass_prim_charsets0(PS));
3918  }
3919  else
3920  {
3921     return(min_ass_prim_charsets1(PS));
3922  }
3923}
3924///////////////////////////////////////////////////////
3925// min_ass_prim_charsets0
3926// input: generators of an ideal PS
3927// output: the minimal associated primes of PS
3928// algorithm: via characteristic sets
3929// the given ordering of the variables is used
3930//////////////////////////////////////////////////////
3931
3932
3933static proc min_ass_prim_charsets0 (ideal PS)
3934{
3935  intvec op;
3936  matrix m=char_series(PS);  // We compute an irreducible
3937                             // characteristic series
3938  int i,j,k;
3939  list PSI;
3940  list PHI;  // the ideals given by the characteristic series
3941  for(i=nrows(m);i>=1; i--)
3942  {
3943     PHI[i]=ideal(m[i,1..ncols(m)]);
3944  }
3945  // We compute the radical of each ideal in PHI
3946  ideal I,JS,II;
3947  int sizeJS, sizeII;
3948  for(i=size(PHI);i>=1; i--)
3949  {
3950     I=0;
3951     for(j=size(PHI[i]);j>0;j=j-1)
3952     {
3953       I=I+ini_mod(PHI[i][j]);
3954     }
3955     JS=std(PHI[i]);
3956     sizeJS=size(JS);
3957     for(j=size(I);j>0;j=j-1)
3958     {
3959       II=0;
3960       sizeII=0;
3961       k=0;
3962       while(k<=sizeII)                  // successive saturation
3963       {
3964         op=option(get);
3965         option(returnSB);
3966         II=quotient(JS,I[j]);
3967         option(set,op);
3968         sizeII=size(II);
3969         if(sizeII==sizeJS)
3970         {
3971            for(k=1;k<=sizeII;k++)
3972            {
3973              if(leadexp(II[k])!=leadexp(JS[k])) break;
3974            }
3975         }
3976         JS=II;
3977         sizeJS=sizeII;
3978       }
3979    }
3980    PSI=insert(PSI,JS);
3981  }
3982  int sizePSI=size(PSI);
3983  // We eliminate redundant ideals
3984  for(i=1;i<sizePSI;i++)
3985  {
3986    for(j=i+1;j<=sizePSI;j++)
3987    {
3988      if(size(PSI[i])!=0)
3989      {
3990        if(size(PSI[j])!=0)
3991        {
3992          if(size(NF(PSI[i],PSI[j],1))==0)
3993          {
3994            PSI[j]=ideal(0);
3995          }
3996          else
3997          {
3998            if(size(NF(PSI[j],PSI[i],1))==0)
3999            {
4000              PSI[i]=ideal(0);
4001            }
4002          }
4003        }
4004      }
4005    }
4006  }
4007  for(i=sizePSI;i>=1;i--)
4008  {
4009    if(size(PSI[i])==0)
4010    {
4011      PSI=delete(PSI,i);
4012    }
4013  }
4014  return (PSI);
4015}
4016
4017///////////////////////////////////////////////////////
4018// min_ass_prim_charsets1
4019// input: generators of an ideal PS
4020// output: the minimal associated primes of PS
4021// algorithm: via characteristic sets
4022// input: generators of an ideal PS and an integer i
4023// The system tries to find an "optimal ordering" of
4024// the variables
4025//////////////////////////////////////////////////////
4026
4027
4028static proc min_ass_prim_charsets1 (ideal PS)
4029{
4030  intvec op;
4031  def oldring=basering;
4032  string n=system("neworder",PS);
4033  execute("ring r=("+charstr(oldring)+"),("+n+"),dp;");
4034  ideal PS=imap(oldring,PS);
4035  matrix m=char_series(PS);  // We compute an irreducible
4036                             // characteristic series
4037  int i,j,k;
4038  ideal I;
4039  list PSI;
4040  list PHI;    // the ideals given by the characteristic series
4041  list ITPHI;  // their initial terms
4042  for(i=nrows(m);i>=1; i--)
4043  {
4044     PHI[i]=ideal(m[i,1..ncols(m)]);
4045     I=0;
4046     for(j=size(PHI[i]);j>0;j=j-1)
4047     {
4048       I=I,ini_mod(PHI[i][j]);
4049     }
4050      I=I[2..ncols(I)];
4051      ITPHI[i]=I;
4052  }
4053  setring oldring;
4054  matrix m=imap(r,m);
4055  list PHI=imap(r,PHI);
4056  list ITPHI=imap(r,ITPHI);
4057  // We compute the radical of each ideal in PHI
4058  ideal I,JS,II;
4059  int sizeJS, sizeII;
4060  for(i=size(PHI);i>=1; i--)
4061  {
4062     I=0;
4063     for(j=size(PHI[i]);j>0;j=j-1)
4064     {
4065       I=I+ITPHI[i][j];
4066     }
4067     JS=std(PHI[i]);
4068     sizeJS=size(JS);
4069     for(j=size(I);j>0;j=j-1)
4070     {
4071       II=0;
4072       sizeII=0;
4073       k=0;
4074       while(k<=sizeII)                  // successive iteration
4075       {
4076         op=option(get);
4077         option(returnSB);
4078         II=quotient(JS,I[j]);
4079         option(set,op);
4080//std
4081//         II=std(II);
4082         sizeII=size(II);
4083         if(sizeII==sizeJS)
4084         {
4085            for(k=1;k<=sizeII;k++)
4086            {
4087              if(leadexp(II[k])!=leadexp(JS[k])) break;
4088            }
4089         }
4090         JS=II;
4091         sizeJS=sizeII;
4092       }
4093    }
4094    PSI=insert(PSI,JS);
4095  }
4096  int sizePSI=size(PSI);
4097  // We eliminate redundant ideals
4098  for(i=1;i<sizePSI;i++)
4099  {
4100    for(j=i+1;j<=sizePSI;j++)
4101    {
4102      if(size(PSI[i])!=0)
4103      {
4104        if(size(PSI[j])!=0)
4105        {
4106          if(size(NF(PSI[i],PSI[j],1))==0)
4107          {
4108            PSI[j]=ideal(0);
4109          }
4110          else
4111          {
4112            if(size(NF(PSI[j],PSI[i],1))==0)
4113            {
4114              PSI[i]=ideal(0);
4115            }
4116          }
4117        }
4118      }
4119    }
4120  }
4121  for(i=sizePSI;i>=1;i--)
4122  {
4123    if(size(PSI[i])==0)
4124    {
4125      PSI=delete(PSI,i);
4126    }
4127  }
4128  return (PSI);
4129}
4130
4131
4132/////////////////////////////////////////////////////
4133// proc prim_dec
4134// input:  generators of an ideal I and an integer choose
4135// If choose=0, min_ass_prim_charsets with the given
4136// ordering of the variables is used.
4137// If choose=1, min_ass_prim_charsets with the "optimized"
4138// ordering of the variables is used.
4139// If choose=2, minAssPrimes from primdec.lib is used
4140// If choose=3, minAssPrimes+factorizing Buchberger from primdec.lib is used
4141// output: a primary decomposition of I, i.e., a list
4142// of pairs consisting of a standard basis of a primary component
4143// of I and a standard basis of the corresponding associated prime.
4144// To compute the minimal associated primes of a given ideal
4145// min_ass_prim_l is called, i.e., the minimal associated primes
4146// are computed via characteristic sets.
4147// In the homogeneous case, the performance of the procedure
4148// will be improved if I is already given by a minimal set of
4149// generators. Apply minbase if necessary.
4150//////////////////////////////////////////////////////////
4151
4152
4153static proc prim_dec(ideal I, int choose)
4154{
4155   if((choose<0) or (choose>3))
4156   {
4157     "ERROR: <int> must be 0 or 1 or 2 or 3";
4158      return();
4159   }
4160   if(system("version")>933)
4161   {
4162      option(notWarnSB);
4163   }
4164  ideal H=1; // The intersection of the primary components
4165  list U;    // the leaves of the decomposition tree, i.e.,
4166             // pairs consisting of a primary component of I
4167             // and the corresponding associated prime
4168  list W;    // the non-leaf vertices in the decomposition tree.
4169             // every entry has 6 components:
4170                // 1- the vertex itself , i.e., a standard bais of the
4171                //    given ideal I (type 1), or a standard basis of a
4172                //    pseudo-primary component arising from
4173                //    pseudo-primary decomposition (type 2), or a
4174                //    standard basis of a remaining component arising from
4175                //    pseudo-primary decomposition or extraction (type 3)
4176                // 2- the type of the vertex as indicated above
4177                // 3- the weighted_tree_depth of the vertex
4178                // 4- the tester of the vertex
4179                // 5- a standard basis of the associated prime
4180                //    of a vertex of type 2, or 0 otherwise
4181                // 6- a list of pairs consisting of a standard
4182                //    basis of a minimal associated prime ideal
4183                //    of the father of the vertex and the
4184                //    irreducible factors of the "minimal
4185                //    divisor" of the seperator or extractor
4186                //    corresponding to the prime ideal
4187                //    as computed by the procedure minsat,
4188                //    if the vertex is of type 3, or
4189                //    the empty list otherwise
4190  ideal SI=std(I);
4191  if(SI[1]==1)  // primdecSY(ideal(1))
4192  {
4193    return(list());
4194  }
4195  int ncolsSI=ncols(SI);
4196  int ncolsH=1;
4197  W[1]=list(I,1,0,poly(1),ideal(0),list()); // The root of the tree
4198  int weighted_tree_depth;
4199  int i,j;
4200  int check;
4201  list V;  // current vertex
4202  list VV; // new vertex
4203  list QQ;
4204  list WI;
4205  ideal Qi,SQ,SRest,fac;
4206  poly tester;
4207
4208  while(1)
4209  {
4210    i=1;
4211    while(1)
4212    {
4213      while(i<=size(W)) // find vertex V of smallest weighted tree-depth
4214      {
4215        if (W[i][3]<=weighted_tree_depth) break;
4216        i++;
4217      }
4218      if (i<=size(W)) break;
4219      i=1;
4220      weighted_tree_depth++;
4221    }
4222    V=W[i];
4223    W=delete(W,i); // delete V from W
4224
4225    // now proceed by type of vertex V
4226
4227    if (V[2]==2)  // extraction needed
4228    {
4229      SQ,SRest,fac=extraction(V[1],V[5]);
4230                        // standard basis of primary component,
4231                        // standard basis of remaining component,
4232                        // irreducible factors of
4233                        // the "minimal divisor" of the extractor
4234                        // as computed by the procedure minsat,
4235      check=0;
4236      for(j=1;j<=ncolsH;j++)
4237      {
4238        if (NF(H[j],SQ,1)!=0) // Q is not redundant
4239        {
4240          check=1;
4241          break;
4242        }
4243      }
4244      if(check==1)             // Q is not redundant
4245      {
4246        QQ=list();
4247        QQ[1]=list(SQ,V[5]);  // primary component, associated prime,
4248                              // i.e., standard bases thereof
4249        U=U+QQ;
4250        H=intersect(H,SQ);
4251        H=std(H);
4252        ncolsH=ncols(H);
4253        check=0;
4254        if(ncolsH==ncolsSI)
4255        {
4256          for(j=1;j<=ncolsSI;j++)
4257          {
4258            if(leadexp(H[j])!=leadexp(SI[j]))
4259            {
4260              check=1;
4261              break;
4262            }
4263          }
4264        }
4265        else
4266        {
4267          check=1;
4268        }
4269        if(check==0) // H==I => U is a primary decomposition
4270        {
4271          return(U);
4272        }
4273      }
4274      if (SRest[1]!=1)        // the remaining component is not
4275                              // the whole ring
4276      {
4277        if (rad_con(V[4],SRest)==0) // the new vertex is not the
4278                                    // root of a redundant subtree
4279        {
4280          VV[1]=SRest;     // remaining component
4281          VV[2]=3;         // pseudoprimdec_special
4282          VV[3]=V[3]+1;    // weighted depth
4283          VV[4]=V[4];      // the tester did not change
4284          VV[5]=ideal(0);
4285          VV[6]=list(list(V[5],fac));
4286          W=insert(W,VV,size(W));
4287        }
4288      }
4289    }
4290    else
4291    {
4292      if (V[2]==3) // pseudo_prim_dec_special is needed
4293      {
4294        QQ,SRest=pseudo_prim_dec_special_charsets(V[1],V[6],choose);
4295                         // QQ = quadruples:
4296                         // standard basis of pseudo-primary component,
4297                         // standard basis of corresponding prime,
4298                         // seperator, irreducible factors of
4299                         // the "minimal divisor" of the seperator
4300                         // as computed by the procedure minsat,
4301                         // SRest=standard basis of remaining component
4302      }
4303      else     // V is the root, pseudo_prim_dec is needed
4304      {
4305        QQ,SRest=pseudo_prim_dec_charsets(I,SI,choose);
4306                         // QQ = quadruples:
4307                         // standard basis of pseudo-primary component,
4308                         // standard basis of corresponding prime,
4309                         // seperator, irreducible factors of
4310                         // the "minimal divisor" of the seperator
4311                         // as computed by the procedure minsat,
4312                         // SRest=standard basis of remaining component
4313
4314      }
4315      //check
4316      for(i=size(QQ);i>=1;i--)
4317      //for(i=1;i<=size(QQ);i++)
4318      {
4319        tester=QQ[i][3]*V[4];
4320        Qi=QQ[i][2];
4321        if(NF(tester,Qi,1)!=0)  // the new vertex is not the
4322                                // root of a redundant subtree
4323        {
4324          VV[1]=QQ[i][1];
4325          VV[2]=2;
4326          VV[3]=V[3]+1;
4327          VV[4]=tester;      // the new tester as computed above
4328          VV[5]=Qi;          // QQ[i][2];
4329          VV[6]=list();
4330          W=insert(W,VV,size(W));
4331        }
4332      }
4333      if (SRest[1]!=1)        // the remaining component is not
4334                              // the whole ring
4335      {
4336        if (rad_con(V[4],SRest)==0) // the vertex is not the root
4337                                    // of a redundant subtree
4338        {
4339          VV[1]=SRest;
4340          VV[2]=3;
4341          VV[3]=V[3]+2;
4342          VV[4]=V[4];      // the tester did not change
4343          VV[5]=ideal(0);
4344          WI=list();
4345          for(i=1;i<=size(QQ);i++)
4346          {
4347            WI=insert(WI,list(QQ[i][2],QQ[i][4]));
4348          }
4349          VV[6]=WI;
4350          W=insert(W,VV,size(W));
4351        }
4352      }
4353    }
4354  }
4355}
4356
4357//////////////////////////////////////////////////////////////////////////
4358// proc pseudo_prim_dec_charsets
4359// input: Generators of an arbitrary ideal I, a standard basis SI of I,
4360// and an integer choo
4361// If choo=0, min_ass_prim_charsets with the given
4362// ordering of the variables is used.
4363// If choo=1, min_ass_prim_charsets with the "optimized"
4364// ordering of the variables is used.
4365// If choo=2, minAssPrimes from primdec.lib is used
4366// If choo=3, minAssPrimes+factorizing Buchberger from primdec.lib is used
4367// output: a pseudo primary decomposition of I, i.e., a list
4368// of pseudo primary components together with a standard basis of the
4369// remaining component. Each pseudo primary component is
4370// represented by a quadrupel: A standard basis of the component,
4371// a standard basis of the corresponding associated prime, the
4372// seperator of the component, and the irreducible factors of the
4373// "minimal divisor" of the seperator as computed by the procedure minsat,
4374// calls  proc pseudo_prim_dec_i
4375//////////////////////////////////////////////////////////////////////////
4376
4377
4378static proc pseudo_prim_dec_charsets (ideal I, ideal SI, int choo)
4379{
4380  list L;          // The list of minimal associated primes,
4381                   // each one given by a standard basis
4382  if((choo==0) or (choo==1))
4383    {
4384       L=min_ass_prim_charsets(I,choo);
4385    }
4386  else
4387    {
4388      if(choo==2)
4389      {
4390        L=minAssPrimes(I);
4391      }
4392      else
4393      {
4394        L=minAssPrimes(I,1);
4395      }
4396      for(int i=size(L);i>=1;i=i-1)
4397        {
4398          L[i]=std(L[i]);
4399        }
4400    }
4401  return (pseudo_prim_dec_i(SI,L));
4402}
4403
4404////////////////////////////////////////////////////////////////
4405// proc pseudo_prim_dec_special_charsets
4406// input: a standard basis of an ideal I whose radical is the
4407// intersection of the radicals of ideals generated by one prime ideal
4408// P_i together with one polynomial f_i, the list V6 must be the list of
4409// pairs (standard basis of P_i, irreducible factors of f_i),
4410// and an integer choo
4411// If choo=0, min_ass_prim_charsets with the given
4412// ordering of the variables is used.
4413// If choo=1, min_ass_prim_charsets with the "optimized"
4414// ordering of the variables is used.
4415// If choo=2, minAssPrimes from primdec.lib is used
4416// If choo=3, minAssPrimes+factorizing Buchberger from primdec.lib is used
4417// output: a pseudo primary decomposition of I, i.e., a list
4418// of pseudo primary components together with a standard basis of the
4419// remaining component. Each pseudo primary component is
4420// represented by a quadrupel: A standard basis of the component,
4421// a standard basis of the corresponding associated prime, the
4422// seperator of the component, and the irreducible factors of the
4423// "minimal divisor" of the seperator as computed by the procedure minsat,
4424// calls  proc pseudo_prim_dec_i
4425////////////////////////////////////////////////////////////////
4426
4427
4428static proc pseudo_prim_dec_special_charsets (ideal SI,list V6, int choo)
4429{
4430  int i,j,l;
4431  list m;
4432  list L;
4433  int sizeL;
4434  ideal P,SP; ideal fac;
4435  int dimSP;
4436  for(l=size(V6);l>=1;l--)   // creates a list of associated primes
4437                             // of I, possibly redundant
4438  {
4439    P=V6[l][1];
4440    fac=V6[l][2];
4441    for(i=ncols(fac);i>=1;i--)
4442    {
4443      SP=P+fac[i];
4444      SP=std(SP);
4445      if(SP[1]!=1)
4446      {
4447        if((choo==0) or (choo==1))
4448        {
4449          m=min_ass_prim_charsets(SP,choo);  // a list of SB
4450        }
4451        else
4452        {
4453          if(choo==2)
4454          {
4455            m=minAssPrimes(SP);
4456          }
4457          else
4458          {
4459            m=minAssPrimes(SP,1);
4460          }
4461          for(j=size(m);j>=1;j=j-1)
4462            {
4463              m[j]=std(m[j]);
4464            }
4465        }
4466        dimSP=dim(SP);
4467        for(j=size(m);j>=1; j--)
4468        {
4469          if(dim(m[j])==dimSP)
4470          {
4471            L=insert(L,m[j],size(L));
4472          }
4473        }
4474      }
4475    }
4476  }
4477  sizeL=size(L);
4478  for(i=1;i<sizeL;i++)     // get rid of redundant primes
4479  {
4480    for(j=i+1;j<=sizeL;j++)
4481    {
4482      if(size(L[i])!=0)
4483      {
4484        if(size(L[j])!=0)
4485        {
4486          if(size(NF(L[i],L[j],1))==0)
4487          {
4488            L[j]=ideal(0);
4489          }
4490          else
4491          {
4492            if(size(NF(L[j],L[i],1))==0)
4493            {
4494              L[i]=ideal(0);
4495            }
4496          }
4497        }
4498      }
4499    }
4500  }
4501  for(i=sizeL;i>=1;i--)
4502  {
4503    if(size(L[i])==0)
4504    {
4505      L=delete(L,i);
4506    }
4507  }
4508  return (pseudo_prim_dec_i(SI,L));
4509}
4510
4511
4512////////////////////////////////////////////////////////////////
4513// proc pseudo_prim_dec_i
4514// input: A standard basis of an arbitrary ideal I, and standard bases
4515// of the minimal associated primes of I
4516// output: a pseudo primary decomposition of I, i.e., a list
4517// of pseudo primary components together with a standard basis of the
4518// remaining component. Each pseudo primary component is
4519// represented by a quadrupel: A standard basis of the component Q_i,
4520// a standard basis of the corresponding associated prime P_i, the
4521// seperator of the component, and the irreducible factors of the
4522// "minimal divisor" of the seperator as computed by the procedure minsat,
4523////////////////////////////////////////////////////////////////
4524
4525
4526static proc pseudo_prim_dec_i (ideal SI, list L)
4527{
4528  list Q;
4529  if (size(L)==1)               // one minimal associated prime only
4530                                // the ideal is already pseudo primary
4531  {
4532    Q=SI,L[1],1;
4533    list QQ;
4534    QQ[1]=Q;
4535    return (QQ,ideal(1));
4536  }
4537
4538  poly f0,f,g;
4539  ideal fac;
4540  int i,j,k,l;
4541  ideal SQi;
4542  ideal I'=SI;
4543  list QP;
4544  int sizeL=size(L);
4545  for(i=1;i<=sizeL;i++)
4546  {
4547    fac=0;
4548    for(j=1;j<=sizeL;j++)           // compute the seperator sep_i
4549                                    // of the i-th component
4550    {
4551      if (i!=j)                       // search g not in L[i], but L[j]
4552      {
4553        for(k=1;k<=ncols(L[j]);k++)
4554        {
4555          if(NF(L[j][k],L[i],1)!=0)
4556          {
4557            break;
4558          }
4559        }
4560        fac=fac+L[j][k];
4561      }
4562    }
4563    // delete superfluous polynomials
4564    fac=simplify(fac,8);
4565    // saturation
4566    SQi,f0,f,fac=minsat_ppd(SI,fac);
4567    I'=I',f;
4568    QP=SQi,L[i],f0,fac;
4569             // the quadrupel:
4570             // a standard basis of Q_i,
4571             // a standard basis of P_i,
4572             // sep_i,
4573             // irreducible factors of
4574             // the "minimal divisor" of the seperator
4575             //  as computed by the procedure minsat,
4576    Q[i]=QP;
4577  }
4578  I'=std(I');
4579  return (Q, I');
4580                   // I' = remaining component
4581}
4582
4583
4584////////////////////////////////////////////////////////////////
4585// proc extraction
4586// input: A standard basis of a pseudo primary ideal I, and a standard
4587// basis of the unique minimal associated prime P of I
4588// output: an extraction of I, i.e., a standard basis of the primary
4589// component Q of I with associated prime P, a standard basis of the
4590// remaining component, and the irreducible factors of the
4591// "minimal divisor" of the extractor as computed by the procedure minsat
4592////////////////////////////////////////////////////////////////
4593
4594
4595static proc extraction (ideal SI, ideal SP)
4596{
4597  list indsets=indepSet(SP,0);
4598  poly f;
4599  if(size(indsets)!=0)      //check, whether dim P != 0
4600  {
4601    intvec v;               // a maximal independent set of variables
4602                            // modulo P
4603    string U;               // the independent variables
4604    string A;               // the dependent variables
4605    int j,k;
4606    int a;                  //  the size of A
4607    int degf;
4608    ideal g;
4609    list polys;
4610    int sizepolys;
4611    list newpoly;
4612    def R=basering;
4613    //intvec hv=hilb(SI,1);
4614    for (k=1;k<=size(indsets);k++)
4615    {
4616      v=indsets[k];
4617      for (j=1;j<=nvars(R);j++)
4618      {
4619        if (v[j]==1)
4620        {
4621          U=U+varstr(j)+",";
4622        }
4623        else
4624        {
4625          A=A+varstr(j)+",";
4626          a++;
4627        }
4628      }
4629
4630      U[size(U)]=")";           // we compute the extractor of I (w.r.t. U)
4631      execute("ring RAU=("+charstr(basering)+"),("+A+U+",(dp("+string(a)+"),dp);");
4632      ideal I=imap(R,SI);
4633      //I=std(I,hv);            // the standard basis in (R[U])[A]
4634      I=std(I);            // the standard basis in (R[U])[A]
4635      A[size(A)]=")";
4636      execute("ring Rloc=("+charstr(basering)+","+U+",("+A+",dp;");
4637      ideal I=imap(RAU,I);
4638      //"std in lokalisierung:"+newline,I;
4639      ideal h;
4640      for(j=ncols(I);j>=1;j--)
4641      {
4642        h[j]=leadcoef(I[j]);  // consider I in (R(U))[A]
4643      }
4644      setring R;
4645      g=imap(Rloc,h);
4646      kill RAU,Rloc;
4647      U="";
4648      A="";
4649      a=0;
4650      f=lcm(g);
4651      newpoly[1]=f;
4652      polys=polys+newpoly;
4653      newpoly=list();
4654    }
4655    f=polys[1];
4656    degf=deg(f);
4657    sizepolys=size(polys);
4658    for (k=2;k<=sizepolys;k++)
4659    {
4660      if (deg(polys[k])<degf)
4661      {
4662        f=polys[k];
4663        degf=deg(f);
4664      }
4665    }
4666  }
4667  else
4668  {
4669    f=1;
4670  }
4671  poly f0,h0; ideal SQ; ideal fac;
4672  if(f!=1)
4673  {
4674    SQ,f0,h0,fac=minsat(SI,f);
4675    return(SQ,std(SI+h0),fac);
4676             // the tripel
4677             // a standard basis of Q,
4678             // a standard basis of remaining component,
4679             // irreducible factors of
4680             // the "minimal divisor" of the extractor
4681             // as computed by the procedure minsat
4682  }
4683  else
4684  {
4685    return(SI,ideal(1),ideal(1));
4686  }
4687}
4688
4689/////////////////////////////////////////////////////
4690// proc minsat
4691// input:  a standard basis of an ideal I and a polynomial p
4692// output: a standard basis IS of the saturation of I w.r. to p,
4693// the maximal squarefree factor f0 of p,
4694// the "minimal divisor" f of f0 such that the saturation of
4695// I w.r. to f equals the saturation of I w.r. to f0 (which is IS),
4696// the irreducible factors of f
4697//////////////////////////////////////////////////////////
4698
4699
4700static proc minsat(ideal SI, poly p)
4701{
4702  ideal fac=factorize(p,1);       //the irreducible factors of p
4703  fac=sort(fac)[1];
4704  int i,k;
4705  poly f0=1;
4706  for(i=ncols(fac);i>=1;i--)
4707  {
4708    f0=f0*fac[i];
4709  }
4710  poly f=1;
4711  ideal iold;
4712  list quotM;
4713  quotM[1]=SI;
4714  quotM[2]=fac;
4715  quotM[3]=f0;
4716  // we deal seperately with the first quotient;
4717  // factors, which do not contribute to this one,
4718  // are omitted
4719  iold=quotM[1];
4720  quotM=minquot(quotM);
4721  fac=quotM[2];
4722  if(quotM[3]==1)
4723    {
4724      return(quotM[1],f0,f,fac);
4725    }
4726  while(special_ideals_equal(iold,quotM[1])==0)
4727    {
4728      f=f*quotM[3];
4729      iold=quotM[1];
4730      quotM=minquot(quotM);
4731    }
4732  return(quotM[1],f0,f,fac);           // the quadrupel ((I:p),f0,f, irr. factors of f)
4733}
4734
4735/////////////////////////////////////////////////////
4736// proc minsat_ppd
4737// input:  a standard basis of an ideal I and a polynomial p
4738// output: a standard basis IS of the saturation of I w.r. to p,
4739// the maximal squarefree factor f0 of p,
4740// the "minimal divisor" f of f0 such that the saturation of
4741// I w.r. to f equals the saturation of I w.r. to f0 (which is IS),
4742// the irreducible factors of f
4743//////////////////////////////////////////////////////////
4744
4745
4746static proc minsat_ppd(ideal SI, ideal fac)
4747{
4748  fac=sort(fac)[1];
4749  int i,k;
4750  poly f0=1;
4751  for(i=ncols(fac);i>=1;i--)
4752  {
4753    f0=f0*fac[i];
4754  }
4755  poly f=1;
4756  ideal iold;
4757  list quotM;
4758  quotM[1]=SI;
4759  quotM[2]=fac;
4760  quotM[3]=f0;
4761  // we deal seperately with the first quotient;
4762  // factors, which do not contribute to this one,
4763  // are omitted
4764  iold=quotM[1];
4765  quotM=minquot(quotM);
4766  fac=quotM[2];
4767  if(quotM[3]==1)
4768    {
4769      return(quotM[1],f0,f,fac);
4770    }
4771  while(special_ideals_equal(iold,quotM[1])==0)
4772  {
4773    f=f*quotM[3];
4774    iold=quotM[1];
4775    quotM=minquot(quotM);
4776    k++;
4777  }
4778  return(quotM[1],f0,f,fac);           // the quadrupel ((I:p),f0,f, irr. factors of f)
4779}
4780/////////////////////////////////////////////////////////////////
4781// proc minquot
4782// input: a list with 3 components: a standard basis
4783// of an ideal I, a set of irreducible polynomials, and
4784// there product f0
4785// output: a standard basis of the ideal (I:f0), the irreducible
4786// factors of the "minimal divisor" f of f0 with (I:f0) = (I:f),
4787// the "minimal divisor" f
4788/////////////////////////////////////////////////////////////////
4789
4790static proc minquot(list tsil)
4791{
4792   intvec op;
4793   int i,j,k,action;
4794   ideal verg;
4795   list l;
4796   poly g;
4797   ideal laedi=tsil[1];
4798   ideal fac=tsil[2];
4799   poly f=tsil[3];
4800
4801//std
4802//   ideal star=quotient(laedi,f);
4803//   star=std(star);
4804   op=option(get);
4805   option(returnSB);
4806   ideal star=quotient(laedi,f);
4807   option(set,op);
4808   if(special_ideals_equal(laedi,star)==1)
4809     {
4810       return(laedi,ideal(1),1);
4811     }
4812   action=1;
4813   while(action==1)
4814   {
4815      if(size(fac)==1)
4816      {
4817         action=0;
4818         break;
4819      }
4820      for(i=1;i<=size(fac);i++)
4821      {
4822        g=1;
4823         for(j=1;j<=size(fac);j++)
4824         {
4825            if(i!=j)
4826            {
4827               g=g*fac[j];
4828            }
4829         }
4830//std
4831//         verg=quotient(laedi,g);
4832//         verg=std(verg);
4833         op=option(get);
4834         option(returnSB);
4835         verg=quotient(laedi,g);
4836         option(set,op);
4837         if(special_ideals_equal(verg,star)==1)
4838         {
4839            f=g;
4840            fac[i]=0;
4841            fac=simplify(fac,2);
4842            break;
4843         }
4844         if(i==size(fac))
4845         {
4846            action=0;
4847         }
4848      }
4849   }
4850   l=star,fac,f;
4851   return(l);
4852}
4853/////////////////////////////////////////////////
4854// proc special_ideals_equal
4855// input: standard bases of ideal k1 and k2 such that
4856// k1 is contained in k2, or k2 is contained ink1
4857// output: 1, if k1 equals k2, 0 otherwise
4858//////////////////////////////////////////////////
4859
4860static proc special_ideals_equal( ideal k1, ideal k2)
4861{
4862   int j;
4863   if(size(k1)==size(k2))
4864   {
4865      for(j=1;j<=size(k1);j++)
4866      {
4867         if(leadexp(k1[j])!=leadexp(k2[j]))
4868         {
4869            return(0);
4870         }
4871      }
4872      return(1);
4873   }
4874   return(0);
4875}
4876
4877
4878///////////////////////////////////////////////////////////////////////////////
4879
4880static proc convList(list l)
4881{
4882   int i;
4883   list re,he;
4884   for(i=1;i<=size(l)/2;i++)
4885   {
4886      he=l[2*i-1],l[2*i];
4887      re[i]=he;
4888   }
4889   return(re);
4890}
4891///////////////////////////////////////////////////////////////////////////////
4892
4893static proc reconvList(list l)
4894{
4895   int i;
4896   list re;
4897   for(i=1;i<=size(l);i++)
4898   {
4899      re[2*i-1]=l[i][1];
4900      re[2*i]=l[i][2];
4901   }
4902   return(re);
4903}
4904
4905///////////////////////////////////////////////////////////////////////////////
4906//
4907//     The main procedures
4908//
4909///////////////////////////////////////////////////////////////////////////////
4910
4911proc primdecGTZ(ideal i)
4912"USAGE:   primdecGTZ(i); i ideal
4913RETURN:  a list pr of primary ideals and their associated primes:
4914@format
4915   pr[i][1]   the i-th primary component,
4916   pr[i][2]   the i-th prime component.
4917@end format
4918NOTE:    Algorithm of Gianni/Trager/Zacharias.
4919         Designed for characteristic 0, works also in char k > 0, if it
4920         terminates (may result in an infinite loop in small characteristic!)
4921EXAMPLE: example primdecGTZ; shows an example
4922"
4923{
4924   if(ord_test(basering)!=1)
4925   {
4926      ERROR(
4927      "// Not implemented for this ordering, please change to global ordering."
4928      );
4929   }
4930   if(minpoly!=0)
4931   {
4932      return(algeDeco(i,0));
4933      ERROR(
4934      "// Not implemented yet for algebraic extensions.Simulate the ring extension by adding the minpoly to the ideal"
4935      );
4936   }
4937  return(convList(decomp(i)));
4938}
4939example
4940{ "EXAMPLE:";  echo = 2;
4941   ring  r = 0,(x,y,z),lp;
4942   poly  p = z2+1;
4943   poly  q = z3+2;
4944   ideal i = p*q^2,y-z2;
4945   list pr = primdecGTZ(i);
4946   pr;
4947}
4948///////////////////////////////////////////////////////////////////////////////
4949
4950proc primdecSY(ideal i, list #)
4951"USAGE:   primdecSY(i); i ideal, c int
4952RETURN:  a list pr of primary ideals and their associated primes:
4953@format
4954   pr[i][1]   the i-th primary component,
4955   pr[i][2]   the i-th prime component.
4956@end format
4957NOTE:    Algorithm of Shimoyama/Yokoyama.
4958@format
4959   if c=0,  the given ordering of the variables is used,
4960   if c=1,  minAssChar tries to use an optimal ordering,
4961   if c=2,  minAssGTZ is used,
4962   if c=3,  minAssGTZ and facstd are used.
4963@end format
4964EXAMPLE: example primdecSY; shows an example
4965"
4966{
4967   if(ord_test(basering)!=1)
4968   {
4969      ERROR(
4970      "// Not implemented for this ordering, please change to global ordering."
4971      );
4972   }
4973   i=simplify(i,2);
4974   if ((i[1]==0)||(i[1]==1))
4975   {
4976     list L=list(ideal(i[1]),ideal(i[1]));
4977     return(list(L));
4978   }
4979   if(minpoly!=0)
4980   {
4981      return(algeDeco(i,1));
4982   }
4983   if (size(#)==1)
4984   { return(prim_dec(i,#[1])); }
4985   else
4986   { return(prim_dec(i,1)); }
4987}
4988example
4989{ "EXAMPLE:";  echo = 2;
4990   ring  r = 0,(x,y,z),lp;
4991   poly  p = z2+1;
4992   poly  q = z3+2;
4993   ideal i = p*q^2,y-z2;
4994   list pr = primdecSY(i);
4995   pr;
4996}
4997///////////////////////////////////////////////////////////////////////////////
4998proc minAssGTZ(ideal i,list #)
4999"USAGE:   minAssGTZ(i); i ideal
5000          minAssGTZ(i,1); i ideal  does not use the factorizing Groebner
5001RETURN:  a list, the minimal associated prime ideals of i.
5002NOTE:    Designed for characteristic 0, works also in char k > 0 based
5003         on an algorithm of Yokoyama
5004EXAMPLE: example minAssGTZ; shows an example
5005"
5006{
5007   if(ord_test(basering)!=1)
5008   {
5009      ERROR(
5010      "// Not implemented for this ordering, please change to global ordering."
5011      );
5012   }
5013   if(minpoly!=0)
5014   {
5015      return(algeDeco(i,2));
5016      ERROR(
5017      "// Not implemented for algebraic extensions. Simulate the ring extension by adding the minpoly to the ideal"
5018      );
5019   }
5020  if(size(#)==0)
5021   {
5022      return(minAssPrimes(i,1));
5023   }
5024   return(minAssPrimes(i));
5025}
5026example
5027{ "EXAMPLE:";  echo = 2;
5028   ring  r = 0,(x,y,z),dp;
5029   poly  p = z2+1;
5030   poly  q = z3+2;
5031   ideal i = p*q^2,y-z2;
5032   list pr = minAssGTZ(i);
5033   pr;
5034}
5035
5036///////////////////////////////////////////////////////////////////////////////
5037proc minAssChar(ideal i, list #)
5038"USAGE:   minAssChar(i[,c]); i ideal, c int.
5039RETURN:  list, the minimal associated prime ideals of i.
5040NOTE:    If c=0, the given ordering of the variables is used. @*
5041         Otherwise, the system tries to find an optimal ordering,
5042         which in some cases may considerably speed up the algorithm. @*
5043         Due to a bug in the factorization, the result may be not completely
5044         decomposed in small characteristic.
5045EXAMPLE: example minAssChar; shows an example
5046"
5047{
5048   if(ord_test(basering)!=1)
5049   {
5050      ERROR(
5051      "// Not implemented for this ordering, please change to global ordering."
5052      );
5053   }
5054   if (size(#)==1)
5055   { return(min_ass_prim_charsets(i,#[1])); }
5056   else
5057   { return(min_ass_prim_charsets(i,1)); }
5058}
5059example
5060{ "EXAMPLE:";  echo = 2;
5061   ring  r = 0,(x,y,z),dp;
5062   poly  p = z2+1;
5063   poly  q = z3+2;
5064   ideal i = p*q^2,y-z2;
5065   list pr = minAssChar(i);
5066   pr;
5067}
5068///////////////////////////////////////////////////////////////////////////////
5069proc equiRadical(ideal i)
5070"USAGE:   equiRadical(i); i ideal
5071RETURN:  ideal, intersection of associated primes of i of maximal dimension.
5072NOTE:    A combination of the algorithms of Krick/Logar and Kemper is used.
5073         Works also in positive characteristic (Kempers algorithm).
5074EXAMPLE: example equiRadical; shows an example
5075"
5076{
5077   if(ord_test(basering)!=1)
5078   {
5079      ERROR(
5080      "// Not implemented for this ordering, please change to global ordering."
5081      );
5082   }
5083   return(radical(i,1));
5084}
5085example
5086{ "EXAMPLE:";  echo = 2;
5087   ring  r = 0,(x,y,z),dp;
5088   poly  p = z2+1;
5089   poly  q = z3+2;
5090   ideal i = p*q^2,y-z2;
5091   ideal pr= equiRadical(i);
5092   pr;
5093}
5094///////////////////////////////////////////////////////////////////////////////
5095proc radical(ideal i,list #)
5096"USAGE:   radical(i); i ideal.
5097RETURN:  ideal, the radical of i.
5098NOTE:    A combination of the algorithms of Krick/Logar and Kemper is used.
5099         Works also in positive characteristic (Kempers algorithm).
5100EXAMPLE: example radical; shows an example
5101"
5102{
5103   if(ord_test(basering)!=1)
5104   {
5105      ERROR(
5106      "// Not implemented for this ordering, please change to global ordering."
5107      );
5108   }
5109   def @P=basering;
5110   int j,il;
5111   if(size(#)>0){il=#[1];}
5112   if(size(i)==0){return(ideal(0));}
5113   ideal re=1;
5114   intvec op = option(get);
5115   list qr=simplifyIdeal(i);
5116   map phi=@P,qr[2];
5117
5118   option(redSB);
5119   i=groebner(qr[1]);
5120   option(set,op);
5121   int di=dim(i);
5122
5123   if(di==0)
5124   {
5125     i=zeroRad(i,qr[1]);
5126     return(interred(phi(i)));
5127   }
5128
5129   option(redSB);
5130   list pr=i;
5131   if (!homog(i))
5132   {
5133     pr=facstd(i);
5134   }
5135   option(set,op);
5136   int s=size(pr);
5137
5138   for(j=1;j<=s;j++)
5139   {
5140      attrib(pr[s+1-j],"isSB",1);
5141      if((size(reduce(re,pr[s+1-j],1))!=0)&&((dim(pr[s+1-j])==di)||!il))
5142      {
5143         re=intersect(re,radicalKL(pr[s+1-j],re,il));
5144      }
5145   }
5146   return(interred(phi(re)));
5147}
5148example
5149{ "EXAMPLE:";  echo = 2;
5150   ring  r = 0,(x,y,z),dp;
5151   poly  p = z2+1;
5152   poly  q = z3+2;
5153   ideal i = p*q^2,y-z2;
5154   ideal pr= radical(i);
5155   pr;
5156}
5157///////////////////////////////////////////////////////////////////////////////
5158proc prepareAss(ideal i)
5159"USAGE:   prepareAss(i); i ideal
5160RETURN:  list, the radicals of the maximal dimensional components of i.
5161NOTE:    Uses algorithm of Eisenbud/Huneke/Vasconcelos.
5162EXAMPLE: example prepareAss; shows an example
5163"
5164{
5165  if(ord_test(basering)!=1)
5166  {
5167      ERROR(
5168      "// Not implemented for this ordering, please change to global ordering."
5169      );
5170  }
5171  ideal j=std(i);
5172  int cod=nvars(basering)-dim(j);
5173  int e;
5174  list er;
5175  ideal ann;
5176  if(homog(i)==1)
5177  {
5178     list re=sres(j,0);                   //the resolution
5179     re=minres(re);                       //minimized resolution
5180  }
5181  else
5182  {
5183    list re=mres(i,0);
5184  }
5185  for(e=cod;e<=nvars(basering);e++)
5186  {
5187     ann=AnnExt_R(e,re);
5188
5189     if(nvars(basering)-dim(std(ann))==e)
5190     {
5191        er[size(er)+1]=equiRadical(ann);
5192     }
5193  }
5194  return(er);
5195}
5196example
5197{ "EXAMPLE:";  echo = 2;
5198   ring  r = 0,(x,y,z),dp;
5199   poly  p = z2+1;
5200   poly  q = z3+2;
5201   ideal i = p*q^2,y-z2;
5202   list pr = prepareAss(i);
5203   pr;
5204}
5205///////////////////////////////////////////////////////////////////////////////
5206proc equidimMaxEHV(ideal i)
5207"USAGE:  equidimMaxEHV(i); i ideal
5208RETURN:  ideal, the equidimensional component (of maximal dimension) of i.
5209NOTE:    Uses algorithm of Eisenbud, Huneke and Vasconcelos.
5210EXAMPLE: example equidimMaxEHV; shows an example
5211"
5212{
5213  if(ord_test(basering)!=1)
5214  {
5215      ERROR(
5216      "// Not implemented for this ordering, please change to global ordering."
5217      );
5218  }
5219  ideal j=groebner(i);
5220  int cod=nvars(basering)-dim(j);
5221  int e;
5222  ideal ann;
5223  if(homog(i)==1)
5224  {
5225     list re=sres(j,0);                   //the resolution
5226     re=minres(re);                       //minimized resolution
5227  }
5228  else
5229  {
5230    list re=mres(i,0);
5231  }
5232  ann=AnnExt_R(cod,re);
5233  return(ann);
5234}
5235example
5236{ "EXAMPLE:";  echo = 2;
5237   ring  r = 0,(x,y,z),dp;
5238   ideal i=intersect(ideal(z),ideal(x,y),ideal(x2,z2),ideal(x5,y5,z5));
5239   equidimMaxEHV(i);
5240}
5241
5242proc testPrimary(list pr, ideal k)
5243"USAGE:   testPrimary(pr,k); pr a list, k an ideal.
5244ASSUME:  pr is the result of primdecGTZ(k) or primdecSY(k).
5245RETURN:  int, 1 if the intersection of the ideals in pr is k, 0 if not
5246EXAMPLE: example testPrimary; shows an example
5247"
5248{
5249   int i;
5250   pr=reconvList(pr);
5251   ideal j=pr[1];
5252   for (i=2;i<=size(pr)/2;i++)
5253   {
5254       j=intersect(j,pr[2*i-1]);
5255   }
5256   return(idealsEqual(j,k));
5257}
5258example
5259{ "EXAMPLE:";  echo = 2;
5260   ring  r = 32003,(x,y,z),dp;
5261   poly  p = z2+1;
5262   poly  q = z4+2;
5263   ideal i = p^2*q^3,(y-z3)^3,(x-yz+z4)^4;
5264   list pr = primdecGTZ(i);
5265   testPrimary(pr,i);
5266}
5267
5268///////////////////////////////////////////////////////////////////////////////
5269proc zerodec(ideal I)
5270"USAGE:   zerodec(I); I ideal
5271ASSUME:  I is zero-dimensional, the characteristic of the ground field is 0
5272RETURN:  list of primary ideals, the zero-dimensional decomposition of I
5273NOTE:    The algorithm (of Monico), works well only for a small total number
5274         of solutions (@code{vdim(std(I))} should be < 100) and without
5275         parameters. In practice, it works also in large characteristic p>0
5276         but may fail for small p.
5277@*       If printlevel > 0 (default = 0) additional information is displayed.
5278EXAMPLE: example zerodec; shows an example
5279"
5280{
5281   if(ord_test(basering)!=1)
5282   {
5283      ERROR(
5284      "// Not implemented for this ordering, please change to global ordering."
5285      );
5286   }
5287   def R=basering;
5288   poly q;
5289   int j,time;
5290   matrix m;
5291   list re;
5292   poly va=var(1);
5293   ideal J=groebner(I);
5294   ideal ba=kbase(J);
5295   int d=vdim(J);
5296   dbprint(printlevel-voice+2,"// multiplicity of ideal : "+ string(d));
5297//------ compute matrix of multiplication on R/I with generic element p -----
5298   int e=nvars(basering);
5299   poly p=randomLast(100)[e]+random(-50,50);     //the generic element
5300   matrix n[d][d];
5301   time = timer;
5302   for(j=2;j<=e;j++)
5303   {
5304      va=va*var(j);
5305   }
5306   for(j=1;j<=d;j++)
5307   {
5308      q=reduce(p*ba[j],J);
5309      m=coeffs(q,ba,va);
5310      n[j,1..d]=m[1..d,1];
5311   }
5312   dbprint(printlevel-voice+2,
5313      "// time for computing multiplication matrix (with generic element) : "+
5314      string(timer-time));
5315//---------------- compute characteristic polynomial of matrix --------------
5316   execute("ring P1=("+charstr(R)+"),T,dp;");
5317   matrix n=imap(R,n);
5318   time = timer;
5319   poly charpol=det(n-T*freemodule(d));
5320   dbprint(printlevel-voice+2,"// time for computing char poly: "+
5321           string(timer-time));
5322//------------------- factorize characteristic polynomial -------------------
5323//check first if constant term of charpoly is != 0 (which is true for
5324//sufficiently generic element)
5325   if(charpol[size(charpol)]!=0)
5326   {
5327     time = timer;
5328     list fac=factor(charpol);
5329     testFactor(fac,charpol);
5330     dbprint(printlevel-voice+2,"// time for factorizing char poly: "+
5331             string(timer-time));
5332     int f=size(fac[1]);
5333//--------------------------- the irreducible case --------------------------
5334     if(f==1)
5335     {
5336       setring R;
5337       re=I;
5338       return(re);
5339     }
5340//---------------------------- the reducible case ---------------------------
5341//if f_i are the irreducible factors of charpoly, mult=ri, then <I,g_i^ri>
5342//are the primary components where g_i = f_i(p). However, substituting p in
5343//f_i may result in a huge object although the final result may be small.
5344//Hence it is better to simultaneously reduce with I. For this we need a new
5345//ring.
5346     execute("ring P=("+charstr(R)+"),(T,"+varstr(R)+"),(dp(1),dp);");
5347     list rfac=imap(P1,fac);
5348     intvec ov=option(get);;
5349     option(redSB);
5350     list re1;
5351     ideal new = T-imap(R,p),imap(R,J);
5352     attrib(new, "isSB",1);    //we know that new is a standard basis
5353     for(j=1;j<=f;j++)
5354     {
5355        re1[j]=reduce(rfac[1][j]^rfac[2][j],new);
5356     }
5357     setring R;
5358     re = imap(P,re1);
5359     for(j=1;j<=f;j++)
5360     {
5361        J=I,re[j];
5362        re[j]=interred(J);
5363     }
5364     option(set,ov);
5365     return(re);
5366  }
5367  else
5368//------------------- choice of generic element failed -------------------
5369  {
5370     dbprint(printlevel-voice+2,"// try new generic element!");
5371     setring R;
5372     return(zerodec(I));
5373  }
5374}
5375example
5376{ "EXAMPLE:";  echo = 2;
5377   ring r  = 0,(x,y),dp;
5378   ideal i = x2-2,y2-2;
5379   list pr = zerodec(i);
5380   pr;
5381}
5382////////////////////////////////////////////////////////////////////////////
5383/*
5384//Beispiele Wenk-Dipl (in ~/Texfiles/Diplom/Wenk/Examples/)
5385//Zeiten: Singular/Singular/Singular -r123456789 -v :wilde13 (PentiumPro200)
5386//Singular for HPUX-9 version 1-3-8  (2000060214)  Jun  2 2000 15:31:26
5387//(wilde13)
5388
5389//1. vdim=20, 3  Komponenten
5390//zerodec-time:2(1)  (matrix:1 charpoly:0 factor:1)
5391//primdecGTZ-time: 1(0)
5392ring rs= 0,(a,b,c),dp;
5393poly f1= a^2*b*c + a*b^2*c + a*b*c^2 + a*b*c + a*b + a*c + b*c;
5394poly f2= a^2*b^2*c + a*b^2*c^2 + a^2*b*c + a*b*c + b*c + a + c;
5395poly f3= a^2*b^2*c^2 + a^2*b^2*c + a*b^2*c + a*b*c + a*c + c + 1;
5396ideal gls=f1,f2,f3;
5397int time=timer;
5398printlevel =1;
5399time=timer; list pr1=zerodec(gls); timer-time;size(pr1);
5400time=timer; list pr =primdecGTZ(gls); timer-time;size(pr);
5401time=timer; ideal ra =radical(gls); timer-time;size(pr);
5402
5403//2.cyclic5  vdim=70, 20 Komponenten
5404//zerodec-time:36(28)  (matrix:1(0) charpoly:18(19) factor:17(9)
5405//primdecGTZ-time: 28(5)
5406//radical : 0
5407ring rs= 0,(a,b,c,d,e),dp;
5408poly f0= a + b + c + d + e + 1;
5409poly f1= a + b + c + d + e;
5410poly f2= a*b + b*c + c*d + a*e + d*e;
5411poly f3= a*b*c + b*c*d + a*b*e + a*d*e + c*d*e;
5412poly f4= a*b*c*d + a*b*c*e + a*b*d*e + a*c*d*e + b*c*d*e;
5413poly f5= a*b*c*d*e - 1;
5414ideal gls= f1,f2,f3,f4,f5;
5415
5416//3. random vdim=40, 1 Komponente
5417//zerodec-time:126(304)  (matrix:1 charpoly:115(298) factor:10(5))
5418//primdecGTZ-time:17 (11)
5419ring rs=0,(x,y,z),dp;
5420poly f1=2*x^2 + 4*x + 3*y^2 + 7*x*z + 9*y*z + 5*z^2;
5421poly f2=7*x^3 + 8*x*y + 12*y^2 + 18*x*z + 3*y^4*z + 10*z^3 + 12;
5422poly f3=3*x^4 + 1*x*y*z + 6*y^3 + 3*x*z^2 + 2*y*z^2 + 4*z^2 + 5;
5423ideal gls=f1,f2,f3;
5424
5425//4. introduction into resultants, sturmfels, vdim=28, 1 Komponente
5426//zerodec-time:4  (matrix:0 charpoly:0 factor:4)
5427//primdecGTZ-time:1
5428ring rs=0,(x,y),dp;
5429poly f1= x4+y4-1;
5430poly f2= x5y2-4x3y3+x2y5-1;
5431ideal gls=f1,f2;
5432
5433//5. 3 quadratic equations with random coeffs, vdim=8, 1 Komponente
5434//zerodec-time:0(0)  (matrix:0 charpoly:0 factor:0)
5435//primdecGTZ-time:1(0)
5436ring rs=0,(x,y,z),dp;
5437poly f1=2*x^2 + 4*x*y + 3*y^2 + 7*x*z + 9*y*z + 5*z^2 + 2;
5438poly f2=7*x^2 + 8*x*y + 12*y^2 + 18*x*z + 3*y*z + 10*z^2 + 12;
5439poly f3=3*x^2 + 1*x*y + 6*y^2 + 3*x*z + 2*y*z + 4*z^2 + 5;
5440ideal gls=f1,f2,f3;
5441
5442//6. 3 polys    vdim=24, 1 Komponente
5443// run("ex14",2);
5444//zerodec-time:5(4)  (matrix:0 charpoly:3(3) factor:2(1))
5445//primdecGTZ-time:4 (2)
5446ring rs=0,(x1,x2,x3,x4),dp;
5447poly f1=16*x1^2 + 3*x2^2 + 5*x3^4 - 1 - 4*x4 + x4^3;
5448poly f2=5*x1^3 + 3*x2^2 + 4*x3^2*x4 + 2*x1*x4 - 1 + x4 + 4*x1 + x2 + x3 + x4;
5449poly f3=-4*x1^2 + x2^2 + x3^2 - 3 + x4^2 + 4*x1 + x2 + x3 + x4;
5450poly f4=-4*x1 + x2 + x3 + x4;
5451ideal gls=f1,f2,f3,f4;
5452
5453//7. ex43, PoSSo, caprasse   vdim=56, 16 Komponenten
5454//zerodec-time:23(15)  (matrix:0 charpoly:16(13) factor:3(2))
5455//primdecGTZ-time:3 (2)
5456ring rs= 0,(y,z,x,t),dp;
5457ideal gls=y^2*z+2*y*x*t-z-2*x,
54584*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,
54592*y*z*t+x*t^2-2*z-x,
5460-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;
5461
5462//8. Arnborg-System, n=6 (II),    vdim=156, 90 Komponenten
5463//zerodec-time (char32003):127(45)(matrix:2(0) charpoly:106(37) factor:16(7))
5464//primdecGTZ-time(char32003) :81 (18)
5465//ring rs= 0,(a,b,c,d,x,f),dp;
5466ring rs= 32003,(a,b,c,d,x,f),dp;
5467ideal gls=a+b+c+d+x+f, ab+bc+cd+dx+xf+af, abc+bcd+cdx+d*xf+axf+abf,
5468abcd+bcdx+cd*xf+ad*xf+abxf+abcf, abcdx+bcd*xf+acd*xf+abd*xf+abcxf+abcdf,
5469abcd*xf-1;
5470
5471//9. ex42, PoSSo, Methan6_1, vdim=27, 2 Komponenten
5472//zerodec-time:610  (matrix:10 charpoly:557 factor:26)
5473//primdecGTZ-time: 118
5474//zerodec-time(char32003):2
5475//primdecGTZ-time(char32003):4
5476//ring rs= 0,(x1,x2,x3,x4,x5,x6,x7,x8,x9,x10),dp;
5477ring rs= 32003,(x1,x2,x3,x4,x5,x6,x7,x8,x9,x10),dp;
5478ideal gls=64*x2*x7-10*x1*x8+10*x7*x9+11*x7*x10-320000*x1,
5479-32*x2*x7-5*x2*x8-5*x2*x10+160000*x1-5000*x2,
5480-x3*x8+x6*x8+x9*x10+210*x6+1300000,
5481-x4*x8+700000,
5482x10^2-2*x5,
5483-x6*x8+x7*x9-210*x6,
5484-64*x2*x7-10*x7*x9-11*x7*x10+320000*x1-16*x7+7000000,
5485-10*x1*x8-10*x2*x8-10*x3*x8-10*x4*x8-10*x6*x8+10*x2*x10+11*x7*x10
5486    +20000*x2+14*x5,
5487x4*x8-x7*x9-x9*x10-410*x9,
548810*x2*x8+10*x3*x8+10*x6*x8+10*x7*x9-10*x2*x10-11*x7*x10-10*x9*x10
5489    -10*x10^2+1400*x6-4200*x10;
5490
5491//10. ex33, walk-s7, Diplomarbeit von Tim, vdim=114
5492//zerfaellt in unterschiedlich viele Komponenten in versch. Charkteristiken:
5493//char32003:30, char0:3(2xdeg1,1xdeg112!), char181:4(2xdeg1,1xdeg28,1xdeg84)
5494//char 0: zerodec-time:10075 (ca 3h) (matrix:3 charpoly:9367, factor:680
5495//        + 24 sec fuer Normalform (anstatt einsetzen), total [29623k])
5496//        primdecGTZ-time: 214
5497//char 32003:zerodec-time:197(68) (matrix:2(1) charpoly:173(60) factor:15(6))
5498//        primdecGTZ-time:14 (5)
5499//char 181:zerodec-time:(87) (matrix:(1) charpoly:(58) factor:(25))
5500//        primdecGTZ-time:(2)
5501//in char181 stimmen Ergebnisse von zerodec und primdecGTZ ueberein (gecheckt)
5502
5503//ring rs= 0,(a,b,c,d,e,f,g),dp;
5504ring rs= 32003,(a,b,c,d,e,f,g),dp;
5505poly f1= 2gb + 2fc + 2ed + a2 + a;
5506poly f2= 2gc + 2fd + e2 + 2ba + b;
5507poly f3= 2gd + 2fe + 2ca + c + b2;
5508poly f4= 2ge + f2 + 2da + d + 2cb;
5509poly f5= 2fg + 2ea + e + 2db + c2;
5510poly f6= g2 + 2fa + f + 2eb + 2dc;
5511poly f7= 2ga + g + 2fb + 2ec + d2;
5512ideal gls= f1,f2,f3,f4,f5,f6,f7;
5513
5514~/Singular/Singular/Singular -r123456789 -v
5515LIB"./primdec.lib";
5516timer=1;
5517int time=timer;
5518printlevel =1;
5519option(prot,mem);
5520time=timer; list pr1=zerodec(gls); timer-time;
5521
5522time=timer; list pr =primdecGTZ(gls); timer-time;
5523time=timer; list pr =primdecSY(gls); timer-time;
5524time=timer; ideal ra =radical(gls); timer-time;size(pr);
5525LIB"all.lib";
5526
5527ring R=0,(a,b,c,d,e,f),dp;
5528ideal I=cyclic(6);
5529minAssGTZ(I);
5530
5531
5532ring S=(2,a,b),(x,y),lp;
5533ideal I=x8-b,y4+a;
5534minAssGTZ(I);
5535
5536ring S1=2,(x,y,a,b),lp;
5537ideal I=x8-b,y4+a;
5538minAssGTZ(I);
5539
5540
5541ring S2=(2,z),(x,y),dp;
5542minpoly=z2+z+1;
5543ideal I=y3+y+1,x4+x+1;
5544primdecGTZ(I);
5545minAssGTZ(I);
5546
5547ring S3=2,(x,y,z),dp;
5548ideal I=y3+y+1,x4+x+1,z2+z+1;
5549primdecGTZ(I);
5550minAssGTZ(I);
5551
5552
5553ring R1=2,(x,y,z),lp;
5554ideal I=y6+y5+y3+y2+1,x4+x+1,z2+z+1;
5555primdecGTZ(I);
5556minAssGTZ(I);
5557
5558
5559ring R2=(2,z),(x,y),lp;
5560minpoly=z3+z+1;
5561ideal I=y2+y+(z2+z+1),x4+x+1;
5562primdecGTZ(I);
5563minAssGTZ(I);
5564
5565*/
Note: See TracBrowser for help on using the repository browser.