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

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