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

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