source: git/Singular/LIB/primdec.lib @ 1b2216

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