source: git/Singular/LIB/primdec.lib @ 85e68dd

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