source: git/Singular/LIB/mprimdec.lib @ 0cfbf94

spielwiese
Last change on this file since 0cfbf94 was 0610f0e, checked in by Hans Schoenemann <hannes@…>, 14 years ago
format git-svn-id: file:///usr/local/Singular/svn/trunk@12790 2c84dea3-7e68-4137-9b89-c4e89433aadc
  • Property mode set to 100644
File size: 62.1 KB
Line 
1// $Id$
2///////////////////////////////////////////////////////////////////////////////
3// mprimdec.lib
4// algorithms for primary decomposition for modules based on
5// the algorithms of Gianni, Trager and Zacharias and
6// Shimoyama and Yokoyama (generalization of the latter
7// suggested by Hans-Gert Graebe, Leipzig  )
8// using elments of primdec.lib
9// written by Alexander Dreyer
10//
11// $Log: not supported by cvs2svn $
12// Revision 1.6  2006/07/25 17:54:27  Singular
13// *hannes: Michael C.
14//
15// Revision 1.5  2005/04/28 09:22:17  Singular
16// *hannes/lossen: new ring.lib
17//
18// Revision 1.4  2001/08/27 14:47:54  Singular
19// *hannes: merge-2-0-2
20//
21// Revision 1.3  2001/07/10 11:49:19  dreyer
22// + changed commands factor to factorize(...,2), idealsEqual to modulesEqual
23//   minAssPrimes to minAssGTZ;  minAssChar;
24//
25//
26///////////////////////////////////////////////////////////////////////////////
27
28version="$Id$";
29category="Commutative Algebra";
30
31info="
32LIBRARY: mprimdec.lib   PROCEDURES FOR PRIMARY DECOMPOSITION OF MODULES
33AUTHORS:  Alexander Dreyer, dreyer@mathematik.uni-kl.de; adreyer@web.de
34
35REMARK:
36These procedures are implemented to be used in characteristic 0.
37@*They also work in positive characteristic >> 0.
38@*In small characteristic and for algebraic extensions, the
39procedures via Gianni, Trager, Zacharias may not terminate.
40
41PROCEDURES:
42  separator(l);                computes a list of separators of prime ideals
43  PrimdecA(N[,i]);             (not necessarily minimal) primary decomposition
44                               via Shimoyama/Yokoyama (suggested by Graebe)
45  PrimdecB(N,p);               (not necessarily minimal) primary decomposition
46                               for pseudo-primary ideals
47  modDec(N[,i]);               minimal primary decomposition
48                               via Shimoyama/Yokoyama (suggested by Graebe)
49  zeroMod(N[,check]);          minimal zero-dimensional primary decomposition
50                               via Gianni, Trager and Zacharias
51  GTZmod(N[,check]);           minimal primary decomposition
52                               via Gianni, Trager and Zacharias
53  dec1var(N[,check[,ann]]);    primary decomposition for one variable
54  annil(N);                    the annihilator of M/N in the basering
55  splitting(N[,check[,ann]]);  splitting to simpler modules
56  primTest(i[,p]);             tests whether i is prime or homogeneous
57  preComp(N,check[,ann]);      enhanced Version of splitting
58  indSet(i);                   lists with varstrings of(in)dependend variables
59  GTZopt(N[,check[,ann]]);     a faster version of GTZmod
60  zeroOpt(N[,check[,ann]]);    a faster version of zeroMod
61";
62
63LIB "primdec.lib";
64LIB "ring.lib";
65
66
67/////////////////////////////////////////////////////////////////////////////
68// separator(l)
69// computes a list of separators for a list of prime ideals
70// it in a generalization of parts of pseudo_prim_dec_i from primdec.lib
71/////////////////////////////////////////////////////////////////////////////
72
73proc separator (list @L)
74"USAGE:   separator(l); list l of prime ideals
75RETURN:  list sepList;
76         a list of separators of the prime ideals in l,
77         i.e. polynomials p_ij, s.th. p_ij is in l[j],
78         for all l[j] not contained in l[i]
79         but p_ij is not in l[i]
80EXAMPLE: example separator; shows an example
81"
82
83{
84  ideal p_ij;                        // generating p_ij in @L[@j], not in @L[@i]
85  list f_i;                        // generating f_i NOT in @L[@i], but in all @L[@j]
86  int @i,@j,@k;
87  int sizeL=size(@L);
88  poly @tmp;
89
90  for(@i=1;@i<=sizeL;@i++)
91  {
92    p_ij=0;
93
94    @L[@i]=std(@L[@i]);
95    for(@j=1;@j<=sizeL;@j++)            // compute the separator sep_i
96                                        // of the i-th component
97                                        // f_i separates {Pj not incl in Pi} from Pi
98    {
99      if (@i!=@j)                       // searching for g: not in @L[@i], but @L[@j]
100      {
101        for(@k=1;@k<=ncols(@L[@j]);@k++)
102        {
103          if(NF(@L[@j][@k],@L[@i],1)!=0)
104          {
105            p_ij=p_ij+@L[@j][@k];
106            break;
107          }
108        }
109      }
110    }
111  @tmp=lcm(p_ij);
112  if(@tmp==0)
113  {
114    @tmp=1;
115  }
116  f_i=f_i+list(@tmp);
117  }
118  return(f_i);
119}
120example
121{ "EXAMPLE:"; echo = 2;
122  ring r=0,(x,y,z),dp;
123  ideal i=(x2y,xz2,y2z,z3);
124  list l=minAssGTZ(i);
125  list sepL=separator(l);
126  sepL;
127}
128
129/////////////////////////////////////////////////////////////////////////////
130// PrimdecA(N[,i])
131// computes a primary decomposition, not necessarily minimal,
132// using a generalization of the algorithm of Shimoyama/Yokoyama,
133// suggested by Hans-Gerd Graebe, Leipzig
134// [Hans-Gert Graebe, Minimal Primary Decompostion
135//  and Factorized Groebner Bases, AAECC 8, 265-278 (1997)]
136/////////////////////////////////////////////////////////////////////////////
137
138
139proc PrimdecA(module @N, list #)
140"USAGE:   PrimdecA (N[, i]); module N, int i
141RETURN:  list l
142         a (not necessarily minimal) primary decomposition of N
143         computed by a generalized version of the algorithm of Shimoyama/Yokoyama,
144         @*if i!=0 is given, the factorizing Groebner is used to compute the
145         isolated primes
146EXAMPLE: example PrimdecA; shows an example
147"
148
149{
150  module @M=freemodule(nrows(@N));        // @M=basering^k
151  ideal ann=annil(@N);                    // the annihilator of @N
152  ////////////////////////////////////////////////////////////////
153  // in the trivial case we avoid to compute anything
154  ////////////////////////////////////////////////////////////////
155  if (ann[1]==1)
156  {
157    return(list());
158  }
159  ////////////////////////////////////////////////////////////////
160  // Computation of the Associated Primes
161  ////////////////////////////////////////////////////////////////
162  if (ann[1]==0)
163  {
164    list pr=list(ideal(0));
165  }
166  else
167  {
168    if( (size(#)>0) ){
169      list pr = minAssChar(ann);   // causes message  "/ ** redefining @res **"
170    }
171    else{
172      list pr = minAssGTZ(ann);
173    }
174  }
175
176  list sp, pprimary;     // the separators and the pseudo-primary modules
177  int @i;
178  ideal rest;            // for the computation of the remaining components
179  sp=separator(pr);
180  int sizeSp=size(sp);   // the number of separators
181
182  ////////////////////////////////////////////////////////////////
183  // Computation of the pseudo-primary modules
184  // and an ideal rest s.th. @N is the intersection of the
185  // pseudo-primary modules and @N+rest*@M
186  ////////////////////////////////////////////////////////////////
187  for(@i=1;@i<=sizeSp;@i++)
188  {
189    pprimary=pprimary+list(sat(@N,sp[@i]));
190    rest=rest+sp[@i]^pprimary[@i][2];
191  }
192  list result;           // a primary decomposition of @N
193
194  ////////////////////////////////////////////////////////////////
195  // Extraction of the pseudo-primary modules
196  ////////////////////////////////////////////////////////////////
197  for (@i=1;@i<=size(pprimary);@i++)
198  {
199   result=result+PrimdecB(pprimary[@i][1],pr[@i]);
200  }
201
202  ////////////////////////////////////////////////////////////////
203  // Computation of remaining components
204  ////////////////////////////////////////////////////////////////
205  result=result+PrimdecA(@N+rest*@M);
206
207  return(result);
208}
209example
210{ "EXAMPLE:"; echo = 2;
211  ring r=0,(x,y,z),dp;
212  module N=x*gen(1)+ y*gen(2),
213           x*gen(1)-x2*gen(2);
214  list l=PrimdecA(N);
215  l;
216}
217
218
219/////////////////////////////////////////////////////////////////////////////
220// PrimdecB(N, p)
221// computes a primary decomposition, not necessarily minimal,
222// of a pseudo-primary module N with isolated prime p
223// it is based on extraction in primdec.lib
224/////////////////////////////////////////////////////////////////////////////
225
226proc PrimdecB(module @N, ideal isoPrim)
227"USAGE:   PrimdecB (N, p); pseudo-primary module N, isolated prime ideal p
228RETURN:  list l
229         a (not necessarily minimal) primary decomposition of N
230EXAMPLE: example PrimdecB; shows an example
231"
232
233{
234  module @M=freemodule(nrows(@N));        // @M=basering^k
235  ideal ann=annil(@N);                    // the annihilator of @N
236
237  ////////////////////////////////////////////////////////////////
238  // the not-that-trivial case of ann==0
239  ////////////////////////////////////////////////////////////////
240  if(size(ann)==0)
241  {
242    def BAS=basering;
243    execute("ring Rloc=("+charstr(basering)+","+varstr(basering)+"),dummy,("+ordstr(basering)+");");
244    module @N=imap(BAS, @N);
245    poly @q=prepareSat(@N);
246
247    setring BAS;
248    poly @q=imap(Rloc, @q);
249    list satu=sat(@N,@q);
250    if(satu[2]==0)
251    {
252      return(list(list(@N,ideal(0))));
253    }
254    else
255    {
256      return(list(list(satu[1],ideal(0)))+ PrimdecA(@N+(@q^satu[2])*@M));
257    }
258  }
259
260  ////////////////////////////////////////////////////////////////
261  // Extraction of the isolated component @N' and
262  // searching for a polynomial @f of minimal degree
263  // s.th. @N=intersect(@N', @N+@f*@M)
264  ////////////////////////////////////////////////////////////////
265  list indSets=indepSet(ann,0);
266  poly @f;
267  if(size(indSets)!=0)           //check, whether dim isoPrim !=0
268  {
269    intvec indVec;               // a maximal independent set of variables
270                                 // modulo isoPrim
271    string @U;                   // the independent variables
272    string @A;                   // the dependent variables
273    int @j,@k;
274    int szA;                     //  the size of @A
275    int degf;
276    ideal @g;
277    list polys;
278    int sizePolys;
279    list newPoly;
280
281    ////////////////////////////////////////////////////////////////
282    // the preparation of the quotient ring
283    ////////////////////////////////////////////////////////////////
284    def BAS=basering;
285    for (@k=1;@k<=size(indSets);@k++)
286    {
287      indVec=indSets[@k];
288      for (@j=1;@j<=nvars(BAS);@j++)
289      {
290        if (indVec[@j]==1)
291        {
292          @U=@U+varstr(@j)+",";
293        }
294        else
295        {
296          @A=@A+varstr(@j)+",";
297          szA++;
298        }
299      }
300
301      @U[size(@U)]=")";           // we compute the extractor (w.r.t. @U)
302      execute("ring RAU="+charstr(basering)+",("+@A+@U+",(C,dp("+string(szA)+"),dp);");
303      module @N=std(imap(BAS,@N));
304                                  // this is also a standard basis in (R[U])[A]
305      @A[size(@A)]=")";
306      execute("ring Rloc=("+charstr(basering)+","+@U+",("+@A+",(C,dp);");
307      ideal @N=imap(RAU,@N);
308      ideal @h;
309      for(@j=ncols(@N);@j>=1;@j--)
310      {
311        @h[@j]=leadcoef(@N[@j]);  // consider I in (R(U))[A]
312      }
313      setring BAS;
314      @g=imap(Rloc,@h);
315      kill RAU,Rloc;
316      @U="";
317      @A="";
318      szA=0;
319      @f=lcm(@g);
320      newPoly[1]=@f;
321      polys=polys+newPoly;
322      newPoly=list();
323    }
324    @f=polys[1];
325    degf=deg(@f);
326    sizePolys=size(polys);
327    for (@k=2;@k<=sizePolys;@k++)
328    {
329      if (deg(polys[@k])<degf)
330      {
331        //Waehlt das poly mit dem geringsten Grad.
332        @f=polys[@k];
333        degf=deg(@f);
334      }
335    }
336  }
337  else
338  {
339    @f=1;
340  }
341  if(@f!=1)
342  {
343    list satu = minSatMod(@N,@f);
344    return(list(list(satu[1],isoPrim))+ PrimdecA(@N+satu[2]*@M));
345    //    list satu = sat(@N,@f);
346    //return(list(list(satu[1],isoPrim))+ PrimdecA(@N+@f^satu[2]*@M));
347  }
348  else
349  {
350    return(list(list(@N,isoPrim)));
351  }
352}
353example
354{ "EXAMPLE:"; echo = 2;
355  ring r=0,(x,y,z),dp;
356  module N=y*gen(1),y2*gen(2),yz*gen(2),yx*gen(2);
357  ideal p=y;
358  list l=PrimdecB(N,p);
359  l;
360}
361
362/////////////////////////////////////////////////////////////////////////////
363// modDec(N[,i])
364// extracts a minimal primary decomposition from the
365// primary decomposition computed by PrimdecA(N[, i])
366// using a Minimality Test suggested by Hans-Gerd Graebe, Leipzig
367/////////////////////////////////////////////////////////////////////////////
368
369proc modDec(module @N, list #)
370"USAGE:   modDec (N[, i]); module N, int i
371RETURN:  list l
372         a minimal primary decomposition of N
373         computed by an generalized version of the algorithm of Shimoyama/Yokoyama,
374         @*if i=1 is given, the factorizing Groebner basis algorithm is used internally.
375EXAMPLE: example modDec; shows an example
376"
377{
378  list prim = PrimdecA(@N, #);
379  int @i,@j,@k,@l;
380  int sizePrim=size(prim);
381
382  ////////////////////////////////////////////////////////////////
383  // the trivial case
384  ////////////////////////////////////////////////////////////////
385  if (sizePrim==0)
386  {
387    return(list(list(@N, ideal(1))));
388  }
389
390  ////////////////////////////////////////////////////////////////
391  // collect primary components with the same associated prime
392  // and substitute them by their intersection
393  ////////////////////////////////////////////////////////////////
394  for(@i=1;@i<=sizePrim;@i++)
395  {
396    for(@j=@i+1;@j<=sizePrim;@j++)
397    {
398      if (@j!=@i)
399      {
400        if (modulesEqual(prim[@i][2],prim[@j-@l][2])==1)
401        {
402          prim[@i][1]=intersect(prim[@i][1],prim[@j-@l][1]);
403          prim=delete(prim,@j-@l);
404          @l++;
405          sizePrim--;
406        }
407      }
408    }
409  }
410
411  ////////////////////////////////////////////////////////////////
412  // minimality test suggested by Graebe:
413  // if f separates the prime p from the primes not contained in p,
414  // then p is not in Ass(M/N) <=> sat(N,f)=sat(sat(N,f),p)
415  ////////////////////////////////////////////////////////////////
416  list tempList;
417  for(@i=1;@i<=sizePrim;@i++)
418  {
419    tempList=tempList+list(prim[@i][2]);
420  }
421  list sepPrimes=separator(tempList);   // the separators of the primes
422  tempList=list();
423  for(@i=1;@i<=sizePrim;@i++)     // compute sat(N,f), for all separators f
424  {
425    tempList=tempList+list(sat(@N,sepPrimes[@i])[1]);
426  }
427  module testMod;
428  @k=0;
429  for(@i=1;@i<=sizePrim;@i++)
430  {
431    testMod=sat(tempList[@i],prim[@i-@k][2])[1];  // computes sat(sat(N,f),p)
432    if (size(NF(testMod,std(tempList[@i]),1))==0) // tests if equal to sat(N,f)
433    {
434      prim=delete(prim,@i-@k);                    // if yes: the component
435      @k++;                                       // is superfluous
436    }
437  }
438
439  return(prim);
440}
441example
442{ "EXAMPLE:"; echo = 2;
443  ring r=0,(x,y,z),dp;
444  module N=x*gen(1)+ y*gen(2),
445           x*gen(1)-x2*gen(2);
446  list l=modDec(N);
447  l;
448}
449
450/////////////////////////////////////////////////////////////////////////////
451// zeroMod (N[, check])
452// computes a minimal primary decomposition of a zero-dimensional Module
453// using a generalized version of the algorithm of
454// Gianni, Trager and Zacharias, suggested by Alexander Dreyer
455// [Diploma Thesis, University of Kaiserslautern, 2001]
456/////////////////////////////////////////////////////////////////////////////
457
458proc zeroMod (module @N, list #)
459"USAGE:   zeroMod (N[, check]); zero-dimensional module N[, module check]
460RETURN:  list l
461         the minimal primary decomposition of a zero-dimensional module N,
462         computed by a generalized version of the algorithm of Gianni, Trager and Zacharias
463NOTE:    if the parameter check is given, only components not containing check are computed
464EXAMPLE: example zeroMod; shows an example
465"
466{
467  ////////////////////////////////////////////////////////////////
468  // the module check is needed to compute a minimal decomposition
469  // components containing check are ignored
470  ////////////////////////////////////////////////////////////////
471  if (size(#)>0)
472  {
473    module check=#[1];
474    if (size(NF(check,std(@N),1))==0)
475    {
476      return(list());
477    }
478  }
479  else
480  {
481    module check=freemodule(nrows(@N));
482  }
483
484  ////////////////////////////////////////////////////////////////
485  // the ordering is changed to lex
486  ////////////////////////////////////////////////////////////////
487  def BAS = basering;
488  def @R=changeord("lp");
489  setring @R;
490  module @N=fetch(BAS,@N);
491  int nVar=nvars(@R);
492  module @M=freemodule(nrows(@N));     // @M=basering^k
493  ideal ann=std(quotient(@N,@M));      // the annihilator of @M/@N
494  int @k;
495  list result, rest;
496  ideal primary, prim;
497  module primMod;
498
499  ////////////////////////////////////////////////////////////////
500  // the random coordnate change and its inverse
501  ////////////////////////////////////////////////////////////////
502  option(redSB);
503  ideal prepMap=maxideal(1);
504  prepMap[nVar]=0;
505  prepMap[nVar]=(random(100,1,nVar)*transpose(prepMap))[1,1]+var(nVar);
506  map phi=@R,prepMap;
507  prepMap[nVar]=2*var(nVar)-prepMap[nVar];
508  map invphi=@R,prepMap;
509
510  ideal @j=std(phi(ann));
511
512  list fac=factorize(@j[1],2);   // factorization of the 1st elt. in Ann(@N)
513
514  ////////////////////////////////////////////////////////////////
515  // Case: 1st element irreducible
516  ////////////////////////////////////////////////////////////////
517  if(size(fac[2])==1)
518  {
519    prim=primaryTest(@j,fac[1][1]);
520    prim=invphi(prim);
521    setring BAS;
522    @N=std(@N);
523    ideal prim=std(imap(@R,prim));
524    kill @R;
525    if(prim!=0)
526    {
527      return(list(list(@N,prim)));
528    }
529    else
530    {
531      return(zeroMod(@N,check));
532    }
533   }
5342;
535  ////////////////////////////////////////////////////////////////
536  // Computation of the - hopefully primary - modules
537  // their annihilators and associated primes
538  ////////////////////////////////////////////////////////////////
539  poly @p, @h;
540  module check;
541  for (@k=1;@k<=size(fac[1]);@k++)
542  {
543    @p=fac[1][@k]^fac[2][@k];
544    @h=@j[1]/@p;
545    primMod=std(quotient(phi(@N),@h));
546    check=imap(BAS,check);
547    check=phi(check);
548    if (size(NF(check,primMod,1))>0)
549    {
550      primary=std(@j+@p);
551      // test if the modules were primary and in general position
552      prim=primaryTest(primary,fac[1][@k]);
553      if (prim==0)
554      {
555            rest[size(rest)+1]=invphi(primMod);
556      }
557      else
558      {
559            result[size(result)+1]=list(std(invphi(primMod)),std(invphi(prim)));
560      }
561
562    }
563  }
564
565  ////////////////////////////////////////////////////////////////
566  // the bad cases
567  ////////////////////////////////////////////////////////////////
568
569  for (@k=1; @k<=size(rest);@k++)
570  {
571    result = result+zeroMod(rest[@k],invphi(check));
572  }
573
574  option(noredSB);
575  setring BAS;
576  list result=imap(@R, result);
577  kill @R;
578  return(result);
579}
580example
581{ "EXAMPLE:"; echo = 2;
582  ring r=0,z,dp;
583  module N=z*gen(1),(z-1)*gen(2),(z+1)*gen(3);
584  list l=zeroMod(N);
585  l;
586}
587
588
589/////////////////////////////////////////////////////////////////////////////
590// GTZmod (N[, check])
591// computes a minimal primary decomposition of N
592// using a generalized version of the algorithm of
593// Gianni, Trager and Zacharias, suggested by Alexander Dreyer
594// [Diploma Thesis, University of Kaiserslautern, Germany, 2001]
595/////////////////////////////////////////////////////////////////////////////
596
597proc GTZmod (module @N, list #)
598"USAGE:   GTZmod (N[, check]); module N[, module check]
599RETURN:  list l
600         the minimal primary decomposition of the module N,
601         computed by a generalized version of the algorithm of Gianni, Trager and Zacharias
602NOTE:    if the parameter check is given, only components not containing check are computed
603EXAMPLE: example GTZmod; shows an example
604"
605{
606  if (size(@N)==0)
607  {
608    return(list(@N,ideal(0)));
609  }
610
611  ////////////////////////////////////////////////////////////////
612  // the module check is needed to compute a minimal decomposition
613  // components containing check are ignored
614  ////////////////////////////////////////////////////////////////
615  if (size(#)>0)
616  {
617    module check=#[1];
618    if (size(NF(check,std(@N),1))==0)
619    {
620      return(list());
621    }
622  }
623  else
624  {
625    module check= freemodule(nrows(@N));
626  }
627
628  module @M=freemodule(nrows(@N));
629  def BAS = basering;
630  int @j;
631  int nVar=nvars(BAS);
632  int @k;
633  string @U;                       // the independent variables
634  string @A;                       // the dependent variables
635  @N=std(@N);
636  ideal ann=std(quotient(@N,@M));  // the annihilator of @M/@N
637
638
639  ////////////////////////////////////////////////////////////////
640  // the trivial and the zero-dimensional case
641  ////////////////////////////////////////////////////////////////
642  int Ndim=dim(@N);
643  if ((Ndim==0)||(Ndim==-1))
644  {
645    return(zeroMod(@N, check));
646  }
647
648  ////////////////////////////////////////////////////////////////
649  // the not-that-trivial case of ann==0
650  ////////////////////////////////////////////////////////////////
651  if(size(ann)==0)
652  {
653    execute("ring Rloc=("+charstr(basering)+","+varstr(basering)+"),dummy,("+ordstr(basering)+");");
654    module @N=imap(BAS, @N);
655    poly @q=prepareSat(@N);
656
657    setring BAS;
658    poly @q=imap(Rloc, @q);
659    list satu=sat(@N,@q);
660    if(satu[2]==0)
661    {
662      return(list(list(@N,ideal(0))));
663    }
664    else
665    {
666      check=intersect(check,satu[1]);
667      return(list(list(satu[1],ideal(0)))+GTZmod(@N+(@q^satu[2])*@M,check));
668    }
669  }
670
671  ////////////////////////////////////////////////////////////////
672  // the preparation of the quotient ring
673  ////////////////////////////////////////////////////////////////
674  intvec indVec=indepSet(ann);
675  int szA;
676  for (@k=1;@k<=size(indVec);@k++)
677  {
678    if (indVec[@k]==1)
679    {
680      @U=@U+varstr(@k)+",";
681    }
682    else
683    {
684      @A=@A+varstr(@k)+",";
685      szA++;
686    }
687  }
688  @U[size(@U)]=")";             // we compute the extractor (w.r.t. @U)
689  execute("ring RAU="+charstr(basering)+",("+@A+@U+",(C,dp("+string(szA)+"),dp);");
690  module @N=std(imap(BAS,@N));  // this is also a standard basis in (R[U])[A]
691  @A[size(@A)]=")";
692  execute("ring Rloc=("+charstr(basering)+","+@U+",("+@A+",(C,dp);");
693  module @N=imap(RAU,@N);
694  kill RAU;
695
696  ////////////////////////////////////////////////////////////////
697  // the zero-dimensional decomposition
698  ////////////////////////////////////////////////////////////////
699  list qprim=zeroMod(@N,imap(BAS,check));
700
701  ////////////////////////////////////////////////////////////////
702  //  preparation for saturation
703  ////////////////////////////////////////////////////////////////
704  poly @q=prepareSat(@N);
705  if (size(qprim)==0)
706  {
707    setring BAS;
708    poly @q=imap(Rloc,@q);
709    kill Rloc;
710    @q=@q^sat(@N,@q)[2];
711    if (deg(@q)>0)
712    {
713      return(GTZmod(@N+@q*@M,check));
714    }
715    else
716    {
717      return(list());
718    }
719  }
720
721  list @p;
722  for (@k=1;@k<=size(qprim);@k++)
723  {
724    @p[@k]=list(prepareSat(qprim[@k][1]),prepareSat(qprim[@k][2]));
725  }
726
727  ////////////////////////////////////////////////////////////////
728  // compute the recontractions
729  // back in the original ring
730  ////////////////////////////////////////////////////////////////
731  setring BAS;
732  list @p=imap(Rloc,@p);
733  list qprim=imap(Rloc,qprim);
734  poly @q=imap(Rloc,@q);
735  kill Rloc;
736  for(@k=1;@k<=size(qprim);@k++)
737  {
738    qprim[@k]=list(sat(qprim[@k][1],@p[@k][1])[1],
739                   sat(qprim[@k][2],@p[@k][2])[1]);
740    check=intersect(check,qprim[@k][1]);
741  }
742  @q=@q^sat(@N,@q)[2];
743  if (deg(@q)>0)
744  {
745    qprim=qprim+GTZmod(@N+@q*@M,check);
746  }
747
748  return(qprim);
749}
750example
751{ "EXAMPLE:"; echo = 2;
752  ring r=0,(x,y,z),dp;
753  module N=x*gen(1)+ y*gen(2),
754           x*gen(1)-x2*gen(2);
755  list l=GTZmod(N);
756  l;
757}
758
759
760proc prepareSat(module @N, list #)
761
762{
763  int @k;
764  poly @p=leadcoef(@N[1]);
765  for (@k=2;@k<=size(@N);@k++)
766  {
767    @p=lcm_chr(@p,leadcoef(@N[@k]));
768    //    @p=@p*leadcoef(@N[@k]);
769  }
770  return(@p);
771}
772
773proc lcm_chr(poly @i, poly @j)
774
775{
776  def LBAS = basering;
777  if (npars(basering)==0)
778  {
779    string strg="";
780  }
781  else
782  {
783     if (nvars(basering)==0)
784     {
785       string strg=parstr(basering);
786     }
787     else
788     {
789       string strg=parstr(basering)+",";
790     }
791  }
792  execute("ring PRing="+string(char(basering))+",("+strg+varstr(basering)+"),dp");
793  ideal @a=ideal(imap(LBAS,@i),imap(LBAS,@j));
794  poly @p=lcm(@a);
795  setring LBAS;
796  poly @p=imap(PRing,@p);
797  kill PRing;
798  return(@p);
799}
800
801///////////////////////////////////////////////////////////////////////
802// The optimized procedures and procdures needed for this optimization
803///////////////////////////////////////////////////////////////////////
804
805/////////////////////////////////////////////////////////////////////////////
806// testit (N, l)
807// a small procedure, which checks whether
808// N=intersect(l[1][1],...,l[size(l)][1])
809// and whether annil(l[i][1]) is primary
810// Just for testing the procedures.
811/////////////////////////////////////////////////////////////////////////////
812
813proc testit (module N, list #)
814"USAGE:   testit (N, l); module N, list l
815EXAMPLE: example testit; shows an example
816"
817{
818  if (size(#)==0)
819  {
820    return()
821  }
822  int i;
823  list l=#;
824  module nn=freemodule(nrows(N));
825  module M=freemodule(nrows(N));
826
827  for(i=1;i<=size(l);i++)
828  {
829    nn=intersect(nn,l[i][1]);
830    if ((size(decomp(quotient(l[i][1],M)))>2)&&(size(l[i][2])>0))
831    {
832     "nicht primary obwohl erkannt!";
833     l[i];std(quotient(l[i][1],M));std(radical(quotient(l[i][1],M)));
834      pause();
835     }
836  }
837  int j,k;
838  j=size(NF(nn,std(N),1));
839  k=size(NF(N,std(nn),1));
840  if ((j!=0)||(k!=0))
841  {
842    "testit fehler!!!";
843    pause();
844  }
845}
846example
847{ "EXAMPLE:"; echo = 2;
848  ring r=0,(x,y,z),dp;
849  module N=x*gen(1)+ y*gen(2),
850           x*gen(1)-x2*gen(2);
851  list l=GTZmod(N);
852  testit(N,l);
853}
854
855/////////////////////////////////////////////////////////////////////////////
856// annil (N)
857// computes the annihilator of M/N in the basering
858/////////////////////////////////////////////////////////////////////////////
859
860proc annil (module N)
861"USAGE:   annil(N);  modul N
862RETURN:  ideal ann=std(quotient(N,freemodule(nrows(N))));
863         the annihilator of M/N in the basering
864NOTE:    ann is a std basis in the basering
865EXAMPLE: example annil; shows an example
866"
867{
868 intvec optionsVec=option(get);
869 option (returnSB);
870 ideal ann=quotient(N,freemodule(nrows(N)));
871 attrib (ann, "isSB",1);
872 option (set,optionsVec);
873 return(ann);
874}
875example
876{ "EXAMPLE:"; echo = 2;
877  ring r=0,(x,y,z),dp;
878  module N=x*gen(1), y*gen(2);
879  ideal ann=annil(N);
880  ann;
881}
882
883/////////////////////////////////////////////////////////////////////////////
884//  splitting(N[,check[, ann]])
885//  INPUT:  a zero-dimensional module N, module check, ideal ann=annil(N)
886//          splitting computes an list of modules
887//          using the factorization of the elements of annil(N)
888//          s.th. N is equal to the intersections of these modules
889//          A prim test is used to check if the modules are primary
890//  OUTPUT: (l, check)
891/////////////////////////////////////////////////////////////////////////////
892
893proc splitting (module @N, list #)
894"USAGE:   splitting(N[,check[, ann]]);  modul N, module check, ideal ann
895RETURN:  (l, check) list l, module check
896         the elements of l consists of quadruples, where
897         [1] is of type module, [2], [3] and [4] are of type ideal,
898         s.th. the intersection of the modules is equal to the
899         zero-dimensional module N, furthermore l[j][3]=annil(l[j][1])
900         and l[j][4] contains internal ideal data;
901         if l[j][2]!=0 then the module l[j][1] is primary
902            with associated prime l[j][2], and check=intersect(check, l[j][1]) is computed
903NOTE:    if the parameter check is given, only components not containing
904         check are computed; if ann is given, ann is used instead of annil(N)
905EXAMPLE: example splitting; shows an example
906"
907{
908  ideal ann; module check, @M; int checked;
909  (ann, check, @M,checked)=getData(@N,#);
910  if(checked)
911  {
912    return(list());
913  }
914  if(size(#)>=3)
915  {
916    ideal splitPrime=#[3];
917  }
918  else
919  {
920    ideal splitPrime=ann;
921  }
922
923  list fact, result, splitTemp;
924  int @i,@k,@j,szFact;
925  for (@i=1;@i<=size(ann);@i++)
926  {
927    fact=factorize(ann[@i],2);
928    szFact=size(fact[2]);
929    // if the element is the power of an irreducible element
930    if(szFact==1)
931    {
932      if(vdim(ann)==deg(ann[@i]))
933      {
934        splitPrime=interred(splitPrime+ideal(fact[1][1]));
935        result=result+list(list(@N,splitPrime,ann,splitPrime));
936      }
937      else
938      {
939        splitPrime=interred(splitPrime+ideal(fact[1][1]));
940        if (homog(splitPrime))
941        {
942           result=result+list(list(@N,maxideal(1),ann,splitPrime));
943        }
944      }
945    }
946    else
947    {
948      if(gcdTest(fact[1]))       // Case: (f1,...,fk)=(1)
949      {
950        (splitTemp, check)=sp1(@N,fact,check,ann,splitPrime);
951        result=result+splitTemp;
952      }
953      else
954      {
955                                // if the element is not irreducible
956        (splitTemp, check)=sp2(@N,fact[1][1],check,ann,splitPrime);
957        result=result+splitTemp;
958      }
959    }
960  }
961  @i=1;@k=size(result);
962
963  ////////////////////////////////////////////////////////////////
964  // delete multiple Modules
965  ////////////////////////////////////////////////////////////////
966  while (@i<=@k)
967  {
968    @j=1;
969    while(@j<=@i-1)
970    {
971      if (stdModulesEqual(result[@j][1],result[@k][1]))
972      {
973        result=delete(result,@i);
974        @k--;@i--;break;
975      }
976      @j++;
977    }
978    @i++;
979  }
980  list rest;
981  @i=1;@k=size(result);
982
983  ////////////////////////////////////////////////////////////////
984  // if not primary then split the obtained modules once again
985  ////////////////////////////////////////////////////////////////
986  while (@i<=@k)
987  {
988    if (size(result[@i][2])==0)
989    {
990      rest=rest+list(list(result[@i][1],result[@i][3],result[@i][4]));
991      result=delete(result,@i);
992      @k--;@i--;
993    }
994    else
995    {
996      check=intersect(check,result[@i][1]);
997    }
998    @i++;
999  }
1000  for(@i=1;@i<=size(rest);@i++)
1001  {
1002    (splitTemp,check)=splitting(rest[@i][1],check,rest[@i][2],rest[@i][3]);
1003    result=result+splitTemp;
1004  }
1005
1006  if (size(result)==0)
1007  {
1008    result=list(list(@N,ideal(0),ann,ann));
1009  }
1010  return(result, check);
1011}
1012example
1013{ "EXAMPLE:"; echo = 2;
1014  ring r=0,z,lp;
1015  module N=z*gen(1), (z+1)*gen(2);
1016  N=std(N);
1017  list l; module check;
1018  (l, check)=splitting(N);
1019  l;
1020  check;
1021}
1022
1023  ////////////////////////////////////////////////////////////////
1024  // sp1: splits a module as follows
1025  // (N+f*g*M)=intersect((N+f*M),(N+g*M)) if (f,g)=(1)
1026  ////////////////////////////////////////////////////////////////
1027
1028static proc sp1(module @N,list fact,list #)
1029{
1030  ideal ann; module check, @M; int @i;
1031  (ann, check, @M, @i)=getData(@N, #);
1032  if(size(#)>=3)
1033  {
1034    ideal splitPrime=#[3];
1035  }
1036  else
1037  {
1038    ideal splitPrime=ann;
1039  }
1040  list pr;
1041  module splitMod;
1042  ideal splitAnn, prim, tempPrime;
1043  for(@i=1;@i<=size(fact[2]);@i++)
1044  {
1045    splitMod=std(@N+(fact[1][@i]^fact[2][@i])*@M);
1046    if(size(NF(check,splitMod,1))>0)
1047    {
1048      splitAnn=std(ann,(fact[1][@i]^fact[2][@i]));
1049      tempPrime=interred(splitPrime+ideal(fact[1][@i]));
1050      prim=primTest(splitAnn,fact[1][@i],tempPrime);
1051      pr=pr+list(list(splitMod,prim,splitAnn,tempPrime));
1052      if (size(prim)>0)
1053      {
1054        check=intersect(check,splitMod);
1055      }
1056    }
1057  }
1058  return (pr, check);
1059}
1060
1061  ////////////////////////////////////////////////////////////////
1062  // sp2: splits a module as follows
1063  // N=intersect((N:f),(N+f*M))
1064  ////////////////////////////////////////////////////////////////
1065
1066static proc sp2(module @N,  poly p, list #)
1067{
1068  ideal ann; module check, @M; int @i;
1069  (ann, check, @M, @i)=getData(@N, #);
1070  if(size(#)>=3)
1071  {
1072    ideal splitPrime=#[3];
1073  }
1074  else
1075  {
1076    ideal splitPrime=ann;
1077  }
1078  list fact=sat(@N, p);
1079  list splitList;
1080  ideal splitAnn, prim, tempPrime;
1081  if (fact[2]>0)
1082  {
1083   module n1=std(@N+(p^fact[2]*@M));
1084   module n2=fact[1];
1085   if (size(NF(check,n1,1))>0)
1086   {
1087    splitAnn=std(ann+ideal(p^fact[2]));
1088    tempPrime=interred(splitPrime+ideal(p));
1089    prim=primTest(tempPrime);
1090    splitList=list(list(n1, prim, splitAnn,tempPrime));
1091    if(size(prim)>0)
1092    {
1093      check=intersect(check, n1);
1094    }
1095   }
1096   if(size(NF(check,n2,1))>0)
1097   {
1098    splitAnn=annil(n2);
1099    prim=primTest(splitAnn);
1100    splitList=splitList+list(list(n2,prim,splitAnn,splitAnn));
1101    if(size(prim)>0)
1102    {
1103    check=intersect(check, n2);
1104    }
1105   }
1106   return(splitList, check);
1107  }
1108  else
1109  {
1110   return (list(list(@N,ideal(0),ideal(0))), check);
1111  }
1112}
1113
1114/////////////////////////////////////////////////////////////////////////////
1115//  primeTest(i[, p])
1116//  tests whether i is prime or homogeneous
1117//  is both cases radical(i) is returned
1118/////////////////////////////////////////////////////////////////////////////
1119
1120proc primTest(ideal id, list #)
1121"USAGE:   primTest(i[, p]); a zero-dimensional ideal i, irreducible poly p in i
1122RETURN:  if i is neither prime nor homogeneous then ideal(0) is returned,
1123         otherwise radical(i)
1124EXAMPLE: example primTest; shows an example
1125"
1126{
1127  ideal tempPrime;
1128  int testTempPrime;
1129  if (size(#)>0)
1130  {
1131    poly @p=#[1];
1132    if(size(#)>1)
1133    {
1134      tempPrime=#[2];
1135      testTempPrime=1;
1136    }
1137  }
1138  else
1139  {
1140    poly @p=0;
1141
1142  }
1143  ideal prim=ideal(0);
1144  if((size(#)>0)&&(vdim(id)==deg(@p)))
1145  {
1146    prim=id;
1147  }
1148  else
1149  {
1150    if ((homog(id))||((testTempPrime)&&(homog(tempPrime))))
1151    {
1152      prim=maxideal(1);
1153    }
1154  }
1155  return (prim);
1156}
1157example
1158{ "EXAMPLE:"; echo=2;
1159  ring r=0,(x,y,z),lp;
1160  ideal i=x+1,y-1,z;
1161  i=std(i);
1162  ideal primId=primTest(i,z);
1163  primId;
1164
1165  i=x,z2,yz,y2;
1166  i=std(i);
1167  primId=primTest(i);
1168  primId;
1169}
1170
1171/////////////////////////////////////////////////////////////////////////////
1172// preComp(N, check[, ann])
1173// preComp is an enhanced version of splitting,
1174// but before computing splitting the first element of std(annil(N))
1175// is factorized and the obtained modules are tested for primarity
1176/////////////////////////////////////////////////////////////////////////////
1177
1178proc preComp (module @N, list #)
1179"USAGE:   preComp(N,check[, ann]);  modul N, module check, ideal ann
1180RETURN:  (l, check) list l, module check
1181         the elements of l consists of a triple with
1182         [1] of type module [2] and [3] of type ideal
1183         s.th. the intersection of the modules is equal to the
1184         zero-dimensional module N, furthermore l[j][3]=annil(l[j][1])
1185         if l[j][2]!=0 then the module l[j][1] is primary
1186            with associated prime l[j][2],
1187            and check=intersect(check, l[j][1]) is computed
1188NOTE:    only components not containing check are computed;
1189         if ann is given, ann is used instead of annil(N)
1190EXAMPLE: example preComp; shows an example
1191"
1192{
1193  def BAS=basering;
1194  def @R=changeord("C,lp");
1195  setring @R;
1196  module @N=std(imap(BAS,@N));
1197  ideal ann; module check, @M; int @k;
1198  (ann, check, @M, @k)=getData(@N,imap(BAS,#),1);
1199  list act,primary;
1200  ideal primid,helpid;
1201  module primmod;
1202
1203  ////////////////////////////////////////////////////////////////
1204  // the first element of the standardbase is factorized
1205  ////////////////////////////////////////////////////////////////
1206  if(deg(ann[1])>0)
1207  {
1208    act=factorize(ann[1],2);
1209  }
1210  else
1211  {
1212    setring BAS;
1213    module check=imap(@R,check);
1214    kill @R;
1215    return(list(), check);
1216  }
1217
1218  ////////////////////////////////////////////////////////////////
1219  // with the factors new modules are created
1220  // (hopefully the primary decomposition)
1221  ////////////////////////////////////////////////////////////////
1222  if(size(act[1])>1)               // Case: act[1] not irreducible
1223  {
1224     for(@k=1;@k<=size(act[1]);@k++)
1225     {
1226       primmod=std(@N+(act[1][@k]^act[2][@k])*@M);
1227       if (size(NF(check,primmod,1))>0)
1228       {
1229         primid=std(ann,act[1][@k]^act[2][@k]);
1230         if((act[2][@k]==1)&&(vdim(primid)==deg(act[1][@k])))
1231         {
1232           primary = primary+list(list(primmod,primid,primid));
1233         }
1234         else
1235         {
1236           helpid=primid;
1237           primid=primaryTest(primid,act[1][@k]);
1238           primary = primary+list(list(primmod,primid,helpid));
1239         }
1240       }
1241       if (size(primid)>0)
1242       {
1243         check=intersect(check, primmod);
1244       }
1245     }
1246   }
1247   else                            // Case: act[1]  irreducible
1248   {
1249     primid=ann;
1250     primmod=@N;
1251
1252     if (size(NF(check,primmod,1))>0)
1253     {
1254       if((act[2][1]==1)&&(vdim(primid)==deg(act[1][1])))
1255       {
1256         primary = primary+list(list(primmod,primid,primid));
1257       }
1258       else
1259       {
1260         primid = primaryTest(primid,act[1][1]);
1261         primary = primary+list(list(primmod,primid,ann));
1262       }
1263       if (size(primid)>0)
1264       {
1265         check=intersect(check,primmod);
1266       }
1267     }
1268  }
1269
1270  if (size(primary)==0)
1271  {
1272    setring BAS;
1273    module check=imap(@R,check);
1274    kill @R;
1275    return(list(), check);
1276  }
1277
1278  ////////////////////////////////////////////////////////////////
1279  // the modules which are not primary are splitted
1280  ////////////////////////////////////////////////////////////////
1281  list splitTemp;
1282  int sz=size(primary);
1283  @k=1;
1284  while (@k<=sz)
1285  {
1286    if (size(primary[@k][2])==0)
1287    {
1288      (splitTemp, check)=splitting(primary[@k][1],check,primary[@k][3]);
1289      primary = delete(primary, @k)+splitTemp;
1290      @k--;sz--;
1291    }
1292    @k++;
1293  }
1294
1295  setring BAS;
1296  list primary=imap(@R,primary);
1297  module check=imap(@R,check);
1298  kill @R;
1299  return(primary,check);
1300}
1301example
1302{ "EXAMPLE:"; echo = 2;
1303  ring r=0,z,lp;
1304  module N=z*gen(1), (z+1)*gen(2);
1305  N=std(N);
1306  list l; module check;
1307  (l, check)=preComp(N,freemodule(2));
1308  l;
1309  check;
1310}
1311
1312/////////////////////////////////////////////////////////////////////////////
1313// indSet(i)
1314// based on independendSet from primdec.lib
1315/////////////////////////////////////////////////////////////////////////////
1316
1317proc indSet (ideal @j)
1318"USAGE:   indSet(i); i ideal
1319RETURN:  list with two entries
1320         both are lists of new varstrings with the dependent variables,
1321         the independent set, the ordstring with the corresp. block ordering,
1322         and the integer where the independent set starts in the varstring
1323NOTE:    the first entry gives the strings for all maximal independent sets
1324         the second gives the strings for the independent sets,
1325         which cannot be enhanced
1326EXAMPLE: example indSet; shows an example
1327"
1328{
1329   int n,k,di;
1330   int jdim=dim(@j);
1331   list maxind, rest,hilf;
1332   string var1,var2;
1333   list v=indepSet(@j,1);
1334
1335   for(n=1;n<=size(v);n++)
1336   {
1337      di=0;
1338      var1="";
1339      var2="";
1340      for(k=1;k<=size(v[n]);k++)
1341      {
1342         if(v[n][k]!=0)
1343         {
1344            di++;
1345            var2=var2+string(var(k))+",";
1346         }
1347         else
1348         {
1349            var1=var1+string(var(k))+",";
1350         }
1351      }
1352      if(di>0)
1353      {
1354         var1=var1[1..size(var1)-1];
1355         var2=var2[1..size(var2)-1];
1356         hilf[1]=var1;
1357         hilf[2]=var2;
1358         hilf[3]="(C,dp("+string(nvars(basering)-di)+"),dp)";
1359         //"lp("+string(nvars(basering)-di)+"),dp("+string(di)+")";
1360         hilf[4]=di;
1361         if(di==jdim)
1362         {
1363          maxind=maxind+list(hilf);
1364         }
1365         else
1366         {
1367          rest=rest+list(hilf);
1368         }
1369     }
1370      else
1371      {
1372
1373        if(jdim==0)
1374         {
1375          maxind=maxind+list(varstr(basering),"dummy",ordstr(basering),0);
1376         }
1377         else
1378         {
1379          rest=rest+list(varstr(basering),"dummy",ordstr(basering),0);
1380         }
1381         resu[n]=varstr(basering),ordstr(basering),0;
1382      }
1383   }
1384   return(list(maxind,rest));
1385}
1386example
1387{ "EXAMPLE:"; echo = 2;
1388   ring s1=(0,x,y),(a,b,c,d,e,f,g),lp;
1389   ideal i=ea-fbg,fa+be,ec-fdg,fc+de;
1390   i=std(i);
1391   list  l=indSet(i);
1392   l;
1393}
1394
1395/////////////////////////////////////////////////////////////////////////////
1396// GTZopt(N[,check[, ann]])
1397// a faster version of GTZMod
1398/////////////////////////////////////////////////////////////////////////////
1399
1400proc GTZopt (module @N, list #)
1401"USAGE:   GTZopt (N[, check]); module N[, module check]
1402RETURN:  list l
1403         the minimal primary decomposition of the module N,
1404         computed by a generalized and optimized version of
1405         the algorithm of Gianni, Trager and Zacharias
1406NOTE:    if the parameter check is given, only components
1407         not containing check are computed
1408EXAMPLE: example GTZmod; shows an example
1409"
1410{
1411  @N=std(@N);
1412  if (size(@N)==0)
1413  {
1414    return(list(@N,ideal(0)));
1415  }
1416
1417  ////////////////////////////////////////////////////////////////
1418  // the module check is needed to compute a minimal decomposition
1419  // components containing check are ignored
1420  ////////////////////////////////////////////////////////////////
1421  ideal ann; module check, @M; int checked;
1422  (ann, check, @M, checked)=getData(@N, #);
1423  if (checked)
1424  {
1425    return(list());
1426  }
1427
1428  ////////////////////////////////////////////////////////////////
1429  // if ann is zero-dimensional and homogeneous
1430  // then it is primary with associated prime maxideal(1)
1431  ////////////////////////////////////////////////////////////////
1432  if((homog(ann)==1)&&(dim(ann)==0))
1433  {
1434    return(list(list(@N,maxideal(1))));
1435  }
1436
1437  ////////////////////////////////////////////////////////////////
1438  // the not-that-trivial case of ann==0
1439  ////////////////////////////////////////////////////////////////
1440  def BAS = basering;
1441  if(size(ann)==0)      //check, whether ann=0
1442  {
1443   execute("ring Rloc=("+charstr(basering)+","+varstr(basering)+"),dummy,("+ordstr(basering)+");");
1444   module @N=clrSBmod(imap(BAS, @N));
1445   module @M=freemodule(nrows(@N));
1446   poly @q=prepareSat(@N);
1447
1448   setring BAS;
1449   poly @q=imap(Rloc, @q);
1450   list satu=sat(@N,@q);
1451
1452   if(satu[2]==0)
1453   {
1454     return(list(list(@N,ideal(0))));
1455   }
1456   else
1457   {
1458    check=intersect(check,satu[1]);
1459    return(list(list(satu[1],ideal(0)))+GTZopt(@N+(@q^satu[2])*@M,check));
1460   }
1461  }
1462
1463  int @k1, @k2, @k3, @k4;   // the indices for nested for/while loops
1464  int nVar=nvars(BAS);
1465  int Ndim=dim(@N);
1466
1467  ////////////////////////////////////////////////////////////////
1468  // Simplification of the modules using
1469  // N=N/(a*x_i+b)*M+(a*x_i+b)*M, for (a*x_i+b) in ann
1470  ////////////////////////////////////////////////////////////////
1471  if (size(#)==0)
1472  {
1473    ideal fried;
1474    @k2=size(ann);
1475    for(@k1=1;@k1<=@k2;@k1++)
1476    {
1477      if(deg(lead(ann[@k1]))==1)
1478      {
1479        fried[size(fried)+1]=ann[@k1];
1480      }
1481    }
1482    if(size(fried)==nVar)
1483    {
1484       return(list(list(@N, ann)));
1485    }
1486    if(size(fried)>0)
1487    {
1488       string newva;
1489       string newma;
1490       for(@k1=1;@k1<=nVar;@k1++)
1491       {
1492          checked=0;
1493          for(@k2=1;@k2<=size(fried);@k2++)
1494          {
1495             if(leadmonom(fried[@k2])==var(@k1))
1496             {
1497                checked=1;
1498                break;
1499             }
1500          }
1501          if(checked==0)
1502          {
1503            newva=newva+string(var(@k1))+",";
1504            newma=newma+string(var(@k1))+",";
1505          }
1506          else
1507          {
1508            newma=newma+string(var(@k1)-((1/leadcoef(fried[@k2]))*fried[@k2]))+",";
1509          }
1510       }
1511       newva[size(newva)]=")";
1512       newma[size(newma)]=";";
1513       execute("ring @deirf=("+charstr(BAS)+"),("+newva+",(C,lp);");
1514       execute("map @kappa=BAS,"+newma);
1515       ideal @j = @kappa(ann);
1516       module @N = @kappa(@N);
1517       @N=simplify(@N,2);
1518       @j=simplify(@j,2);
1519       list pr=GTZopt(@N,freemodule(nrows(@N)),@j);
1520       setring BAS;
1521       list pr=imap(@deirf,pr);
1522
1523       for(@k1=1;@k1<=size(pr);@k1++)
1524       {
1525         pr[@k1][1]=std(pr[@k1][1]+fried*@M);
1526         pr[@k1][2]=std(pr[@k1][2]+fried);
1527       }
1528       return(pr);
1529    }
1530  }
1531
1532  ////////////////////////////////////////////////////////////////
1533  // the trivial case
1534  ////////////////////////////////////////////////////////////////
1535  if(Ndim==-1)
1536  {
1537    return(list(list(@N,ideal(1))));
1538  }
1539
1540  ////////////////////////////////////////////////////////////////
1541  // the case of one variable
1542  ////////////////////////////////////////////////////////////////
1543  if(nVar==1)
1544  {
1545    return(dec1var(@N));
1546  }
1547
1548  ////////////////////////////////////////////////////////////////
1549  // the zerodimensional case
1550  ////////////////////////////////////////////////////////////////
1551  if (Ndim==0)
1552  {
1553    return(zeroOpt(@N, check, ann));
1554  }
1555
1556  ////////////////////////////////////////////////////////////////
1557  // the preparation of the quotient ring
1558  ////////////////////////////////////////////////////////////////
1559  list result;
1560  list indep =indSet(ann);
1561  poly @q;
1562  list @p,primary;
1563  ideal @h;
1564  int szIndep;
1565  for (@k1=1;@k1<=2;@k1++)
1566  {
1567    szIndep=size(indep[@k1]);
1568    for (@k2=1;@k2<=szIndep;@k2++)
1569    {
1570      execute("ring RAU=("+charstr(basering)+"),("+indep[@k1][@k2][1]+","+indep[@k1][@k2][2]+"),"+indep[@k1][@k2][3]+";");
1571      module @N=std(imap(BAS,@N)); // the standard basis in (R[U])[A]
1572      execute("ring Rloc=("+charstr(basering)+","+indep[@k1][@k2][2]+"),("+indep[@k1][@k2][1]+"),(C,dp);");
1573      module @N=imap(RAU,@N); //std in lokalisierung
1574      @N=clrSBmod(@N);
1575      kill RAU;
1576
1577      ////////////////////////////////////////////////////////////////
1578      // the zero-dimensional decomposition
1579      ////////////////////////////////////////////////////////////////
1580      list qprim, preList;
1581      module check=imap(BAS, check);
1582      (preList,check)=preComp(@N,check);
1583      for (@k3=1; @k3<=size(preList); @k3++)
1584      {
1585        if(size(preList[@k3][2])>0)
1586        {
1587          qprim=qprim+list(list(preList[@k3][1],preList[@k3][2]));
1588        }
1589        else
1590        {
1591          checked=size(qprim);
1592          qprim=qprim+zeroOpt(preList[@k3][1], check, preList[@k3][3]);
1593          for(@k4=checked+1;@k4<=size(qprim);@k4++)
1594          {
1595            check=intersect(check, qprim[@k4][1]);
1596          }
1597        }
1598      }  // end of for(@k3...)
1599      kill preList;
1600
1601      ////////////////////////////////////////////////////////////////
1602      // Preparation of the saturation of @N
1603      ////////////////////////////////////////////////////////////////
1604      //poly pp=prepareSat(@N);
1605      ideal @h2;
1606      for (@k3=1;@k3<=size(@N);@k3++)
1607      {
1608        @h2[@k3]=leadcoef(@N[@k3]);
1609      }
1610
1611      if (size(qprim)==0)     // there aren't any new components
1612      {
1613        setring BAS;
1614        check=imap(Rloc,check);
1615        @h=imap(Rloc,@h2);
1616        @q=minSatMod(imap(BAS,@N),@h)[2];
1617        // @q=imap(Rloc,pp)^sat(imap(BAS,@N),imap(Rloc,pp))[2];
1618        kill Rloc;
1619        if (deg(@q)>0)
1620        {
1621          @N=std(@N+@q*@M);
1622          ann=std(ideal(ann+@q));
1623          kill qprim;
1624        }
1625      }
1626      else                    // there are new components
1627      {
1628        ////////////////////////////////////////////////////////////////
1629        // Preparation of the saturation of qprim
1630        ////////////////////////////////////////////////////////////////
1631        list @p2;
1632        for (@k3=1;@k3<=size(qprim);@k3++)
1633        {
1634          @p2[@k3]=list(prepareSat(qprim[@k3][1]),prepareSat(qprim[@k3][2]));
1635        }
1636
1637
1638        ////////////////////////////////////////////////////////////////
1639        // compute the recontractions
1640        // back in the original ring
1641        ////////////////////////////////////////////////////////////////
1642        setring BAS;
1643        @p=imap(Rloc,@p2);
1644        primary=imap(Rloc,qprim);
1645        @h=imap(Rloc,@h2);
1646        kill Rloc;
1647        for(@k3=1;@k3<=size(primary);@k3++)
1648        {
1649          primary[@k3]=list(sat(primary[@k3][1],@p[@k3][1])[1],
1650                            sat(primary[@k3][2],@p[@k3][2])[1]);
1651          check=intersect(check,primary[@k3][1]);
1652        }
1653        @q=minSatMod(imap(BAS,@N),@h)[2];
1654        result=result+primary;
1655        if (deg(@q)>0)
1656        {
1657          @N=std(@N+@q*@M);
1658          ann=std(ideal(ann+@q));
1659        }
1660      }                       // end of else
1661      if ((@k1==1)&&(@k2<szIndep)&&(Ndim>dim(ann)))
1662      {
1663        break;
1664      }
1665    }
1666  }
1667  return(result+GTZopt(@N,check,ann));
1668}
1669example
1670{ "EXAMPLE:"; echo = 2;
1671  ring r=0,(x,y,z),dp;
1672  module N=x*gen(1)+ y*gen(2),
1673           x*gen(1)-x2*gen(2);
1674  list l=GTZopt(N);
1675  l;
1676}
1677
1678
1679/////////////////////////////////////////////////////////////////////////////
1680// dec1var(N[,check[, ann]])
1681// primary decompostion for a ring with one variable
1682/////////////////////////////////////////////////////////////////////////////
1683
1684proc dec1var (module @N, list #)
1685"USAGE:   dec1var (N); zero-dimensional module N[, module check]
1686RETURN:  list l
1687         the minimal primary decomposition of a submodule N of R^s
1688         if nvars(R)=1
1689NOTE:    if the parameter check is given, only components not containing check are computed
1690EXAMPLE: example zeroMod; shows an example
1691"
1692{
1693  ideal ann; module @M, check; int checked;
1694  (ann, check, @M, checked)=getData(@N, #);
1695
1696  list fac = factorize(ann[1],2);
1697  if(size(fac[2])==1)
1698  {
1699   return(list(list(@N,ann)));
1700  }
1701  // comp of the primary modules, the primary ideals and the primes
1702  poly @h;
1703  module primod;
1704  list result;
1705  int @k;
1706  for (@k=1;@k<=size(fac[1]);@k++)
1707  {
1708    @h=ann[1]/(fac[1][@k]^fac[2][@k]);
1709    result =result+list(list(std(quotient(@N,@h)), std(ann,fac[1][@k])));
1710  }
1711    return(result);
1712}
1713example
1714{ "EXAMPLE:"; echo = 2;
1715  ring r=0,z,dp;
1716  module N=z*gen(1),(z-1)*gen(2),(z+1)*gen(3);
1717  list l=dec1var(N);
1718  l;
1719}
1720
1721/////////////////////////////////////////////////////////////////////////////
1722// zeroOpt(N[,check[, ann]])
1723// a faster version of zeroMod
1724/////////////////////////////////////////////////////////////////////////////
1725
1726proc zeroOpt (module @N, list #)
1727"USAGE:   zeroOpt (N[, check]); zero-dimensional module N[, module check]
1728RETURN:  list l
1729         the minimal primary decomposition of a zero-dimensional module N,
1730         computed by a generalized and optimized version of the algorithm
1731         of Gianni, Trager and Zacharias
1732NOTE:    if the parameter check is given, only components
1733         not containing check are computed
1734EXAMPLE: example zeroMod; shows an example
1735"
1736{
1737  @N=interred(@N);
1738  attrib(@N,"isSB",1);
1739
1740  ////////////////////////////////////////////////////////////////
1741  // the module check is needed to compute a minimal decomposition
1742  // components containing check are ignored
1743  ////////////////////////////////////////////////////////////////
1744  ideal ann; module @M, check; int checked;
1745  (ann, check, @M, checked)=getData(@N, #);
1746
1747  if (checked)
1748  {
1749    return(list());
1750  }
1751  ////////////////////////////////////////////////////////////////
1752  // the ordering is changed to lex
1753  ////////////////////////////////////////////////////////////////
1754  def BAS = basering;
1755  def @R=changeord("C,lp");
1756  setring @R;
1757  module @N=std(imap(BAS,@N));
1758  module @M=imap(BAS,@M);
1759  ideal ann=std(imap(BAS,ann));
1760  module check=imap(BAS,check);
1761
1762  ////////////////////////////////////////////////////////////////
1763  if(vdim(ann)==deg(ann[1]))           // if ann ist prime
1764  {
1765    list fact=factorize(ann[1],2);
1766    int k;ideal id;list result;
1767    module hilf;
1768    for(k=1;k<=size(fact[1]);k++)
1769    {
1770      id=ann;
1771      hilf=std(@N+(fact[1][k]^fact[2][k])*@M);
1772      id[1]=fact[1][k];
1773      if(size(NF(check,hilf,1))>0)
1774      {
1775        result=result+list(list(hilf,interred(id)));
1776      }
1777    }
1778    setring BAS;
1779    list result=imap(@R, result);
1780    kill @R;
1781    return(result);
1782
1783  }
1784
1785
1786  if (homog(ann))                      // if ann is homogeneous
1787  {                                    // then radical(ann)=maxideal(1)
1788    if(size(NF(check,@N,1))>0)
1789    {
1790      setring BAS;
1791      kill @R;
1792      return (list(list(@N,maxideal(1))));
1793    }
1794    else
1795    {
1796      setring BAS;
1797      kill @R;
1798      return(list());
1799    }
1800  }
1801
1802  ////////////////////////////////////////////////////////////////
1803  // the random coordnate change and its inverse
1804  // furthermore the module is simplified using
1805  // N=N/(a*x_i+b)+(a*x_i+b)*M, for a*x_i+b in ann
1806  ////////////////////////////////////////////////////////////////
1807  int nVar=nvars(@R);
1808  int @k, @k1;
1809  list result, rest;
1810  ideal primary, prim;
1811  module primmod;
1812  ideal fried;
1813  intvec optionsVec=option(get);
1814  option(redSB);
1815  ideal prepMap = randomLast(100);
1816  ideal prepInv=maxideal(1);
1817  for(@k=1;@k<=size(ann);@k++)
1818  {
1819    if(deg(lead(ann[@k]))==1)
1820    {
1821      fried[size(fried)+1]=ann[@k];
1822    }
1823  }
1824  if(size(fried)==nVar)
1825  {
1826    return(list(list(@N, ann)));
1827  }
1828  if(size(fried)>0)
1829  {
1830    for(@k=1;@k<@k1;@k1++)
1831    {
1832      for(@k1=1;@k1<=size(fried);@k1++)
1833      {
1834        if(leadmonom(fried[@k1])==var(@k))
1835        {
1836          prepMap[@k]=var(@k)+((1/leadcoef(fried[@k1]))*(var(@k)-fried[@k1]));
1837          prepMap[nVar]=subst(prepMap[nVar],var(@k),0);
1838          prepInv[@k]=fried[@k1];
1839        }
1840      }
1841    }
1842  }
1843  map phi=@R,prepMap;
1844  prepInv[nVar]=2*var(nVar)-prepMap[nVar];
1845  map invphi=@R,prepInv;
1846  ideal @j=std(phi(ann));         // factorization of the 1st elt. in Ann(@N)
1847  list fac = factorize(@j[1],2);
1848
1849  ////////////////////////////////////////////////////////////////
1850  // Case: 1st element irreducible
1851  ////////////////////////////////////////////////////////////////
1852  if(size(fac[2])==1)
1853  {
1854    prim=primaryTest(@j,fac[1][1]);
1855    prim=invphi(prim);
1856    setring BAS;
1857    @N=std(@N);
1858    ideal prim =imap(@R,prim);
1859    kill @R;
1860    if(prim!=0)
1861    {
1862      return(list(list(@N,prim)));
1863    }
1864    else
1865    {
1866      return(zeroOpt(@N,check));
1867    }
1868  }
1869
1870  ////////////////////////////////////////////////////////////////
1871  // Computation of the - hopefully primary - modules
1872  // their annihilators and associated primes
1873  ////////////////////////////////////////////////////////////////
1874  poly @p, @h;
1875  for (@k=1;@k<=size(fac[1]);@k++)
1876  {
1877    @p=fac[1][@k]^fac[2][@k];
1878    @h=@j[1]/@p;
1879    primmod=std(quotient(phi(@N),@h));
1880    check=phi(check);
1881    if (size(NF(check,primmod,1))>0)
1882    {
1883      primary=std(@j+@p);
1884      // test if the modules were primary and in general position
1885      prim=primTest(primary,fac[1][@k]);
1886      if(size(prim)==0)
1887      {
1888        prim=primaryTest(primary,fac[1][@k]);
1889      }
1890      if (prim==0)
1891      {
1892        rest[size(rest)+1]=invphi(primmod);
1893      }
1894      else
1895      {
1896        result[size(result)+1]=list(std(invphi(primmod)),std(invphi(prim)));
1897      }
1898    }
1899  }
1900
1901  ////////////////////////////////////////////////////////////////
1902  // the bad cases
1903  ////////////////////////////////////////////////////////////////
1904  for (@k=1; @k<=size(rest);@k++)
1905  {
1906    result = result+zeroOpt(rest[@k],check);
1907  }
1908  option (set,optionsVec);
1909  if(size(result)==0)
1910  {
1911    setring BAS;
1912    kill @R;
1913    return(list());
1914  }
1915  setring BAS;
1916  list result=imap(@R, result);
1917  kill @R;
1918
1919  return(result);
1920}
1921example
1922{ "EXAMPLE:"; echo = 2;
1923  ring r=0,z,dp;
1924  module N=z*gen(1),(z-1)*gen(2),(z+1)*gen(3);
1925  list l=zeroOpt(N);
1926  l;
1927}
1928
1929/////////////////////////////////////////////////////////////////////////////
1930// clrSBmod(N)
1931// Generalization of clearSB from primdec.lib
1932/////////////////////////////////////////////////////////////////////////////
1933
1934static proc clrSBmod (module @N)
1935"USAGE:   clrSBmod(N); N module which is SB ordered by monomial ordering
1936RETURN:  module = minimal SB
1937EXAMPLE: example clrSBmod; shows an example
1938"
1939{
1940  int @k,@j;
1941  list Nsizes;
1942  for (@k=1;@k<=size(@N);@k++)
1943  {
1944    Nsizes[@k]=size(@N[@k]);
1945  }
1946  module leadVec;
1947  int szN=size(@N);
1948  @j=0;
1949  while(@j<szN-1)
1950  {
1951    @j++;
1952    if(deg(@N[@j])>0)
1953    {
1954      leadVec=lead(@N[@j]);
1955      attrib(leadVec,"isSB",1);
1956      for(@k=@j+1;@k<=szN;@k++)
1957      {
1958        if(size(NF(lead(@N[@k]),leadVec,1))==0)
1959        {
1960          if((leadexp(leadVec[1])!=leadexp(@N[@k]))||(Nsizes[@j]<=Nsizes[@k]))
1961          {
1962            @N[@k]=0;
1963          }
1964          else
1965          {
1966            @N[@j]=0;
1967             break;
1968          }
1969        }
1970      }
1971    }
1972  }
1973  return(simplify(@N,2));
1974}
1975example
1976{ "EXAMPLE:"; echo = 2;
1977   ring  r = (0,a,b),(x,y,z),dp;
1978   module N1=ax2+y,a2x+y,bx;
1979   module N2=clrSBmod(N1);
1980   N2;
1981}
1982
1983
1984/////////////////////////////////////////////////////////////////////////////
1985// minSatMod(N, id)
1986// Generalization of minsat from primdec.lib
1987/////////////////////////////////////////////////////////////////////////////
1988
1989static proc minSatMod(module Nnew, ideal @h)
1990"USAGE:   minSatMod(N, I); module N, ideal I
1991RETURN:  list with 2 elements:
1992         [1]=sat(N,product(I))[1],
1993         [2]=p, the polynomial of minimal degree s.th. [1]=quotient(N,p)
1994EXAMPLE: example minSatMod; shows an example
1995"
1996{
1997   int @i,@k;
1998   poly @f=1;
1999   module Nold;
2000   ideal fac;
2001   list quotM,@l;
2002
2003   for(@i=1;@i<=ncols(@h);@i++)
2004   {
2005      if(deg(@h[@i])>0)
2006      {
2007         fac=fac+factorize(@h[@i],1);
2008      }
2009   }
2010   fac=simplify(fac,4);
2011   if(size(fac)==0)
2012   {
2013      @l=Nnew,1;
2014      return(@l);
2015   }
2016   fac=sort(fac)[1];
2017   for(@i=1;@i<=size(fac);@i++)
2018   {
2019      @f=@f*fac[@i];
2020   }
2021   quotM[1]=Nnew;
2022   quotM[2]=fac;
2023   quotM[3]=@f;
2024   @f=1;
2025   while(specialModulesEqual(Nold,quotM[1])==0)
2026   {
2027      if(@k>0)
2028      {
2029         @f=@f*quotM[3];
2030      }
2031      Nold=quotM[1];
2032      quotM=quotMinMod(quotM);
2033      @k++;
2034   }
2035   @l=quotM[1],@f;
2036   return(@l);
2037}
2038example
2039{ "EXAMPLE:"; echo = 2;
2040   ring  r = 0,(x,y,z),dp;
2041   module N=xy*gen(1);
2042   ideal h=yz,z2;
2043   list l=minSatMod(N,h);
2044   l;
2045}
2046
2047/////////////////////////////////////////////////////////////////////////////
2048// quotMinMod(N, fac, f)
2049// Generalization of quotMin from primdec.lib
2050/////////////////////////////////////////////////////////////////////////////
2051
2052proc quotMinMod(list tsil)
2053{
2054   int @i,@j,action;
2055   module verg;
2056   list @l;
2057   poly @g;
2058   intvec optionsVec;
2059
2060   module laedi=tsil[1];
2061   ideal fac=tsil[2];
2062   poly @f=tsil[3];
2063   optionsVec=option(get);
2064   option(returnSB);
2065   module star=quotient(laedi,@f);
2066   option(set,optionsVec);
2067   if(specialModulesEqual(star,laedi))
2068   {
2069      @l=star,fac,@f;
2070      return(@l);
2071   }
2072
2073   action=1;
2074   while(action==1)
2075   {
2076      if(size(fac)==1)
2077      {
2078         action=0;
2079         break;
2080      }
2081      for(@i=1;@i<=size(fac);@i++)
2082      {
2083        @g=1;
2084        verg=laedi;
2085
2086         for(@j=1;@j<=size(fac);@j++)
2087         {
2088            if(@i!=@j)
2089            {
2090               @g=@g*fac[@j];
2091            }
2092         }
2093         optionsVec=option(get);
2094         option(returnSB);
2095         verg=quotient(laedi,@g);
2096         option(set,optionsVec);
2097         if(specialModulesEqual(verg,star)==1)
2098         {
2099            @f=@g;
2100            fac[@i]=0;
2101            fac=simplify(fac,2);
2102            break;
2103         }
2104
2105         if(@i==size(fac))
2106         {
2107            action=0;
2108         }
2109      }
2110   }
2111   @l=star,fac,@f;
2112   return(@l);
2113}
2114
2115/////////////////////////////////////////////////////////////////////////////
2116// specialModulesEqual(N1,N2)
2117// Generalization of specialIdealsEqual from primdec.lib
2118/////////////////////////////////////////////////////////////////////////////
2119
2120static proc specialModulesEqual( module k1, module k2)
2121"USAGE:   specialModulesEqual(N1, N2) N1, N2 standard bases of modules,
2122         s.th. N1 is contained in N2 or vice versa
2123RETURN:  int i
2124         if (N1==N2) then i=1
2125         else i=0
2126EXAMPLE: example specialModulesEqual; shows an example
2127"
2128{
2129   int @j;
2130
2131   if(size(k1)==size(k2))
2132   {
2133      for(@j=1;@j<=size(k1);@j++)
2134      {
2135         if(leadexp(k1[@j])!=leadexp(k2[@j]))
2136         {
2137            return(0);
2138         }
2139      }
2140      return(1);
2141   }
2142   return(0);
2143}
2144example
2145{ "EXAMPLE:"; echo = 2;
2146   ring  r = 0,(x,y,z),dp;
2147   module N1=x*freemodule(2);
2148   module N2=xy*freemodule(2);
2149   int i=specialModulesEqual(N1,N2);
2150   i;
2151
2152   N2=N1;
2153   i=specialModulesEqual(N1,N2);
2154   i;
2155}
2156
2157/////////////////////////////////////////////////////////////////////////////
2158// sat2mod(N,i)
2159// Generalization of sat2 from primdec.lib
2160/////////////////////////////////////////////////////////////////////////////
2161
2162proc sat2mod (module id, ideal h1)
2163"USAGE:   sat2mod(id,j);  id ideal, j polynomial
2164RETURN:  saturation of id with respect to j (= union_(k=1...) of id:j^k)
2165NOTE:    result is a std basis in the basering
2166"
2167{
2168   int @k,@i;
2169   def @P= basering;
2170   if(ordstr(basering)[1,2]!="dp")
2171   {
2172      execute("ring @Phelp=("+charstr(@P)+"),("+varstr(@P)+"),(C,dp);");
2173      module inew=std(imap(@P,id));
2174      ideal  @h=imap(@P,h1);
2175   }
2176   else
2177   {
2178      ideal @h=h1;
2179      module inew=std(id);
2180   }
2181   ideal fac;
2182
2183   for(@i=1;@i<=ncols(@h);@i++)
2184   {
2185     if(deg(@h[@i])>0)
2186     {
2187        fac=fac+factorize(@h[@i],1);
2188     }
2189   }
2190   fac=simplify(fac,4);
2191   poly @f=1;
2192   if(deg(fac[1])>0)
2193   {
2194      module iold;
2195
2196      for(@i=1;@i<=size(fac);@i++)
2197      {
2198        @f=@f*fac[@i];
2199      }
2200      intvec optionsVec=option(get)
2201      option(returnSB);
2202      while(specialModulesEqual(iold,inew)==0 )
2203      {
2204         iold=inew;
2205         if(deg(iold[size(iold)])!=1)
2206         {
2207            inew=quotient(iold,@f);
2208         }
2209         else
2210         {
2211            inew=iold;
2212         }
2213         @k++;
2214      }
2215      option(set,optionsVec);
2216      @k--;
2217   }
2218
2219   if(ordstr(@P)[1,2]!="dp")
2220   {
2221      setring @P;
2222      module inew=std(imap(@Phelp,inew));
2223      poly @f=imap(@Phelp,@f);
2224   }
2225   list L =inew,@f^@k;
2226   return (L);
2227}
2228
2229/////////////////////////////////////////////////////////////////////////////
2230// stdModulesEqual(N1,N2)
2231// Generalization of stdIdealsEqual from primdec.lib
2232/////////////////////////////////////////////////////////////////////////////
2233
2234static proc stdModulesEqual(module k1, module k2)
2235"USAGE:   stdModulesEqual(N1, N2) N1, N2 standard bases of modules,
2236RETURN:  int i
2237         if (N1==N2) then i=1
2238         else i=0
2239EXAMPLE: example stdModulesEqual; shows an example
2240"
2241{
2242   int @j;
2243
2244   if(size(k1)==size(k2))
2245   {
2246      for(@j=1;@j<=size(k1);@j++)
2247      {
2248         if(leadexp(k1[@j])!=leadexp(k2[@j]))
2249         {
2250            return(0);
2251         }
2252      }
2253      attrib(k2,"isSB",1);
2254      if(size(reduce(k1,k2,1))==0)
2255      {
2256         return(1);
2257      }
2258   }
2259   return(0);
2260}
2261example
2262{ "EXAMPLE:"; echo = 2;
2263   ring  r = 0,(x,y,z),dp;
2264   module N1=x*freemodule(2);
2265   module N2=xy*freemodule(2);
2266   int i=stdModulesEqual(N1,N2);
2267   i;
2268
2269   N2=N1;
2270   i=stdModulesEqual(N1,N2);
2271   i;
2272}
2273
2274/////////////////////////////////////////////////////////////////////////////
2275// ModulesEqual(N1,N2)
2276// Generalization of IdealsEqual from primdec.lib
2277/////////////////////////////////////////////////////////////////////////////
2278
2279static proc modulesEqual( module @k, module @j)
2280"USAGE:   modulesEqual(N1, N2) N1, N2 modules,
2281RETURN:  int i
2282         if (N1==N2) then i=1
2283         else i=0
2284EXAMPLE: example modulesEqual; shows an example
2285"
2286{
2287   return(stdModulesEqual(std(@k),std(@j)));
2288}
2289example
2290{ "EXAMPLE:"; echo = 2;
2291   ring  r = 0,(x,y,z),dp;
2292   module N1=x*freemodule(2);
2293   module N2=xy*freemodule(2);
2294   int i=stdModulesEqual(N1,N2);
2295   i;
2296
2297   N2=N1;
2298   i=modulesEqual(N1,N2);
2299   i;
2300}
2301example
2302{ "EXAMPLE:"; echo = 2;
2303   ring  r = 0,(x,y,z),dp;
2304   module N1=x*freemodule(2);
2305   module N2=xy*freemodule(2);
2306   int i=modulesEqual(N1,N2);
2307   i;
2308
2309   N2=N1;
2310   i=modulesEqual(N1,N2);
2311   i;
2312}
2313
2314static proc getData (module @N, list oldData, list #)
2315"USAGE:   getData(N, l[, noCheck]);  module N, list l[, int noCheck]
2316RETURN:  (ann, check, M, checked)
2317         ideal ann, module check, M, int checked
2318
2319         if l[1] is contained in N [and noCheck is not given]
2320            then checked=1, ann=ideal(0), check=0, M=0;
2321         else checked=0, M=freemodule(nrows(N)); check=l[1]
2322            (resp. check=M if l is an empty list) and
2323            if size(l)>1 then  ann=l[2] else ann is the annihilator of M/N.
2324
2325NOTE:    ann is a std basis in the basering
2326EXAMPLE: example getData; shows an example
2327"
2328{
2329  if (size(oldData)>0)
2330  {
2331    if ((size(#)==0)&&(size(NF(oldData[1],@N,1))==0))
2332    {
2333      return(ideal(0), 0 ,  0, 1);
2334    }
2335    module @M=freemodule(nrows(@N));
2336    if (size(oldData)>1)
2337    {
2338      ideal ann=oldData[2];
2339      attrib(ann,"isSB",1);
2340    }
2341    else
2342    {
2343      ideal ann=annil(@N);
2344    }
2345  }
2346  else
2347  {
2348   module @M=freemodule(nrows(@N));
2349   oldData[1]=@M;
2350   ideal ann=annil(@N);
2351  }
2352 return(ann, oldData[1], @M, 0);
2353}
2354example
2355{ "EXAMPLE:"; echo = 2;
2356   ring  r = 0,(x,y,z),lp;
2357   module N=x*gen(1),y*gen(2);
2358   N=std(N);
2359   ideal ann; module check, M; int checked; list l;
2360   (ann, check, M, checked)=getData(N,l);
2361   ann; check; M; checked;
2362
2363   l=list(check,ann);
2364   (ann, check, M, checked)=getData(N,l);
2365   ann; check; M; checked;
2366
2367   l=list(N);
2368   (ann, check, M, checked)=getData(N,l);
2369   ann; check; M; checked;
2370}
Note: See TracBrowser for help on using the repository browser.