source: git/Singular/LIB/primdec.lib @ 4719f0

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