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

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