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

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