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

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