source: git/Singular/LIB/primdec.lib @ 70ab73

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