source: git/Singular/LIB/standard.lib @ d617b27

spielwiese
Last change on this file since d617b27 was d617b27, checked in by Hans Schönemann <hannes@…>, 16 years ago
*hannes: use a given invec in stdhilb git-svn-id: file:///usr/local/Singular/svn/trunk@10463 2c84dea3-7e68-4137-9b89-c4e89433aadc
  • Property mode set to 100644
File size: 65.4 KB
Line 
1//////////////////////////////////////////////////////////////////////////////
2//major revision Jan/Feb. 2007, GMG
3//groebner mit Optionen versehen
4//////////////////////////////////////////////////////////////////////////////
5version="$Id: standard.lib,v 1.99 2007-12-13 14:32:05 Singular Exp $";
6category="Miscellaneous";
7info="
8LIBRARY: standard.lib   Procedures which are always loaded at Start-up
9
10PROCEDURES:
11 stdfglm(ideal[,ord])   standard basis of ideal via fglm [and ordering ord]
12 stdhilb(ideal[,h])     Hilbert driven Groebner basis of ideal
13 groebner(ideal,...)    standard basis using a heuristically chosen method
14 res(ideal/module,[i])  free resolution of ideal or module
15 sprintf(fmt,...)       returns fomatted string
16 fprintf(link,fmt,..)   writes formatted string to link
17 printf(fmt,...)        displays formatted string
18 weightKB(stc,dd,vl)    degree dd part of a kbase wrt. some weigths
19 qslimgb(i)             computes a standard basis with slimgb in a qring
20 par2varRing([i])       create a ring with pars to vars together with i
21";
22// hilbRing([i])          create a ring containing the homogenized i
23// quotientList(L,...)    a list, say QL, s.t. ring(QL) creates a correct qring
24
25//////////////////////////////////////////////////////////////////////////////
26
27proc stdfglm (i, list #)
28"SYNTAX: @code{stdfglm (} ideal_expression @code{)} @*
29         @code{stdfglm (} ideal_expression@code{,} string_expression @code{)}
30TYPE:    ideal
31PURPOSE: computes the standard basis of the ideal in the basering
32         via @code{fglm} from the ordering given as the second argument
33         to the ordering of the basering. If no second argument is given,
34         \"dp\" is used. The standard basis for the given ordering (resp. for
35         \"dp\") is computed via the command groebner except if a further
36         argument \"std\" or \"slimgb\" is given in which case std resp.
37         slimgb is used.
38SEE ALSO: fglm, groebner, std, slimgb, stdhilb
39KEYWORDS: fglm
40EXAMPLE: example stdfglm; shows an example"
41{
42  if (nrows(i) > 1)
43  {
44    ERROR("first argument of 'stdfglm' must be an ideal");
45  }
46  string os;
47  int s = size(#);
48  def P= basering;
49  string algorithm;
50  int ii;
51  for( ii=1; ii<=s; ii++)
52  {
53    if ( typeof(#[ii])== "string" )
54    {
55      if ( #[ii]=="std" || #[ii]=="slimgb" )
56      {
57        algorithm =  #[ii];
58        # = delete(#,ii);
59        s--;
60        ii--;
61      }
62    }
63  }
64
65  if( s > 0 && (typeof(#[1]) == "string") )
66  {
67    os = #[1];
68    ideal Qideal = ideal(P);
69    int sQ = size(Qideal);
70    int sM = size(minpoly);
71    if ( sM!=0 )
72    {
73      string mpoly = string(minpoly);
74    }
75    if (sQ!=0 )
76    {
77      execute("ring Rfglm=("+charstr(P)+"),("+varstr(P)+"),"+os+";");
78      ideal Qideal = fetch(P,Qideal);
79      qring Pfglm = groebner(Qideal,"std","slimgb");
80    }
81    else
82    {
83      execute("ring Pfglm=("+charstr(P)+"),("+varstr(P)+"),"+os+";");
84    }
85    if ( sM!=0 )
86    {
87      execute("minpoly="+mpoly+";");
88    }
89  }
90  else
91  {
92    list BRlist = ringlist(P);
93    int nvarP = nvars(P);
94    intvec w;                       //for ringweights of basering P
95    int k;
96    for(k=1;  k <= nvarP; k++)
97    {
98      w[k]=deg(var(k));
99    }
100
101    BRlist[3] = list();
102    if( s==0 or (typeof(#[1]) != "string") )
103    {
104      if( w==1 )
105      {
106        BRlist[3][1]=list("dp",w);
107      }
108      else
109      {
110        BRlist[3][1]=list("wp",w);
111      }
112      BRlist[3][2]=list("C",intvec(0));
113      def Pfglm = ring(quotientList(BRlist));
114      setring Pfglm;
115    }
116  }
117  ideal i = fetch(P,i);
118
119  intvec opt = option(get);            //save options
120  option(redSB);
121  if (size(algorithm) > 0)
122  {
123    i = groebner(i,algorithm);
124  }
125  else
126  {
127    i = groebner(i);
128  }
129  option(set,opt);
130  setring P;
131  return (fglm(Pfglm,i));
132}
133example
134{ "EXAMPLE:"; echo = 2;
135   ring r  = 0,(x,y,z),lp;
136   ideal i = y3+x2,x2y+x2,x3-x2,z4-x2-y;
137   stdfglm(i);                   //uses fglm from "dp" (with groebner) to "lp"
138   stdfglm(i,"std");             //uses fglm from "dp" (with std) to "lp"
139
140   ring s  = (0,x),(y,z,u,v),lp;
141   minpoly = x2+1;
142   ideal i = u5-v4,zv-u2,zu3-v3,z2u-v2,z3-uv,yv-zu,yu-z2,yz-v,y2-u,u-xy2;
143   weight(i);
144   stdfglm(i,"(a(2,3,4,5),dp)"); //uses fglm from "(a(2,3,4,5),dp)" to "lp"
145}
146
147/////////////////////////////////////////////////////////////////////////////
148
149proc stdhilb(i,list #)
150"SYNTAX: @code{stdhilb (} ideal_expression @code{)} @*
151         @code{stdhilb (} module_expression @code{)} @*
152         @code{stdhilb (} ideal_expression@code{,} intvec_expression @code{)}
153         @code{stdhilb (} ideal_expression@code{,} list of string_expressions
154               and intvec_expressin @code{)} @*
155TYPE:    type of the first argument
156PURPOSE: Compute a Groebner basis of the ideal/module in the basering by
157         using the Hilbert driven Groebner basis algorithm.
158         If an argument of type string @code{\"std\"} resp. @code{\"slimgb\"}
159         is given, the standard basis computation uses @code{std} or
160         @code{slimgb}, otherwise a heuristically chosen method (default)
161THEORY:  If the ideal is not homogeneous compute first a Groebner basis
162         of the homogenization of the ideal, then the Hilbert function and,
163         finally, a Groebner basis in the original ring by using the
164         computed Hilbert function.@*
165         If the ideal is homogeneous and a second argument of type intvec
166         is given it will be used as 1st Hilbert function in the Hilbert
167         driven algorithm.
168NOTE:    'homogeneous' means weighted homogeneous with respect to the weights
169         w[i] of the variables var(i) of the basering. Parameters are not
170         converted to variables.
171ASSUME:  The argument of type intvec is the 1st Hilbert series, computed
172         by @code{hilb} using an intvector w, w[i]=deg(var(i)), as third
173         argument
174SEE ALSO: stdfglm, std, slimgb, groebner
175KEYWORDS: Hilbert function
176EXAMPLE: example stdhilb;  shows an example"
177{
178
179//--------------------- save data from basering --------------------------
180  def P=basering;
181  int nr = nrows(i);            //nr=1 iff i is an ideal
182  ideal Qideal = ideal(P);      //defining the quotient ideal if P is a qring
183  int was_qring;                //remembers if basering was a qring
184  int is_homog =homog(i);       //check for homogeneity of i and Qideal
185  if (size(Qideal) > 0)
186  {
187     was_qring = 1;
188  }
189
190  // save ordering of basering P for later use
191  list ord_P = ringlist(P)[3];     //ordering of basering in ringlist
192  string ordstr_P = ordstr(P);     //ordering of basering as string
193  int nvarP = nvars(P);
194  intvec w;                        //for ringweights of basering P
195  int k;
196  for(k=1;  k<=nvarP; k++)
197  {
198    w[k]=deg(var(k));
199  }
200  int neg=1-attrib (P,"global");
201
202  //save options:
203  int p_opt;
204  string s_opt = option();
205  if (find(s_opt, "prot"))  { p_opt = 1; }
206
207//--------------------- check the given method ---------------------------
208  string method;
209  for (k=1; k<=size(#); k++)
210  {
211    if (typeof(#[k]) == "intvec")
212    {
213      intvec hi = #[k];
214    }
215    if (typeof(#[k]) == "string")
216    {
217      method = method + "," + #[k];
218    }
219  }
220
221  if (npars(P) > 0)             //clear denominators of parameters
222  {
223    for( k=ncols(i); k>0; k-- )
224    {
225      i[k]=cleardenom(i[k]);
226    }
227  }
228
229//---------- exclude cases to which stdhilb should no be applied  ----------
230//Note that quotient ideal of qring must be homogeneous too
231
232  if( find(ordstr_P,"s") || find(ordstr_P,"M")
233      || find(ordstr_P,"a") || (neg > 0) )
234  {
235    if( defined(hi) && is_homog )
236    {
237      if (p_opt){"std with given Hilbert function in basering";}
238      return( std(i,hi,w) );
239    }
240    if (p_opt){"//--stdhilb not implemented, use std in basering";}
241    //if ( neg )
242    //{
243    //  "//*** WARNING: non-positive ring weights, computation may not finish";
244    //}
245    return( std(i) );
246  }
247
248//------------------------ change to hilbRing ----------------------------
249
250  list hiRi = hilbRing(i);  //The ground field of P and Philb coincide
251  intvec W = hiRi[2];       //Philb has an extra variable @ or @(k)
252  def Philb = hiRi[1];      //Philb is no qring and the predefined
253  setring Philb;            //ideal/module Id(1) in Philb is homogeneous
254                            //Parameters of P are not converted in Philb
255//-------- compute Hilbert function of homogenized ideal in Philb ---------
256//Philb has only 1 block. There are three cases
257
258  string algorithm;       //possibilities: std, slimgb, stdorslimgb
259  //define algorithm:
260  if( find(method,"std") && !find(method,"slimgb") )
261  {
262    algorithm = "std";
263  }
264  if( find(method,"slimgb") && !find(method,"std") )
265  {
266    algorithm = "slimgb";
267  }
268  if( find(method,"std") && find(method,"slimgb") ||
269    (!find(method,"std") && !find(method,"slimgb")) )
270  {
271    algorithm = "stdorslimgb";
272  }
273
274  if (( algorithm=="std" || ( algorithm=="stdorslimgb" && char(P)>0 ) )
275  && (defined(hi)!=voice))
276  {
277    if (p_opt) {"std in ring " + string(Philb);}
278    intvec hi = hilb( std(Id(1)),1,W );
279  }
280  if (( algorithm=="slimgb" || ( algorithm=="stdorslimgb" && char(P)==0 ) )
281  && (defined(hi)!=voice))
282  {
283    intvec hi = hilb(qslimgb(Id(1)),1,W);
284  }
285
286  //-------------- we need another intermediate ring Phelp ----------------
287  //In Phelp we change the ordering from Philb, otherwise it coincides with
288  //Philb, that is, it has in addition to P an extra homogenizing variable
289  //with name @, resp. @(i) if @ and @(1), ..., @(i-1) are defined.
290  //Phelp has the same ordering as P on common variables. In Phelp
291  //a quotient ideal from P is added to the input
292
293  list BRlist = ringlist(Philb);
294  BRlist[3] = list();
295  int so = size(ord_P);
296  if( ord_P[so][1] =="c" || ord_P[so][1] =="C" )
297  {
298    list moduleord = ord_P[so];
299    so = so-1;
300  }
301  for (k=1; k<=so; k++)
302  {
303    BRlist[3][k] = ord_P[k];
304  }
305
306  BRlist[3][so+1] = list("dp",1);
307  w = w,1;
308
309  if( defined(moduleord) )
310  {
311    BRlist[3][so+2] = moduleord;
312  }
313
314//------ change to extended ring and compute std with hilbert series ------
315  def Phelp = ring(quotientList(BRlist));
316  setring Phelp;
317  def i = imap(Philb, Id(1));
318  kill Philb;
319
320  // compute std with Hilbert series
321  if (w ==1)
322  {
323    if (p_opt){ "std with hilb in " + string(Phelp);}
324    i = std(i, hi);
325  }
326  else
327  {
328    if(p_opt){"std with weighted hilb in "+string(Phelp);}
329    i = std(i, hi, w);
330  }
331
332//-------------------- go back to original ring ---------------------------
333//The main computation is done. Do not forget to simplfy before maping.
334
335  // subst 1 for homogenizing var
336  if ( p_opt ) { "dehomogenization"; }
337  i = subst(i, var(nvars(basering)), 1);
338
339  if (p_opt) { "simplification"; }
340  i= simplify(i,34);
341
342  setring P;
343  if (p_opt) { "imap to ring "+string(P); }
344  i = imap(Phelp,i);
345  kill Phelp;
346  if( was_qring)
347  {
348    i = NF(i,std(0));
349  }
350  i = simplify(i,34);
351
352  // compute reduced SB
353  if (find(s_opt, "redSB") > 0)
354  {
355    if (p_opt) { "//interreduction"; }
356    i=interred(i);
357  }
358  attrib(i, "isSB", 1);
359  return (i);
360}
361example
362{ "EXAMPLE:"; echo = 2;
363   ring  r = 0,(x,y,z),lp;
364   ideal i = y3+x2,x2y+x2z2,x3-z9,z4-y2-xz;
365   ideal j = stdhilb(i); j;
366
367   ring  r1 = 0,(x,y,z),wp(3,2,1);
368   ideal  i = y3+x2,x2y+x2z2,x3-z9,z4-y2-xz;  //ideal is homogeneous
369   ideal j = stdhilb(i,"std"); j;
370   //this is equivalent to:
371   intvec v = hilb(std(i),1);
372   ideal j1 = std(i,v,intvec(3,2,1)); j1;
373   size(NF(j,j1))+size(NF(j1,j));            //j and j1 define the same ideal
374}
375
376///////////////////////////////////////////////////////////////////////////////
377proc quotientList (list RL, list #)
378"SYNTAX: @code{quotientList (} list_expression @code{)} @*
379         @code{quotientList (} list_expression @code{,} string_expression@code{)}
380TYPE:    list
381PURPOSE: define a ringlist, say QL, of the first argument, say RL, which is
382         assumed to be the ringlist of a qring, but where the quotient ideal
383         RL[4] is not a standard basis with respect to the given monomial
384         order in RL[3]. Then QL will be obtained from RL just by replacing
385         RL[4] by a standard of it with respect to this order. RL itself
386         will be returnd if size(RL[4]) <= 1 (in which case it is known to be
387         a standard basis w.r.t. any ordering) or if a second argument
388         \"isSB\" of type string is given.
389NOTE:    the command ring(quotientList(RL)) defines a quotient ring correctly
390         and should be used instead of ring(RL) if the quotient ideal RL[4]
391         is not (or not known to be) a standard basis with respect to the
392         monomial ordering specified in RL[3].
393SEE ALSO: ringlist, ring
394EXAMPLE: example quotientList; shows an example"
395{
396  def P = basering;
397  if( size(#) > 0 )
398  {
399    if ( #[1] == "isSB")
400    {
401      return (RL);
402    }
403  }
404  ideal Qideal  = RL[4];  //##Achtung: falls basering Nullteiler hat, kann
405                           //die SB eines Elements mehrere Elemente enthalten
406  if( size(Qideal) <= 0)
407  {
408    return (RL);
409  }
410
411  RL[4] = ideal(0);
412  def Phelp = ring(RL);
413  setring Phelp;
414  ideal Qideal = groebner(fetch(P,Qideal));
415  setring P;
416  RL[4]=fetch(Phelp,Qideal);
417  return (RL);
418}
419example
420{ "EXAMPLE:"; echo = 2;
421   ring P = 0,(y,z,u,v),lp;
422   ideal i = y+u2+uv3, z+uv3;            //i is an lp-SB but not a dp_SB
423   qring Q = std(i);
424   list LQ = ringlist(Q);
425   LQ[3][1][1]="dp";
426   def Q1 = ring(quotientList(LQ));
427   setring Q1;
428   Q1;
429
430   setring Q;
431   ideal q1 = uv3+z, u2+y-z, yv3-zv3-zu; //q1 is a dp-standard basis
432   LQ[4] = q1;
433   def Q2 = ring(quotientList(LQ,"isSB"));
434   setring Q2;
435   Q2;
436}
437
438///////////////////////////////////////////////////////////////////////////////
439proc par2varRing (list #)
440"USAGE:   par2varRing([l]); l list of ideals/modules [default:l=empty list]
441RETURN:  list, say L, with L[1] a ring where the parameters of the
442         basering have been converted to an additional last block of
443         variables, all of weight 1, and ordering dp.
444         If a list l with l[i] an ideal/module is given, then
445         l[i] + minpoly*freemodule(nrows(l[i])) is mapped to an ideal/module
446         in L[1] with name Id(i).
447         If the basering has no parameters then L[1] is the basering.
448EXAMPLE: example par2varRing; shows an example"
449{
450  def P = basering;
451  int npar = npars(P);  //number of parameters
452  int s = size(#);
453  int ii;
454  if ( npar == 0)
455  {
456    dbprint(printlevel-voice+3,"// ** no parameters, ring was not changed");
457    for( ii = 1; ii <= s; ii++)
458    {
459      def Id(ii) = #[ii];
460      export (Id(ii));
461    }
462    return(list(P));
463  }
464
465  list rlist = ringlist(P);
466  list parlist = rlist[1];
467  rlist[1] = parlist[1];
468  poly Minpoly = minpoly;     //check for minpoly:
469  int sm = size(Minpoly);
470
471  //now create new ring
472  for( ii = 1; ii <= s; ii++)
473  {
474    def Id(ii) = #[ii];
475  }
476  int nvar = size(rlist[2]);
477  int nblock = size(rlist[3]);
478  int k;
479  for (k=1; k<=npar; k++)
480  {
481    rlist[2][nvar+k] = parlist[2][k];   //change variable list
482  }
483
484  //converted parameters get one block dp. If module ordering was in front
485  //it stays in front, otherwise it will be moved to the end
486  intvec OW = 1:npar;
487  if( rlist[3][nblock][1] =="c" || rlist[3][nblock][1] =="C" )
488  {
489    rlist[3][nblock+1] = rlist[3][nblock];
490    rlist[3][nblock] = list("dp",OW);
491  }
492  else
493  {
494    rlist[3][nblock+1] = list("dp",OW);
495  }
496
497  def Ppar2var = ring(quotientList(rlist));
498  setring Ppar2var;
499  if ( sm == 0 )
500  {
501    for( ii = 1; ii <= s; ii++)
502    {
503      def Id(ii) = imap(P,Id(ii));
504      export (Id(ii));
505    }
506  }
507  else
508  {
509    if( find(option(),"prot") ){"//add minpoly to input";}
510    poly Minpoly = imap(P,Minpoly);
511    for( ii = 1; ii <= s; ii++)
512    {
513      def Id(ii) = imap(P,Id(ii));
514      Id(ii) = Id(ii),Minpoly*freemodule(nrows(Id(ii)));
515      export (Id(ii));
516    }
517  }
518  list Lpar2var = Ppar2var;
519  return(Lpar2var);
520}
521example
522{ "EXAMPLE:"; echo = 2;
523   ring R = (0,x),(y,z,u,v),lp;
524   minpoly = x2+1;
525   ideal i = x3,x2+y+z+u+v,xyzuv-1; i;
526   def P = par2varRing(i)[1]; P;
527   setring(P);
528   Id(1);
529
530   setring R;
531   module m = x3*[1,1,1], (xyzuv-1)*[1,0,1];
532   def Q = par2varRing(m)[1]; Q;
533   setring(Q);
534   print(Id(1));
535}
536
537//////////////////////////////////////////////////////////////////////////////
538proc hilbRing ( list # )
539"USAGE:   hilbRing([l]); l list of ideals/modules [default:l=empty list]
540RETURN:  list, say L: L[1] is a ring and L[2] an intvec
541         L[1] is a ring whith an extra homogenizing variable with name @,
542         resp. @(i) if @ and @(1), ..., @(i-1) are defined.
543         The monomial ordering of L[1] is 1 block dp if the
544         weights of the variables of the basering, say R, are all 1, resp.
545         wp(w,1) wehre w is the intvec of weights of the variables of R.
546         If R is a quotient ring P/Q, then L[1] is not a quotient ring but
547         contains the ideal @Qidealhilb@, the homogenized ideal Q of P.
548         (Parameters of R are not touched).
549         If a list l is given with l[i] an ideal, then l[i] is
550         mapped to the homogenized ideal Id(i) in L[1].
551         L[2] is the intvec (w,1)
552PURPOSE: Prepare a ring for computing the (weighted) hilbert series of
553         an ideal with an easy monomial ordering.
554EXAMPLE: example hilbRing; shows an example
555"
556{
557  def P = basering;
558  ideal Qideal = ideal(P);    //defining the quotient ideal if P is a qring
559  if( size(Qideal) != 0 )
560  {
561    int is_qring =1;
562  }
563  list BRlist = ringlist(P);
564  BRlist[4] = ideal(0);
565
566  int nvarP = nvars(P);
567  int s = size(#);
568  intvec w;                   //for ringweights of basering P
569  int k;
570  for(k=1;  k<=nvarP; k++)
571  {
572    w[k]=deg(var(k));
573  }
574
575  for(k = 1; k <= s; k++)
576  {
577    def Id(k) = #[k];
578    int nr(k) = nrows(Id(k));
579  }
580
581  // a homogenizing variable is added:
582  // call it @, resp. @(k) if @(1),...,@(k-1) are defined
583  string homvar;
584  if ( defined(@)==0 )
585  {
586    homvar = "@";
587  }
588  else
589  {
590    k=1;
591    while( defined(@(k)) != 0 )
592    {
593      k++;
594    }
595    homvar = "@("+string(k)+")";
596  }
597  BRlist[2][nvarP+1] = homvar;
598  w[nvarP +1]=1;
599
600  //ordering is set to (dp,C) if weights of all variables are 1
601  //resp. to (wp(w,1),C) where w are the ringweights of basering P
602  //homogenizing var gets weight 1:
603
604  BRlist[3] = list();
605  BRlist[3][2]=list("C",intvec(0));
606  if(w==1)
607  {
608    BRlist[3][1]=list("dp",w);
609  }
610  else
611  {
612    BRlist[3][1]=list("wp",w);
613  }
614
615  //change ring and get ideal from previous ring
616  def Philb = ring(quotientList(BRlist));
617  kill BRlist;
618  setring Philb;
619  if( defined(is_qring) )
620  {
621    ideal @Qidealhilb@ =  homog( imap(P,Qideal), `homvar` );
622    export(@Qidealhilb@);
623
624    if( find(option(),"prot") ){"add quotient ideal to input";}
625    for(k = 1; k <= s; k++)
626    {  //homogenize
627      def Id(k) =  homog( imap(P,Id(k)), `homvar` );
628      Id(k) =  Id(k),@Qidealhilb@*freemodule(nr(k)) ;
629      export(Id(k));
630    }
631  }
632  else
633  {
634    for(k = 1; k <= s; k++)
635    { //homogenize
636      def Id(k) =  homog( imap(P,Id(k)), `homvar` );
637      export(Id(k));
638    }
639  }
640  list Lhilb = Philb,w;
641  return(Lhilb);
642}
643example
644{ "EXAMPLE:"; echo = 2;
645   ring R = 0,(x,y,z,u,v),lp;
646   ideal i = x+y2+z3,xy+xv+yz+zu+uv,xyzuv-1;
647   def P = hilbRing(i)[1];  P;
648   setring P;
649   Id(1);
650   hilb(std(Id(1)),1);
651
652   ring S =  0,(x,y,z,u,v),lp;
653   qring T = std(x+y2+z3);
654   ideal i = xy+xv+yz+zu+uv,xyzuv-v5;
655   module m = i*[0,1,1] + (xyzuv-v5)*[1,1,0];
656   def Q = hilbRing(m)[1];  Q;
657   setring Q;
658   print(Id(1));
659}
660
661//////////////////////////////////////////////////////////////////////////////
662proc qslimgb (i)
663"USAGE:   qslimgb(i); i ideal or module
664RETURN:  same type as input, a standard basis of i computed with slimgb
665NOTE:    Only as long as slimgb does not know qrings qslimgb should be used
666         in case the basering is (possibly) a quotient ring.
667         The quotient ideal is added to the input and slimgb is applied.
668EXAMPLE: example qslimgb; shows an example"
669{
670  def P = basering;
671  ideal Qideal = ideal(P);      //defining the quotient ideal if P is a qring
672  int p_opt;
673  if( find(option(),"prot") )
674  {
675    p_opt=1;
676  }
677  if (size(Qideal) == 0)
678  {
679    if (p_opt) { "slimgb in ring " + string(P); }
680    return(slimgb(i));
681  }
682
683  //case of a qring; since slimgb does not know qrings we
684  //delete the quotient ideal and add it to i
685
686  list BRlist = ringlist(P);
687  BRlist[4] = ideal(0);
688  def Phelp = ring(BRlist);
689  kill BRlist;
690  setring Phelp;
691  // module case:
692  def iq = imap(P,i);
693  iq = iq, imap(P,Qideal)*freemodule(nrows(iq));
694  if (p_opt)
695  {
696    "slimgb in ring " + string(Phelp);
697    "(with quotient ideal added to input)";
698  }
699  iq = slimgb(iq);
700
701  setring P;
702  if (p_opt) { "//imap to original ring"; }
703  i = imap(Phelp,iq);
704  kill Phelp;
705
706  if (find(option(),"redSB") > 0)
707  {
708    if (p_opt) { "//interreduction"; }
709    i=reduce(i,std(0));
710    i=interred(i);
711  }
712  attrib(i, "isSB", 1);
713  return (i);
714}
715example
716{ "EXAMPLE:"; echo = 2;
717   ring R  = (0,v),(x,y,z,u),dp;
718   qring Q = std(x2-y3);
719   ideal i = x+y2,xy+yz+zu+u*v,xyzu*v-1;
720   ideal j = qslimgb(i); j;
721
722   module m = [x+y2,1,0], [1,1,x2+y2+xyz];
723   print(qslimgb(m));
724}
725
726//////////////////////////////////////////////////////////////////////////////
727proc groebner(def i_par, list #)
728"SYNTAX: @code{groebner (} ideal_expression @code{)} @*
729         @code{groebner (} module_expression @code{)} @*
730         @code{groebner (} ideal_expression@code{,} int_expression @code{)} @*
731         @code{groebner (} module_expression@code{,} int_expression @code{)}
732         @code{groebner (} ideal_expression@code{,} list of string_expressions
733               @code{)} @*
734         @code{groebner (} ideal_expression@code{,} list of string_expressions
735               and int_expression @code{)} @*
736         @code{groebner (} ideal_expression@code{,} int_expression @code{)} @*
737TYPE:    type of the first argument
738PURPOSE: computes a standard basis of the first argument @code{I}
739         (ideal or module), by a heuristically chosen method (default)
740         or by a method specified by further arguments of type string.
741         Possible methods are:  @*
742         - the direct methods @code{\"std\"} or @code{\"slimgb\"} without
743           conversion @*
744         - conversion methods @code{\"hilb\"} or @code{\"fglm\"} where
745           a Groebner basis is first computed with an \"easy\" ordering
746           and then converted to the ordering of the basering by the
747           Hilbert driven Groebner basis computation or by linear algebra.
748           The actual computation of the Groebner basis can be
749           specified by @code{\"std\"} or by @code{\"slimgb\"}
750           (not implemented for all orderings) @*
751         A further string @code{\"par2var\"} converts parameters to an extra
752         block of variables before a Groebner basis computation (and
753         afterwards back).
754         @code{option(prot)} tells about the chosen method.
755NOTE:    If a further argument, say @code{wait}, of type int is given,
756         then the computation proceeds at most @code{wait} seconds.
757         That is, if no result could be computed in @code{wait} seconds,
758         then the computation is interrupted, 0 is returned, a warning
759         message is displayed, and the global variable
760         @code{Standard::groebner_error} is defined.
761         This feature uses MP and is hence only available on UNIX platforms.
762HINT:    Since there exists no uniform best method for computing standard
763         bases, and since the difference in performance of a method on
764         different examples can be huge, it is recommended to test, for hard
765         examples, first various methods on a simplified example (e.g. use
766         characteristic 32003 instead of 0 or substitute a subset of
767         parameters/variables by integers, etc.). @*
768SEE ALSO: stdhilb, stdfglm, std, slimgb
769KEYWORDS: time limit on computations; MP, groebner basis computations
770EXAMPLE: example groebner;  shows an example"
771
772{
773//Vorgabe einer Teilmenge aus {hilb,fglm,par2var,std,slimgb}
774//Aktuelle Einstellungen (Jan 2007):
775//---------------------------------
776//0. Immer Aufruf von std unabhaengig von der Vorgabe:
777//   gemischte Ordnungen, extra Gewichtsvektor, Matrix Ordnungen
778
779//1. Keine Vorgabe: es wirkt die aktuelle Heuristk:
780//   - Char p: std
781//   - Char = 0: slimgb (im qring wird Quotientenideal zum Input addiert)
782//   - 1-Block-Ordnungen/non-commutative: direkt Aufruf von std oder slimgb
783//   - Komplizierte Ordnungen (lp oder > 1 Block): hilb
784//   - Parameter werden grundsaetzlich nicht in Variable umgewandelt
785//   ? alternativ: more than 1 parameter will be converted to ring variable ?
786//   - fglm is keine Heuristik, da sonst vorher dim==0 peprueft werden muss
787
788//2. Vorgabe aus {std,slimgb}: es wird wo immer moeglich das angegebene
789//   gewaehlt (da slimgb keine Hilbertfunktion kennt, wird std verwendet).
790//   Bei slimgb im qring, wird das Quotientenideal zum Ideal addiert.
791//   Bei Angabe von std zusammen mit slimgb (aequivalent zur Angabe von
792//   keinem von beidem) wirkt obige Heuristik.
793
794//3. Nichtleere Vorgabe aus {hilb,fglm,std,slimgb}:
795//   es wird nur das angegebene und moegliche sowie das notwendige verwendet
796//   und bei Wahlmoeglickeit je nach Heuristik.
797//   Z.B. Vorgabe von {hilb} ist aequivalent zu {hilb,std,slimgb} und es wird
798//   hilb und nach Heuristik std oder slimgb verwendet, aber nicht par2var;
799//   bei Vorgabe von {hilb,slimgb} wird hilb und wo moeglich slimgb verwendet.
800
801//4. Bei Vorgabe von {par2var} wird par2var immer mit hilb und nach Heuristik
802//   std oder slimgb verwendet. Zu Variablen konvertierte Parameter haben
803//   extra letzten Block und Gewichte 1.
804
805
806  def P=basering;
807  if ((typeof(i_par)=="vector")||(typeof(i_par)=="module")) {module i=i_par;}
808  else {ideal i=i_par; }
809  kill i_par;
810
811//----------------------- save the given method ---------------------------
812  string method;
813  list Method;
814  int k;
815  for (k=1; k<=size(#); k++)
816  {
817     if (typeof(#[k]) == "int")
818     {
819       int wait = #[k];
820     }
821     if (typeof(#[k]) == "string")
822     {
823       method = method + "," + #[k];
824       Method = Method + list(#[k]);
825     }
826  }
827
828 //======= we have an argument of type int -- try to use MPfork links =======
829  if ( defined(wait) == voice )
830  {
831    if ( system("with", "MP") )
832    {
833        int j = 10;
834        string bs = nameof(basering);
835        link l_fork = "MPtcp:fork";
836        open(l_fork);
837        write(l_fork, quote(system("pid")));
838        int pid = read(l_fork);
839//        write(l_fork, quote(groebner(eval(i))));
840        write(l_fork, quote(groebner(eval(i),eval(Method))));
841//###Fehlermeldung:
842// ***dError: undef. ringorder used
843// occured at:
844
845        // sleep in small intervalls for appr. one second
846        if (wait > 0)
847        {
848          while(j < 1000000)
849          {
850            if (status(l_fork, "read", "ready", j)) {break;}
851            j = j + j;
852          }
853        }
854
855        // sleep in intervalls of one second from now on
856        j = 1;
857        while (j < wait)
858        {
859          if (status(l_fork, "read", "ready", 1000000)) {break;}
860          j = j + 1;
861        }
862
863        if (status(l_fork, "read", "ready"))
864        {
865          def result = read(l_fork);
866          if (bs != nameof(basering))
867          {
868            def PP = basering;
869            setring P;
870            def result = imap(PP, result);
871            kill PP;
872          }
873          if (defined(groebner_error))
874          {
875            kill groebner_error;
876          }
877          kill l_fork;
878        }
879        else
880        {
881          ideal result;
882          if (! defined(groebner_error))
883          {
884            int groebner_error = 1;
885            export groebner_error;
886          }
887          "** groebner did not finish";
888          j = system("sh", "kill " + string(pid));
889        }
890        return (result);
891    }
892    else
893    {
894      "** groebner with a time limit on computation is not supported
895          in this configuration";
896    }
897  }
898
899 //=========== we are still here -- do the actual computation =============
900
901//--------------------- save data from basering ---------------------------
902  poly Minpoly = minpoly;      //minimal polynomial
903  int was_minpoly;             //remembers if there was a minpoly in P
904  if (size(Minpoly) > 0)
905  {
906     was_minpoly = 1;
907  }
908
909  ideal Qideal = ideal(P);      //defining the quotient ideal if P is a qring
910  int was_qring;                //remembers if basering was a qring
911  //int is_homog = 1;
912  if (size(Qideal) > 0)
913  {
914     was_qring = 1;
915     //is_homog = homog(Qideal); //remembers if Qideal was homog (homog(0)=1)
916  }
917  list BRlist = ringlist(P);
918
919  // save ordering of basering P for later use
920  list ord_P = BRlist[3];       //should be available in all rings
921  string ordstr_P = ordstr(P);
922  int nvars_P = nvars(P);
923  int npars_P = npars(P);
924  intvec w;                     //for ringweights of basering P
925  for(k=1;  k<=nvars_P; k++)
926  {
927     w[k]=deg(var(k));
928  }
929  int neg=1-attrib (P,"global");
930
931  //save options:
932  intvec opt=option(get);
933  string s_opt = option();
934  int p_opt;
935  if (find(s_opt, "prot"))  { p_opt = 1; }
936
937//------------------ cases where std is always used ------------------------
938//If other methods are not implemented or do not make sense, i.e. for
939//local or mixed orderings, matrix orderings, extra weight vector and modules
940
941  if(  //( find(ordstr_P,"s") > 0 ) || // covered by neg
942       ( find(ordstr_P,"M") > 0 )
943    || ( find(ordstr_P,"a") > 0 )
944    || ( neg>0 ) )
945  {
946    if (p_opt) { "std in basering"; }
947    return(std(i));
948  }
949
950//now we have:
951//ideal or module, global ordering, no matrix ordering, no extra weight vector
952//The interesting cases start now.
953
954 //------------------ classify the possible settings ---------------------
955  string algorithm;       //possibilities: std, slimgb, stdorslimgb
956  string conversion;      //possibilities: hilb, fglm, hilborfglm, no
957  string partovar;        //possibilities: yes, no
958  string order;           //possibilities: simple, !simple
959  string direct;          //possibilities: yes, no
960
961  //define algorithm:
962  if( find(method,"std") && !find(method,"slimgb") )
963  {
964    algorithm = "std";
965  }
966  if( find(method,"slimgb") && !find(method,"std") )
967  {
968    algorithm = "slimgb";
969  }
970  if( find(method,"std") && find(method,"slimgb") ||
971      (!find(method,"std") && !find(method,"slimgb")) )
972  {
973    algorithm = "stdorslimgb";
974  }
975
976  //define conversion:
977  if( find(method,"hilb") && !find(method,"fglm") )
978  {
979     conversion = "hilb";
980  }
981  if( find(method,"fglm") && !find(method,"hilb") )
982  {
983    conversion = "fglm";
984  }
985  if( find(method,"fglm") && find(method,"hilb") )
986  {
987    conversion = "hilborfglm";
988  }
989  if( !find(method,"fglm") && !find(method,"hilb") )
990  {
991    conversion = "no";
992  }
993
994  //define partovar:
995  if( find(method,"par2var") && npars_P > 0 )
996  {
997     partovar = "yes";
998  }
999  else
1000  {
1001     partovar = "no";
1002  }
1003
1004  //define order:
1005  if (system("nblocks") <= 2)
1006  {
1007    if ( find(ordstr_P,"M")+find(ordstr_P,"lp")+find(ordstr_P,"rp") <= 0 )
1008    {
1009      order = "simple";
1010    }
1011  }
1012
1013  //define direct:
1014  if ( (order=="simple" && (size(method)==0)) ||
1015       (size(BRlist)>4) ||
1016        (order=="simple" && (method==",par2var" && npars_P==0 )) ||
1017         (conversion=="no" && partovar=="no" &&
1018           (algorithm=="std" || algorithm=="slimgb" ||
1019            (find(method,"std") && find(method,"slimgb")) ) ) )
1020  {
1021    direct = "yes";
1022  }
1023  else
1024  {
1025    direct = "no";
1026  }
1027
1028  //order=="simple" means that the ordering of the variables consists of one
1029  //block which is not a matrix ordering and not a lexicographical ordering.
1030  //(Note:Singular counts always least 2 blocks, one is for module component):
1031  //Call a method "direct" if conversion=="no" && partovar="no" which means
1032  //that we apply std or slimgb dircet in the basering (exception
1033  //as long as slimgb does not know qrings: in a qring of a ring P
1034  //the ideal Qideal is added to the ideal and slimgb is applied in P).
1035  //We apply a direct method if we have a simple monomial ordering, if no
1036  //conversion (fglm or hilb) is specified and if the parameters shall
1037  //not be made to variables
1038
1039//---------------------------- direct methods -----------------------------
1040  if ( direct == "yes" )
1041  {
1042    if ( algorithm=="std" || (algorithm=="stdorslimgb" && char(P)>0) )
1043    {
1044      if (p_opt) { "std in " + string(P); }
1045      return(std(i));
1046    }
1047    if ( algorithm=="slimgb" || (algorithm=="stdorslimgb" && char(P)==0) )
1048    {
1049      return(qslimgb(i));
1050    }
1051  }
1052
1053//--------------------------- indirect methods -----------------------------
1054//indirect methods are methods where a conversion is used with a ring change
1055//We are in the following situation:
1056//direct=="no" (i.e. "hilb" or "fglm" or "par2var" is given)
1057//or no method is given and we have a complicated monomial ordering
1058//Note thar "par2var" is not a default strategy, it must be explicitely
1059//given in order to be performed.
1060
1061//------------ case where no parameters are made to variables  -------------
1062  if (  partovar == "no" && conversion == "hilb"
1063    || (partovar == "no" && conversion == "fglm" )
1064    || (partovar == "no" && conversion == "hilborfglm" )
1065    || (partovar == "no" && conversion == "no" && direct == "no") )
1066  //last case: heuristic
1067  {
1068    if ( conversion=="fglm" )
1069    {
1070      if ( algorithm=="std" || (algorithm=="stdorslimgb" && char(P)>0) )
1071      {
1072        return (stdfglm(i,"std"));
1073      }
1074      if ( algorithm=="slimgb" || (algorithm=="stdorslimgb" && char(P)==0) )
1075      {
1076        return (stdfglm(i,"slimgb"));
1077      }
1078    }
1079    else
1080    {
1081      if ( algorithm=="std" || (algorithm=="stdorslimgb" && char(P)>0) )
1082      {
1083        return (stdhilb(i,"std"));
1084      }
1085      if ( algorithm=="slimgb" || (algorithm=="stdorslimgb" && char(P)==0) )
1086      {
1087        return (stdhilb(i,"slimgb"));
1088      }
1089    }
1090  }
1091
1092//------------ case where parameters are made to variables  ----------------
1093//define a ring Phelp via par2varRing in which the parameters are variables
1094
1095  else
1096  {
1097    // reset options
1098    option(none);
1099    // turn on options prot, mem, redSB, intStrategy if previously set
1100    if ( find(s_opt, "prot") )
1101      { option(prot); }
1102    if ( find(s_opt, "mem") )
1103      { option(mem); }
1104    if ( find(s_opt, "redSB") )
1105      { option(redSB); }
1106    if ( find(s_opt, "intStrategy") )
1107      { option(intStrategy); }
1108
1109    //first clear denominators of parameters
1110    if (npars_P > 0)
1111    {
1112      for( k=ncols(i); k>0; k-- )
1113      { i[k]=cleardenom(i[k]); }
1114    }
1115
1116    def Phelp = par2varRing(i)[1];   //minpoly is mapped with i
1117    setring Phelp;
1118    def i = Id(1);
1119    //is_homog = homog(i);
1120
1121    //If parameters are converted to ring variables, they appear in an extra
1122    //block. Therefore we use always hilb for this block ordering:
1123    if ( conversion=="fglm" )
1124    {
1125      i = (stdfglm(i));       //only uesful for 1 parameter with minpoly
1126    }
1127    else
1128    {
1129      if ( algorithm=="std" || (algorithm=="stdorslimgb" && char(P)>0) )
1130      {
1131        i = stdhilb(i,"std");
1132      }
1133      if ( algorithm=="slimgb" || (algorithm=="stdorslimgb" && char(P)==0) )
1134      {
1135        i = stdhilb(i,"slimgb");
1136      }
1137    }
1138  }
1139
1140//-------------------- go back to original ring ---------------------------
1141//The main computation is done. However, the SB coming from a ring with
1142//extra variables is in general too big. We simplify it befor mapping it
1143//to the basering.
1144
1145  if (p_opt) { "//simplification"; }
1146
1147  if (was_minpoly)
1148  {
1149    ideal Minpoly = imap(P,Minpoly);
1150    attrib(Minpoly,"isSB",1);
1151    i = simplify(NF(i,Minpoly),2);
1152  }
1153
1154  def Li = lead(i);
1155  setring P;
1156  def Li = imap(Phelp,Li);
1157  Li = simplify(Li,32);
1158  intvec vi;
1159  for (k=1; k<=ncols(Li); k++)
1160  {
1161    vi[k] = Li[k]==0;
1162  }
1163
1164  setring Phelp;
1165  for (k=1;  k<=size(i) ;k++)
1166  {
1167    if(vi[k]==1)
1168    {
1169      i[k]=0;
1170    }
1171  }
1172  i = simplify(i,2);
1173
1174  setring P;
1175  if (p_opt) { "//imap to original ring"; }
1176  i = imap(Phelp,i);
1177  kill Phelp;
1178  i = simplify(i,34);
1179
1180  // clean-up time
1181  option(set, opt);
1182  if (find(s_opt, "redSB") > 0)
1183  {
1184    if (p_opt) { "//interreduction"; }
1185    i=interred(i);
1186  }
1187  attrib(i, "isSB", 1);
1188  return (i);
1189}
1190example
1191{ "EXAMPLE: "; echo=2;
1192  intvec opt = option(get);
1193  option(prot);
1194  ring r  = 0,(a,b,c,d),dp;
1195  ideal i = a+b+c+d,ab+ad+bc+cd,abc+abd+acd+bcd,abcd-1;
1196  groebner(i);
1197
1198  ring s  = 0,(a,b,c,d),lp;
1199  ideal i = imap(r,i);
1200  groebner(i,"hilb");
1201
1202  ring R  = (0,a),(b,c,d),lp;
1203  minpoly = a2+1;
1204  ideal i = a+b+c+d,ab+ad+bc+cd,abc+abd+acd+bcd,d2-c2b2;
1205  groebner(i,"par2var","slimgb");
1206
1207  groebner(i,"fglm");          //computes a reduced standard basis
1208
1209  if (system("with","MP")) {groebner(i,10,"std");}
1210  defined(Standard::groebner_error);
1211  option(set,opt);
1212}
1213
1214//////////////////////////////////////////////////////////////////////////
1215
1216proc res(list #)
1217"@c we do texinfo here:
1218@cindex resolution, computation of
1219@table @code
1220@item @strong{Syntax:}
1221@code{res (} ideal_expression@code{,} int_expression @code{[,} any_expression @code{])}
1222@*@code{res (} module_expression@code{,} int_expression @code{[,} any_expression @code{])}
1223@item @strong{Type:}
1224resolution
1225@item @strong{Purpose:}
1226computes a (possibly minimal) free resolution of an ideal or module using
1227a heuristically chosen method.
1228@* The second (int) argument (say, @code{k}) specifies the length of
1229the resolution. If it is not positive then @code{k} is assumed to be the
1230number of variables of the basering.
1231@* If a third argument is given, the returned resolution is minimized.
1232
1233Depending on the input, the returned resolution is computed using the
1234following methods:
1235@table @asis
1236@item @strong{quotient rings:}
1237@code{nres} (classical method using syzygies) , see @ref{nres}.
1238
1239@item @strong{homogeneous ideals and k=0:}
1240@code{lres} (La'Scala's method), see @ref{lres}.
1241
1242@item @strong{not minimized resolution and (homogeneous input with k not 0, or local rings):}
1243@code{sres} (Schreyer's method), see @ref{sres}.
1244
1245@item @strong{all other inputs:}
1246@code{mres} (classical method), see @ref{mres}.
1247@end table
1248@item @strong{Note:}
1249Accessing single elements of a resolution may require that some partial
1250computations have to be finished and may therefore take some time.
1251@end table
1252@c ref
1253See also
1254@ref{betti};
1255@ref{ideal};
1256@ref{minres};
1257@ref{module};
1258@ref{mres};
1259@ref{nres};
1260@ref{lres};
1261@ref{hres};
1262@ref{sres}.
1263@ref{resolution}
1264@c ref
1265"
1266{
1267   def P=basering;
1268   if (size(#) < 2)
1269   {
1270     ERROR("res: need at least two arguments: ideal/module, int");
1271   }
1272
1273   def m=#[1]; //the ideal or module
1274   int i=#[2]; //the length of the resolution
1275   if (i< 0) { i=0;}
1276
1277   string varstr_P = varstr(P);
1278
1279   int p_opt;
1280   string s_opt = option();
1281   // set p_opt, if option(prot) is set
1282   if (find(s_opt, "prot"))
1283   {
1284     p_opt = 1;
1285   }
1286
1287   if(size(ideal(basering)) > 0)
1288   {
1289     // the quick hack for qrings - seems to fit most needs
1290     // (lres is not implemented for qrings, sres is not so efficient)
1291     if (p_opt) { "using nres";}
1292     return(nres(m,i));
1293   }
1294
1295   if(homog(m)==1)
1296   {
1297      resolution re;
1298      if (((i==0) or (i>=nvars(basering))) && typeof(m) != "module")
1299      {
1300        //LaScala for the homogeneous case and i == 0
1301        if (p_opt) { "using lres";}
1302        re=lres(m,i);
1303        if(size(#)>2)
1304        {
1305           re=minres(re);
1306        }
1307      }
1308      else
1309      {
1310        if(size(#)>2)
1311        {
1312          if (p_opt) { "using mres";}
1313          re=mres(m,i);
1314        }
1315        else
1316        {
1317          if (p_opt) { "using sres";}
1318          re=sres(std(m),i);
1319        }
1320      }
1321      return(re);
1322   }
1323
1324   //mres for the global non homogeneous case
1325   if(find(ordstr(P),"s")==0)
1326   {
1327      string ri= "ring Phelp ="
1328                  +string(char(P))+",("+varstr_P+"),(dp,C);";
1329      execute(ri);
1330      def m=imap(P,m);
1331      if (p_opt) { "using mres in another ring";}
1332      list re=mres(m,i);
1333      setring P;
1334      resolution result=imap(Phelp,re);
1335      if (size(#) > 2) {result = minres(result);}
1336      return(result);
1337   }
1338
1339   //sres for the local case and not minimal resolution
1340   if(size(#)<=2)
1341   {
1342      string ri= "ring Phelp ="
1343                  +string(char(P))+",("+varstr_P+"),(ls,c);";
1344      execute(ri);
1345      def m=imap(P,m);
1346      m=std(m);
1347      if (p_opt) { "using sres in another ring";}
1348      list re=sres(m,i);
1349      setring P;
1350      resolution result=imap(Phelp,re);
1351      return(result);
1352   }
1353
1354   //mres for the local case and minimal resolution
1355   string ri= "ring Phelp ="
1356                  +string(char(P))+",("+varstr_P+"),(ls,C);";
1357   execute(ri);
1358   def m=imap(P,m);
1359    if (p_opt) { "using mres in another ring";}
1360   list re=mres(m,i);
1361   setring P;
1362   resolution result=imap(Phelp,re);
1363   result = minres(result);
1364   return(result);
1365}
1366example
1367{"EXAMPLE:"; echo = 2;
1368  ring r=0,(x,y,z),dp;
1369  ideal i=xz,yz,x3-y3;
1370  def l=res(i,0); // homogeneous ideal: uses lres
1371  l;
1372  print(betti(l), "betti"); // input to betti may be of type resolution
1373  l[2];         // element access may take some time
1374  i=i,x+1;
1375  l=res(i,0);   // inhomogeneous ideal: uses mres
1376  l;
1377  ring rs=0,(x,y,z),ds;
1378  ideal i=imap(r,i);
1379  def l=res(i,0); // local ring not minimized: uses sres
1380  l;
1381  res(i,0,0);     // local ring and minimized: uses mres
1382}
1383/////////////////////////////////////////////////////////////////////////
1384
1385proc quot (m1,m2,list #)
1386"SYNTAX: @code{quot (} module_expression@code{,} module_expression @code{)}
1387         @*@code{quot (} module_expression@code{,} module_expression@code{,}
1388            int_expression @code{)}
1389         @*@code{quot (} ideal_expression@code{,} ideal_expression @code{)}
1390         @*@code{quot (} ideal_expression@code{,} ideal_expression@code{,}
1391            int_expression @code{)}
1392TYPE:    ideal
1393SYNTAX:  @code{quot (} module_expression@code{,} ideal_expression @code{)}
1394TYPE:    module
1395PURPOSE: computes the quotient of the 1st and the 2nd argument.
1396         If a 3rd argument @code{n} is given the @code{n}-th method is used
1397         (@code{n}=1...5).
1398SEE ALSO: quotient
1399EXAMPLE: example quot; shows an example"
1400{
1401  if (((typeof(m1)!="ideal") and (typeof(m1)!="module"))
1402     or ((typeof(m2)!="ideal") and (typeof(m2)!="module")))
1403  {
1404    "USAGE:   quot(m1, m2[, n]); m1, m2 two submodules of k^s,";
1405    "         n (optional) integer (1<= n <=5)";
1406    "RETURN:  the quotient of m1 and m2";
1407    "EXAMPLE: example quot; shows an example";
1408    return();
1409  }
1410  if (typeof(m1)!=typeof(m2))
1411  {
1412    return(quotient(m1,m2));
1413  }
1414  if (size(#)>0)
1415  {
1416    if (typeof(#[1])=="int" )
1417    {
1418      return(quot1(m1,m2,#[1]));
1419    }
1420  }
1421  else
1422  {
1423    return(quot1(m1,m2,2));
1424  }
1425}
1426example
1427{ "EXAMPLE:"; echo = 2;
1428  ring r=181,(x,y,z),(c,ls);
1429  ideal id1=maxideal(4);
1430  ideal id2=x2+xyz,y2-z3y,z3+y5xz;
1431  option(prot);
1432  ideal id3=quotient(id1,id2);
1433  id3;
1434  ideal id4=quot(id1,id2,1);
1435  id4;
1436  ideal id5=quot(id1,id2,2);
1437  id5;
1438}
1439
1440static proc quot1 (module m1, module m2,int n)
1441"USAGE:   quot1(m1, m2, n); m1, m2 two submodules of k^s,
1442         n integer (1<= n <=5)
1443RETURN:  the quotient of m1 and m2
1444EXAMPLE: example quot1; shows an example"
1445{
1446  if (n==1)
1447  {
1448    return(quotient1(m1,m2));
1449  }
1450  else
1451  {
1452    if (n==2)
1453    {
1454      return(quotient2(m1,m2));
1455    }
1456    else
1457    {
1458      if (n==3)
1459      {
1460        return(quotient3(m1,m2));
1461      }
1462      else
1463      {
1464        if (n==4)
1465        {
1466          return(quotient4(m1,m2));
1467        }
1468        else
1469        {
1470          if (n==5)
1471          {
1472            return(quotient5(m1,m2));
1473          }
1474          else
1475          {
1476            return(quotient(m1,m2));
1477          }
1478        }
1479      }
1480    }
1481  }
1482}
1483example
1484{ "EXAMPLE:"; echo = 2;
1485  ring r=181,(x,y,z),(c,ls);
1486  ideal id1=maxideal(4);
1487  ideal id2=x2+xyz,y2-z3y,z3+y5xz;
1488  option(prot);
1489  ideal id6=quotient(id1,id2);
1490  id6;
1491  ideal id7=quot1(id1,id2,1);
1492  id7;
1493  ideal id8=quot1(id1,id2,2);
1494  id8;
1495}
1496
1497static proc quotient0(module a,module b)
1498{
1499  module mm=b+a;
1500  resolution rs=lres(mm,0);
1501  list I=list(rs);
1502  matrix M=I[2];
1503  matrix A[1][nrows(M)]=M[1..nrows(M),1];
1504  ideal i=A;
1505  return (i);
1506}
1507proc quotient1(module a,module b)  //17sec
1508"USAGE:   quotient1(m1, m2); m1, m2 two submodules of k^s,
1509RETURN:  the quotient of m1 and m2"
1510{
1511  int i;
1512  a=std(a);
1513  module dummy;
1514  module B=NF(b,a)+dummy;
1515  ideal re=quotient(a,module(B[1]));
1516  for(i=2;i<=ncols(B);i++)
1517  {
1518     re=intersect1(re,quotient(a,module(B[i])));
1519  }
1520  return(re);
1521}
1522proc quotient2(module a,module b)    //13sec
1523"USAGE:   quotient2(m1, m2); m1, m2 two submodules of k^s,
1524RETURN:  the quotient of m1 and m2"
1525{
1526  a=std(a);
1527  module dummy;
1528  module bb=NF(b,a)+dummy;
1529  int i=ncols(bb);
1530  ideal re=quotient(a,module(bb[i]));
1531  bb[i]=0;
1532  module temp;
1533  module temp1;
1534  module bbb;
1535  int mx;
1536  i=i-1;
1537  while (1)
1538  {
1539    if (i==0) break;
1540    temp = a+bb*re;
1541    temp1 = lead(interred(temp));
1542    mx=ncols(a);
1543    if (ncols(temp1)>ncols(a))
1544    {
1545      mx=ncols(temp1);
1546    }
1547    temp1 = matrix(temp1,1,mx)-matrix(lead(a),1,mx);
1548    temp1 = dummy+temp1;
1549    if (deg(temp1[1])<0) break;
1550    re=intersect1(re,quotient(a,module(bb[i])));
1551    bb[i]=0;
1552    i = i-1;
1553  }
1554  return(re);
1555}
1556proc quotient3(module a,module b)   //89sec
1557"USAGE:   quotient3(m1, m2); m1, m2 two submodules of k^s,
1558         only for global rings
1559RETURN:  the quotient of m1 and m2"
1560{
1561  string s="ring @newr=("+charstr(basering)+
1562           "),("+varstr(basering)+",@t,@w),dp;";
1563  def @newP=basering;
1564  execute(s);
1565  module b=imap(@newP,b);
1566  module a=imap(@newP,a);
1567  int i;
1568  int j=ncols(b);
1569  vector @b;
1570  for(i=1;i<=j;i++)
1571  {
1572     @b=@b+@t^(i-1)*@w^(j-i+1)*b[i];
1573  }
1574  ideal re=quotient(a,module(@b));
1575  setring @newP;
1576  ideal re=imap(@newr,re);
1577  return(re);
1578}
1579proc quotient5(module a,module b)   //89sec
1580"USAGE:   quotient5(m1, m2); m1, m2 two submodules of k^s,
1581         only for global rings
1582RETURN:  the quotient of m1 and m2"
1583{
1584  string s="ring @newr=("+charstr(basering)+
1585           "),("+varstr(basering)+",@t),dp;";
1586  def @newP=basering;
1587  execute(s);
1588  module b=imap(@newP,b);
1589  module a=imap(@newP,a);
1590  int i;
1591  int j=ncols(b);
1592  vector @b;
1593  for(i=1;i<=j;i++)
1594  {
1595     @b=@b+@t^(i-1)*b[i];
1596  }
1597  @b=homog(@b,@w);
1598  ideal re=quotient(a,module(@b));
1599  setring @newP;
1600  ideal re=imap(@newr,re);
1601  return(re);
1602}
1603proc quotient4(module a,module b)   //95sec
1604"USAGE:   quotient4(m1, m2); m1, m2 two submodules of k^s,
1605         only for global rings
1606RETURN:  the quotient of m1 and m2"
1607{
1608  string s="ring @newr=("+charstr(basering)+
1609           "),("+varstr(basering)+",@t),dp;";
1610  def @newP=basering;
1611  execute(s);
1612  module b=imap(@newP,b);
1613  module a=imap(@newP,a);
1614  int i;
1615  vector @b=b[1];
1616  for(i=2;i<=ncols(b);i++)
1617  {
1618     @b=@b+@t^(i-1)*b[i];
1619  }
1620  matrix sy=modulo(@b,a);
1621  ideal re=sy;
1622  setring @newP;
1623  ideal re=imap(@newr,re);
1624  return(re);
1625}
1626static proc intersect1(ideal i,ideal j)
1627{
1628  def R=basering;
1629  execute("ring gnir = ("+charstr(basering)+"),
1630                       ("+varstr(basering)+",@t),(C,dp);");
1631  ideal i=var(nvars(basering))*imap(R,i)+(var(nvars(basering))-1)*imap(R,j);
1632  ideal j=eliminate(i,var(nvars(basering)));
1633  setring R;
1634  map phi=gnir,maxideal(1);
1635  return(phi(j));
1636}
1637
1638//////////////////////////////////////////////////////////////////
1639///
1640/// sprintf, fprintf printf
1641///
1642proc sprintf(string fmt, list #)
1643"SYNTAX:  @code{sprintf (} string_expression @code{[,} any_expressions
1644               @code{] )}
1645RETURN:   string
1646PURPOSE:  @code{sprintf(fmt,...);} performs output formatting. The first
1647          argument is a format control string. Additional arguments may be
1648          required, depending on the content of the control string. A series
1649          of output characters is generated as directed by the control string;
1650          these characters are returned as a string. @*
1651          The control string @code{fmt} is simply text to be copied,
1652          except that the string may contain conversion specifications.@*
1653          Do @code{help print;} for a listing of valid conversion
1654          specifications. As an addition to the conversions of @code{print},
1655          the @code{%n} and @code{%2} conversion specification does not
1656          consume an additional argument, but simply generates a newline
1657          character.
1658NOTE:     If one of the additional arguments is a list, then it should be
1659          enclosed once more into a @code{list()} command, since passing a list
1660          as an argument flattens the list by one level.
1661SEE ALSO: fprintf, printf, print, string
1662EXAMPLE : example sprintf; shows an example
1663"
1664{
1665  int sfmt = size(fmt);
1666  if (sfmt  <= 1)
1667  {
1668    return (fmt);
1669  }
1670  int next, l, nnext;
1671  string ret;
1672  list formats = "%l", "%s", "%2l", "%2s", "%t", "%;", "%p", "%b", "%n", "%2";
1673  while (1)
1674  {
1675    if (size(#) <= 0)
1676    {
1677      return (ret + fmt);
1678    }
1679    nnext = 0;
1680    while (nnext < sfmt)
1681    {
1682      nnext = find(fmt, "%", nnext + 1);
1683      if (nnext == 0)
1684      {
1685        next = 0;
1686        break;
1687      }
1688      l = 1;
1689      while (l <= size(formats))
1690      {
1691        next = find(fmt, formats[l], nnext);
1692        if (next == nnext) break;
1693        l++;
1694      }
1695      if (next == nnext) break;
1696    }
1697    if (next == 0)
1698    {
1699      return (ret + fmt);
1700    }
1701    if (formats[l] != "%2" && formats[l] != "%n")
1702    {
1703      ret = ret + fmt[1, next - 1] + print(#[1], formats[l]);
1704      # = delete(#, 1);
1705    }
1706    else
1707    {
1708      ret = ret + fmt[1, next - 1] + print("", "%2s");
1709    }
1710    if (size(fmt) <= (next + size(formats[l]) - 1))
1711    {
1712      return (ret);
1713    }
1714    fmt = fmt[next + size(formats[l]), size(fmt)-next-size(formats[l]) + 1];
1715  }
1716}
1717example
1718{ "EXAMPLE:"; echo=2;
1719  ring r=0,(x,y,z),dp;
1720  module m=[1,y],[0,x+z];
1721  intmat M=betti(mres(m,0));
1722  list l = r, m, M;
1723  string s = sprintf("s:%s,%n l:%l", 1, 2); s;
1724  s = sprintf("s:%n%s", l); s;
1725  s = sprintf("s:%2%s", list(l)); s;
1726  s = sprintf("2l:%n%2l", list(l)); s;
1727  s = sprintf("%p", list(l)); s;
1728  s = sprintf("%;", list(l)); s;
1729  s = sprintf("%b", M); s;
1730}
1731
1732proc printf(string fmt, list #)
1733"SYNTAX:  @code{printf (} string_expression @code{[,} any_expressions@code{] )}
1734RETURN:   none
1735PURPOSE:  @code{printf(fmt,...);} performs output formatting. The first
1736          argument is a format control string. Additional arguments may be
1737          required, depending on the content of the control string. A series
1738          of output characters is generated as directed by the control string;
1739          these characters are displayed (i.e., printed to standard out). @*
1740          The control string @code{fmt} is simply text to be copied, except
1741          that the string may contain conversion specifications. @*
1742          Do @code{help print;} for a listing of valid conversion
1743          specifications. As an addition to the conversions of @code{print},
1744          the @code{%n} and @code{%2} conversion specification does not
1745          consume an additional argument, but simply generates a newline
1746          character.
1747NOTE:     If one of the additional arguments is a list, then it should be
1748          enclosed once more into a @code{list()} command, since passing a
1749          list as an argument flattens the list by one level.
1750SEE ALSO: sprintf, fprintf, print, string
1751EXAMPLE : example printf; shows an example
1752"
1753{
1754  write("", sprintf(fmt, #));
1755}
1756example
1757{ "EXAMPLE:"; echo=2;
1758  ring r=0,(x,y,z),dp;
1759  module m=[1,y],[0,x+z];
1760  intmat M=betti(mres(m,0));
1761  list l=r,m,matrix(M);
1762  printf("s:%s,l:%l",1,2);
1763  printf("s:%s",l);
1764  printf("s:%s",list(l));
1765  printf("2l:%2l",list(l));
1766  printf("%p",matrix(M));
1767  printf("%;",matrix(M));
1768  printf("%b",M);
1769}
1770
1771
1772proc fprintf(link l, string fmt, list #)
1773"SYNTAX:  @code{fprintf (} link_expression@code{,} string_expression @code{[,}
1774                any_expressions@code{] )}
1775RETURN:   none
1776PURPOSE:  @code{fprintf(l,fmt,...);} performs output formatting.
1777          The second argument is a format control string. Additional
1778          arguments may be required, depending on the content of the
1779          control string. A series of output characters is generated as
1780          directed by the control string; these characters are
1781          written to the link l.
1782          The control string @code{fmt} is simply text to be copied, except
1783          that the string may contain conversion specifications.@*
1784          Do @code{help print;} for a listing of valid conversion
1785          specifications. As an addition to the conversions of @code{print},
1786          the @code{%n} and @code{%2} conversion specification does not
1787          consume an additional argument, but simply generates a newline
1788          character.
1789NOTE:     If one of the additional arguments is a list, then it should be
1790          enclosed once more into a @code{list()} command, since passing
1791          a list as an argument flattens the list by one level.
1792SEE ALSO: sprintf, printf, print, string
1793EXAMPLE : example fprintf; shows an example
1794"
1795{
1796  write(l, sprintf(fmt, #));
1797}
1798example
1799{ "EXAMPLE:"; echo=2;
1800  ring r=0,(x,y,z),dp;
1801  module m=[1,y],[0,x+z];
1802  intmat M=betti(mres(m,0));
1803  list l=r,m,M;
1804  link li="";   // link to stdout
1805  fprintf(li,"s:%s,l:%l",1,2);
1806  fprintf(li,"s:%s",l);
1807  fprintf(li,"s:%s",list(l));
1808  fprintf(li,"2l:%2l",list(l));
1809  fprintf(li,"%p",list(l));
1810  fprintf(li,"%;",list(l));
1811  fprintf(li,"%b",M);
1812}
1813
1814//////////////////////////////////////////////////////////////////////////
1815
1816/*
1817proc minres(list #)
1818{
1819  if (size(#) == 2)
1820  {
1821    if (typeof(#[1]) == "ideal" || typeof(#[1]) == "module")
1822    {
1823      if (typeof(#[2] == "int"))
1824      {
1825        return (res(#[1],#[2],1));
1826      }
1827    }
1828  }
1829
1830  if (typeof(#[1]) == "resolution")
1831  {
1832    return minimizeres(#[1]);
1833  }
1834  else
1835  {
1836    return minimizeres(#);
1837  }
1838
1839}
1840*/
1841///////////////////////////////////////////////////////////////////////////////
1842
1843proc weightKB(def stc, int dd, list wim)
1844"SYNTAX: @code{weightKB (} module_expression@code{,} int_expression @code{,}
1845            list_expression @code{)}@*
1846         @code{weightKB (} ideal_expression@code{,} int_expression@code{,}
1847            list_expression @code{)}
1848RETURN:  the same as the input type of the first argument
1849PURPOSE: If @code{I,d,wim} denotes the three arguments then weightKB
1850         computes the weighted degree- @code{d} part of a vector space basis
1851         (consisting of monomials) of the quotient ring, resp. of the
1852         quotient module, modulo @code{I} w.r.t. weights given by @code{wim}
1853         The information about the weights is given as a list of two intvec:
1854            @code{wim[1]} weights for all variables (positive),
1855            @code{wim[2]} weights for the module generators.
1856NOTE:    This is a generalisation for the command @code{kbase} with the same
1857         first two arguments.
1858SEE ALSO: kbase
1859EXAMPLE: example weightKB; shows an example
1860"
1861{
1862  if(checkww(wim)){ERROR("wrong weights";);}
1863  kbclass();
1864  wwtop=wim[1];
1865  stc=interred(lead(stc));
1866  if(typeof(stc)=="ideal")
1867  {
1868    stdtop=stc;
1869    ideal out=widkbase(dd);
1870    delkbclass();
1871    out=simplify(out,2); // delete 0
1872    return(out);
1873  }
1874  list mbase=kbprepare(stc);
1875  module mout;
1876  int im,ii;
1877  if(size(wim)>1){mmtop=wim[2];}
1878  else{mmtop=0;}
1879  for(im=size(mbase);im>0;im--)
1880  {
1881    stdtop=mbase[im];
1882    if(im>size(mmtop)){ii=dd;}
1883    else{ii=dd-mmtop[im];}
1884    mout=mout+widkbase(ii)*gen(im);
1885  }
1886  delkbclass();
1887  mout=simplify(mout,2); // delete 0
1888  return(mout);
1889}
1890example
1891{ "EXAMPLE:"; echo=2;
1892  ring R=0, (x,y), wp(1,2);
1893  weightKB(ideal(0),3,intvec(1,2));
1894}
1895
1896///////////////////////////////////////////////////////////////////////////////
1897// construct global values
1898static proc kbclass()
1899{
1900  intvec wwtop,mmtop;
1901  export (wwtop,mmtop);
1902  ideal stdtop,kbtop;
1903  export (stdtop,kbtop);
1904}
1905// delete global values
1906static proc delkbclass()
1907{
1908  kill wwtop,mmtop;
1909  kill stdtop,kbtop;
1910}
1911//  select parts of the modul
1912static proc kbprepare(module mstc)
1913{
1914  list rr;
1915  ideal kk;
1916  int i1,i2;
1917  mstc=transpose(mstc);
1918  for(i1=ncols(mstc);i1>0;i1--)
1919  {
1920    kk=0;
1921    for(i2=nrows(mstc[i1]);i2>0;i2--)
1922    {
1923      kk=kk+mstc[i1][i2];
1924    }
1925    rr[i1]=kk;
1926  }
1927  return(rr);
1928}
1929//  check for weights
1930static proc checkww(list vv)
1931{
1932  if(typeof(vv[1])!="intvec"){return(1);}
1933  intvec ww=vv[1];
1934  int mv=nvars(basering);
1935  if(size(ww)<mv){return(1);}
1936  while(mv>0)
1937  {
1938    if(ww[mv]<=0){return(1);}
1939    mv--;
1940  }
1941  if(size(vv)>1)
1942  {
1943    if(typeof(vv[2])!="intvec"){return(1);}
1944  }
1945  return(0);
1946}
1947///////////////////////////////////////////////////////
1948// The "Caller" for ideals
1949//    dd   - the degree of the result
1950static proc widkbase(int dd)
1951{
1952  if((size(stdtop)==1)&&(deg(stdtop[1])==0)){return(0);}
1953  if(dd<=0)
1954  {
1955    if(dd<0){return(0);}
1956    else{return(1);}
1957  }
1958  int m1,m2;
1959  m1=nvars(basering);
1960  while(wwtop[m1]>dd)
1961  {
1962    m1--;
1963    if(m1==0){return(0);}
1964  }
1965  attrib(stdtop,"isSB",1);
1966  poly mo=1;
1967  if(m1==1)
1968  {
1969    m2=dd/wwtop[1];
1970    if((m2*wwtop[1])==dd)
1971    {
1972      mo=var(1)^m2;
1973      if(reduce(mo,stdtop)==mo){return(mo);}
1974      else{return(0);}
1975    }
1976  }
1977  kbtop=0;
1978  m2=dd;
1979  weightmon(m1-1,m2,mo);
1980  while(m2>=wwtop[m1])
1981  {
1982    m2=m2-wwtop[m1];
1983    mo=var(m1)*mo;
1984    if(m2==0)
1985    {
1986      if((mo!=0) and (reduce(mo,stdtop)==mo))
1987      {
1988        kbtop[ncols(kbtop)+1]=mo;
1989        return(kbtop);
1990      }
1991    }
1992    weightmon(m1-1,m2,mo);
1993  }
1994  return(kbtop);
1995}
1996/////////////////////////////////////////////////////////
1997// the recursive procedure
1998//    va     - number of the variable
1999//    drest  - rest of the degree
2000//    mm     - the candidate
2001static proc weightmon(int va, int drest, poly mm)
2002{
2003  while(wwtop[va]>drest)
2004  {
2005    va--;
2006    if(va==0){return();}
2007  }
2008  int m2;
2009  if(va==1)
2010  {
2011    m2=drest/wwtop[1];
2012    if((m2*wwtop[1])==drest)
2013    {
2014      mm=var(1)^m2*mm;
2015      if ((mm!=0) and (reduce(mm,stdtop)==mm))
2016      {
2017        kbtop[ncols(kbtop)+1]=mm;
2018      }
2019    }
2020    return();
2021  }
2022  m2=drest;
2023  if ((mm!=0) and (reduce(mm,stdtop)==mm))
2024  {
2025    weightmon(va-1,m2,mm);
2026  }
2027  while(m2>=wwtop[va])
2028  {
2029    m2=m2-wwtop[va];
2030    mm=var(va)*mm;
2031    if(m2==0)
2032    {
2033      if ((mm!=0) and (reduce(mm,stdtop)==mm))
2034      {
2035        kbtop[ncols(kbtop)+1]=mm;
2036        return();
2037      }
2038    }
2039     if ((mm!=0) and (reduce(mm,stdtop)==mm))
2040     {
2041       weightmon(va-1,m2,mm);
2042     }
2043  }
2044  return();
2045}
2046example
2047{ "EXAMPLE:"; echo=2;
2048  ring r=0,(x,y,z),dp;
2049  ideal i = x6,y4,xyz;
2050  intvec w = 2,3,6;
2051  weightKB(i, 12, list(w));
2052}
2053//////////////////////////////////////////////////////////////////////////////
2054
2055/*
2056Versuche:
2057///////////////////////////////////////////////////////////////////////////////
2058proc downsizeSB (I, list #)
2059"USAGE:   downsizeSB(I [,l]); I ideal, l list of integers [default: l=0]
2060RETURN:  intvec, say v, with v[j] either 1 or 0. We have v[j]=1 if
2061         leadmonom(I[j]) is divisible by some leadmonom(I[k]) or if
2062         leadmonom(i[j]) == leadmonom(i[k]) and l[j] >= l[k], with k!=j.
2063PURPOSE: The procedure is applied in a situation where the standard basis
2064         computation in the basering R is done via a conversion through an
2065         overring Phelp with additional variables and where a direct
2066         imap from Phelp to R is too expensive.
2067         Assume Phelp is created by the procedure @code{par2varRing} or
2068         @code{hilbRing} and IPhelp is a SB in Phelp [ with l[j]=
2069         length(IPhelp(j)) or any other integer reflecting the complexity
2070         of a IPhelp[j] ]. Let I = lead(IPhelp) mapped to R and compute
2071         v = downsizeSB(imap(Phelp,I),l) in R. Then, if Ihelp[j] is deleted
2072         for all j with v[j]=1, we can apply imap to the remaining generators
2073         of Ihelp and still get SB in R  (in general not minimal).
2074EXAMPLE: example downsizeSB; shows an example"
2075{
2076   int k,j;
2077   intvec v,l;
2078   poly M,N,W;
2079   int c=size(I);
2080   if( size(#) != 0 )
2081   {
2082     if ( typeof(#[1]) == "intvec" )
2083     {
2084       l = #[1];
2085     }
2086     else
2087     {
2088        ERROR("// 2nd argument must be an intvec");
2089     }
2090   }
2091
2092   l[c+1]=0;
2093   v[c]=0;
2094
2095   j=0;
2096   while(j<c-1)
2097   {
2098     j++;
2099     M = leadmonom(I[j]);
2100     if( M != 0 )
2101     {
2102        for( k=j+1; k<=c; k++ )
2103        {
2104          N = leadmonom(I[k]);
2105          if( N != 0 )
2106          {
2107             if( (M==N) && (l[j]>l[k]) )
2108             {
2109               I[j]=0;
2110               v[j]=1;
2111               break;
2112             }
2113             if( (M==N) && (l[j]<=l[k]) || N/M != 0 )
2114             {
2115               I[k]=0;
2116               v[k]=1;
2117             }
2118          }
2119        }
2120      }
2121   }
2122   return(v);
2123}
2124example
2125{ "EXAMPLE:"; echo = 2;
2126   ring  r = 0,(x,y,z,t),(dp(3),dp);
2127   ideal i = x+y+z+t,xy+yz+xt+zt,xyz+xyt+xzt+yzt,xyzt-t4;
2128   ideal Id = std(i);
2129   ideal I = lead(Id);  I;
2130   ring S = (0,t),(x,y,z),dp;
2131   downsizeSB(imap(r,I));
2132   //Id[5] can be deleted, we still have a SB of i in the ring S
2133
2134   ring R = (0,x),(y,z,u),lp;
2135   ideal i = x+y+z+u,xy+xu+yz+zu,xyz+xyu+xzu+yzu,xyzu-1;
2136   def Phelp = par2varRing()[1];
2137   setring Phelp;
2138   ideal IPhelp = std(imap(R,i));
2139   ideal I = lead(IPhelp);
2140   setring R;
2141   ideal I = imap(Phelp,I); I;
2142   intvec v = downsizeSB(I); v;
2143}
2144///////////////////////////////////////////////////////////////////////////
2145// PROBLEM: Die Prozedur funktioniert nur fuer Ringe die global bekannt
2146//          sind, also interaktiv, aber nicht aus einer Prozedur.
2147//          Z.B. funktioniert example imapDownsize; nicht
2148
2149proc imapDownsize (string R, string I)
2150"SYNTAX: @code{imapDownsize (} string @code{,} string @code{)} *@
2151         First string must be the string of the name of a ring, second
2152         string must be the string of the name of an object in the ring.
2153TYPE:    same type as the object with name the second string
2154PURPOSE: maps the object given by the second string to the basering.
2155         If R resp. I are the first resp. second string, then
2156         imapDownsize(R,I) is equivalent to simplify(imap(`R`,`I`),34).
2157NOTE:    imapDownsize is usually faster than imap if `I` is large and if
2158         simplify has a great effect, since the procedure maps only those
2159         generators from `I` which are not killed by simplify( - ,34).
2160         This is useful if `I` is a standard bases for a block ordering of
2161         `R` and if some variables from the last block in `R` are mapped
2162         to parameters. Then the returned result is a standard basis in
2163         the basering.
2164SEE ALSO: imap, fetch, map
2165EXAMPLE: example imapDownsize; shows an example"
2166{
2167       def BR = basering;
2168       int k;
2169
2170       setring `R`;
2171       def @leadI@ = lead(`I`);
2172       int s = ncols(@leadI@);
2173       setring BR;
2174       ideal @leadI@ = simplify(imap(`R`,@leadI@),32);
2175       intvec vi;
2176       for (k=1; k<=s; k++)
2177       {
2178         vi[k] = @leadI@[k]==0;
2179       }
2180       kill @leadI@;
2181
2182       setring `R`;
2183       kill @leadI@;
2184       for (k=1;  k<=s; k++)
2185       {
2186           if( vi[k]==1 )
2187           {
2188              `I`[k]=0;
2189           }
2190       }
2191       `I` = simplify(`I`,2);
2192
2193       setring BR;
2194       return(imap(`R`,`I`));
2195}
2196example
2197{ "EXAMPLE:"; echo = 2;
2198   ring  r = 0,(x,y,z,t),(dp(3),dp);
2199   ideal i = x+y+z+t,xy+yz+xt+zt,xyz+xyt+xzt+yzt,xyzt-1;
2200   i = std(i); i;
2201
2202   ring s = (0,t),(x,y,z),dp;
2203   imapDownsize("r","i");     //i[5] is omitted since lead(i[2]) | lead(i[5])
2204}
2205///////////////////////////////////////////////////////////////////////////////
2206//die folgende proc war fuer groebner mit fglm vorgesehen
2207//um die projektive Dimension korrekt zu berechnen, muss man aber
2208//voerher ein SB bzgl. einer Gradordnung berechnen und dann homogenisieren.
2209//Sonst koennen hoeherdimensionale Komponenten in Unendlich entstehen
2210
2211proc projInvariants(ideal i,list #)
2212"SYNTAX: @code{projInvariants (} ideal_expression @code{)} @*
2213         @code{projInvariants (} ideal_expression@code{,} list of string_expres          sions@code{)}
2214TYPE:    list, say L, with L[1] and L[2] of type int and L[3] of type intvec
2215PURPOSE: Computes the (projective) dimension (L[1]), degree (L[2]) and the
2216         first Hilbert series (L[3], as intvec) of the homogenized ideal
2217         in the ring given by the procedure @code{hilbRing} with global
2218         ordering dp (resp. wp if the variables have weights >1)
2219         If an argument of type string @code{\"std\"} resp. @code{\"slimgb\"}
2220         is given, the standard basis computatuion uses @code{std} or
2221         @code{slimgb}, otherwise a heuristically chosen method (default)
2222NOTE:    Homogenized means weighted homogenized with respect to the weights
2223         w[i] of the variables var(i) of the basering. The returned dimension,
2224         degree and Hilbertseries are the respective invariants of the
2225         projective variety defined by the homogenized ideal. The dimension
2226         is equal to the (affine) dimension of the ideal in the basering
2227         (degree and Hilbert series make only sense for homogeneous ideals).
2228SEE ALSO: dim, dmult, hilb
2229KEYWORDS: dimension, degree, Hilbert function
2230EXAMPLE: example projInvariants;  shows an example"
2231{
2232  def P = basering;
2233  int p_opt;
2234  string s_opt = option();
2235  if (find(option(), "prot"))  { p_opt = 1; }
2236
2237//---------------- check method and clear denomintors --------------------
2238  int k;
2239  string method;
2240  for (k=1; k<=size(#); k++)
2241  {
2242     if (typeof(#[k]) == "string")
2243     {
2244       method = method + "," + #[k];
2245     }
2246  }
2247
2248  if (npars(P) > 0)             //clear denominators of parameters
2249  {
2250    for( k=ncols(i); k>0; k-- )
2251    {
2252       i[k]=cleardenom(i[k]);
2253    }
2254  }
2255
2256//------------------------ change to hilbRing ----------------------------
2257     list hiRi = hilbRing(i);
2258     intvec W = hiRi[2];
2259     def Philb = hiRi[1];      //note: Philb is no qring and the predefined
2260     setring Philb;            //ideal Id(1) in Philb is homogeneous
2261     int di, de;               //for dimension, degree
2262     intvec hi;                //for hilbert series
2263
2264//-------- compute Hilbert function of homogenized ideal in Philb ---------
2265//Philb has only 1 block. There are three cases
2266
2267     string algorithm;       //possibilities: std, slimgb, stdorslimgb
2268     //define algorithm:
2269     if( find(method,"std") && !find(method,"slimgb") )
2270     {
2271        algorithm = "std";
2272     }
2273     if( find(method,"slimgb") && !find(method,"std") )
2274     {
2275         algorithm = "slimgb";
2276     }
2277     if( find(method,"std") && find(method,"slimgb") ||
2278         (!find(method,"std") && !find(method,"slimgb")) )
2279     {
2280         algorithm = "stdorslimgb";
2281     }
2282
2283     if ( algorithm=="std" || ( algorithm=="stdorslimgb" && char(P)>0 ) )
2284     {
2285        if (p_opt) {"std in ring " + string(Philb);}
2286        Id(1) = std(Id(1));
2287        di = dim(Id(1))-1;
2288        de = mult(Id(1));
2289        hi = hilb( Id(1),1,W );
2290     }
2291     if ( algorithm=="slimgb" || ( algorithm=="stdorslimgb" && char(P)==0 ) )
2292     {
2293        if (p_opt) {"slimgb in ring " + string(Philb);}
2294        Id(1) = slimgb(Id(1));
2295        di = dim( Id(1) );
2296        if (di > -1)
2297        {
2298           di = di-1;
2299        }
2300        de = mult( Id(1) );
2301        hi = hilb( Id(1),1,W );
2302     }
2303     kill Philb;
2304     list L = di,de,hi;
2305     return(L);
2306}
2307example
2308{ "EXAMPLE:"; echo = 2;
2309   ring r = 32003,(x,y,z),lp;
2310   ideal i = y2-xz,x2-z;
2311   projInvariants(i);
2312
2313   ring R = (0),(x,y,z,u,v),lp;
2314   //minpoly = x2+1;
2315   ideal i = x2+1,x2+y+z+u+v,xyzuv-1;
2316   projInvariants(i);
2317   qring S =std(x2+1);
2318   ideal i = imap(R,i);
2319   projInvariants(i);
2320}
2321
2322*/
2323
Note: See TracBrowser for help on using the repository browser.