source: git/Singular/LIB/primdec.lib @ 80aab02

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