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

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