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

spielwiese
Last change on this file since f3a046 was f3a046, checked in by Hans Schönemann <hannes@…>, 14 years ago
*hannes: global, no qring git-svn-id: file:///usr/local/Singular/svn/trunk@11707 2c84dea3-7e68-4137-9b89-c4e89433aadc
  • Property mode set to 100644
File size: 208.1 KB
Line 
1///////////////////////////////////////////////////////////////////////////////
2version="$Id: primdec.lib,v 1.146 2009-04-15 07:41:50 Singular Exp $";
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("FEHLER 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("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  export(primary_decomp);
5237  export(absolute_primes);
5238  setring R;
5239  dbprint( printlevel-voice+3,"
5240// 'absPrimdecGTZ' created a ring, in which two lists absolute_primes (the
5241// absolute prime components) and primary_decomp (the primary and prime
5242// components over the current basering) are stored.
5243// To access the list of absolute prime components, type (if the name S was
5244// assigned to the return value):
5245        setring S; absolute_primes; ");
5246
5247  return(Rz);
5248}
5249example
5250{ "EXAMPLE:";  echo = 2;
5251   ring  r = 0,(x,y,z),lp;
5252   poly  p = z2+1;
5253   poly  q = z3+2;
5254   ideal i = p*q^2,y-z2;
5255   def S = absPrimdecGTZ(i);
5256   setring S;
5257   absolute_primes;
5258}
5259
5260///////////////////////////////////////////////////////////////////////////////
5261
5262proc primdecSY(ideal i, list #)
5263"USAGE:   primdecSY(I, c); I ideal, c int (optional)
5264RETURN:  a list pr of primary ideals and their associated primes:
5265@format
5266   pr[i][1]   the i-th primary component,
5267   pr[i][2]   the i-th prime component.
5268@end format
5269NOTE:    Algorithm of Shimoyama/Yokoyama.
5270@format
5271   if c=0,  the given ordering of the variables is used,
5272   if c=1,  minAssChar tries to use an optimal ordering (default),
5273   if c=2,  minAssGTZ is used,
5274   if c=3,  minAssGTZ and facstd are used.
5275@end format
5276EXAMPLE: example primdecSY; shows an example
5277"
5278{
5279   if(attrib(basering,"global")!=1)
5280   {
5281      ERROR(
5282      "// Not implemented for this ordering, please change to global ordering."
5283      );
5284   }
5285   i=simplify(i,2);
5286   if ((i[1]==0)||(i[1]==1))
5287   {
5288     list L=list(ideal(i[1]),ideal(i[1]));
5289     return(list(L));
5290   }
5291   if(minpoly!=0)
5292   {
5293      return(algeDeco(i,1));
5294   }
5295   if (size(#)==1)
5296   { return(prim_dec(i,#[1])); }
5297   else
5298   { return(prim_dec(i,1)); }
5299}
5300example
5301{ "EXAMPLE:";  echo = 2;
5302   ring  r = 0,(x,y,z),lp;
5303   poly  p = z2+1;
5304   poly  q = z3+2;
5305   ideal i = p*q^2,y-z2;
5306   list pr = primdecSY(i);
5307   pr;
5308}
5309///////////////////////////////////////////////////////////////////////////////
5310proc minAssGTZ(ideal i,list #)
5311"USAGE:    minAssGTZ(I[, l]); I ideal, l list (optional)
5312   @* Optional parameters in list l (can be entered in any order):
5313   @* 0, \"facstd\" -> uses facstd to first decompose the ideal (default)
5314   @* 1, \"noFacstd\" -> does not use facstd
5315   @* \"GTZ\" -> the original algorithm by Gianni, Trager and Zacharias is used
5316   @* \"SL\" -> GTZ algorithm with modificiations by Laplagne is used (default)
5317
5318RETURN:  a list, the minimal associated prime ideals of I.
5319NOTE:    Designed for characteristic 0, works also in char k > 0 based
5320         on an algorithm of Yokoyama
5321EXAMPLE: example minAssGTZ; shows an example
5322"
5323{
5324  int j;
5325  string algorithm;
5326  string facstdOption;
5327  int useFac;
5328
5329  // Set input parameters
5330  algorithm = "SL";         // Default: SL algorithm
5331  facstdOption = "facstd";
5332  if(size(#) > 0)
5333  {
5334    int valid;
5335    for(j = 1; j <= size(#); j++)
5336    {
5337      valid = 0;
5338      if((typeof(#[j]) == "int") or (typeof(#[j]) == "number"))
5339      {
5340        if (#[j] == 1) {facstdOption = "noFacstd"; valid = 1;}    // If #[j] == 1, facstd is not used.
5341        if (#[j] == 0) {facstdOption = "facstd";   valid = 1;}    // If #[j] == 0, facstd is used.
5342      }
5343      if(typeof(#[j]) == "string")
5344      {
5345        if((#[j] == "GTZ") || (#[j] == "SL"))
5346        {
5347          algorithm = #[j];
5348          valid = 1;
5349        }
5350        if((#[j] == "noFacstd") || (#[j] == "facstd"))
5351        {
5352          facstdOption = #[j];
5353          valid = 1;
5354        }
5355      }
5356      if(valid == 0)
5357      {
5358        dbprint(1, "Warning! The following input parameter was not recognized:", #[j]);
5359      }
5360    }
5361  }
5362
5363  if(attrib(basering,"global")!=1)
5364  {
5365    ERROR(
5366      "// Not implemented for this ordering, please change to global ordering."
5367    );
5368  }
5369  if(minpoly!=0)
5370  {
5371    return(algeDeco(i,2));
5372  }
5373
5374  list result = minAssPrimes(i, facstdOption, algorithm);
5375  return(result);
5376}
5377example
5378{ "EXAMPLE:";  echo = 2;
5379   ring  r = 0,(x,y,z),dp;
5380   poly  p = z2+1;
5381   poly  q = z3+2;
5382   ideal i = p*q^2,y-z2;
5383   list pr = minAssGTZ(i);
5384   pr;
5385}
5386
5387///////////////////////////////////////////////////////////////////////////////
5388proc minAssChar(ideal i, list #)
5389"USAGE:   minAssChar(I[,c]); i ideal, c int (optional).
5390RETURN:  list, the minimal associated prime ideals of i.
5391NOTE:    If c=0, the given ordering of the variables is used. @*
5392         Otherwise, the system tries to find an optimal ordering,
5393         which in some cases may considerably speed up the algorithm. @*
5394         Due to a bug in the factorization, the result may be not completely
5395         decomposed in small characteristic.
5396EXAMPLE: example minAssChar; shows an example
5397"
5398{
5399   if(attrib(basering,"global")!=1)
5400   {
5401      ERROR(
5402      "// Not implemented for this ordering, please change to global ordering."
5403      );
5404   }
5405   if (size(#)==1)
5406   { return(min_ass_prim_charsets(i,#[1])); }
5407   else
5408   { return(min_ass_prim_charsets(i,1)); }
5409}
5410example
5411{ "EXAMPLE:";  echo = 2;
5412   ring  r = 0,(x,y,z),dp;
5413   poly  p = z2+1;
5414   poly  q = z3+2;
5415   ideal i = p*q^2,y-z2;
5416   list pr = minAssChar(i);
5417   pr;
5418}
5419///////////////////////////////////////////////////////////////////////////////
5420proc equiRadical(ideal i)
5421"USAGE:   equiRadical(I); I ideal
5422RETURN:  ideal, intersection of associated primes of I of maximal dimension.
5423NOTE:    A combination of the algorithms of Krick/Logar (with modifications by Laplagne) and Kemper is used.
5424         Works also in positive characteristic (Kempers algorithm).
5425EXAMPLE: example equiRadical; shows an example
5426"
5427{
5428  if(attrib(basering,"global")!=1)
5429  {
5430     ERROR(
5431     "// Not implemented for this ordering, please change to global ordering."
5432     );
5433  }
5434  return(radical(i, 1));
5435}
5436example
5437{ "EXAMPLE:";  echo = 2;
5438   ring  r = 0,(x,y,z),dp;
5439   poly  p = z2+1;
5440   poly  q = z3+2;
5441   ideal i = p*q^2,y-z2;
5442   ideal pr= equiRadical(i);
5443   pr;
5444}
5445
5446///////////////////////////////////////////////////////////////////////////////
5447proc radical(ideal i, list #)
5448"USAGE: radical(I[, l]); I ideal, l list (optional)
5449 @*  Optional parameters in list l (can be entered in any order):
5450 @*  0, \"fullRad\" -> full radical is computed (default)
5451 @*  1, \"equiRad\" -> equiRadical is computed
5452 @*  \"KL\" -> Krick/Logar algorithm is used
5453 @*  \"SL\" -> modifications by Laplagne are used (default)
5454 @*  \"facstd\" -> uses facstd to first decompose the ideal (default for non homogeneous ideals)
5455 @*  \"noFacstd\" -> does not use facstd (default for homogeneous ideals)
5456RETURN:  ideal, the radical of I (or the equiradical if required in the input parameters)
5457NOTE:    A combination of the algorithms of Krick/Logar (with modifications by Laplagne) and Kemper is used.
5458         Works also in positive characteristic (Kempers algorithm).
5459EXAMPLE: example radical; shows an example
5460"
5461{
5462  dbprint(printlevel - voice, "Radical, version 2006.05.08");
5463  if(attrib(basering,"global")!=1)
5464  {
5465    ERROR(
5466     "// Not implemented for this ordering, please change to global ordering."
5467    );
5468  }
5469  if(size(i) == 0){return(ideal(0));}
5470  int j;
5471  def P0 = basering;
5472  list Pl=ringlist(P0);
5473  intvec dp_w;
5474  for(j=nvars(P0);j>0;j--) {dp_w[j]=1;}
5475  Pl[3]=list(list("dp",dp_w),list("C",0));
5476  def @P=ring(Pl);
5477  setring @P;
5478  ideal i=imap(P0,i);
5479
5480  int il;
5481  string algorithm;
5482  int useFac;
5483
5484  // Set input parameters
5485  algorithm = "SL";                                 // Default: SL algorithm
5486  il = 0;                                           // Default: Full radical (not only equiRadical)
5487  if (homog(i) == 1)
5488  {   // Default: facStd is used, except if the ideal is homogeneous.
5489    useFac = 0;
5490  }
5491  else
5492  {
5493    useFac = 1;
5494  }
5495  if(size(#) > 0)
5496  {
5497    int valid;
5498    for(j = 1; j <= size(#); j++)
5499    {
5500      valid = 0;
5501      if((typeof(#[j]) == "int") or (typeof(#[j]) == "number"))
5502      {
5503        il = #[j];          // If il == 1, equiRadical is computed
5504        valid = 1;
5505      }
5506      if(typeof(#[j]) == "string")
5507      {
5508        if(#[j] == "KL")
5509        {
5510          algorithm = "KL";
5511          valid = 1;
5512        }
5513        if(#[j] == "SL")
5514        {
5515          algorithm = "SL";
5516          valid = 1;
5517        }
5518        if(#[j] == "noFacstd")
5519        {
5520          useFac = 0;
5521          valid = 1;
5522        }
5523        if(#[j] == "facstd")
5524        {
5525          useFac = 1;
5526          valid = 1;
5527        }
5528        if(#[j] == "equiRad")
5529        {
5530          il = 1;
5531          valid = 1;
5532        }
5533        if(#[j] == "fullRad")
5534        {
5535          il = 0;
5536          valid = 1;
5537        }
5538      }
5539      if(valid == 0)
5540      {
5541        dbprint(1, "Warning! The following input parameter was not recognized:", #[j]);
5542      }
5543    }
5544  }
5545
5546  ideal rad = 1;
5547  intvec op = option(get);
5548  list qr = simplifyIdeal(i);
5549  map phi = @P, qr[2];
5550
5551  option(redSB);
5552  i = groebner(qr[1]);
5553  option(set, op);
5554  int di = dim(i);
5555
5556  if(di == 0)
5557  {
5558    i = zeroRad(i, qr[1]);
5559    option(redSB);
5560    i=interred(phi(i));
5561    option(set, op);
5562    setring(P0);
5563    i=imap(@P,i);
5564    return(i);
5565  }
5566
5567  option(redSB);
5568  list pr;
5569  if(useFac == 1)
5570  {
5571    pr = facstd(i);
5572  }
5573  else
5574  {
5575    pr = i;
5576  }
5577  option(set, op);
5578  int s = size(pr);
5579  if(useFac == 1)
5580  {
5581    dbprint(printlevel - voice, "Number of components returned by facstd: ", s);
5582  }
5583  for(j = 1; j <= s; j++)
5584  {
5585    attrib(pr[s + 1 - j], "isSB", 1);
5586    if((size(reduce(rad, pr[s + 1 - j], 1)) != 0) && ((dim(pr[s + 1 - j]) == di) || !il))
5587    {
5588      // SL Debug messages
5589      dbprint(printlevel-voice, "We shall compute the radical of ", pr[s + 1 - j]);
5590      dbprint(printlevel-voice, "The dimension is: ", dim(pr[s+1-j]));
5591
5592      if(algorithm == "KL")
5593      {
5594        rad = intersect(rad, radicalKL(pr[s + 1 - j], rad, il));
5595      }
5596      if(algorithm == "SL")
5597      {
5598        rad = intersect(rad, radicalSL(pr[s + 1 - j], il));
5599      }
5600    }
5601    else
5602    {
5603      // SL Debug
5604      dbprint(printlevel-voice, "The radical of this component is not needed.");
5605      dbprint(printlevel-voice, "size(reduce(rad, pr[s + 1 - j], 1))",
5606              size(reduce(rad, pr[s + 1 - j], 1)));
5607      dbprint(printlevel-voice, "dim(pr[s + 1 - j])", dim(pr[s + 1 - j]));
5608      dbprint(printlevel-voice, "il", il);
5609    }
5610  }
5611  rad=interred(phi(rad));
5612  setring(P0);
5613  i=imap(@P,rad);
5614  return(i);
5615}
5616example
5617{ "EXAMPLE:";  echo = 2;
5618   ring  r = 0,(x,y,z),dp;
5619   poly  p = z2+1;
5620   poly  q = z3+2;
5621   ideal i = p*q^2,y-z2;
5622   ideal pr = radical(i);
5623   pr;
5624}
5625
5626///////////////////////////////////////////////////////////////////////////////
5627//
5628// Computes the radical of I using KL algorithm.
5629// The only difference with the previous implementation of KL algorithm is
5630// that now it uses block dp instead of lp ordering for the reduction to the
5631// zerodimensional case.
5632// The reduction step has been moved to the new routine radicalReduction, so that it can be
5633// used also by radicalSL procedure.
5634//
5635static proc radicalKL(ideal I, ideal ser, list #)
5636{
5637// ideal I     The ideal for which the radical is computed
5638// ideal ser   Used to reduce components already obtained
5639// list #      If #[1] = 1, equiradical is computed.
5640
5641  // I needs to be a Groebner basis.
5642  if (attrib(I, "isSB") != 1)
5643  {
5644    I = groebner(I);
5645  }
5646
5647  ideal rad;                                // The radical
5648  int allIndep = 1;                // All max independent sets are used
5649
5650  list result = radicalReduction(I, ser, allIndep, #);
5651  int done = result[3];
5652  rad = result[1];
5653  if (done == 0)
5654  {
5655    rad = intersect(rad, radicalKL(result[2], ideal(1), #));
5656  }
5657  return(rad);
5658}
5659
5660
5661///////////////////////////////////////////////////////////////////////////////
5662//
5663// Computes the radical of I via Laplagne algorithm, using zerodimensional radical in
5664// the zero dimensional case.
5665// For the reduction to the zerodimensional case, it uses the procedure
5666// radical, with some modifications to avoid the recursion.
5667//
5668static proc radicalSL(ideal I, list #)
5669// Input = I, ideal
5670//         #, list. If #[1] = 1, then computes only the equiradical.
5671// Output = (P, primaryDec) where P = rad(I) and primaryDec is the list of the radicals
5672// obtained in intermediate steps.
5673{
5674  ideal rad = 1;
5675  ideal equiRad = 1;
5676  list primes;
5677  int k;                        // Counter
5678  int il;                 // If il = 1, only the equiradical is required.
5679  int iDim;                // The dimension of I
5680  int stop = 0;   // Checks if the radical has been obtained
5681
5682  if (attrib(I, "isSB") != 1)
5683  {
5684    I = groebner(I);
5685  }
5686  iDim = dim(I);
5687
5688  // Checks if only equiradical is required
5689  if (size(#) > 0)
5690  {
5691    il = #[1];
5692  }
5693
5694  while(stop == 0)
5695  {
5696    dbprint (printlevel-voice, "// We call radLoopR to find new prime ideals.");
5697    primes = radicalSLIteration(I, rad);                         // A list of primes or intersections of primes, not included in P
5698    dbprint (printlevel - voice, "// Output of Iteration Step:");
5699    dbprint (printlevel - voice, primes);
5700    if (size(primes) > 0)
5701    {
5702      dbprint (printlevel - voice, "// We intersect P with the ideal just obtained.");
5703      for(k = 1; k <= size(primes); k++)
5704      {
5705        rad = intersect(rad, primes[k]);
5706        if (il == 1)
5707        {
5708          if (attrib(primes[k], "isSB") != 1)
5709          {
5710            primes[k] = groebner(primes[k]);
5711          }
5712          if (iDim == dim(primes[k]))
5713          {
5714            equiRad = intersect(equiRad, primes[k]);
5715          }
5716        }
5717      }
5718    }
5719    else
5720    {
5721      stop = 1;
5722    }
5723  }
5724  if (il == 0)
5725  {
5726    return(rad);
5727  }
5728  else
5729  {
5730    return(equiRad);
5731  }
5732}
5733
5734//////////////////////////////////////////////////////////////////////////
5735// Based on radicalKL.
5736// It contains all of old version of proc radicalKL except the recursion call.
5737//
5738// Output:
5739// #1 -> output ideal, the part of the radical that has been computed
5740// #2 -> complementary ideal, the part of the ideal I whose radical remains to be computed
5741//       = (I, h) in KL algorithm
5742//       This is not used in the new algorithm. It is part of KL algorithm
5743// #3 -> done, 1: output = radical, there is no need to continue
5744//                   0: radical = output \cap \sqrt{complementary ideal}
5745//       This is not used in the new algorithm. It is part of KL algorithm
5746
5747static proc radicalReduction(ideal I, ideal ser, int allIndep, list #)
5748{
5749// allMaximal      1 -> Indicates that the reduction to the zerodim case
5750//                    must be done for all indep set of the leading terms ideal
5751//                 0 -> Otherwise
5752// ideal ser       Only for radicalKL. (Same as in radicalKL)
5753// list #          Only for radicalKL (If #[1] = 1,
5754//                    only equiradical is required.
5755//                    It is used to set the value of done.)
5756
5757  attrib(I, "isSB", 1);   // I needs to be a reduced standard basis
5758  list indep, fett;
5759  intvec @w, @hilb, op;
5760  int @wr, @n, @m, lauf, di;
5761  ideal fac, @h, collectrad, lsau;
5762  poly @q;
5763  string @va, quotring;
5764
5765  def @P = basering;
5766  int jdim = dim(I);               // Computes the dimension of I
5767  int  homo = homog(I);            // Finds out if I is homogeneous
5768  ideal rad = ideal(1);            // The unit ideal
5769  ideal te = ser;
5770  if(size(#) > 0)
5771  {
5772    @wr = #[1];
5773  }
5774  if(homo == 1)
5775  {
5776    for(@n = 1; @n <= nvars(basering); @n++)
5777    {
5778      @w[@n] = ord(var(@n));
5779    }
5780    @hilb = hilb(I, 1, @w);
5781  }
5782
5783  // SL 2006.04.11 1 Debug messages
5784  dbprint(printlevel-voice, "//Computes the radical of the ideal:", I);
5785  // SL 2006.04.11 2 Debug messages
5786
5787  //---------------------------------------------------------------------------
5788  //j is the ring
5789  //---------------------------------------------------------------------------
5790
5791  if (jdim==-1)
5792  {
5793    return(ideal(1), ideal(1), 1);
5794  }
5795
5796  //---------------------------------------------------------------------------
5797  //the zero-dimensional case
5798  //---------------------------------------------------------------------------
5799
5800  if (jdim==0)
5801  {
5802    return(zeroRad(I), ideal(1), 1);
5803  }
5804
5805  //-------------------------------------------------------------------------
5806  //search for a maximal independent set indep,i.e.
5807  //look for subring such that the intersection with the ideal is zero
5808  //j intersected with K[var(indep[3]+1),...,var(nvar)] is zero,
5809  //indep[1] is the new varstring, indep[2] the string for the block-ordering
5810  //-------------------------------------------------------------------------
5811
5812  // SL 2006-04-24 1   If allIndep = 0, then it only computes one maximal
5813  //                     independent set.
5814  //                     This looks better for the new algorithm but not for KL
5815  //                     algorithm
5816  list parameters = allIndep;
5817  indep = newMaxIndependSetDp(I, parameters);
5818  // SL 2006-04-24 2
5819
5820  for(@m = 1; @m <= size(indep); @m++)
5821  {
5822    if((indep[@m][1] == varstr(basering)) && (@m == 1))
5823    //this is the good case, nothing to do, just to have the same notations
5824    //change the ring
5825    {
5826      execute("ring gnir1 = ("+charstr(basering)+"),("+varstr(basering)+"),("
5827                              +ordstr(basering)+");");
5828      ideal @j = fetch(@P, I);
5829      attrib(@j, "isSB", 1);
5830    }
5831    else
5832    {
5833      @va = string(maxideal(1));
5834
5835      execute("ring gnir1 = (" + charstr(basering) + "), (" + indep[@m][1] + "),("
5836                              + indep[@m][2] + ");");
5837      execute("map phi = @P," + @va + ";");
5838      if(homo == 1)
5839      {
5840        ideal @j = std(phi(I), @hilb, @w);
5841      }
5842      else
5843      {
5844        ideal @j = groebner(phi(I));
5845      }
5846    }
5847    if((deg(@j[1]) == 0) || (dim(@j) < jdim))
5848    {
5849      setring @P;
5850      break;
5851    }
5852    for (lauf = 1; lauf <= size(@j); lauf++)
5853    {
5854      fett[lauf] = size(@j[lauf]);
5855    }
5856    //------------------------------------------------------------------------
5857    // We have now the following situation:
5858    // j intersected with K[var(nnp+1),..,var(nva)] is zero so we may pass
5859    // to this quotientring, j is there still a standardbasis, the
5860    // leading coefficients of the polynomials there (polynomials in
5861    // K[var(nnp+1),..,var(nva)]) are collected in the list h,
5862    // we need their LCM, gh, because of the following:
5863    // let (j:gh^n)=(j:gh^infinity) then j*K(var(nnp+1),..,var(nva))[..rest..]
5864    // intersected with K[var(1),...,var(nva)] is (j:gh^n)
5865    // on the other hand j = ((j, gh^n) intersected with (j : gh^n))
5866
5867    //------------------------------------------------------------------------
5868    // The arrangement for the quotientring K(var(nnp+1),..,var(nva))[..rest..]
5869    // and the map phi:K[var(1),...,var(nva)] ----->
5870    // K(var(nnpr+1),..,var(nva))[..the rest..]
5871    //------------------------------------------------------------------------
5872    quotring = prepareQuotientRingDp(nvars(basering) - indep[@m][3]);
5873    //------------------------------------------------------------------------
5874    // We pass to the quotientring   K(var(nnp+1),..,var(nva))[..the rest..]
5875    //------------------------------------------------------------------------
5876
5877    execute(quotring);
5878
5879    // @j considered in the quotientring
5880    ideal @j = imap(gnir1, @j);
5881
5882    kill gnir1;
5883
5884    // j is a standardbasis in the quotientring but usually not minimal
5885    // here it becomes minimal
5886
5887    @j = clearSB(@j, fett);
5888
5889    // We need later LCM(h[1],...) = gh for saturation
5890    ideal @h;
5891    if(deg(@j[1]) > 0)
5892    {
5893      for(@n = 1; @n <= size(@j); @n++)
5894      {
5895        @h[@n] = leadcoef(@j[@n]);
5896      }
5897      op = option(get);
5898      option(redSB);
5899      @j = std(@j);  //to obtain a reduced standardbasis
5900      option(set, op);
5901
5902      // SL 1 Debug messages
5903      dbprint(printlevel - voice, "zero_rad", basering, @j, dim(groebner(@j)));
5904      ideal zero_rad = zeroRad(@j);
5905      dbprint(printlevel - voice, "zero_rad passed");
5906      // SL 2
5907    }
5908    else
5909    {
5910      ideal zero_rad = ideal(1);
5911    }
5912
5913    // We need the intersection of the ideals in the list quprimary with the
5914    // polynomialring, i.e. let q=(f1,...,fr) in the quotientring such an ideal
5915    // but fi polynomials, then the intersection of q with the polynomialring
5916    // is the saturation of the ideal generated by f1,...,fr with respect to
5917    // h which is the lcm of the leading coefficients of the fi considered in
5918    // the quotientring: this is coded in saturn
5919
5920    zero_rad = std(zero_rad);
5921
5922    ideal hpl;
5923
5924    for(@n = 1; @n <= size(zero_rad); @n++)
5925    {
5926      hpl = hpl, leadcoef(zero_rad[@n]);
5927    }
5928
5929    //------------------------------------------------------------------------
5930    // We leave  the quotientring   K(var(nnp+1),..,var(nva))[..the rest..]
5931    // back to the polynomialring
5932    //------------------------------------------------------------------------
5933    setring @P;
5934
5935    collectrad = imap(quring, zero_rad);
5936    lsau = simplify(imap(quring, hpl), 2);
5937    @h = imap(quring, @h);
5938
5939    kill quring;
5940
5941    // Here the intersection with the polynomialring
5942    // mentioned above is really computed
5943
5944    collectrad = sat2(collectrad, lsau)[1];
5945    if(deg(@h[1])>=0)
5946    {
5947      fac = ideal(0);
5948      for(lauf = 1; lauf <= ncols(@h); lauf++)
5949      {
5950        if(deg(@h[lauf]) > 0)
5951        {
5952          fac = fac + factorize(@h[lauf], 1);
5953        }
5954      }
5955      fac = simplify(fac, 6);
5956      @q = 1;
5957      for(lauf = 1; lauf <= size(fac); lauf++)
5958      {
5959        @q = @q * fac[lauf];
5960      }
5961      op = option(get);
5962      option(returnSB);
5963      option(redSB);
5964      I = quotient(I + ideal(@q), rad);
5965      attrib(I, "isSB", 1);
5966      option(set, op);
5967    }
5968    if((deg(rad[1]) > 0) && (deg(collectrad[1]) > 0))
5969    {
5970      rad = intersect(rad, collectrad);
5971      te = intersect(te, collectrad);
5972      te = simplify(reduce(te, I, 1), 2);
5973    }
5974    else
5975    {
5976      if(deg(collectrad[1]) > 0)
5977      {
5978        rad = collectrad;
5979        te = intersect(te, collectrad);
5980        te = simplify(reduce(te, I, 1), 2);
5981      }
5982    }
5983
5984    if((dim(I) < jdim)||(size(te) == 0))
5985    {
5986      break;
5987    }
5988    if(homo==1)
5989    {
5990      @hilb = hilb(I, 1, @w);
5991    }
5992  }
5993
5994  // SL 2006.04.11 1 Debug messages
5995  dbprint (printlevel-voice, "// Part of the Radical already computed:", rad);
5996  dbprint (printlevel-voice, "// Dimension:", dim(groebner(rad)));
5997  // SL 2006.04.11 2 Debug messages
5998
5999  // SL 2006.04.21 1    New variable "done".
6000  //                      It tells if the radical is already computed or
6001  //                      if it still has to be computed the radical of the new ideal I
6002  int done;
6003  if(((@wr == 1) && (dim(I)<jdim)) || (deg(I[1])==0) || (size(te) == 0))
6004  {
6005    done = 1;
6006  }
6007  else
6008  {
6009    done = 0;
6010  }
6011  // SL 2006.04.21 2
6012
6013  // SL 2006.04.21 1     See details of the output at the beginning of this proc.
6014  list result = rad, I, done;
6015  return(result);
6016  // SL 2006.04.21 2
6017}
6018
6019///////////////////////////////////////////////////////////////////////////////
6020// Given an ideal I and an ideal P (intersection of some minimal prime ideals
6021// associated to I), it calculates the intersection of new minimal prime ideals
6022// associated to I which where not used to calculate P.
6023// This version uses ZD Radical in the zerodimensional case.
6024static proc radicalSLIteration (ideal I, ideal P);
6025// Input: I, ideal. The ideal from which new prime components will be obtained.
6026//        P, ideal. Intersection of some prime ideals of I.
6027// Output: ideal. Intersection of some primes of I different from the ones in P.
6028{
6029  int k = 1;                     // Counter
6030  int good  = 0;                 // Checks if an element of P is in rad(I)
6031
6032  dbprint (printlevel-voice, "// We search for an element in P - sqrt(I).");
6033  while ((k <= size(P)) and (good == 0))
6034  {
6035    dbprint (printlevel-voice, "// We try with:", P[k]);
6036    good = 1 - rad_con(P[k], I);
6037    k++;
6038  }
6039  k--;
6040  if (good == 0)
6041  {
6042    dbprint (printlevel-voice, "// No element was found, P = sqrt(I).");
6043    list emptyList = list();
6044    return (emptyList);
6045  }
6046  dbprint(printlevel - voice, "// That one was good!");
6047  dbprint(printlevel - voice, "// We saturate I with respect to this element.");
6048  if (P[k] != 1)
6049  {
6050    intvec oo=option(get);
6051    option(redSB);
6052    ideal J = sat(I, P[k])[1];
6053    option(set,oo);
6054
6055  }
6056  else
6057  {
6058    dbprint(printlevel - voice, "// The polynomial is 1, the saturation in not actually computed.");
6059    ideal J = I;
6060  }
6061
6062  // We now call proc radicalNew;
6063  dbprint(printlevel - voice, "// We do the reduction to the zerodimensional case, via radical.");
6064  dbprint(printlevel - voice, "// The ideal is ", J);
6065  dbprint(printlevel - voice, "// The dimension is ", dim(groebner(J)));
6066
6067  int allMaximal = 0;   // Compute the zerodim reduction for only one indep set.
6068  ideal re = 1;         // No reduction is need,
6069                        //    there are not redundant components.
6070  list emptyList = list();   // Look for primes of any dimension,
6071                             //   not only of max dimension.
6072  list result = radicalReduction(J, re, allMaximal, emptyList);
6073
6074  return(result[1]);
6075}
6076
6077///////////////////////////////////////////////////////////////////////////////////
6078// Based on maxIndependSet
6079// Added list # as parameter
6080// If the first element of # is 0, the output is only 1 max indep set.
6081// If no list is specified or #[1] = 1, the output is all the max indep set of the
6082// leading terms ideal. This is the original output of maxIndependSet
6083
6084// The ordering given in the output has been changed to block dp instead of lp.
6085
6086proc newMaxIndependSetDp(ideal j, list #)
6087"USAGE:   newMaxIndependentSetDp(I); I ideal (returns all maximal independent sets of the corresponding leading terms ideal)
6088          newMaxIndependentSetDp(I, 0); I ideal (returns only one maximal independent set)
6089RETURN:  list = #1. new varstring with the maximal independent set at the end,
6090                #2. ordstring with the corresponding dp block ordering,
6091                #3. the number of independent variables
6092NOTE:
6093EXAMPLE: example newMaxIndependentSetDp; shows an example
6094"
6095{
6096  int n, k, di;
6097  list resu, hilf;
6098  string var1, var2;
6099  list v = indepSet(j, 0);
6100
6101  // SL 2006.04.21 1 Lines modified to use only one independent Set
6102  int allMaximal;
6103  if (size(#) > 0)
6104  {
6105    allMaximal = #[1];
6106  }
6107  else
6108  {
6109    allMaximal = 1;
6110  }
6111
6112  int nMax;
6113  if (allMaximal == 1)
6114  {
6115    nMax = size(v);
6116  }
6117  else
6118  {
6119    nMax = 1;
6120  }
6121
6122  for(n = 1; n <= nMax; n++)
6123  // SL 2006.04.21 2
6124  {
6125    di = 0;
6126    var1 = "";
6127    var2 = "";
6128    for(k = 1; k <= size(v[n]); k++)
6129    {
6130     if(v[n][k] != 0)
6131      {
6132        di++;
6133        var2 = var2 + "var(" + string(k) + "), ";
6134      }
6135      else
6136      {
6137        var1 = var1 + "var(" + string(k) + "), ";
6138      }
6139    }
6140    if(di > 0)
6141    {
6142      var1 = var1 + var2;
6143      var1 = var1[1..size(var1) - 2];                         // The "- 2" removes the trailer comma
6144      hilf[1] = var1;
6145      // SL 2006.21.04 1 The order is now block dp instead of lp
6146      hilf[2] = "dp(" + string(nvars(basering) - di) + "), dp(" + string(di) + ")";
6147      // SL 2006.21.04 2
6148      hilf[3] = di;
6149      resu[n] = hilf;
6150    }
6151    else
6152    {
6153      resu[n] = varstr(basering), ordstr(basering), 0;
6154    }
6155  }
6156  return(resu);
6157}
6158example
6159{ "EXAMPLE:"; echo = 2;
6160   ring s1 = (0, x, y), (a, b, c, d, e, f, g), lp;
6161   ideal i = ea - fbg, fa + be, ec - fdg, fc + de;
6162   i = std(i);
6163   list l = newMaxIndependSetDp(i);
6164   l;
6165   i = i, g;
6166   l = newMaxIndependSetDp(i);
6167   l;
6168
6169   ring s = 0, (x, y, z), lp;
6170   ideal i = z, yx;
6171   list l = newMaxIndependSetDp(i);
6172   l;
6173}
6174
6175
6176///////////////////////////////////////////////////////////////////////////////
6177// based on prepareQuotientring
6178// The order returned is now (C, dp) instead of (C, lp)
6179
6180static proc prepareQuotientRingDp (int nnp)
6181"USAGE:   prepareQuotientRingDp(nnp); nnp int
6182RETURN:  string = to define Kvar(nnp+1),...,var(nvars)[..rest ]
6183NOTE:
6184EXAMPLE: example prepareQuotientRingDp; shows an example
6185"
6186{
6187  ideal @ih,@jh;
6188  int npar=npars(basering);
6189  int @n;
6190
6191  string quotring= "ring quring = ("+charstr(basering);
6192  for(@n = nnp + 1; @n <= nvars(basering); @n++)
6193  {
6194     quotring = quotring + ", var(" + string(@n) + ")";
6195     @ih = @ih + var(@n);
6196  }
6197
6198  quotring = quotring+"),(var(1)";
6199  @jh = @jh + var(1);
6200  for(@n = 2; @n <= nnp; @n++)
6201  {
6202    quotring = quotring + ", var(" + string(@n) + ")";
6203    @jh = @jh + var(@n);
6204  }
6205  // SL 2006-04-21 1 The order returned is now (C, dp) instead of (C, lp)
6206  quotring = quotring + "), (C, dp);";
6207  // SL 2006-04-21 2
6208
6209  return(quotring);
6210}
6211example
6212{ "EXAMPLE:"; echo = 2;
6213   ring s1=(0,x),(a,b,c,d,e,f,g),lp;
6214   def @Q=basering;
6215   list l= prepareQuotientRingDp(3);
6216   l;
6217   execute(l[1]);
6218   execute(l[2]);
6219   basering;
6220   phi;
6221   setring @Q;
6222
6223}
6224
6225///////////////////////////////////////////////////////////////////////////////
6226proc prepareAss(ideal i)
6227"USAGE:   prepareAss(I); I ideal
6228RETURN:  list, the radicals of the maximal dimensional components of I.
6229NOTE:    Uses algorithm of Eisenbud/Huneke/Vasconcelos.
6230EXAMPLE: example prepareAss; shows an example
6231"
6232{
6233  if(attrib(basering,"global")!=1)
6234  {
6235      ERROR(
6236      "// Not implemented for this ordering, please change to global ordering."
6237      );
6238  }
6239  ideal j=std(i);
6240  int cod=nvars(basering)-dim(j);
6241  int e;
6242  list er;
6243  ideal ann;
6244  if(homog(i)==1)
6245  {
6246     list re=sres(j,0);                   //the resolution
6247     re=minres(re);                       //minimized resolution
6248  }
6249  else
6250  {
6251    list re=mres(i,0);
6252  }
6253  for(e=cod;e<=nvars(basering);e++)
6254  {
6255     ann=AnnExt_R(e,re);
6256
6257     if(nvars(basering)-dim(std(ann))==e)
6258     {
6259        er[size(er)+1]=equiRadical(ann);
6260     }
6261  }
6262  return(er);
6263}
6264example
6265{ "EXAMPLE:";  echo = 2;
6266   ring  r = 0,(x,y,z),dp;
6267   poly  p = z2+1;
6268   poly  q = z3+2;
6269   ideal i = p*q^2,y-z2;
6270   list pr = prepareAss(i);
6271   pr;
6272}
6273///////////////////////////////////////////////////////////////////////////////
6274proc equidimMaxEHV(ideal i)
6275"USAGE:  equidimMaxEHV(I); I ideal
6276RETURN:  ideal, the equidimensional component (of maximal dimension) of I.
6277NOTE:    Uses algorithm of Eisenbud, Huneke and Vasconcelos.
6278EXAMPLE: example equidimMaxEHV; shows an example
6279"
6280{
6281  if(attrib(basering,"global")!=1)
6282  {
6283      ERROR(
6284      "// Not implemented for this ordering, please change to global ordering."
6285      );
6286  }
6287  ideal j=groebner(i);
6288  int cod=nvars(basering)-dim(j);
6289  int e;
6290  ideal ann;
6291  if(homog(i)==1)
6292  {
6293     list re=sres(j,0);                   //the resolution
6294     re=minres(re);                       //minimized resolution
6295  }
6296  else
6297  {
6298    list re=mres(i,0);
6299  }
6300  ann=AnnExt_R(cod,re);
6301  return(ann);
6302}
6303example
6304{ "EXAMPLE:";  echo = 2;
6305   ring  r = 0,(x,y,z),dp;
6306   ideal i=intersect(ideal(z),ideal(x,y),ideal(x2,z2),ideal(x5,y5,z5));
6307   equidimMaxEHV(i);
6308}
6309
6310proc testPrimary(list pr, ideal k)
6311"USAGE:   testPrimary(pr,k); pr a list, k an ideal.
6312ASSUME:  pr is the result of primdecGTZ(k) or primdecSY(k).
6313RETURN:  int, 1 if the intersection of the ideals in pr is k, 0 if not
6314EXAMPLE: example testPrimary; shows an example
6315"
6316{
6317   int i;
6318   pr=reconvList(pr);
6319   ideal j=pr[1];
6320   for (i=2;i<=size(pr)/2;i++)
6321   {
6322       j=intersect(j,pr[2*i-1]);
6323   }
6324   return(idealsEqual(j,k));
6325}
6326example
6327{ "EXAMPLE:";  echo = 2;
6328   ring  r = 32003,(x,y,z),dp;
6329   poly  p = z2+1;
6330   poly  q = z4+2;
6331   ideal i = p^2*q^3,(y-z3)^3,(x-yz+z4)^4;
6332   list pr = primdecGTZ(i);
6333   testPrimary(pr,i);
6334}
6335
6336///////////////////////////////////////////////////////////////////////////////
6337proc zerodec(ideal I)
6338"USAGE:   zerodec(I); I ideal
6339ASSUME:  I is zero-dimensional, the characteristic of the ground field is 0
6340RETURN:  list of primary ideals, the zero-dimensional decomposition of I
6341NOTE:    The algorithm (of Monico), works well only for a small total number
6342         of solutions (@code{vdim(std(I))} should be < 100) and without
6343         parameters. In practice, it works also in large characteristic p>0
6344         but may fail for small p.
6345@*       If printlevel > 0 (default = 0) additional information is displayed.
6346EXAMPLE: example zerodec; shows an example
6347"
6348{
6349  if(attrib(basering,"global")!=1)
6350  {
6351    ERROR(
6352    "// Not implemented for this ordering, please change to global ordering."
6353    );
6354  }
6355  def R=basering;
6356  poly q;
6357  int j,time;
6358  matrix m;
6359  list re;
6360  poly va=var(1);
6361  ideal J=groebner(I);
6362  ideal ba=kbase(J);
6363  int d=vdim(J);
6364  dbprint(printlevel-voice+2,"// multiplicity of ideal : "+ string(d));
6365//------ compute matrix of multiplication on R/I with generic element p -----
6366  int e=nvars(basering);
6367  poly p=randomLast(100)[e]+random(-50,50);     //the generic element
6368  matrix n[d][d];
6369  time = timer;
6370  for(j=2;j<=e;j++)
6371  {
6372    va=va*var(j);
6373  }
6374  for(j=1;j<=d;j++)
6375  {
6376    q=reduce(p*ba[j],J);
6377    m=coeffs(q,ba,va);
6378    n[j,1..d]=m[1..d,1];
6379  }
6380  dbprint(printlevel-voice+2,
6381    "// time for computing multiplication matrix (with generic element) : "+
6382    string(timer-time));
6383//---------------- compute characteristic polynomial of matrix --------------
6384  execute("ring P1=("+charstr(R)+"),T,dp;");
6385  matrix n=imap(R,n);
6386  time = timer;
6387  poly charpol=det(n-T*freemodule(d));
6388  dbprint(printlevel-voice+2,"// time for computing char poly: "+
6389         string(timer-time));
6390//------------------- factorize characteristic polynomial -------------------
6391//check first if constant term of charpoly is != 0 (which is true for
6392//sufficiently generic element)
6393  if(charpol[size(charpol)]!=0)
6394  {
6395    time = timer;
6396    list fac=factor(charpol);
6397    testFactor(fac,charpol);
6398    dbprint(printlevel-voice+2,"// time for factorizing char poly: "+
6399            string(timer-time));
6400    int f=size(fac[1]);
6401//--------------------------- the irreducible case --------------------------
6402    if(f==1)
6403    {
6404      setring R;
6405      re=I;
6406      return(re);
6407    }
6408//---------------------------- the reducible case ---------------------------
6409//if f_i are the irreducible factors of charpoly, mult=ri, then <I,g_i^ri>
6410//are the primary components where g_i = f_i(p). However, substituting p in
6411//f_i may result in a huge object although the final result may be small.
6412//Hence it is better to simultaneously reduce with I. For this we need a new
6413//ring.
6414    execute("ring P=("+charstr(R)+"),(T,"+varstr(R)+"),(dp(1),dp);");
6415    list rfac=imap(P1,fac);
6416    intvec ov=option(get);;
6417    option(redSB);
6418    list re1;
6419    ideal new = T-imap(R,p),imap(R,J);
6420    attrib(new, "isSB",1);    //we know that new is a standard basis
6421    for(j=1;j<=f;j++)
6422    {
6423      re1[j]=reduce(rfac[1][j]^rfac[2][j],new);
6424    }
6425    setring R;
6426    re = imap(P,re1);
6427    for(j=1;j<=f;j++)
6428    {
6429      J=I,re[j];
6430      re[j]=interred(J);
6431    }
6432    option(set,ov);
6433    return(re);
6434  }
6435  else
6436//------------------- choice of generic element failed -------------------
6437  {
6438    dbprint(printlevel-voice+2,"// try new generic element!");
6439    setring R;
6440    return(zerodec(I));
6441  }
6442}
6443example
6444{ "EXAMPLE:";  echo = 2;
6445   ring r  = 0,(x,y),dp;
6446   ideal i = x2-2,y2-2;
6447   list pr = zerodec(i);
6448   pr;
6449}
6450///////////////////////////////////////////////////////////////////////////////
6451static proc newDecompStep(ideal i, list #)
6452"USAGE:  newDecompStep(i); i ideal  (for primary decomposition)
6453         newDecompStep(i,1);        (for the associated primes of dimension of i)
6454         newDecompStep(i,2);        (for the minimal associated primes)
6455         newDecompStep(i,3);        (for the absolute primary decomposition (not tested!))
6456         "oneIndep";        (for using only one max indep set)
6457         "intersect";        (returns alse the intersection of the components founded)
6458
6459RETURN:  list = list of primary ideals and their associated primes
6460         (at even positions in the list)
6461         (resp. a list of the minimal associated primes)
6462NOTE:    Algorithm of Gianni/Trager/Zacharias
6463EXAMPLE: example newDecompStep; shows an example
6464"
6465{
6466  intvec op,@vv;
6467  def  @P = basering;
6468  list primary,indep,ltras;
6469  intvec @vh,isat,@w;
6470  int @wr,@k,@n,@m,@n1,@n2,@n3,homo,seri,keepdi,abspri,ab,nn;
6471  ideal peek=i;
6472  ideal ser,tras;
6473  list data;
6474  list result;
6475  intvec @hilb;
6476  int isS=(attrib(i,"isSB")==1);
6477
6478  // Debug
6479  dbprint(printlevel - voice, "newDecompStep, v2.0");
6480
6481  string indepOption = "allIndep";
6482  string intersectOption = "noIntersect";
6483
6484  if(size(#)>0)
6485  {
6486    int count = 1;
6487    if(typeof(#[count]) == "string")
6488    {
6489      if ((#[count] == "oneIndep") or (#[count] == "allIndep"))
6490      {
6491        indepOption = #[count];
6492        count++;
6493      }
6494    }
6495    if(typeof(#[count]) == "string")
6496    {
6497      if ((#[count] == "intersect") or (#[count] == "noIntersect"))
6498      {
6499        intersectOption = #[count];
6500        count++;
6501      }
6502    }
6503    if((typeof(#[count]) == "int") or (typeof(#[count]) == "number"))
6504    {
6505      if ((#[count]==1)||(#[count]==2)||(#[count]==3))
6506      {
6507        @wr=#[count];
6508        if(@wr==3){abspri = 1; @wr = 0;}
6509        count++;
6510      }
6511    }
6512    if(size(#)>count)
6513    {
6514      seri=1;
6515      peek=#[count + 1];
6516      ser=#[count + 2];
6517    }
6518  }
6519  if(abspri)
6520  {
6521    list absprimary,abskeep,absprimarytmp,abskeeptmp;
6522  }
6523  homo=homog(i);
6524  if(homo==1)
6525  {
6526    if(attrib(i,"isSB")!=1)
6527    {
6528      //ltras=mstd(i);
6529      tras=groebner(i);
6530      ltras=tras,tras;
6531      attrib(ltras[1],"isSB",1);
6532    }
6533    else
6534    {
6535      ltras=i,i;
6536      attrib(ltras[1],"isSB",1);
6537    }
6538    tras = ltras[1];
6539    attrib(tras,"isSB",1);
6540    if(dim(tras)==0)
6541    {
6542      primary[1]=ltras[2];
6543      primary[2]=maxideal(1);
6544      if(@wr>0)
6545      {
6546        list l;
6547        l[2]=maxideal(1);
6548        l[1]=maxideal(1);
6549        if (intersectOption == "intersect")
6550        {
6551          return(list(l, maxideal(1)));
6552        }
6553        else
6554        {
6555          return(l);
6556        }
6557      }
6558      if (intersectOption == "intersect")
6559      {
6560        return(list(primary, primary[1]));
6561      }
6562      else
6563      {
6564        return(primary);
6565      }
6566    }
6567    for(@n=1;@n<=nvars(basering);@n++)
6568    {
6569      @w[@n]=ord(var(@n));
6570    }
6571    @hilb=hilb(tras,1,@w);
6572    intvec keephilb=@hilb;
6573  }
6574
6575  //----------------------------------------------------------------
6576  //i is the zero-ideal
6577  //----------------------------------------------------------------
6578
6579  if(size(i)==0)
6580  {
6581    primary=i,i;
6582    if (intersectOption == "intersect")
6583    {
6584      return(list(primary, i));
6585    }
6586    else
6587    {
6588      return(primary);
6589    }
6590  }
6591
6592  //----------------------------------------------------------------
6593  //pass to the lexicographical ordering and compute a standardbasis
6594  //----------------------------------------------------------------
6595
6596  int lp=islp();
6597
6598  execute("ring gnir = ("+charstr(basering)+"),("+varstr(basering)+"),(C,lp);");
6599  op=option(get);
6600  option(redSB);
6601
6602  ideal ser=fetch(@P,ser);
6603  if(homo==1)
6604  {
6605    if(!lp)
6606    {
6607      ideal @j=std(fetch(@P,i),@hilb,@w);
6608    }
6609    else
6610    {
6611      ideal @j=fetch(@P,tras);
6612      attrib(@j,"isSB",1);
6613    }
6614  }
6615  else
6616  {
6617    if(lp&&isS)
6618    {
6619      ideal @j=fetch(@P,i);
6620      attrib(@j,"isSB",1);
6621    }
6622    else
6623    {
6624      ideal @j=groebner(fetch(@P,i));
6625    }
6626  }
6627  option(set,op);
6628  if(seri==1)
6629  {
6630    ideal peek=fetch(@P,peek);
6631    attrib(peek,"isSB",1);
6632  }
6633  else
6634  {
6635    ideal peek=@j;
6636  }
6637  if((size(ser)==0)&&(!abspri))
6638  {
6639    ideal fried;
6640    @n=size(@j);
6641    for(@k=1;@k<=@n;@k++)
6642    {
6643      if(deg(lead(@j[@k]))==1)
6644      {
6645        fried[size(fried)+1]=@j[@k];
6646        @j[@k]=0;
6647      }
6648    }
6649    if(size(fried)==nvars(basering))
6650    {
6651      setring @P;
6652      primary[1]=i;
6653      primary[2]=i;
6654      if (intersectOption == "intersect")
6655      {
6656        return(list(primary, i));
6657      }
6658      else
6659      {
6660        return(primary);
6661      }
6662    }
6663    if(size(fried)>0)
6664    {
6665      string newva;
6666      string newma;
6667      for(@k=1;@k<=nvars(basering);@k++)
6668      {
6669        @n1=0;
6670        for(@n=1;@n<=size(fried);@n++)
6671        {
6672          if(leadmonom(fried[@n])==var(@k))
6673          {
6674            @n1=1;
6675            break;
6676          }
6677        }
6678        if(@n1==0)
6679        {
6680          newva=newva+string(var(@k))+",";
6681          newma=newma+string(var(@k))+",";
6682        }
6683        else
6684        {
6685          newma=newma+string(0)+",";
6686        }
6687      }
6688      newva[size(newva)]=")";
6689      newma[size(newma)]=";";
6690      execute("ring @deirf=("+charstr(gnir)+"),("+newva+",lp;");
6691      execute("map @kappa=gnir,"+newma);
6692      ideal @j= @kappa(@j);
6693      @j=simplify(@j, 2);
6694      attrib(@j,"isSB",1);
6695      result = newDecompStep(@j, indepOption, intersectOption, @wr);
6696      if (intersectOption == "intersect")
6697      {
6698       list pr = result[1];
6699       ideal intersection = result[2];
6700      }
6701      else
6702      {
6703        list pr = result;
6704      }
6705
6706      setring gnir;
6707      list pr=imap(@deirf,pr);
6708      for(@k=1;@k<=size(pr);@k++)
6709      {
6710        @j=pr[@k]+fried;
6711        pr[@k]=@j;
6712      }
6713      if (intersectOption == "intersect")
6714      {
6715        ideal intersection = imap(@deirf, intersection);
6716        @j = intersection + fried;
6717        intersection = @j;
6718      }
6719      setring @P;
6720      if (intersectOption == "intersect")
6721      {
6722        return(list(imap(gnir,pr), imap(gnir,intersection)));
6723      }
6724      else
6725      {
6726        return(imap(gnir,pr));
6727      }
6728    }
6729  }
6730  //----------------------------------------------------------------
6731  //j is the ring
6732  //----------------------------------------------------------------
6733
6734  if (dim(@j)==-1)
6735  {
6736    setring @P;
6737    primary=ideal(1),ideal(1);
6738    if (intersectOption == "intersect")
6739    {
6740      return(list(primary, ideal(1)));
6741    }
6742    else
6743    {
6744      return(primary);
6745    }
6746  }
6747
6748  //----------------------------------------------------------------
6749  //  the case of one variable
6750  //----------------------------------------------------------------
6751
6752  if(nvars(basering)==1)
6753  {
6754    list fac=factor(@j[1]);
6755    list gprimary;
6756    poly generator;
6757    ideal gIntersection;
6758    for(@k=1;@k<=size(fac[1]);@k++)
6759    {
6760      if(@wr==0)
6761      {
6762        gprimary[2*@k-1]=ideal(fac[1][@k]^fac[2][@k]);
6763        gprimary[2*@k]=ideal(fac[1][@k]);
6764      }
6765      else
6766      {
6767        gprimary[2*@k-1]=ideal(fac[1][@k]);
6768        gprimary[2*@k]=ideal(fac[1][@k]);
6769      }
6770      if (intersectOption == "intersect")
6771      {
6772        generator = generator * fac[1][@k];
6773      }
6774    }
6775    if (intersectOption == "intersect")
6776    {
6777      gIntersection = generator;
6778    }
6779    setring @P;
6780    primary=fetch(gnir,gprimary);
6781    if (intersectOption == "intersect")
6782    {
6783      ideal intersection = fetch(gnir,gIntersection);
6784    }
6785
6786//HIER
6787    if(abspri)
6788    {
6789      list resu,tempo;
6790      string absotto;
6791      for(ab=1;ab<=size(primary)/2;ab++)
6792      {
6793        absotto= absFactorize(primary[2*ab][1],77);
6794        tempo=primary[2*ab-1],primary[2*ab],absotto,string(var(nvars(basering)));
6795        resu[ab]=tempo;
6796      }
6797      primary=resu;
6798      intersection = 1;
6799      for(ab=1;ab<=size(primary);ab++)
6800      {
6801        intersection = intersect(intersection, primary[ab][2]);
6802      }
6803    }
6804    if (intersectOption == "intersect")
6805    {
6806      return(list(primary, intersection));
6807    }
6808    else
6809    {
6810      return(primary);
6811    }
6812  }
6813
6814 //------------------------------------------------------------------
6815 //the zero-dimensional case
6816 //------------------------------------------------------------------
6817  if (dim(@j)==0)
6818  {
6819    op=option(get);
6820    option(redSB);
6821    list gprimary= newZero_decomp(@j,ser,@wr);
6822
6823    setring @P;
6824    primary=fetch(gnir,gprimary);
6825
6826    if(size(ser)>0)
6827    {
6828      primary=cleanPrimary(primary);
6829    }
6830//HIER
6831    if(abspri)
6832    {
6833      list resu,tempo;
6834      string absotto;
6835      for(ab=1;ab<=size(primary)/2;ab++)
6836      {
6837        absotto= absFactorize(primary[2*ab][1],77);
6838        tempo=primary[2*ab-1],primary[2*ab],absotto,string(var(nvars(basering)));
6839        resu[ab]=tempo;
6840      }
6841      primary=resu;
6842    }
6843    if (intersectOption == "intersect")
6844    {
6845      return(list(primary, fetch(gnir,@j)));
6846    }
6847    else
6848    {
6849      return(primary);
6850    }
6851  }
6852
6853  poly @gs,@gh,@p;
6854  string @va,quotring;
6855  list quprimary,htprimary,collectprimary,lsau,lnew,allindep,restindep;
6856  ideal @h;
6857  int jdim=dim(@j);
6858  list fett;
6859  int lauf,di,newtest;
6860  //------------------------------------------------------------------
6861  //search for a maximal independent set indep,i.e.
6862  //look for subring such that the intersection with the ideal is zero
6863  //j intersected with K[var(indep[3]+1),...,var(nvar] is zero,
6864  //indep[1] is the new varstring and indep[2] the string for block-ordering
6865  //------------------------------------------------------------------
6866  if(@wr!=1)
6867  {
6868    allindep = newMaxIndependSetLp(@j, indepOption);
6869    for(@m=1;@m<=size(allindep);@m++)
6870    {
6871      if(allindep[@m][3]==jdim)
6872      {
6873        di++;
6874        indep[di]=allindep[@m];
6875      }
6876      else
6877      {
6878        lauf++;
6879        restindep[lauf]=allindep[@m];
6880      }
6881    }
6882  }
6883  else
6884  {
6885    indep = newMaxIndependSetLp(@j, indepOption);
6886  }
6887
6888  ideal jkeep=@j;
6889  if(ordstr(@P)[1]=="w")
6890  {
6891    execute("ring @Phelp=("+charstr(gnir)+"),("+varstr(gnir)+"),("+ordstr(@P)+");");
6892  }
6893  else
6894  {
6895    execute( "ring @Phelp=("+charstr(gnir)+"),("+varstr(gnir)+"),(C,dp);");
6896  }
6897
6898  if(homo==1)
6899  {
6900    if((ordstr(@P)[3]=="d")||(ordstr(@P)[1]=="d")||(ordstr(@P)[1]=="w")
6901       ||(ordstr(@P)[3]=="w"))
6902    {
6903      ideal jwork=imap(@P,tras);
6904      attrib(jwork,"isSB",1);
6905    }
6906    else
6907    {
6908      ideal jwork=std(imap(gnir,@j),@hilb,@w);
6909    }
6910  }
6911  else
6912  {
6913    ideal jwork=groebner(imap(gnir,@j));
6914  }
6915  list hquprimary;
6916  poly @p,@q;
6917  ideal @h,fac,ser;
6918//Aenderung================
6919  ideal @Ptest=1;
6920//=========================
6921  di=dim(jwork);
6922  keepdi=di;
6923
6924  ser = 1;
6925
6926  setring gnir;
6927  for(@m=1; @m<=size(indep); @m++)
6928  {
6929    data[1] = indep[@m];
6930    result = newReduction(@j, ser, @hilb, @w, jdim, abspri, @wr, data);
6931    quprimary = quprimary + result[1];
6932    if(abspri)
6933    {
6934      absprimary = absprimary + result[2];
6935      abskeep = abskeep + result[3];
6936    }
6937    @h = result[5];
6938    ser = result[4];
6939    if(size(@h)>0)
6940    {
6941      //---------------------------------------------------------------
6942      //we change to @Phelp to have the ordering dp for saturation
6943      //---------------------------------------------------------------
6944
6945      setring @Phelp;
6946      @h=imap(gnir,@h);
6947//Aenderung==================================
6948      if(defined(@LL)){kill @LL;}
6949      list @LL=minSat(jwork,@h);
6950      @Ptest=intersect(@Ptest,@LL[1]);
6951      ser = intersect(ser, @LL[1]);
6952//===========================================
6953
6954      if(@wr!=1)
6955      {
6956//Aenderung==================================
6957        @q=@LL[2];
6958//===========================================
6959        //@q=minSat(jwork,@h)[2];
6960      }
6961      else
6962      {
6963        fac=ideal(0);
6964        for(lauf=1;lauf<=ncols(@h);lauf++)
6965        {
6966          if(deg(@h[lauf])>0)
6967          {
6968            fac=fac+factorize(@h[lauf],1);
6969          }
6970        }
6971        fac=simplify(fac,6);
6972        @q=1;
6973        for(lauf=1;lauf<=size(fac);lauf++)
6974        {
6975          @q=@q*fac[lauf];
6976        }
6977      }
6978      jwork = std(jwork,@q);
6979      keepdi = dim(jwork);
6980      if(keepdi < di)
6981      {
6982        setring gnir;
6983        @j = imap(@Phelp, jwork);
6984        ser = imap(@Phelp, ser);
6985        break;
6986      }
6987      if(homo == 1)
6988      {
6989        @hilb = hilb(jwork, 1, @w);
6990      }
6991
6992      setring gnir;
6993      ser = imap(@Phelp, ser);
6994      @j = imap(@Phelp, jwork);
6995    }
6996  }
6997
6998  if((size(quprimary)==0)&&(@wr==1))
6999  {
7000     @j=ideal(1);
7001     quprimary[1]=ideal(1);
7002     quprimary[2]=ideal(1);
7003  }
7004  if((size(quprimary)==0))
7005  {
7006    keepdi = di - 1;
7007    quprimary[1]=ideal(1);
7008    quprimary[2]=ideal(1);
7009  }
7010  //---------------------------------------------------------------
7011  //notice that j=sat(j,gh) intersected with (j,gh^n)
7012  //we finished with sat(j,gh) and have to start with (j,gh^n)
7013  //---------------------------------------------------------------
7014  if((deg(@j[1])!=0)&&(@wr!=1))
7015  {
7016     if(size(quprimary)>0)
7017     {
7018        setring @Phelp;
7019        ser=imap(gnir,ser);
7020
7021        hquprimary=imap(gnir,quprimary);
7022        if(@wr==0)
7023        {
7024//Aenderung====================================================
7025//HIER STATT DURCHSCHNITT SATURIEREN!
7026           ideal htest=@Ptest;
7027/*
7028           ideal htest=hquprimary[1];
7029           for (@n1=2;@n1<=size(hquprimary)/2;@n1++)
7030           {
7031              htest=intersect(htest,hquprimary[2*@n1-1]);
7032           }
7033*/
7034//=============================================================
7035        }
7036        else
7037        {
7038           ideal htest=hquprimary[2];
7039
7040           for (@n1=2;@n1<=size(hquprimary)/2;@n1++)
7041           {
7042              htest=intersect(htest,hquprimary[2*@n1]);
7043           }
7044        }
7045
7046        if(size(ser)>0)
7047        {
7048           ser=intersect(htest,ser);
7049        }
7050        else
7051        {
7052          ser=htest;
7053        }
7054        setring gnir;
7055        ser=imap(@Phelp,ser);
7056     }
7057     if(size(reduce(ser,peek,1))!=0)
7058     {
7059        for(@m=1;@m<=size(restindep);@m++)
7060        {
7061         // if(restindep[@m][3]>=keepdi)
7062         // {
7063           isat=0;
7064           @n2=0;
7065
7066           if(restindep[@m][1]==varstr(basering))
7067           //the good case, nothing to do, just to have the same notations
7068           //change the ring
7069           {
7070              execute("ring gnir1 = ("+charstr(basering)+"),("+
7071                varstr(basering)+"),("+ordstr(basering)+");");
7072              ideal @j=fetch(gnir,jkeep);
7073              attrib(@j,"isSB",1);
7074           }
7075           else
7076           {
7077              @va=string(maxideal(1));
7078              execute("ring gnir1 = ("+charstr(basering)+"),("+
7079                      restindep[@m][1]+"),(" +restindep[@m][2]+");");
7080              execute("map phi=gnir,"+@va+";");
7081              op=option(get);
7082              option(redSB);
7083              if(homo==1)
7084              {
7085                 ideal @j=std(phi(jkeep),keephilb,@w);
7086              }
7087              else
7088              {
7089                ideal @j=groebner(phi(jkeep));
7090              }
7091              ideal ser=phi(ser);
7092              option(set,op);
7093           }
7094
7095           for (lauf=1;lauf<=size(@j);lauf++)
7096           {
7097              fett[lauf]=size(@j[lauf]);
7098           }
7099           //------------------------------------------------------------------
7100           //we have now the following situation:
7101           //j intersected with K[var(nnp+1),..,var(nva)] is zero so we may
7102           //pass to this quotientring, j is their still a standardbasis, the
7103           //leading coefficients of the polynomials  there (polynomials in
7104           //K[var(nnp+1),..,var(nva)]) are collected in the list h,
7105           //we need their ggt, gh, because of the following:
7106           //let (j:gh^n)=(j:gh^infinity) then
7107           //j*K(var(nnp+1),..,var(nva))[..the rest..]
7108           //intersected with K[var(1),...,var(nva)] is (j:gh^n)
7109           //on the other hand j=(j,gh^n) intersected with (j:gh^n)
7110
7111           //------------------------------------------------------------------
7112
7113           //the arrangement for the quotientring
7114           // K(var(nnp+1),..,var(nva))[..the rest..]
7115           //and the map phi:K[var(1),...,var(nva)] ---->
7116           //--->K(var(nnpr+1),..,var(nva))[..the rest..]
7117           //------------------------------------------------------------------
7118
7119           quotring=prepareQuotientring(nvars(basering)-restindep[@m][3]);
7120
7121           //------------------------------------------------------------------
7122           //we pass to the quotientring  K(var(nnp+1),..,var(nva))[..rest..]
7123           //------------------------------------------------------------------
7124
7125           execute(quotring);
7126
7127           // @j considered in the quotientring
7128           ideal @j=imap(gnir1,@j);
7129           ideal ser=imap(gnir1,ser);
7130
7131           kill gnir1;
7132
7133           //j is a standardbasis in the quotientring but usually not minimal
7134           //here it becomes minimal
7135           @j=clearSB(@j,fett);
7136           attrib(@j,"isSB",1);
7137
7138           //we need later ggt(h[1],...)=gh for saturation
7139           ideal @h;
7140
7141           for(@n=1;@n<=size(@j);@n++)
7142           {
7143              @h[@n]=leadcoef(@j[@n]);
7144           }
7145           //the primary decomposition of j*K(var(nnp+1),..,var(nva))[..rest..]
7146
7147           op=option(get);
7148           option(redSB);
7149           list uprimary= newZero_decomp(@j,ser,@wr);
7150//HIER
7151           if(abspri)
7152           {
7153              ideal II;
7154              ideal jmap;
7155              map sigma;
7156              nn=nvars(basering);
7157              map invsigma=basering,maxideal(1);
7158              for(ab=1;ab<=size(uprimary)/2;ab++)
7159              {
7160                 II=uprimary[2*ab];
7161                 attrib(II,"isSB",1);
7162                 if(deg(II[1])!=vdim(II))
7163                 {
7164                    jmap=randomLast(50);
7165                    sigma=basering,jmap;
7166                    jmap[nn]=2*var(nn)-jmap[nn];
7167                    invsigma=basering,jmap;
7168                    II=groebner(sigma(II));
7169                  }
7170                  absprimarytmp[ab]= absFactorize(II[1],77);
7171                  II=var(nn);
7172                  abskeeptmp[ab]=string(invsigma(II));
7173                  invsigma=basering,maxideal(1);
7174              }
7175           }
7176           option(set,op);
7177
7178           //we need the intersection of the ideals in the list quprimary with
7179           //the polynomialring, i.e. let q=(f1,...,fr) in the quotientring
7180           //such an ideal but fi polynomials, then the intersection of q with
7181           //the polynomialring is the saturation of the ideal generated by
7182           //f1,...,fr with respect toh which is the lcm of the leading
7183           //coefficients of the fi considered in the quotientring:
7184           //this is coded in saturn
7185
7186           list saturn;
7187           ideal hpl;
7188
7189           for(@n=1;@n<=size(uprimary);@n++)
7190           {
7191              hpl=0;
7192              for(@n1=1;@n1<=size(uprimary[@n]);@n1++)
7193              {
7194                 hpl=hpl,leadcoef(uprimary[@n][@n1]);
7195              }
7196              saturn[@n]=hpl;
7197           }
7198           //------------------------------------------------------------------
7199           //we leave  the quotientring   K(var(nnp+1),..,var(nva))[..rest..]
7200           //back to the polynomialring
7201           //------------------------------------------------------------------
7202           setring gnir;
7203           collectprimary=imap(quring,uprimary);
7204           lsau=imap(quring,saturn);
7205           @h=imap(quring,@h);
7206
7207           kill quring;
7208
7209
7210           @n2=size(quprimary);
7211//================NEU=========================================
7212           if(deg(quprimary[1][1])<=0){ @n2=0; }
7213//============================================================
7214
7215           @n3=@n2;
7216
7217           for(@n1=1;@n1<=size(collectprimary)/2;@n1++)
7218           {
7219              if(deg(collectprimary[2*@n1][1])>0)
7220              {
7221                 @n2++;
7222                 quprimary[@n2]=collectprimary[2*@n1-1];
7223                 lnew[@n2]=lsau[2*@n1-1];
7224                 @n2++;
7225                 lnew[@n2]=lsau[2*@n1];
7226                 quprimary[@n2]=collectprimary[2*@n1];
7227                 if(abspri)
7228                 {
7229                   absprimary[@n2/2]=absprimarytmp[@n1];
7230                   abskeep[@n2/2]=abskeeptmp[@n1];
7231                 }
7232              }
7233           }
7234
7235
7236           //here the intersection with the polynomialring
7237           //mentioned above is really computed
7238
7239           for(@n=@n3/2+1;@n<=@n2/2;@n++)
7240           {
7241              if(specialIdealsEqual(quprimary[2*@n-1],quprimary[2*@n]))
7242              {
7243                 quprimary[2*@n-1]=sat2(quprimary[2*@n-1],lnew[2*@n-1])[1];
7244                 quprimary[2*@n]=quprimary[2*@n-1];
7245              }
7246              else
7247              {
7248                 if(@wr==0)
7249                 {
7250                    quprimary[2*@n-1]=sat2(quprimary[2*@n-1],lnew[2*@n-1])[1];
7251                 }
7252                 quprimary[2*@n]=sat2(quprimary[2*@n],lnew[2*@n])[1];
7253              }
7254           }
7255           if(@n2>=@n3+2)
7256           {
7257              setring @Phelp;
7258              ser=imap(gnir,ser);
7259              hquprimary=imap(gnir,quprimary);
7260              for(@n=@n3/2+1;@n<=@n2/2;@n++)
7261              {
7262                if(@wr==0)
7263                {
7264                   ser=intersect(ser,hquprimary[2*@n-1]);
7265                }
7266                else
7267                {
7268                   ser=intersect(ser,hquprimary[2*@n]);
7269                }
7270              }
7271              setring gnir;
7272              ser=imap(@Phelp,ser);
7273           }
7274
7275         // }
7276        }
7277//HIER
7278        if(abspri)
7279        {
7280          list resu,tempo;
7281          for(ab=1;ab<=size(quprimary)/2;ab++)
7282          {
7283             if (deg(quprimary[2*ab][1])!=0)
7284             {
7285               tempo=quprimary[2*ab-1],quprimary[2*ab],
7286                         absprimary[ab],abskeep[ab];
7287               resu[ab]=tempo;
7288             }
7289          }
7290          quprimary=resu;
7291          @wr=3;
7292        }
7293        if(size(reduce(ser,peek,1))!=0)
7294        {
7295           if(@wr>0)
7296           {
7297              // The following line was dropped to avoid the recursion step:
7298              //htprimary=newDecompStep(@j,@wr,peek,ser);
7299              htprimary = list();
7300           }
7301           else
7302           {
7303              // The following line was dropped to avoid the recursion step:
7304              //htprimary=newDecompStep(@j,peek,ser);
7305              htprimary = list();
7306           }
7307           // here we collect now both results primary(sat(j,gh))
7308           // and primary(j,gh^n)
7309           @n=size(quprimary);
7310           if (deg(quprimary[1][1])<=0) { @n=0; }
7311           for (@k=1;@k<=size(htprimary);@k++)
7312           {
7313              quprimary[@n+@k]=htprimary[@k];
7314           }
7315        }
7316     }
7317   }
7318   else
7319   {
7320      if(abspri)
7321      {
7322        list resu,tempo;
7323        for(ab=1;ab<=size(quprimary)/2;ab++)
7324        {
7325           tempo=quprimary[2*ab-1],quprimary[2*ab],
7326                   absprimary[ab],abskeep[ab];
7327           resu[ab]=tempo;
7328        }
7329        quprimary=resu;
7330      }
7331   }
7332  //---------------------------------------------------------------------------
7333  //back to the ring we started with
7334  //the final result: primary
7335  //---------------------------------------------------------------------------
7336
7337  setring @P;
7338  primary=imap(gnir,quprimary);
7339
7340  if (intersectOption == "intersect")
7341  {
7342     return(list(primary, imap(gnir, ser)));
7343  }
7344  else
7345  {
7346    return(primary);
7347  }
7348}
7349example
7350{ "EXAMPLE:"; echo = 2;
7351   ring  r = 32003,(x,y,z),lp;
7352   poly  p = z2+1;
7353   poly  q = z4+2;
7354   ideal i = p^2*q^3,(y-z3)^3,(x-yz+z4)^4;
7355   list pr= newDecompStep(i);
7356   pr;
7357   testPrimary( pr, i);
7358}
7359
7360// This was part of proc decomp.
7361// In proc newDecompStep, used for the computation of the minimal associated primes,
7362// this part was separated as a soubrutine to make the code more clear.
7363// Also, since the reduction is performed twice in proc newDecompStep, it should use both times this routine.
7364// This is not yet implemented, since the reduction is not exactly the same and some changes should be made.
7365static proc newReduction(ideal @j, ideal ser, intvec @hilb, intvec @w, int jdim, int abspri, int @wr, list data)
7366{
7367   string @va;
7368   string quotring;
7369   intvec op;
7370   intvec @vv;
7371   def gnir = basering;
7372   ideal isat=0;
7373   int @n;
7374   int @n1 = 0;
7375   int @n2 = 0;
7376   int @n3 = 0;
7377   int homo = homog(@j);
7378   int lauf;
7379   int @k;
7380   list fett;
7381   int keepdi;
7382   list collectprimary;
7383   list lsau;
7384   list lnew;
7385   ideal @h;
7386
7387   list indepInfo = data[1];
7388   list quprimary = list();
7389
7390   //if(abspri)
7391   //{
7392     int ab;
7393     list absprimarytmp,abskeeptmp;
7394     list absprimary, abskeep;
7395   //}
7396   // Debug
7397   dbprint(printlevel - voice, "newReduction, v2.0");
7398
7399   if((indepInfo[1]==varstr(basering)))  // &&(@m==1)
7400   //this is the good case, nothing to do, just to have the same notations
7401   //change the ring
7402   {
7403     execute("ring gnir1 = ("+charstr(basering)+"),("+varstr(basering)+"),("
7404                              +ordstr(basering)+");");
7405     ideal @j = fetch(gnir, @j);
7406     attrib(@j,"isSB",1);
7407     ideal ser = fetch(gnir, ser);
7408   }
7409   else
7410   {
7411     @va=string(maxideal(1));
7412//Aenderung==============
7413     //if(@m==1)
7414     //{
7415     //  @j=fetch(@P,i);
7416     //}
7417//=======================
7418     execute("ring gnir1 = ("+charstr(basering)+"),("+indepInfo[1]+"),("
7419                              +indepInfo[2]+");");
7420     execute("map phi=gnir,"+@va+";");
7421     op=option(get);
7422     option(redSB);
7423     if(homo==1)
7424     {
7425       ideal @j=std(phi(@j),@hilb,@w);
7426     }
7427     else
7428     {
7429       ideal @j=groebner(phi(@j));
7430     }
7431     ideal ser=phi(ser);
7432
7433     option(set,op);
7434   }
7435   if((deg(@j[1])==0)||(dim(@j)<jdim))
7436   {
7437     setring gnir;
7438     break;
7439   }
7440   for (lauf=1;lauf<=size(@j);lauf++)
7441   {
7442     fett[lauf]=size(@j[lauf]);
7443   }
7444   //------------------------------------------------------------------------
7445   //we have now the following situation:
7446   //j intersected with K[var(nnp+1),..,var(nva)] is zero so we may pass
7447   //to this quotientring, j is their still a standardbasis, the
7448   //leading coefficients of the polynomials  there (polynomials in
7449   //K[var(nnp+1),..,var(nva)]) are collected in the list h,
7450   //we need their ggt, gh, because of the following: let
7451   //(j:gh^n)=(j:gh^infinity) then j*K(var(nnp+1),..,var(nva))[..the rest..]
7452   //intersected with K[var(1),...,var(nva)] is (j:gh^n)
7453   //on the other hand j=(j,gh^n) intersected with (j:gh^n)
7454
7455   //------------------------------------------------------------------------
7456
7457   //arrangement for quotientring K(var(nnp+1),..,var(nva))[..the rest..] and
7458   //map phi:K[var(1),...,var(nva)] --->K(var(nnpr+1),..,var(nva))[..rest..]
7459   //------------------------------------------------------------------------
7460
7461   quotring=prepareQuotientring(nvars(basering)-indepInfo[3]);
7462
7463   //---------------------------------------------------------------------
7464   //we pass to the quotientring   K(var(nnp+1),..,var(nva))[..the rest..]
7465   //---------------------------------------------------------------------
7466
7467   ideal @jj=lead(@j);               //!! vorn vereinbaren
7468   execute(quotring);
7469
7470   ideal @jj=imap(gnir1,@jj);
7471   @vv=clearSBNeu(@jj,fett);  //!! vorn vereinbaren
7472   setring gnir1;
7473   @k=size(@j);
7474   for (lauf=1;lauf<=@k;lauf++)
7475   {
7476     if(@vv[lauf]==1)
7477     {
7478       @j[lauf]=0;
7479     }
7480   }
7481   @j=simplify(@j,2);
7482   setring quring;
7483   // @j considered in the quotientring
7484   ideal @j=imap(gnir1,@j);
7485
7486   ideal ser=imap(gnir1,ser);
7487
7488   kill gnir1;
7489
7490   //j is a standardbasis in the quotientring but usually not minimal
7491   //here it becomes minimal
7492
7493   attrib(@j,"isSB",1);
7494
7495   //we need later ggt(h[1],...)=gh for saturation
7496   ideal @h;
7497   if(deg(@j[1])>0)
7498   {
7499     for(@n=1;@n<=size(@j);@n++)
7500     {
7501       @h[@n]=leadcoef(@j[@n]);
7502     }
7503     //the primary decomposition of j*K(var(nnp+1),..,var(nva))[..the rest..]
7504     op=option(get);
7505     option(redSB);
7506
7507     int zeroMinAss = @wr;
7508     if (@wr == 2) {zeroMinAss = 1;}
7509     list uprimary= newZero_decomp(@j, ser, zeroMinAss);
7510
7511//HIER
7512     if(abspri)
7513     {
7514       ideal II;
7515       ideal jmap;
7516       map sigma;
7517       nn=nvars(basering);
7518       map invsigma=basering,maxideal(1);
7519       for(ab=1;ab<=size(uprimary)/2;ab++)
7520       {
7521         II=uprimary[2*ab];
7522         attrib(II,"isSB",1);
7523         if(deg(II[1])!=vdim(II))
7524         {
7525           jmap=randomLast(50);
7526           sigma=basering,jmap;
7527           jmap[nn]=2*var(nn)-jmap[nn];
7528           invsigma=basering,jmap;
7529           II=groebner(sigma(II));
7530         }
7531         absprimarytmp[ab]= absFactorize(II[1],77);
7532         II=var(nn);
7533         abskeeptmp[ab]=string(invsigma(II));
7534         invsigma=basering,maxideal(1);
7535       }
7536     }
7537     option(set,op);
7538   }
7539   else
7540   {
7541     list uprimary;
7542     uprimary[1]=ideal(1);
7543     uprimary[2]=ideal(1);
7544   }
7545   //we need the intersection of the ideals in the list quprimary with the
7546   //polynomialring, i.e. let q=(f1,...,fr) in the quotientring such an ideal
7547   //but fi polynomials, then the intersection of q with the polynomialring
7548   //is the saturation of the ideal generated by f1,...,fr with respect to
7549   //h which is the lcm of the leading coefficients of the fi considered in
7550   //in the quotientring: this is coded in saturn
7551
7552   list saturn;
7553   ideal hpl;
7554
7555   for(@n=1;@n<=size(uprimary);@n++)
7556   {
7557     uprimary[@n]=interred(uprimary[@n]); // temporary fix
7558     hpl=0;
7559     for(@n1=1;@n1<=size(uprimary[@n]);@n1++)
7560     {
7561       hpl=hpl,leadcoef(uprimary[@n][@n1]);
7562     }
7563     saturn[@n]=hpl;
7564   }
7565
7566   //--------------------------------------------------------------------
7567   //we leave  the quotientring   K(var(nnp+1),..,var(nva))[..the rest..]
7568   //back to the polynomialring
7569   //---------------------------------------------------------------------
7570   setring gnir;
7571
7572   collectprimary=imap(quring,uprimary);
7573   lsau=imap(quring,saturn);
7574   @h=imap(quring,@h);
7575
7576   kill quring;
7577
7578   @n2=size(quprimary);
7579   @n3=@n2;
7580
7581   for(@n1=1;@n1<=size(collectprimary)/2;@n1++)
7582   {
7583     if(deg(collectprimary[2*@n1][1])>0)
7584     {
7585       @n2++;
7586       quprimary[@n2]=collectprimary[2*@n1-1];
7587       lnew[@n2]=lsau[2*@n1-1];
7588       @n2++;
7589       lnew[@n2]=lsau[2*@n1];
7590       quprimary[@n2]=collectprimary[2*@n1];
7591       if(abspri)
7592       {
7593         absprimary[@n2/2]=absprimarytmp[@n1];
7594         abskeep[@n2/2]=abskeeptmp[@n1];
7595       }
7596     }
7597   }
7598
7599   //here the intersection with the polynomialring
7600   //mentioned above is really computed
7601   for(@n=@n3/2+1;@n<=@n2/2;@n++)
7602   {
7603     if(specialIdealsEqual(quprimary[2*@n-1],quprimary[2*@n]))
7604     {
7605       quprimary[2*@n-1]=sat2(quprimary[2*@n-1],lnew[2*@n-1])[1];
7606       quprimary[2*@n]=quprimary[2*@n-1];
7607     }
7608     else
7609     {
7610       if(@wr==0)
7611       {
7612         quprimary[2*@n-1]=sat2(quprimary[2*@n-1],lnew[2*@n-1])[1];
7613       }
7614       quprimary[2*@n]=sat2(quprimary[2*@n],lnew[2*@n])[1];
7615     }
7616   }
7617
7618   return(quprimary, absprimary, abskeep, ser, @h);
7619}
7620
7621
7622////////////////////////////////////////////////////////////////////////////
7623
7624
7625
7626
7627///////////////////////////////////////////////////////////////////////////////
7628// Based on minAssGTZ
7629
7630proc minAss(ideal i,list #)
7631"USAGE:   minAss(I[, l]); i ideal, l list (optional) of parameters, same as minAssGTZ
7632RETURN:  a list, the minimal associated prime ideals of I.
7633NOTE:    Designed for characteristic 0, works also in char k > 0 based
7634         on an algorithm of Yokoyama
7635EXAMPLE: example minAss; shows an example
7636"
7637{
7638  return(minAssGTZ(i,#));
7639}
7640example
7641{ "EXAMPLE:";  echo = 2;
7642   ring  r = 0, (x, y, z), dp;
7643   poly  p = z2 + 1;
7644   poly  q = z3 + 2;
7645   ideal i = p * q^2, y - z2;
7646   list pr = minAss(i);
7647   pr;
7648}
7649
7650
7651///////////////////////////////////////////////////////////////////////////////
7652//
7653// Computes the minimal associated primes of I via Laplagne algorithm,
7654// using primary decomposition in the zero dimensional case.
7655// For reduction to the zerodimensional case, it uses the procedure
7656// decomp, with some modifications to avoid the recursion.
7657//
7658
7659static proc minAssSL(ideal I)
7660// Input = I, ideal
7661// Output = primaryDec where primaryDec is the list of the minimal
7662// associated primes and the primary components corresponding to these primes.
7663{
7664  ideal P = 1;
7665  list pd = list();
7666  int k;
7667  int stop = 0;
7668  list primaryDec = list();
7669
7670  while (stop == 0)
7671  {
7672    // Debug
7673    dbprint(printlevel - voice, "// We call minAssSLIteration to find new prime ideals!");
7674    pd = minAssSLIteration(I, P);
7675    // Debug
7676    dbprint(printlevel - voice, "// Output of minAssSLIteration:");
7677    dbprint(printlevel - voice, pd);
7678    if (size(pd[1]) > 0)
7679    {
7680      primaryDec = primaryDec + pd[1];
7681      // Debug
7682      dbprint(printlevel - voice, "// We intersect the prime ideals obtained.");
7683      P = intersect(P, pd[2]);
7684      // Debug
7685      dbprint(printlevel - voice, "// Intersection finished.");
7686    }
7687    else
7688    {
7689      stop = 1;
7690    }
7691  }
7692
7693  // Returns only the primary components, not the radical.
7694  return(primaryDec);
7695}
7696
7697///////////////////////////////////////////////////////////////////////////////
7698// Given an ideal I and an ideal P (intersection of some minimal prime ideals
7699// associated to I), it calculates new minimal prime ideals associated to I
7700// which were not used to calculate P.
7701// This version uses Primary Decomposition in the zerodimensional case.
7702static proc minAssSLIteration(ideal I, ideal P);
7703{
7704  int k = 1;
7705  int good  = 0;
7706  list primaryDec = list();
7707  // Debug
7708  dbprint (printlevel-voice, "// We search for an element in P - sqrt(I).");
7709  while ((k <= size(P)) and (good == 0))
7710  {
7711    good = 1 - rad_con(P[k], I);
7712    k++;
7713  }
7714  k--;
7715  if (good == 0)
7716  {
7717    // Debug
7718    dbprint (printlevel - voice, "// No element was found, P = sqrt(I).");
7719    return (list(primaryDec, ideal(0)));
7720  }
7721  // Debug
7722  dbprint (printlevel - voice, "// We found h = ", P[k]);
7723  dbprint (printlevel - voice, "// We calculate the saturation of I with respect to the element just founded.");
7724  ideal J = sat(I, P[k])[1];
7725
7726  // Uses decomp from primdec, modified to avoid the recursion.
7727  // Debug
7728  dbprint(printlevel - voice, "// We do the reduction to the zerodimensional case, via decomp.");
7729
7730  primaryDec = newDecompStep(J, "oneIndep", "intersect", 2);
7731  // Debug
7732  dbprint(printlevel - voice, "// Proc decomp has found", size(primaryDec) / 2, "new primary components.");
7733
7734  return(primaryDec);
7735}
7736
7737
7738
7739///////////////////////////////////////////////////////////////////////////////////
7740// Based on maxIndependSet
7741// Added list # as parameter
7742// If the first element of # is 0, the output is only 1 max indep set.
7743// If no list is specified or #[1] = 1, the output is all the max indep set of the
7744// leading terms ideal. This is the original output of maxIndependSet
7745
7746proc newMaxIndependSetLp(ideal j, list #)
7747"USAGE:   newMaxIndependentSetLp(i); i ideal (returns all maximal independent sets of the corresponding leading terms ideal)
7748          newMaxIndependentSetLp(i, 0); i ideal (returns only one maximal independent set)
7749RETURN:  list = #1. new varstring with the maximal independent set at the end,
7750                #2. ordstring with the lp ordering,
7751                #3. the number of independent variables
7752NOTE:
7753EXAMPLE: example newMaxIndependentSetLp; shows an example
7754"
7755{
7756  int n, k, di;
7757  list resu, hilf;
7758  string var1, var2;
7759  list v = indepSet(j, 0);
7760
7761  // SL 2006.04.21 1 Lines modified to use only one independent Set
7762  string indepOption;
7763  if (size(#) > 0)
7764  {
7765    indepOption = #[1];
7766  }
7767  else
7768  {
7769    indepOption = "allIndep";
7770  }
7771
7772  int nMax;
7773  if (indepOption == "allIndep")
7774  {
7775    nMax = size(v);
7776  }
7777  else
7778  {
7779    nMax = 1;
7780  }
7781
7782  for(n = 1; n <= nMax; n++)
7783  // SL 2006.04.21 2
7784  {
7785    di = 0;
7786    var1 = "";
7787    var2 = "";
7788    for(k = 1; k <= size(v[n]); k++)
7789    {
7790      if(v[n][k] != 0)
7791      {
7792        di++;
7793        var2 = var2 + "var(" + string(k) + "), ";
7794      }
7795      else
7796      {
7797        var1 = var1 + "var(" + string(k) + "), ";
7798      }
7799    }
7800    if(di > 0)
7801    {
7802      var1 = var1 + var2;
7803      var1 = var1[1..size(var1) - 2];       // The "- 2" removes the trailer comma
7804      hilf[1] = var1;
7805      // SL 2006.21.04 1 The order is now block dp instead of lp
7806      //hilf[2] = "dp(" + string(nvars(basering) - di) + "), dp(" + string(di) + ")";
7807      // SL 2006.21.04 2
7808      // For decomp, lp ordering is needed. Nothing is changed.
7809      hilf[2] = "lp";
7810      hilf[3] = di;
7811      resu[n] = hilf;
7812    }
7813    else
7814    {
7815      resu[n] = varstr(basering), ordstr(basering), 0;
7816    }
7817  }
7818  return(resu);
7819}
7820example
7821{ "EXAMPLE:"; echo = 2;
7822   ring s1 = (0, x, y), (a, b, c, d, e, f, g), lp;
7823   ideal i = ea - fbg, fa + be, ec - fdg, fc + de;
7824   i = std(i);
7825   list l = newMaxIndependSetLp(i);
7826   l;
7827   i = i, g;
7828   l = newMaxIndependSetLp(i);
7829   l;
7830
7831   ring s = 0, (x, y, z), lp;
7832   ideal i = z, yx;
7833   list l = newMaxIndependSetLp(i);
7834   l;
7835}
7836
7837
7838///////////////////////////////////////////////////////////////////////////////
7839
7840proc newZero_decomp (ideal j, ideal ser, int @wr, list #)
7841"USAGE:   newZero_decomp(j,ser,@wr); j,ser ideals, @wr=0 or 1
7842         (@wr=0 for primary decomposition, @wr=1 for computation of associated
7843         primes)
7844         if #[1] = "nest", then #[2] indicates the nest level (number of recursive calls)
7845         When the nest level is high it indicates that the computation is difficult,
7846         and different methods are applied.
7847RETURN:  list = list of primary ideals and their radicals (at even positions
7848         in the list) if the input is zero-dimensional and a standardbases
7849         with respect to lex-ordering
7850         If ser!=(0) and ser is contained in j or if j is not zero-dimen-
7851         sional then ideal(1),ideal(1) is returned
7852NOTE:    Algorithm of Gianni/Trager/Zacharias
7853EXAMPLE: example newZero_decomp; shows an example
7854"
7855{
7856  def   @P = basering;
7857  int uytrewq;
7858  int nva = nvars(basering);
7859  int @k,@s,@n,@k1,zz;
7860  list primary,lres0,lres1,act,@lh,@wh;
7861  map phi,psi,phi1,psi1;
7862  ideal jmap,jmap1,jmap2,helpprim,@qh,@qht,ser1;
7863  intvec @vh,@hilb;
7864  string @ri;
7865  poly @f;
7866
7867  // Debug
7868  dbprint(printlevel - voice, "proc newZero_decomp");
7869
7870  if (dim(j)>0)
7871  {
7872    primary[1]=ideal(1);
7873    primary[2]=ideal(1);
7874    return(primary);
7875  }
7876  j=interred(j);
7877
7878  attrib(j,"isSB",1);
7879
7880  int nestLevel = 0;
7881  if (size(#) > 0)
7882  {
7883    if (typeof(#[1]) == "string")
7884    {
7885      if (#[1] == "nest")
7886      {
7887        nestLevel = #[2];
7888      }
7889      # = list();
7890    }
7891  }
7892
7893  if(vdim(j)==deg(j[1]))
7894  {
7895    act=factor(j[1]);
7896    for(@k=1;@k<=size(act[1]);@k++)
7897    {
7898      @qh=j;
7899      if(@wr==0)
7900      {
7901        @qh[1]=act[1][@k]^act[2][@k];
7902      }
7903      else
7904      {
7905        @qh[1]=act[1][@k];
7906      }
7907      primary[2*@k-1]=interred(@qh);
7908      @qh=j;
7909      @qh[1]=act[1][@k];
7910      primary[2*@k]=interred(@qh);
7911      attrib( primary[2*@k-1],"isSB",1);
7912
7913      if((size(ser)>0)&&(size(reduce(ser,primary[2*@k-1],1))==0))
7914      {
7915        primary[2*@k-1]=ideal(1);
7916        primary[2*@k]=ideal(1);
7917      }
7918    }
7919    return(primary);
7920  }
7921
7922  if(homog(j)==1)
7923  {
7924    primary[1]=j;
7925    if((size(ser)>0)&&(size(reduce(ser,j,1))==0))
7926    {
7927      primary[1]=ideal(1);
7928      primary[2]=ideal(1);
7929      return(primary);
7930    }
7931    if(dim(j)==-1)
7932    {
7933      primary[1]=ideal(1);
7934      primary[2]=ideal(1);
7935    }
7936    else
7937    {
7938      primary[2]=maxideal(1);
7939    }
7940    return(primary);
7941  }
7942
7943//the first element in the standardbase is factorized
7944  if(deg(j[1])>0)
7945  {
7946    act=factor(j[1]);
7947    testFactor(act,j[1]);
7948  }
7949  else
7950  {
7951    primary[1]=ideal(1);
7952    primary[2]=ideal(1);
7953    return(primary);
7954  }
7955
7956//with the factors new ideals (hopefully the primary decomposition)
7957//are created
7958  if(size(act[1])>1)
7959  {
7960    if(size(#)>1)
7961    {
7962      primary[1]=ideal(1);
7963      primary[2]=ideal(1);
7964      primary[3]=ideal(1);
7965      primary[4]=ideal(1);
7966      return(primary);
7967    }
7968    for(@k=1;@k<=size(act[1]);@k++)
7969    {
7970      if(@wr==0)
7971      {
7972        primary[2*@k-1]=std(j,act[1][@k]^act[2][@k]);
7973      }
7974      else
7975      {
7976        primary[2*@k-1]=std(j,act[1][@k]);
7977      }
7978      if((act[2][@k]==1)&&(vdim(primary[2*@k-1])==deg(act[1][@k])))
7979      {
7980        primary[2*@k]   = primary[2*@k-1];
7981      }
7982      else
7983      {
7984        primary[2*@k]   = primaryTest(primary[2*@k-1],act[1][@k]);
7985      }
7986    }
7987  }
7988  else
7989  {
7990    primary[1]=j;
7991    if((size(#)>0)&&(act[2][1]>1))
7992    {
7993      act[2]=1;
7994      primary[1]=std(primary[1],act[1][1]);
7995    }
7996    if(@wr!=0)
7997    {
7998      primary[1]=std(j,act[1][1]);
7999    }
8000    if((act[2][1]==1)&&(vdim(primary[1])==deg(act[1][1])))
8001    {
8002      primary[2]=primary[1];
8003    }
8004    else
8005    {
8006      primary[2]=primaryTest(primary[1],act[1][1]);
8007    }
8008  }
8009
8010  if(size(#)==0)
8011  {
8012    primary=splitPrimary(primary,ser,@wr,act);
8013  }
8014
8015  if((voice>=6)&&(char(basering)<=181))
8016  {
8017    primary=splitCharp(primary);
8018  }
8019
8020  if((@wr==2)&&(npars(basering)>0)&&(voice>=6)&&(char(basering)>0))
8021  {
8022  //the prime decomposition of Yokoyama in characteristic p
8023    list ke,ek;
8024    @k=0;
8025    while(@k<size(primary)/2)
8026    {
8027      @k++;
8028      if(size(primary[2*@k])==0)
8029      {
8030        ek=insepDecomp(primary[2*@k-1]);
8031        primary=delete(primary,2*@k);
8032        primary=delete(primary,2*@k-1);
8033        @k--;
8034      }
8035      ke=ke+ek;
8036    }
8037    for(@k=1;@k<=size(ke);@k++)
8038    {
8039      primary[size(primary)+1]=ke[@k];
8040      primary[size(primary)+1]=ke[@k];
8041    }
8042  }
8043
8044  if(nestLevel > 1){primary=extF(primary);}
8045
8046//test whether all ideals in the decomposition are primary and
8047//in general position
8048//if not after a random coordinate transformation of the last
8049//variable the corresponding ideal is decomposed again.
8050  if((npars(basering)>0)&&(nestLevel > 1))
8051  {
8052    poly randp;
8053    for(zz=1;zz<nvars(basering);zz++)
8054    {
8055      randp=randp
8056              +(random(0,5)*par(1)^2+random(0,5)*par(1)+random(0,5))*var(zz);
8057    }
8058    randp=randp+var(nvars(basering));
8059  }
8060  @k=0;
8061  while(@k<(size(primary)/2))
8062  {
8063    @k++;
8064    if (size(primary[2*@k])==0)
8065    {
8066      for(zz=1;zz<size(primary[2*@k-1])-1;zz++)
8067      {
8068        attrib(primary[2*@k-1],"isSB",1);
8069        if(vdim(primary[2*@k-1])==deg(primary[2*@k-1][zz]))
8070        {
8071          primary[2*@k]=primary[2*@k-1];
8072        }
8073      }
8074    }
8075  }
8076
8077  @k=0;
8078  ideal keep;
8079  while(@k<(size(primary)/2))
8080  {
8081    @k++;
8082    if (size(primary[2*@k])==0)
8083    {
8084      jmap=randomLast(100);
8085      jmap1=maxideal(1);
8086      jmap2=maxideal(1);
8087      @qht=primary[2*@k-1];
8088      if((npars(basering)>0)&&(nestLevel > 1))
8089      {
8090        jmap[size(jmap)]=randp;
8091      }
8092
8093      for(@n=2;@n<=size(primary[2*@k-1]);@n++)
8094      {
8095        if(deg(lead(primary[2*@k-1][@n]))==1)
8096        {
8097          for(zz=1;zz<=nva;zz++)
8098          {
8099            if(lead(primary[2*@k-1][@n])/var(zz)!=0)
8100            {
8101              jmap1[zz]=-1/leadcoef(primary[2*@k-1][@n])*primary[2*@k-1][@n]
8102                   +2/leadcoef(primary[2*@k-1][@n])*lead(primary[2*@k-1][@n]);
8103              jmap2[zz]=primary[2*@k-1][@n];
8104              @qht[@n]=var(zz);
8105            }
8106          }
8107          jmap[nva]=subst(jmap[nva],lead(primary[2*@k-1][@n]),0);
8108        }
8109      }
8110      if(size(subst(jmap[nva],var(1),0)-var(nva))!=0)
8111      {
8112        // jmap[nva]=subst(jmap[nva],var(1),0);
8113        //hier geaendert +untersuchen!!!!!!!!!!!!!!
8114      }
8115      phi1=@P,jmap1;
8116      phi=@P,jmap;
8117      for(@n=1;@n<=nva;@n++)
8118      {
8119        jmap[@n]=-(jmap[@n]-2*var(@n));
8120      }
8121      psi=@P,jmap;
8122      psi1=@P,jmap2;
8123      @qh=phi(@qht);
8124
8125//=================== the new part ============================
8126
8127      if (npars(basering)>1) { @qh=groebner(@qh,"par2var"); }
8128      else                   { @qh=groebner(@qh); }
8129
8130//=============================================================
8131//       if(npars(@P)>0)
8132//       {
8133//          @ri= "ring @Phelp ="
8134//                  +string(char(@P))+",
8135//                   ("+varstr(@P)+","+parstr(@P)+",@t),(C,dp);";
8136//       }
8137//       else
8138//       {
8139//          @ri= "ring @Phelp ="
8140//                  +string(char(@P))+",("+varstr(@P)+",@t),(C,dp);";
8141//       }
8142//       execute(@ri);
8143//       ideal @qh=homog(imap(@P,@qht),@t);
8144//
8145//       ideal @qh1=std(@qh);
8146//       @hilb=hilb(@qh1,1);
8147//       @ri= "ring @Phelp1 ="
8148//                  +string(char(@P))+",("+varstr(@Phelp)+"),(C,lp);";
8149//       execute(@ri);
8150//       ideal @qh=homog(imap(@P,@qh),@t);
8151//       kill @Phelp;
8152//       @qh=std(@qh,@hilb);
8153//       @qh=subst(@qh,@t,1);
8154//       setring @P;
8155//       @qh=imap(@Phelp1,@qh);
8156//       kill @Phelp1;
8157//       @qh=clearSB(@qh);
8158//       attrib(@qh,"isSB",1);
8159//=============================================================
8160
8161      ser1=phi1(ser);
8162      @lh=newZero_decomp (@qh,phi(ser1),@wr, list("nest", nestLevel + 1));
8163
8164      kill lres0;
8165      list lres0;
8166      if(size(@lh)==2)
8167      {
8168        helpprim=@lh[2];
8169        lres0[1]=primary[2*@k-1];
8170        ser1=psi(helpprim);
8171        lres0[2]=psi1(ser1);
8172        if(size(reduce(lres0[2],lres0[1],1))==0)
8173        {
8174          primary[2*@k]=primary[2*@k-1];
8175          continue;
8176        }
8177      }
8178      else
8179      {
8180        lres1=psi(@lh);
8181        lres0=psi1(lres1);
8182      }
8183
8184//=================== the new part ============================
8185
8186      primary=delete(primary,2*@k-1);
8187      primary=delete(primary,2*@k-1);
8188      @k--;
8189      if(size(lres0)==2)
8190      {
8191        if (npars(basering)>1) { lres0[2]=groebner(lres0[2],"par2var"); }
8192        else                   { lres0[2]=groebner(lres0[2]); }
8193      }
8194      else
8195      {
8196        for(@n=1;@n<=size(lres0)/2;@n++)
8197        {
8198          if(specialIdealsEqual(lres0[2*@n-1],lres0[2*@n])==1)
8199          {
8200            lres0[2*@n-1]=groebner(lres0[2*@n-1]);
8201            lres0[2*@n]=lres0[2*@n-1];
8202            attrib(lres0[2*@n],"isSB",1);
8203          }
8204          else
8205          {
8206            lres0[2*@n-1]=groebner(lres0[2*@n-1]);
8207            lres0[2*@n]=groebner(lres0[2*@n]);
8208          }
8209        }
8210      }
8211      primary=primary+lres0;
8212
8213//=============================================================
8214//       if(npars(@P)>0)
8215//       {
8216//          @ri= "ring @Phelp ="
8217//                  +string(char(@P))+",
8218//                   ("+varstr(@P)+","+parstr(@P)+",@t),(C,dp);";
8219//       }
8220//       else
8221//       {
8222//          @ri= "ring @Phelp ="
8223//                  +string(char(@P))+",("+varstr(@P)+",@t),(C,dp);";
8224//       }
8225//       execute(@ri);
8226//       list @lvec;
8227//       list @lr=imap(@P,lres0);
8228//       ideal @lr1;
8229//
8230//       if(size(@lr)==2)
8231//       {
8232//          @lr[2]=homog(@lr[2],@t);
8233//          @lr1=std(@lr[2]);
8234//          @lvec[2]=hilb(@lr1,1);
8235//       }
8236//       else
8237//       {
8238//          for(@n=1;@n<=size(@lr)/2;@n++)
8239//          {
8240//             if(specialIdealsEqual(@lr[2*@n-1],@lr[2*@n])==1)
8241//             {
8242//                @lr[2*@n-1]=homog(@lr[2*@n-1],@t);
8243//                @lr1=std(@lr[2*@n-1]);
8244//                @lvec[2*@n-1]=hilb(@lr1,1);
8245//                @lvec[2*@n]=@lvec[2*@n-1];
8246//             }
8247//             else
8248//             {
8249//                @lr[2*@n-1]=homog(@lr[2*@n-1],@t);
8250//                @lr1=std(@lr[2*@n-1]);
8251//                @lvec[2*@n-1]=hilb(@lr1,1);
8252//                @lr[2*@n]=homog(@lr[2*@n],@t);
8253//                @lr1=std(@lr[2*@n]);
8254//                @lvec[2*@n]=hilb(@lr1,1);
8255//
8256//             }
8257//         }
8258//       }
8259//       @ri= "ring @Phelp1 ="
8260//                  +string(char(@P))+",("+varstr(@Phelp)+"),(C,lp);";
8261//       execute(@ri);
8262//       list @lr=imap(@Phelp,@lr);
8263//
8264//       kill @Phelp;
8265//       if(size(@lr)==2)
8266//      {
8267//          @lr[2]=std(@lr[2],@lvec[2]);
8268//          @lr[2]=subst(@lr[2],@t,1);
8269//
8270//       }
8271//       else
8272//       {
8273//          for(@n=1;@n<=size(@lr)/2;@n++)
8274//          {
8275//             if(specialIdealsEqual(@lr[2*@n-1],@lr[2*@n])==1)
8276//             {
8277//                @lr[2*@n-1]=std(@lr[2*@n-1],@lvec[2*@n-1]);
8278//                @lr[2*@n-1]=subst(@lr[2*@n-1],@t,1);
8279//                @lr[2*@n]=@lr[2*@n-1];
8280//                attrib(@lr[2*@n],"isSB",1);
8281//             }
8282//             else
8283//             {
8284//                @lr[2*@n-1]=std(@lr[2*@n-1],@lvec[2*@n-1]);
8285//                @lr[2*@n-1]=subst(@lr[2*@n-1],@t,1);
8286//                @lr[2*@n]=std(@lr[2*@n],@lvec[2*@n]);
8287//                @lr[2*@n]=subst(@lr[2*@n],@t,1);
8288//             }
8289//          }
8290//       }
8291//       kill @lvec;
8292//       setring @P;
8293//       lres0=imap(@Phelp1,@lr);
8294//       kill @Phelp1;
8295//       for(@n=1;@n<=size(lres0);@n++)
8296//       {
8297//          lres0[@n]=clearSB(lres0[@n]);
8298//          attrib(lres0[@n],"isSB",1);
8299//       }
8300//
8301//       primary[2*@k-1]=lres0[1];
8302//       primary[2*@k]=lres0[2];
8303//       @s=size(primary)/2;
8304//       for(@n=1;@n<=size(lres0)/2-1;@n++)
8305//       {
8306//         primary[2*@s+2*@n-1]=lres0[2*@n+1];
8307//         primary[2*@s+2*@n]=lres0[2*@n+2];
8308//       }
8309//       @k--;
8310//=============================================================
8311    }
8312  }
8313  return(primary);
8314}
8315example
8316{ "EXAMPLE:"; echo = 2;
8317   ring  r = 0,(x,y,z),lp;
8318   poly  p = z2+1;
8319   poly  q = z4+2;
8320   ideal i = p^2*q^3,(y-z3)^3,(x-yz+z4)^4;
8321   i=std(i);
8322   list  pr= newZero_decomp(i,ideal(0),0);
8323   pr;
8324}
8325///////////////////////////////////////////////////////////////////////////////
8326
8327////////////////////////////////////////////////////////////////////////////
8328/*
8329//Beispiele Wenk-Dipl (in ~/Texfiles/Diplom/Wenk/Examples/)
8330//Zeiten: Singular/Singular/Singular -r123456789 -v :wilde13 (PentiumPro200)
8331//Singular for HPUX-9 version 1-3-8  (2000060214)  Jun  2 2000 15:31:26
8332//(wilde13)
8333
8334//1. vdim=20, 3  Komponenten
8335//zerodec-time:2(1)  (matrix:1 charpoly:0 factor:1)
8336//primdecGTZ-time: 1(0)
8337ring rs= 0,(a,b,c),dp;
8338poly f1= a^2*b*c + a*b^2*c + a*b*c^2 + a*b*c + a*b + a*c + b*c;
8339poly f2= a^2*b^2*c + a*b^2*c^2 + a^2*b*c + a*b*c + b*c + a + c;
8340poly f3= a^2*b^2*c^2 + a^2*b^2*c + a*b^2*c + a*b*c + a*c + c + 1;
8341ideal gls=f1,f2,f3;
8342int time=timer;
8343printlevel =1;
8344time=timer; list pr1=zerodec(gls); timer-time;size(pr1);
8345time=timer; list pr =primdecGTZ(gls); timer-time;size(pr);
8346time=timer; ideal ra =radical(gls); timer-time;size(pr);
8347
8348//2.cyclic5  vdim=70, 20 Komponenten
8349//zerodec-time:36(28)  (matrix:1(0) charpoly:18(19) factor:17(9)
8350//primdecGTZ-time: 28(5)
8351//radical : 0
8352ring rs= 0,(a,b,c,d,e),dp;
8353poly f0= a + b + c + d + e + 1;
8354poly f1= a + b + c + d + e;
8355poly f2= a*b + b*c + c*d + a*e + d*e;
8356poly f3= a*b*c + b*c*d + a*b*e + a*d*e + c*d*e;
8357poly f4= a*b*c*d + a*b*c*e + a*b*d*e + a*c*d*e + b*c*d*e;
8358poly f5= a*b*c*d*e - 1;
8359ideal gls= f1,f2,f3,f4,f5;
8360
8361//3. random vdim=40, 1 Komponente
8362//zerodec-time:126(304)  (matrix:1 charpoly:115(298) factor:10(5))
8363//primdecGTZ-time:17 (11)
8364ring rs=0,(x,y,z),dp;
8365poly f1=2*x^2 + 4*x + 3*y^2 + 7*x*z + 9*y*z + 5*z^2;
8366poly f2=7*x^3 + 8*x*y + 12*y^2 + 18*x*z + 3*y^4*z + 10*z^3 + 12;
8367poly f3=3*x^4 + 1*x*y*z + 6*y^3 + 3*x*z^2 + 2*y*z^2 + 4*z^2 + 5;
8368ideal gls=f1,f2,f3;
8369
8370//4. introduction into resultants, sturmfels, vdim=28, 1 Komponente
8371//zerodec-time:4  (matrix:0 charpoly:0 factor:4)
8372//primdecGTZ-time:1
8373ring rs=0,(x,y),dp;
8374poly f1= x4+y4-1;
8375poly f2= x5y2-4x3y3+x2y5-1;
8376ideal gls=f1,f2;
8377
8378//5. 3 quadratic equations with random coeffs, vdim=8, 1 Komponente
8379//zerodec-time:0(0)  (matrix:0 charpoly:0 factor:0)
8380//primdecGTZ-time:1(0)
8381ring rs=0,(x,y,z),dp;
8382poly f1=2*x^2 + 4*x*y + 3*y^2 + 7*x*z + 9*y*z + 5*z^2 + 2;
8383poly f2=7*x^2 + 8*x*y + 12*y^2 + 18*x*z + 3*y*z + 10*z^2 + 12;
8384poly f3=3*x^2 + 1*x*y + 6*y^2 + 3*x*z + 2*y*z + 4*z^2 + 5;
8385ideal gls=f1,f2,f3;
8386
8387//6. 3 polys    vdim=24, 1 Komponente
8388// run("ex14",2);
8389//zerodec-time:5(4)  (matrix:0 charpoly:3(3) factor:2(1))
8390//primdecGTZ-time:4 (2)
8391ring rs=0,(x1,x2,x3,x4),dp;
8392poly f1=16*x1^2 + 3*x2^2 + 5*x3^4 - 1 - 4*x4 + x4^3;
8393poly f2=5*x1^3 + 3*x2^2 + 4*x3^2*x4 + 2*x1*x4 - 1 + x4 + 4*x1 + x2 + x3 + x4;
8394poly f3=-4*x1^2 + x2^2 + x3^2 - 3 + x4^2 + 4*x1 + x2 + x3 + x4;
8395poly f4=-4*x1 + x2 + x3 + x4;
8396ideal gls=f1,f2,f3,f4;
8397
8398//7. ex43, PoSSo, caprasse   vdim=56, 16 Komponenten
8399//zerodec-time:23(15)  (matrix:0 charpoly:16(13) factor:3(2))
8400//primdecGTZ-time:3 (2)
8401ring rs= 0,(y,z,x,t),dp;
8402ideal gls=y^2*z+2*y*x*t-z-2*x,
84034*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,
84042*y*z*t+x*t^2-2*z-x,
8405-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;
8406
8407//8. Arnborg-System, n=6 (II),    vdim=156, 90 Komponenten
8408//zerodec-time (char32003):127(45)(matrix:2(0) charpoly:106(37) factor:16(7))
8409//primdecGTZ-time(char32003) :81 (18)
8410//ring rs= 0,(a,b,c,d,x,f),dp;
8411ring rs= 32003,(a,b,c,d,x,f),dp;
8412ideal gls=a+b+c+d+x+f, ab+bc+cd+dx+xf+af, abc+bcd+cdx+d*xf+axf+abf,
8413abcd+bcdx+cd*xf+ad*xf+abxf+abcf, abcdx+bcd*xf+acd*xf+abd*xf+abcxf+abcdf,
8414abcd*xf-1;
8415
8416//9. ex42, PoSSo, Methan6_1, vdim=27, 2 Komponenten
8417//zerodec-time:610  (matrix:10 charpoly:557 factor:26)
8418//primdecGTZ-time: 118
8419//zerodec-time(char32003):2
8420//primdecGTZ-time(char32003):4
8421//ring rs= 0,(x1,x2,x3,x4,x5,x6,x7,x8,x9,x10),dp;
8422ring rs= 32003,(x1,x2,x3,x4,x5,x6,x7,x8,x9,x10),dp;
8423ideal gls=64*x2*x7-10*x1*x8+10*x7*x9+11*x7*x10-320000*x1,
8424-32*x2*x7-5*x2*x8-5*x2*x10+160000*x1-5000*x2,
8425-x3*x8+x6*x8+x9*x10+210*x6+1300000,
8426-x4*x8+700000,
8427x10^2-2*x5,
8428-x6*x8+x7*x9-210*x6,
8429-64*x2*x7-10*x7*x9-11*x7*x10+320000*x1-16*x7+7000000,
8430-10*x1*x8-10*x2*x8-10*x3*x8-10*x4*x8-10*x6*x8+10*x2*x10+11*x7*x10
8431    +20000*x2+14*x5,
8432x4*x8-x7*x9-x9*x10-410*x9,
843310*x2*x8+10*x3*x8+10*x6*x8+10*x7*x9-10*x2*x10-11*x7*x10-10*x9*x10
8434    -10*x10^2+1400*x6-4200*x10;
8435
8436//10. ex33, walk-s7, Diplomarbeit von Tim, vdim=114
8437//zerfaellt in unterschiedlich viele Komponenten in versch. Charkteristiken:
8438//char32003:30, char0:3(2xdeg1,1xdeg112!), char181:4(2xdeg1,1xdeg28,1xdeg84)
8439//char 0: zerodec-time:10075 (ca 3h) (matrix:3 charpoly:9367, factor:680
8440//        + 24 sec fuer Normalform (anstatt einsetzen), total [29623k])
8441//        primdecGTZ-time: 214
8442//char 32003:zerodec-time:197(68) (matrix:2(1) charpoly:173(60) factor:15(6))
8443//        primdecGTZ-time:14 (5)
8444//char 181:zerodec-time:(87) (matrix:(1) charpoly:(58) factor:(25))
8445//        primdecGTZ-time:(2)
8446//in char181 stimmen Ergebnisse von zerodec und primdecGTZ ueberein (gecheckt)
8447
8448//ring rs= 0,(a,b,c,d,e,f,g),dp;
8449ring rs= 32003,(a,b,c,d,e,f,g),dp;
8450poly f1= 2gb + 2fc + 2ed + a2 + a;
8451poly f2= 2gc + 2fd + e2 + 2ba + b;
8452poly f3= 2gd + 2fe + 2ca + c + b2;
8453poly f4= 2ge + f2 + 2da + d + 2cb;
8454poly f5= 2fg + 2ea + e + 2db + c2;
8455poly f6= g2 + 2fa + f + 2eb + 2dc;
8456poly f7= 2ga + g + 2fb + 2ec + d2;
8457ideal gls= f1,f2,f3,f4,f5,f6,f7;
8458
8459~/Singular/Singular/Singular -r123456789 -v
8460LIB"./primdec.lib";
8461timer=1;
8462int time=timer;
8463printlevel =1;
8464option(prot,mem);
8465time=timer; list pr1=zerodec(gls); timer-time;
8466
8467time=timer; list pr =primdecGTZ(gls); timer-time;
8468time=timer; list pr =primdecSY(gls); timer-time;
8469time=timer; ideal ra =radical(gls); timer-time;size(pr);
8470LIB"all.lib";
8471
8472ring R=0,(a,b,c,d,e,f),dp;
8473ideal I=cyclic(6);
8474minAssGTZ(I);
8475
8476
8477ring S=(2,a,b),(x,y),lp;
8478ideal I=x8-b,y4+a;
8479minAssGTZ(I);
8480
8481ring S1=2,(x,y,a,b),lp;
8482ideal I=x8-b,y4+a;
8483minAssGTZ(I);
8484
8485
8486ring S2=(2,z),(x,y),dp;
8487minpoly=z2+z+1;
8488ideal I=y3+y+1,x4+x+1;
8489primdecGTZ(I);
8490minAssGTZ(I);
8491
8492ring S3=2,(x,y,z),dp;
8493ideal I=y3+y+1,x4+x+1,z2+z+1;
8494primdecGTZ(I);
8495minAssGTZ(I);
8496
8497
8498ring R1=2,(x,y,z),lp;
8499ideal I=y6+y5+y3+y2+1,x4+x+1,z2+z+1;
8500primdecGTZ(I);
8501minAssGTZ(I);
8502
8503
8504ring R2=(2,z),(x,y),lp;
8505minpoly=z3+z+1;
8506ideal I=y2+y+(z2+z+1),x4+x+1;
8507primdecGTZ(I);
8508minAssGTZ(I);
8509
8510*/
Note: See TracBrowser for help on using the repository browser.