source: git/Singular/LIB/mprimdec.lib @ 291c20

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