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

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