source: git/Singular/LIB/mprimdec.lib @ fa8122

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