source: git/Singular/LIB/primdec.lib @ 5babd2e

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