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

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