source: git/Singular/LIB/freegb.lib @ 238c959

spielwiese
Last change on this file since 238c959 was dabe365, checked in by Viktor Levandovskyy <levandov@…>, 16 years ago
*levandov: shiftbba prepared for release git-svn-id: file:///usr/local/Singular/svn/trunk@10968 2c84dea3-7e68-4137-9b89-c4e89433aadc
  • Property mode set to 100644
File size: 45.9 KB
Line 
1//////////////////////////////////////////////////////////////////////////////
2version="$Id: freegb.lib,v 1.10 2008-08-07 18:08:37 levandov Exp $";
3category="Noncommutative";
4info="
5LIBRARY: freegb.lib   Twosided Noncommutative Groebner bases in Free Algebras
6AUTHOR: Viktor Levandovskyy,     levandov@math.rwth-aachen.de
7
8PROCEDURES:
9freegbRing(int d);    creates a ring with d blocks of shifted original variables
10freegbasis(list L, int n);   compute two-sided Groebner basis of ideal, encoded via L, up to degree n
11
12CONVERSION ROUTINES:
13
14lp2lstr(ideal K, def save): converts letter-place ideal to a list of modules
15lst2str(list L[,int n]);            convert a list (of modules) into polynomials in free algebra
16mod2str(module M[,int n]);  convert a module into a polynomial in free algebra
17vct2str(module M[,int n]);  convert a vector into a word in free algebra
18"
19
20// this library computes two-sided GB of an ideal
21// in a free associative algebra
22
23// a monomial is encoded via a vector V
24// where V[1] = coefficient
25// V[1+i] = the corresponding symbol
26
27LIB "discretize.lib"; // for replace
28LIB "qhmoduli.lib"; // for Max
29
30
31// obsolete?
32
33proc lshift(module M, int s, string varing, def lpring)
34{
35  // FINALLY IMPLEMENTED AS A PART OT THE CODE
36  // shifts a poly from the ring @R to s positions
37  // M lives in varing, the result in lpring
38  // to be run from varing
39  int i, j, k, sm, sv;
40  vector v;
41  //  execute("setring "+lpring);
42  setring lpring;
43  poly @@p;
44  ideal I;
45  execute("setring "+varing);
46  sm = ncols(M);
47  for (i=1; i<=s; i++)
48  {
49    // modules, e.g. free polynomials
50    for (j=1; j<=sm; j++)
51    {
52      //vectors, e.g. free monomials
53      v  = M[j];
54      sv = size(v);
55      sp = "@@p = @@p + ";
56      for (k=2; k<=sv; k++)
57      {
58        sp = sp + string(v[k])+"("+string(k-1+s)+")*";
59      }
60      sp = sp + string(v[1])+";"; // coef;
61      setring lpring;
62      //      execute("setring "+lpring);
63      execute(sp);
64      execute("setring "+varing);
65    }
66    setring lpring;
67    //    execute("setring "+lpring);
68    I = I,@@p;
69    @@p = 0;
70  }
71  setring lpring;
72  //execute("setring "+lpring);
73  export(I);
74  //  setring varing;
75  execute("setring "+varing);
76}
77
78proc skip0(vector v)
79{
80  // skips zeros in a vector, producing another vector
81  int sv = nrows(v);
82  int sw = size(v);
83  if (sv == sw)
84  {
85    return(v);
86  }
87  int i;
88  int j=1;
89  vector w;
90  for (i=1; i<=sv; i++)
91  {
92    if (v[i] != 0)
93    {
94      w = w + v[i]*gen(j);
95      j++;
96    }
97  }
98  return(w);
99}
100
101proc lst2str(list L, list #)
102"USAGE:  lst2str(L[,n]);  L a list of modules, n an optional integer
103RETURN:  list (of strings)
104PURPOSE: convert a list (of modules) into polynomials in free algebra
105EXAMPLE: example lst2str; shows examples
106NOTE: if an optional integer is not 0, stars signs are used in multiplication
107"
108{
109  // returns a list of strings
110  // being sentences in words built from L
111  // if #[1] = 1, use * between generators
112  int useStar = 0;
113  if ( size(#)>0 )
114  {
115    if (#[1])
116    {
117      useStar = 1;
118    }
119  }
120  int i;
121  int s    = size(L);
122  list N;
123  for(i=1; i<=s; i++)
124  {
125    if ((typeof(L[i]) == "module") || (typeof(L[i]) == "matrix") )
126    {
127      N[i] = mod2str(L[i],useStar);
128    }
129    else
130    {
131      "module or matrix expected in the list";
132      return(N);
133    }
134  }
135  return(N);
136}
137example
138{
139  "EXAMPLE:"; echo = 2;
140  ring r = 0,(x,y,z),(dp(1),dp(2));
141  module M = [-1,x,y],[-7,y,y],[3,x,x];
142  module N = [1,x,y,x,y],[-2,y,x,y,x],[6,x,y,y,x,y];
143  list L; L[1] = M; L[2] = N;
144  lst2str(L);
145  lst2str(L[1],1);
146}
147
148
149proc mod2str(module M, list #)
150"USAGE:  mod2str(M[,n]);  M a module, n an optional integer
151RETURN:  string
152PURPOSE: convert a module into a polynomial in free algebra
153EXAMPLE: example mod2str; shows examples
154NOTE: if an optional integer is not 0, stars signs are used in multiplication
155"
156{
157  // returns a string
158  // a sentence in words built from M
159  // if #[1] = 1, use * between generators
160  int useStar = 0;
161  if ( size(#)>0 )
162  {
163    if (#[1])
164    {
165      useStar = 1;
166    }
167  }
168  int i;
169  int s    = ncols(M);
170  string t;
171  string mp;
172  for(i=1; i<=s; i++)
173  {
174    mp = vct2str(M[i],useStar);
175    if (mp[1] == "-")
176    {
177      t = t + mp;
178    }
179    else
180    {
181      t = t + "+" + mp;
182    }
183  }
184  if (t[1]=="+")
185  {
186    t = t[2..size(t)]; // remove first "+"
187  }
188  return(t);
189}
190example
191{
192  "EXAMPLE:"; echo = 2;
193  ring r = 0,(x,y,z),(dp);
194  module M = [1,x,y,x,y],[-2,y,x,y,x],[6,x,y,y,x,y];
195  mod2str(M);
196  mod2str(M,1);
197}
198
199proc vct2str(vector v, list #)
200"USAGE:  vct2str(v[,n]);  v a vector, n an optional integer
201RETURN:  string
202PURPOSE: convert a vector into a word in free algebra
203EXAMPLE: example vct2str; shows examples
204NOTE: if an optional integer is not 0, stars signs are used in multiplication
205"
206{
207  // if #[1] = 1, use * between generators
208  int useStar = 0;
209  if ( size(#)>0 )
210  {
211    if (#[1])
212    {
213      useStar = 1;
214    }
215  }
216  int ppl = printlevel-voice+2;
217  // for a word, encoded by v
218  // produces a string for it
219  v = skip0(v);
220  number cf = leadcoef(v[1]);
221  int s = size(v);
222  string vs,vv,vp,err;
223  int i,j,p,q;
224  for (i=1; i<=s-1; i++)
225  {
226    p     = IsVar(v[i+1]);
227    if (p==0)
228    {
229      err = "Error: monomial expected at" + string(i+1);
230      dbprint(ppl,err);
231      return("_");
232    }
233    if (p==1)
234    {
235      if (useStar && (size(vs) >0))       {   vs = vs + "*"; }
236        vs = vs + string(v[i+1]);
237    }
238    else //power
239    {
240      vv = string(v[i+1]);
241      q = find(vv,"^");
242      if (q==0)
243      {
244        q = find(vv,string(p));
245        if (q==0)
246        {
247          err = "error in find for string "+vv;
248          dbprint(ppl,err);
249          return("_");
250        }
251      }
252      // q>0
253      vp = vv[1..q-1];
254      for(j=1;j<=p;j++)
255      {
256         if (useStar && (size(vs) >0))       {   vs = vs + "*"; }
257         vs = vs + vp;
258      }
259    }
260  }
261  string scf;
262  if (cf == -1)
263  {
264    scf = "-";
265  }
266  else
267  {
268    scf = string(cf);
269    if (cf == 1)
270    {
271      scf = "";
272    }
273  }
274  if (useStar && (size(scf) >0) && (scf!="-") )       {   scf = scf + "*"; }
275  vs = scf + vs;
276  return(vs);
277}
278example
279{
280  "EXAMPLE:"; echo = 2;
281  ring r = (0,a),(x,y3,z(1)),dp;
282  vector v = [-7,x,y3^4,x2,z(1)^3];
283  vct2str(v);
284  vct2str(v,1);
285  vector w = [-7a^5+6a,x,y3,y3,x,z(1),z(1)];
286  vct2str(w);
287  vct2str(w,1);
288}
289
290proc IsVar(poly p)
291{
292  // checks whether p is a variable indeed
293  // if it's a power of a variable, returns the power
294  if (p==0) {  return(0); } //"p=0";
295  poly q   = leadmonom(p);
296  if ( (p-lead(p)) !=0 ) { return(0); } // "p-lm(p)>0";
297  intvec v = leadexp(p);
298  int s = size(v);
299  int i=1;
300  int cnt = 0;
301  int pwr = 0;
302  for (i=1; i<=s; i++)
303  {
304    if (v[i] != 0)
305    {
306      cnt++;
307      pwr = v[i];
308    }
309  }
310  //  "cnt:";  cnt;
311  if (cnt==1) { return(pwr); }
312  else { return(0); }
313}
314example
315{
316  "EXAMPLE:"; echo = 2;
317  ring r = 0,(x,y),dp;
318  poly f = xy+1;
319  IsVar(f);
320  poly g = xy;
321  IsVar(g);
322  poly h = y^3;
323  IsVar(h);
324  poly i = 1;
325  IsVar(i);
326}
327
328// new conversion routines
329
330proc id2words(ideal I, int d)
331{
332  // NOT FINISHED
333  // input: ideal I of polys in letter-place notation
334  // in the ring with d real vars
335  // output: the list of strings: associative words
336  // extract names of vars
337  int i,m,n; string s; string place = "(1)";
338  list lv;
339  for(i=1; i<=d; i++)
340  {
341    s = string(var(i));
342    // get rid of place
343    n = find(s, place);
344    if (n>0)
345    {
346      s = s[1..n-1];
347    }
348    lv[i] = s;
349  }
350  poly p,q;
351  for (i=1; i<=ncols(I); i++)
352  {
353    if (I[i] != 0)
354    {
355      p = I[i];
356      while (p!=0)
357      {
358         q = leadmonom(p);
359         
360      }
361    }
362  }
363
364  return(lv);
365}
366example
367{
368  "EXAMPLE:"; echo = 2;
369  ring r = 0,(x(1),y(1),z(1),x(2),y(2),z(2)),dp;
370  ideal I = x(1)*y(2) -z(1)*x(2);
371  id2words(I,3);
372}
373
374proc mono2word(poly p, int d)
375{
376}
377
378// given the element -7xy^2x, it is represented as [-7,x,y^2,x] or as [-7,x,y,y,x]
379// use the orig ord on (x,y,z) and expand it blockwise to (x(i),y(i),z(i))
380
381// the correspondences:
382// monomial in K<x,y,z>    <<--->> vector in R
383// polynomial in K<x,y,z>  <<--->> list of vectors (matrix/module) in R
384// ideal in K<x,y,z>       <<--->> list of matrices/modules in R
385
386
387// 1. form a new ring
388// 2. NOP
389// 3. compute GB -> with the kernel stuff
390// 4. skip shifted elts (check that no such exist?)
391// 5. go back to orig vars, produce strings/modules
392// 6. return the result
393
394proc freegbasis(list LM, int d)
395"USAGE:  freegbasis(L, d);  L a list of modules, d an integer
396RETURN:  ring
397PURPOSE: compute the two-sided Groebner basis of an ideal, encoded by L in
398the free associative algebra, up to degree d
399EXAMPLE: example freegbasis; shows examples
400"
401{
402  // d = up to degree, will be shifted to d+1
403  if (d<1) {"bad d"; return(0);}
404
405  int ppl = printlevel-voice+2;
406  string err = "";
407
408  int i,j,s;
409  def save = basering;
410  // determine max no of places in the input
411  int slm = size(LM); // numbers of polys in the ideal
412  int sm;
413  intvec iv;
414  module M;
415  for (i=1; i<=slm; i++)
416  {
417    // modules, e.g. free polynomials
418    M  = LM[i];
419    sm = ncols(M);
420    for (j=1; j<=sm; j++)
421    {
422      //vectors, e.g. free monomials
423      iv = iv, size(M[j])-1; // 1 place is reserved by the coeff
424    }
425  }
426  int D = Max(iv); // max size of input words
427  if (d<D) {"bad d"; return(LM);}
428  D = D + d-1;
429  //  D = d;
430  list LR  = ringlist(save);
431  list L, tmp;
432  L[1] = LR[1]; // ground field
433  L[4] = LR[4]; // quotient ideal
434  tmp  = LR[2]; // varnames
435  s = size(LR[2]);
436  for (i=1; i<=D; i++)
437  {
438    for (j=1; j<=s; j++)
439    {
440      tmp[i*s+j] = string(tmp[j])+"("+string(i+1)+")";
441    }
442  }
443  for (i=1; i<=s; i++)
444  {
445    tmp[i] = string(tmp[i])+"("+string(1)+")";
446  }
447  L[2] = tmp;
448  list OrigNames = LR[2];
449  // ordering: d blocks of the ord on r
450  // try to get whether the ord on r is blockord itself
451  s = size(LR[3]);
452  if (s==2)
453  {
454    // not a blockord, 1 block + module ord
455    tmp = LR[3][s]; // module ord
456    for (i=1; i<=D; i++)
457    {
458      LR[3][s-1+i] = LR[3][1];
459    }
460    LR[3][s+D] = tmp;
461  }
462  if (s>2)
463  {
464    // there are s-1 blocks
465    int nb = s-1;
466    tmp = LR[3][s]; // module ord
467    for (i=1; i<=D; i++)
468    {
469      for (j=1; j<=nb; j++)
470      {
471        LR[3][i*nb+j] = LR[3][j];
472      }
473    }
474    //    size(LR[3]);
475    LR[3][nb*(D+1)+1] = tmp;
476  }
477  L[3] = LR[3];
478  def @R = ring(L);
479  setring @R;
480  ideal I;
481  poly @p;
482  s = size(OrigNames);
483  //  "s:";s;
484  // convert LM to canonical vectors (no powers)
485  setring save;
486  kill M; // M was defined earlier
487  module M;
488  slm = size(LM); // numbers of polys in the ideal
489  int sv,k,l;
490  vector v;
491  //  poly p;
492  string sp;
493  setring @R;
494  poly @@p=0;
495  setring save;
496  for (l=1; l<=slm; l++)
497  {
498    // modules, e.g. free polynomials
499    M  = LM[l];
500    sm = ncols(M); // in intvec iv the sizes are stored
501    // modules, e.g. free polynomials
502    for (j=1; j<=sm; j++)
503    {
504      //vectors, e.g. free monomials
505      v  = M[j];
506      sv = size(v);
507      //        "sv:";sv;
508      sp = "@@p = @@p + ";
509      for (k=2; k<=sv; k++)
510      {
511        sp = sp + string(v[k])+"("+string(k-1)+")*";
512      }
513      sp = sp + string(v[1])+";"; // coef;
514      setring @R;
515      execute(sp);
516      setring save;
517    }
518    setring @R;
519    //      "@@p:"; @@p;
520    I = I,@@p;
521    @@p = 0;
522    setring save;
523  }
524  kill sp;
525  // 3. compute GB
526  setring @R;
527  dbprint(ppl,"computing GB");
528  ideal J = system("freegb",I,d,nvars(save));
529  //  ideal J = slimgb(I);
530  dbprint(ppl,J);
531  // 4. skip shifted elts
532  ideal K = select1(J,1,s); // s = size(OrigNames)
533  dbprint(ppl,K);
534  dbprint(ppl, "done with GB");
535  // K contains vars x(1),...z(1) = images of originals
536  // 5. go back to orig vars, produce strings/modules
537  if (K[1] == 0)
538  {
539    "no reasonable output, GB gives 0";
540    return(0);
541  }
542  int sk = size(K);
543  int sp, sx, a, b;
544  intvec x;
545  poly p,q;
546  poly pn;
547  // vars in 'save'
548  setring save;
549  module N;
550  list LN;
551  vector V;
552  poly pn;
553  // test and skip exponents >=2
554  setring @R;
555  for(i=1; i<=sk; i++)
556  {
557    p  = K[i];
558    while (p!=0)
559    {
560      q  = lead(p);
561      //      "processing q:";q;
562      x  = leadexp(q);
563      sx = size(x);
564      for(k=1; k<=sx; k++)
565      {
566        if ( x[k] >= 2 )
567        {
568          err = "skip: the value x[k] is " + string(x[k]);
569          dbprint(ppl,err);
570          //        return(0);
571          K[i] = 0;
572          p    = 0;
573          q    = 0;
574          break;
575        }
576      }
577      p  = p - q;
578    }
579  }
580  K  = simplify(K,2);
581  sk = size(K);
582  for(i=1; i<=sk; i++)
583  {
584    //    setring save;
585    //    V  = 0;
586    setring @R;
587    p  = K[i];
588    while (p!=0)
589    {
590      q  = lead(p);
591      err =  "processing q:" + string(q);
592      dbprint(ppl,err);
593      x  = leadexp(q);
594      sx = size(x);
595      pn = leadcoef(q);
596      setring save;
597      pn = imap(@R,pn);
598      V  = V + leadcoef(pn)*gen(1);
599      for(k=1; k<=sx; k++)
600      {
601        if (x[k] ==1)
602        {
603          a = k / s; // block number=a+1, a!=0
604          b = k % s; // remainder
605          //      printf("a: %s, b: %s",a,b);
606          if (b == 0)
607          {
608            // that is it's the last var in the block
609            b = s;
610            a = a-1;
611          }
612          V = V + var(b)*gen(a+2);
613        }
614//      else
615//      {
616//        printf("error: the value x[k] is %s", x[k]);
617//        return(0);
618//      }
619      }
620      err = "V: " + string(V);
621      dbprint(ppl,err);
622      //      printf("V: %s", string(V));
623      N = N,V;
624      V  = 0;
625      setring @R;
626      p  = p - q;
627      pn = 0;
628    }
629    setring save;
630    LN[i] = simplify(N,2);
631    N     = 0;
632  }
633  setring save;
634  return(LN);
635}
636example
637{
638  "EXAMPLE:"; echo = 2;
639  ring r = 0,(x,y,z),(dp(1),dp(2));
640  module M = [-1,x,y],[-7,y,y],[3,x,x];
641  module N = [1,x,y,x],[-1,y,x,y];
642  list L; L[1] = M; L[2] = N;
643  lst2str(L);
644  def U = freegbasis(L,5);
645  lst2str(U);
646}
647
648proc crs(list LM, int d)
649"USAGE:  crs(L, d);  L a list of modules, d an integer
650RETURN:  ring
651PURPOSE: create a ring and shift the ideal
652EXAMPLE: example crs; shows examples
653"
654{
655  // d = up to degree, will be shifted to d+1
656  if (d<1) {"bad d"; return(0);}
657
658  int ppl = printlevel-voice+2;
659  string err = "";
660
661  int i,j,s;
662  def save = basering;
663  // determine max no of places in the input
664  int slm = size(LM); // numbers of polys in the ideal
665  int sm;
666  intvec iv;
667  module M;
668  for (i=1; i<=slm; i++)
669  {
670    // modules, e.g. free polynomials
671    M  = LM[i];
672    sm = ncols(M);
673    for (j=1; j<=sm; j++)
674    {
675      //vectors, e.g. free monomials
676      iv = iv, size(M[j])-1; // 1 place is reserved by the coeff
677    }
678  }
679  int D = Max(iv); // max size of input words
680  if (d<D) {"bad d"; return(LM);}
681  D = D + d-1;
682  //  D = d;
683  list LR  = ringlist(save);
684  list L, tmp;
685  L[1] = LR[1]; // ground field
686  L[4] = LR[4]; // quotient ideal
687  tmp  = LR[2]; // varnames
688  s = size(LR[2]);
689  for (i=1; i<=D; i++)
690  {
691    for (j=1; j<=s; j++)
692    {
693      tmp[i*s+j] = string(tmp[j])+"("+string(i)+")";
694    }
695  }
696  for (i=1; i<=s; i++)
697  {
698    tmp[i] = string(tmp[i])+"("+string(0)+")";
699  }
700  L[2] = tmp;
701  list OrigNames = LR[2];
702  // ordering: d blocks of the ord on r
703  // try to get whether the ord on r is blockord itself
704  s = size(LR[3]);
705  if (s==2)
706  {
707    // not a blockord, 1 block + module ord
708    tmp = LR[3][s]; // module ord
709    for (i=1; i<=D; i++)
710    {
711      LR[3][s-1+i] = LR[3][1];
712    }
713    LR[3][s+D] = tmp;
714  }
715  if (s>2)
716  {
717    // there are s-1 blocks
718    int nb = s-1;
719    tmp = LR[3][s]; // module ord
720    for (i=1; i<=D; i++)
721    {
722      for (j=1; j<=nb; j++)
723      {
724        LR[3][i*nb+j] = LR[3][j];
725      }
726    }
727    //    size(LR[3]);
728    LR[3][nb*(D+1)+1] = tmp;
729  }
730  L[3] = LR[3];
731  def @R = ring(L);
732  setring @R;
733  ideal I;
734  poly @p;
735  s = size(OrigNames);
736  //  "s:";s;
737  // convert LM to canonical vectors (no powers)
738  setring save;
739  kill M; // M was defined earlier
740  module M;
741  slm = size(LM); // numbers of polys in the ideal
742  int sv,k,l;
743  vector v;
744  //  poly p;
745  string sp;
746  setring @R;
747  poly @@p=0;
748  setring save;
749  for (l=1; l<=slm; l++)
750  {
751    // modules, e.g. free polynomials
752    M  = LM[l];
753    sm = ncols(M); // in intvec iv the sizes are stored
754    for (i=0; i<=d-iv[l]; i++)
755    {
756      // modules, e.g. free polynomials
757      for (j=1; j<=sm; j++)
758      {
759        //vectors, e.g. free monomials
760        v  = M[j];
761        sv = size(v);
762        //      "sv:";sv;
763        sp = "@@p = @@p + ";
764        for (k=2; k<=sv; k++)
765        {
766          sp = sp + string(v[k])+"("+string(k-2+i)+")*";
767        }
768        sp = sp + string(v[1])+";"; // coef;
769        setring @R;
770        execute(sp);
771        setring save;
772      }
773      setring @R;
774      //      "@@p:"; @@p;
775      I = I,@@p;
776      @@p = 0;
777      setring save;
778    }
779  }
780  setring @R;
781  export I;
782  return(@R);
783}
784example
785{
786  "EXAMPLE:"; echo = 2;
787  ring r = 0,(x,y,z),(dp(1),dp(2));
788  module M = [-1,x,y],[-7,y,y],[3,x,x];
789  module N = [1,x,y,x],[-1,y,x,y];
790  list L; L[1] = M; L[2] = N;
791  lst2str(L);
792  def U = crs(L,5);
793  setring U; U;
794  I;
795}
796
797proc polylen(ideal I)
798{
799  // returns the ideal of length of polys
800  int i;
801  intvec J;
802  number s = 0;
803  for(i=1;i<=ncols(I);i++)
804  {
805    J[i] = size(I[i]);
806    s = s + J[i];
807  }
808  printf("the sum of length %s",s);
809  //  print(s);
810  return(J);
811}
812
813proc freegbRing(int d)
814"USAGE:  freegbRing(d); d an integer
815RETURN:  ring
816PURPOSE: creates a ring with d blocks of shifted original variables
817EXAMPLE: example freegbRing; shows examples
818"
819{
820  // d = up to degree, will be shifted to d+1
821  if (d<1) {"bad d"; return(0);}
822
823  int ppl = printlevel-voice+2;
824  string err = "";
825
826  int i,j,s;
827  def save = basering;
828  int D = d-1;
829  list LR  = ringlist(save);
830  list L, tmp;
831  L[1] = LR[1]; // ground field
832  L[4] = LR[4]; // quotient ideal
833  tmp  = LR[2]; // varnames
834  s = size(LR[2]);
835  for (i=1; i<=D; i++)
836  {
837    for (j=1; j<=s; j++)
838    {
839      tmp[i*s+j] = string(tmp[j])+"("+string(i+1)+")";
840    }
841  }
842  for (i=1; i<=s; i++)
843  {
844    tmp[i] = string(tmp[i])+"("+string(1)+")";
845  }
846  L[2] = tmp;
847  list OrigNames = LR[2];
848  // ordering: d blocks of the ord on r
849  // try to get whether the ord on r is blockord itself
850  // TODO: make L(2) ordering! exponent is maximally 2
851  s = size(LR[3]);
852  if (s==2)
853  {
854    // not a blockord, 1 block + module ord
855    tmp = LR[3][s]; // module ord
856    for (i=1; i<=D; i++)
857    {
858      LR[3][s-1+i] = LR[3][1];
859    }
860    LR[3][s+D] = tmp;
861  }
862  if (s>2)
863  {
864    // there are s-1 blocks
865    int nb = s-1;
866    tmp = LR[3][s]; // module ord
867    for (i=1; i<=D; i++)
868    {
869      for (j=1; j<=nb; j++)
870      {
871        LR[3][i*nb+j] = LR[3][j];
872      }
873    }
874    //    size(LR[3]);
875    LR[3][nb*(D+1)+1] = tmp;
876  }
877  L[3] = LR[3];
878  def @R = ring(L);
879  //  setring @R;
880  return (@R);
881}
882example
883{
884  "EXAMPLE:"; echo = 2;
885  ring r = 0,(x,y,z),(dp(1),dp(2));
886  def A = freegbRing(2);
887  setring A;
888  A;
889}
890
891proc ex_shift()
892{
893  LIB "freegb.lib";
894  ring r = 0,(x,y,z),(dp(1),dp(2));
895  module M = [-1,x,y],[-7,y,y],[3,x,x];
896  module N = [1,x,y,x],[-1,y,x,y];
897  list L; L[1] = M; L[2] = N;
898  lst2str(L);
899  def U = crs(L,5);
900  setring U; U;
901  I;
902  poly p = I[2]; // I[8];
903  p;
904  system("stest",p,7,7,3); // error -> the world is ok
905  poly q1 = system("stest",p,1,7,3); //ok
906  poly q6 = system("stest",p,6,7,3); //ok
907  system("btest",p,3); //ok
908  system("btest",q1,3); //ok
909  system("btest",q6,3); //ok
910}
911
912proc test_shrink()
913{
914  LIB "freegb.lib";
915  ring r =0,(x,y,z),dp;
916  int d = 5;
917  def R = freegbRing(d);
918  setring R;
919  poly p1 = x(1)*y(2)*z(3);
920  poly p2 = x(1)*y(4)*z(5);
921  poly p3 = x(1)*y(1)*z(3);
922  poly p4 = x(1)*y(2)*z(2);
923  poly p5 = x(3)*z(5);
924  poly p6 = x(1)*y(1)*x(3)*z(5);
925  poly p7 = x(1)*y(2)*x(3)*y(4)*z(5);
926  poly p8 = p1+p2+p3+p4+p5 + p6 + p7;
927  p1; system("shrinktest",p1,3);
928  p2; system("shrinktest",p2,3);
929  p3; system("shrinktest",p3,3);
930  p4; system("shrinktest",p4,3);
931  p5; system("shrinktest",p5,3);
932  p6; system("shrinktest",p6,3);
933  p7; system("shrinktest",p7,3);
934  p8; system("shrinktest",p8,3);
935  poly p9 = p1 + 2*p2 + 5*p5 + 7*p7;
936  p9; system("shrinktest",p9,3);
937}
938
939proc ex2()
940{
941  option(prot);
942  LIB "freegb.lib";
943  ring r = 0,(x,y),dp;
944  module M = [-1,x,y],[3,x,x]; // 3x^2 - xy
945  def U = freegb(M,7);
946  lst2str(U);
947}
948
949proc ex_nonhomog()
950{
951  option(prot);
952  LIB "freegb.lib";
953  ring r = 0,(x,y,h),dp;
954  list L;
955  module M;
956  M = [-1,y,y],[1,x,x,x];  // x3-y2
957  L[1] = M;
958  M = [1,x,h],[-1,h,x];  // xh-hx
959  L[2] = M;
960  M = [1,y,h],[-1,h,y];  // yh-hy
961  L[3] = M;
962  def U = freegb(L,4);
963  lst2str(U);
964  // strange elements in the basis
965}
966
967proc ex_nonhomog_comm()
968{
969  option(prot);
970  LIB "freegb.lib";
971  ring r = 0,(x,y),dp;
972  module M = [-1,y,y],[1,x,x,x];
973  def U = freegb(M,5);
974  lst2str(U);
975}
976
977proc ex_nonhomog_h()
978{
979  option(prot);
980  LIB "freegb.lib";
981  ring r = 0,(x,y,h),(a(1,1),dp);
982  module M = [-1,y,y,h],[1,x,x,x]; // x3 - y2h
983  def U = freegb(M,6);
984  lst2str(U);
985}
986
987proc ex_nonhomog_h2()
988{
989  option(prot);
990  LIB "freegb.lib";
991  ring r = 0,(x,y,h),(dp);
992  list L;
993  module M;
994  M = [-1,y,y,h],[1,x,x,x]; // x3 - y2h
995  L[1] = M;
996  M = [1,x,h],[-1,h,x]; // xh - hx
997  L[2] = M;
998  M = [1,y,h],[-1,h,y]; // yh - hy
999  L[3] = M;
1000  def U = freegbasis(L,3);
1001  lst2str(U);
1002  // strange answer CHECK
1003}
1004
1005
1006proc ex_nonhomog_3()
1007{
1008  option(prot);
1009  LIB "./freegb.lib";
1010  ring r = 0,(x,y,z),(dp);
1011  list L;
1012  module M;
1013  M = [1,z,y],[-1,x]; // zy - x
1014  L[1] = M;
1015  M = [1,z,x],[-1,y]; // zx - y
1016  L[2] = M;
1017  M = [1,y,x],[-1,z]; // yx - z
1018  L[3] = M;
1019  lst2str(L);
1020  list U = freegb(L,4);
1021  lst2str(U);
1022  // strange answer CHECK
1023}
1024
1025proc ex_densep_2()
1026{
1027  option(prot);
1028  LIB "freegb.lib";
1029  ring r = (0,a,b,c),(x,y),(Dp); // deglex
1030  module M = [1,x,x], [a,x,y], [b,y,x], [c,y,y];
1031  lst2str(M);
1032  list U = freegb(M,5);
1033  lst2str(U);
1034  // a=b is important -> finite basis!!!
1035  module M = [1,x,x], [a,x,y], [a,y,x], [c,y,y];
1036  lst2str(M);
1037  list U = freegb(M,5);
1038  lst2str(U);
1039}
1040
1041
1042// 1. form a new ring
1043// 2. produce shifted generators
1044// 3. compute GB
1045// 4. skip shifted elts
1046// 5. go back to orig vars, produce strings/modules
1047// 6. return the result
1048
1049proc freegbold(list LM, int d)
1050"USAGE:  freegbold(L, d);  L a list of modules, d an integer
1051RETURN:  ring
1052PURPOSE: compute the two-sided Groebner basis of an ideal, encoded by L in
1053the free associative algebra, up to degree d
1054EXAMPLE: example freegbold; shows examples
1055"
1056{
1057  // d = up to degree, will be shifted to d+1
1058  if (d<1) {"bad d"; return(0);}
1059
1060  int ppl = printlevel-voice+2;
1061  string err = "";
1062
1063  int i,j,s;
1064  def save = basering;
1065  // determine max no of places in the input
1066  int slm = size(LM); // numbers of polys in the ideal
1067  int sm;
1068  intvec iv;
1069  module M;
1070  for (i=1; i<=slm; i++)
1071  {
1072    // modules, e.g. free polynomials
1073    M  = LM[i];
1074    sm = ncols(M);
1075    for (j=1; j<=sm; j++)
1076    {
1077      //vectors, e.g. free monomials
1078      iv = iv, size(M[j])-1; // 1 place is reserved by the coeff
1079    }
1080  }
1081  int D = Max(iv); // max size of input words
1082  if (d<D) {"bad d"; return(LM);}
1083  D = D + d-1;
1084  //  D = d;
1085  list LR  = ringlist(save);
1086  list L, tmp;
1087  L[1] = LR[1]; // ground field
1088  L[4] = LR[4]; // quotient ideal
1089  tmp  = LR[2]; // varnames
1090  s = size(LR[2]);
1091  for (i=1; i<=D; i++)
1092  {
1093    for (j=1; j<=s; j++)
1094    {
1095      tmp[i*s+j] = string(tmp[j])+"("+string(i+1)+")";
1096    }
1097  }
1098  for (i=1; i<=s; i++)
1099  {
1100    tmp[i] = string(tmp[i])+"("+string(1)+")";
1101  }
1102  L[2] = tmp;
1103  list OrigNames = LR[2];
1104  // ordering: d blocks of the ord on r
1105  // try to get whether the ord on r is blockord itself
1106  // TODO: make L(2) ordering! exponent is maximally 2
1107  s = size(LR[3]);
1108  if (s==2)
1109  {
1110    // not a blockord, 1 block + module ord
1111    tmp = LR[3][s]; // module ord
1112    for (i=1; i<=D; i++)
1113    {
1114      LR[3][s-1+i] = LR[3][1];
1115    }
1116    LR[3][s+D] = tmp;
1117  }
1118  if (s>2)
1119  {
1120    // there are s-1 blocks
1121    int nb = s-1;
1122    tmp = LR[3][s]; // module ord
1123    for (i=1; i<=D; i++)
1124    {
1125      for (j=1; j<=nb; j++)
1126      {
1127        LR[3][i*nb+j] = LR[3][j];
1128      }
1129    }
1130    //    size(LR[3]);
1131    LR[3][nb*(D+1)+1] = tmp;
1132  }
1133  L[3] = LR[3];
1134  def @R = ring(L);
1135  setring @R;
1136  ideal I;
1137  poly @p;
1138  s = size(OrigNames);
1139  //  "s:";s;
1140  // convert LM to canonical vectors (no powers)
1141  setring save;
1142  kill M; // M was defined earlier
1143  module M;
1144  slm = size(LM); // numbers of polys in the ideal
1145  int sv,k,l;
1146  vector v;
1147  //  poly p;
1148  string sp;
1149  setring @R;
1150  poly @@p=0;
1151  setring save;
1152  for (l=1; l<=slm; l++)
1153  {
1154    // modules, e.g. free polynomials
1155    M  = LM[l];
1156    sm = ncols(M); // in intvec iv the sizes are stored
1157    for (i=0; i<=d-iv[l]; i++)
1158    {
1159      // modules, e.g. free polynomials
1160      for (j=1; j<=sm; j++)
1161      {
1162        //vectors, e.g. free monomials
1163        v  = M[j];
1164        sv = size(v);
1165        //      "sv:";sv;
1166        sp = "@@p = @@p + ";
1167        for (k=2; k<=sv; k++)
1168        {
1169          sp = sp + string(v[k])+"("+string(k-1+i)+")*";
1170        }
1171        sp = sp + string(v[1])+";"; // coef;
1172        setring @R;
1173        execute(sp);
1174        setring save;
1175      }
1176      setring @R;
1177      //      "@@p:"; @@p;
1178      I = I,@@p;
1179      @@p = 0;
1180      setring save;
1181    }
1182  }
1183  kill sp;
1184  // 3. compute GB
1185  setring @R;
1186  dbprint(ppl,"computing GB");
1187  //  ideal J = groebner(I);
1188  ideal J = slimgb(I);
1189  dbprint(ppl,J);
1190  // 4. skip shifted elts
1191  ideal K = select1(J,1,s); // s = size(OrigNames)
1192  dbprint(ppl,K);
1193  dbprint(ppl, "done with GB");
1194  // K contains vars x(1),...z(1) = images of originals
1195  // 5. go back to orig vars, produce strings/modules
1196  if (K[1] == 0)
1197  {
1198    "no reasonable output, GB gives 0";
1199    return(0);
1200  }
1201  int sk = size(K);
1202  int sp, sx, a, b;
1203  intvec x;
1204  poly p,q;
1205  poly pn;
1206  // vars in 'save'
1207  setring save;
1208  module N;
1209  list LN;
1210  vector V;
1211  poly pn;
1212  // test and skip exponents >=2
1213  setring @R;
1214  for(i=1; i<=sk; i++)
1215  {
1216    p  = K[i];
1217    while (p!=0)
1218    {
1219      q  = lead(p);
1220      //      "processing q:";q;
1221      x  = leadexp(q);
1222      sx = size(x);
1223      for(k=1; k<=sx; k++)
1224      {
1225        if ( x[k] >= 2 )
1226        {
1227          err = "skip: the value x[k] is " + string(x[k]);
1228          dbprint(ppl,err);
1229          //        return(0);
1230          K[i] = 0;
1231          p    = 0;
1232          q    = 0;
1233          break;
1234        }
1235      }
1236      p  = p - q;
1237    }
1238  }
1239  K  = simplify(K,2);
1240  sk = size(K);
1241  for(i=1; i<=sk; i++)
1242  {
1243    //    setring save;
1244    //    V  = 0;
1245    setring @R;
1246    p  = K[i];
1247    while (p!=0)
1248    {
1249      q  = lead(p);
1250      err =  "processing q:" + string(q);
1251      dbprint(ppl,err);
1252      x  = leadexp(q);
1253      sx = size(x);
1254      pn = leadcoef(q);
1255      setring save;
1256      pn = imap(@R,pn);
1257      V  = V + leadcoef(pn)*gen(1);
1258      for(k=1; k<=sx; k++)
1259      {
1260        if (x[k] ==1)
1261        {
1262          a = k / s; // block number=a+1, a!=0
1263          b = k % s; // remainder
1264          //      printf("a: %s, b: %s",a,b);
1265          if (b == 0)
1266          {
1267            // that is it's the last var in the block
1268            b = s;
1269            a = a-1;
1270          }
1271          V = V + var(b)*gen(a+2);
1272        }
1273//      else
1274//      {
1275//        printf("error: the value x[k] is %s", x[k]);
1276//        return(0);
1277//      }
1278      }
1279      err = "V: " + string(V);
1280      dbprint(ppl,err);
1281      //      printf("V: %s", string(V));
1282      N = N,V;
1283      V  = 0;
1284      setring @R;
1285      p  = p - q;
1286      pn = 0;
1287    }
1288    setring save;
1289    LN[i] = simplify(N,2);
1290    N     = 0;
1291  }
1292  setring save;
1293  return(LN);
1294}
1295example
1296{
1297  "EXAMPLE:"; echo = 2;
1298  ring r = 0,(x,y,z),(dp(1),dp(2));
1299  module M = [-1,x,y],[-7,y,y],[3,x,x];
1300  module N = [1,x,y,x],[-1,y,x,y];
1301  list L; L[1] = M; L[2] = N;
1302  lst2str(L);
1303  def U = freegbold(L,5);
1304  lst2str(U);
1305}
1306
1307proc sgb(ideal I, int d)
1308{
1309  // new code
1310  // map x_i to x_i(1) via map()
1311  //LIB "freegb.lib";
1312  def save = basering;
1313  //int d =7;// degree
1314  int nv = nvars(save);
1315  def R = freegbRing(d);
1316  setring R;
1317  int i;
1318  ideal Imap;
1319  for (i=1; i<=nv; i++)
1320  {
1321    Imap[i] = var(i);
1322  }
1323  //ideal I = x(1)*y(2), y(1)*x(2)+z(1)*z(2);
1324  ideal I = x(1)*x(2),x(1)*y(2) + z(1)*x(2);
1325  option(prot);
1326  //option(teach);
1327  ideal J = system("freegb",I,d,nv);
1328}
1329
1330
1331
1332static proc checkCeq()
1333{
1334  ring r = 0,(x,y),Dp;
1335  def A = freegbRing(4);
1336  setring A;
1337  A;
1338  // I = x2-xy
1339  ideal I = x(1)*x(2) - x(1)*y(2), x(2)*x(3) - x(2)*y(3), x(3)*x(4) - x(3)*y(4);
1340  ideal C = x(2)-x(1),x(3)-x(2),x(4)-x(3),y(2)-y(1),y(3)-y(2),y(4)-y(3);
1341  ideal K = I,C;
1342  groebner(K);
1343}
1344
1345
1346proc exHom1()
1347{
1348  // we start with
1349  // z*y - x, z*x - y, y*x - z
1350  LIB "freegb.lib";
1351  LIB "elim.lib";
1352  ring r = 0,(x,y,z,h),dp;
1353  list L;
1354  module M;
1355  M = [1,z,y],[-1,x,h]; // zy - xh
1356  L[1] = M;
1357  M = [1,z,x],[-1,y,h]; // zx - yh
1358  L[2] = M;
1359  M = [1,y,x],[-1,z,h]; // yx - zh
1360  L[3] = M;
1361  lst2str(L);
1362  def U = crs(L,4);
1363  setring U;
1364  I = I,
1365    y(2)*h(3)+z(2)*x(3),     y(3)*h(4)+z(3)*x(4),
1366    y(2)*x(3)-z(2)*h(3),     y(3)*x(4)-z(3)*h(4);
1367  I = simplify(I,2);
1368  ring r2 = 0,(x(0..4),y(0..4),z(0..4),h(0..4)),dp;
1369  ideal J = imap(U,I);
1370  //  ideal K = homog(J,h);
1371  option(redSB);
1372  option(redTail);
1373  ideal L = groebner(J); //(K);
1374  ideal LL = sat(L,ideal(h))[1];
1375  ideal M = subst(LL,h,1);
1376  M = simplify(M,2);
1377  setring U;
1378  ideal M = imap(r2,M);
1379  lst2str(U);
1380}
1381
1382static proc test1()
1383{
1384  LIB "freegb.lib";
1385  ring r = 0,(x,y),Dp;
1386  int d = 10; // degree
1387  def R = freegbRing(d);
1388  setring R;
1389  ideal I = x(1)*x(2) - y(1)*y(2);
1390  option(prot);
1391  option(teach);
1392  ideal J = system("freegb",I,d,2);
1393  J;
1394}
1395
1396static proc test2()
1397{
1398  LIB "freegb.lib";
1399  ring r = 0,(x,y),Dp;
1400  int d = 10; // degree
1401  def R = freegbRing(d);
1402  setring R;
1403  ideal I = x(1)*x(2) - x(1)*y(2);
1404  option(prot);
1405  option(teach);
1406  ideal J = system("freegb",I,d,2);
1407  J;
1408}
1409
1410static proc test3()
1411{
1412  LIB "freegb.lib";
1413  ring r = 0,(x,y,z),dp;
1414  int d =5; // degree
1415  def R = freegbRing(d);
1416  setring R;
1417  ideal I = x(1)*y(2), y(1)*x(2)+z(1)*z(2);
1418  option(prot);
1419  option(teach);
1420  ideal J = system("freegb",I,d,3);
1421}
1422
1423proc schur2-3()
1424{
1425  // nonhomog:
1426  //  h^4-10*h^2+9,f*e-e*f+h, h*2-e*h-2*e,h*f-f*h+2*f
1427  // homogenized with t
1428  //  h^4-10*h^2*t^2+9*t^4,f*e-e*f+h*t, h*2-e*h-2*e*t,h*f-f*h+2*f*t,
1429  // t*h - h*t, t*f - f*t, t*e - e*t
1430}
1431
1432proc adem(int i, int j)
1433{
1434  // produces Adem relations for i<2j in char 0
1435  // assume: 0<i<2j
1436  // requires presence of vars up to i+j
1437  if ( (i<0) || (i >= 2*j) )
1438  {
1439    ERROR("arguments out of range"); return(0);
1440  }
1441  ring @r = 0,(s(i+j..0)),lp;
1442  poly p,q;
1443  number n;
1444  int ii = i div 2; int k;
1445  // k=0 => s(0)=1
1446  n = binomial(j-1,i);
1447  q = n*s(i+j)*s(0);
1448  printf("k=0, term=%s",q);
1449  p = p + q;
1450  for (k=1; k<= ii; k++)
1451  {
1452    n = binomial(j-k-1,i-2*k);
1453    q = n*s(i+j-k)*s(k);;
1454    printf("k=%s, term=%s",k,q);
1455    p = p + q;
1456  }
1457  poly AdemRel = p;
1458  export AdemRel;
1459  return(@r);
1460}
1461example
1462{
1463  "EXAMPLE:"; echo = 2;
1464  def A = adem(2,5);
1465  setring A;
1466  AdemRel;
1467}
1468
1469/*
14701,1: 0
14711,2: s(3)*s(0) == s(3) -> def for s(3):=s(1)s(2)
14722,1: adm
14732,2: s(3)*s(1) == s(1)s(2)s(1)
14741,3: 0 ( since 2*s(4)*s(0) = 0 mod 2)
14753,1: adm
14762,3: s(5)*s(0)+s(4)*s(1) == s(5)+s(4)*s(1)
14773,2: 0
14783,3: s(5)*s(1)
14791,4: 3*s(5)*s(0) == s(5)  -> def for s(5):=s(1)*s(4)
14804,1: adm
14812,4: 3*s(6)*s(0)+s(5)*s(1) == s(6) + s(5)*s(1) == s(6) + s(1)*s(4)*s(1)
14824,2: adm
14834,3: s(5)*s(2)
14843,4: s(7)*s(0)+2*s(6)*s(1) == s(7) -> def for s(7):=s(3)*s(4)
14854,4: s(7)*s(1)+s(6)*s(2)
1486*/
1487
1488/* s1,s2:
1489s1*s1 =0, s2*s2 = s1*s2*s1
1490*/
1491
1492/*
1493try char 0:
1494s1,s2:
1495s1*s1 =0, s2*s2 = s1*s2*s1, s(1)*s(3)== s(1)*s(1)*s(3) == 0 = 2*s(4) ->def for s(4)
1496hence 2==0! only in char 2
1497 */
1498
1499proc adem2mod(int n)
1500{
1501  // Adem rels modulo 2 
1502}
1503
1504proc stringpoly2lplace(string s)
1505{
1506  // decomposes sentence into terms
1507  s = replace(s,newline,""); // get rid of newlines
1508  s = replace(s," ",""); // get rid of empties
1509  //arith symbols: +,-
1510  // decompose into words with coeffs
1511  list LS;
1512  int i,j,ie,je,k,cnt;
1513  // s[1]="-" situation
1514  if (s[1]=="-")
1515  {
1516    LS = stringpoly2lplace(string(s[2..size(s)]));
1517    LS[1] = string("-"+string(LS[1]));
1518    return(LS);
1519  }
1520  i = find(s,"-",2);
1521  // i==1 might happen if the 1st symbol coeff is negative
1522  j = find(s,"+");
1523  list LL;
1524  if (i==j)
1525  {
1526    "return a monomial";
1527    // that is both are 0 -> s is a monomial
1528    LS[1] = s;
1529    return(LS);
1530  }
1531  if (i==0)
1532  {
1533    "i==0 situation";
1534    // no minuses at all => pluses only
1535    cnt++;
1536    LS[cnt] = string(s[1..j-1]);
1537    s = s[j+1..size(s)];
1538    while (s!= "")
1539    {
1540      j = find(s,"+");
1541      cnt++;
1542      if (j==0)
1543      {
1544        LS[cnt] = string(s);
1545        s = "";
1546      }
1547      else
1548      {
1549        LS[cnt] = string(s[1..j-1]);
1550        s = s[j+1..size(s)];
1551      }
1552    }
1553    return(LS);
1554  }
1555  if (j==0)
1556  {
1557    "j==0 situation";
1558    // no pluses at all except the lead coef => the rest are minuses only
1559    cnt++;
1560    LS[cnt] = string(s[1..i-1]);
1561    s = s[i..size(s)];
1562    while (s!= "")
1563    {
1564      i = find(s,"-",2);
1565      cnt++;
1566      if (i==0)
1567      {
1568        LS[cnt] = string(s);
1569        s = "";
1570      }
1571      else
1572      {
1573        LS[cnt] = string(s[1..i-1]);
1574        s = s[i..size(s)];
1575      }
1576    }
1577    return(LS);
1578  }
1579  // now i, j are nonzero
1580  if (i>j)
1581  {
1582    "i>j situation";
1583    // + comes first, at place j
1584    cnt++;
1585    //    "cnt:"; cnt; "j:"; j;
1586    LS[cnt] = string(s[1..j-1]);
1587    s = s[j+1..size(s)];
1588    LL = stringpoly2lplace(s);
1589    LS = LS + LL;
1590    kill LL;
1591    return(LS);
1592  }
1593  else
1594  {
1595    "j>i situation";
1596    // - might come first, at place i
1597    if (i>1)
1598    {
1599      cnt++;
1600      LS[cnt] = string(s[1..i-1]);
1601      s = s[i..size(s)];
1602    }
1603    else
1604    {
1605      // i==1->  minus at leadcoef
1606      ie = find(s,"-",i+1);
1607      je = find(s,"+",i+1);
1608      if (je == ie)
1609      {
1610         "ie=je situation";
1611        //monomial
1612        cnt++;
1613        LS[cnt] = s;
1614        return(LS);
1615      }
1616      if (je < ie)
1617      {
1618         "je<ie situation";
1619        // + comes first
1620        cnt++;
1621        LS[cnt] = s[1..je-1];
1622        s = s[je+1..size(s)];
1623      }
1624      else
1625      {
1626        // ie < je
1627         "ie<je situation";
1628        cnt++;
1629        LS[cnt] = s[1..ie-1];
1630        s = s[ie..size(s)];
1631      }
1632    }
1633    "going into recursion with "+s;
1634    LL = stringpoly2lplace(s);
1635    LS = LS + LL;
1636    return(LS);
1637  }
1638}
1639example
1640{
1641  "EXAMPLE:"; echo = 2;
1642  string s = "x*y+y*z+z*t"; // + only
1643  stringpoly2lplace(s);
1644  string s2 = "x*y - y*z-z*t*w*w"; // +1, - only
1645  stringpoly2lplace(s2);
1646  string s3 = "-x*y + y - 2*x +7*w*w*w";
1647  stringpoly2lplace(s3);
1648}
1649
1650proc addplaces(list L)
1651{
1652  // adds places to the list of strings
1653  // according to their order in the list
1654  int s = size(L);
1655  int i;
1656  for (i=1; i<=s; i++)
1657  {
1658    if (typeof(L[i]) == "string")
1659    {
1660      L[i] = L[i] + "(" + string(i) + ")";
1661    }
1662    else
1663    {
1664      ERROR("entry of type string expected");
1665      return(0);
1666    }
1667  }
1668  return(L);
1669}
1670example
1671{
1672  "EXAMPLE:"; echo = 2;
1673  string a = "f1";   string b = "f2";
1674  list L = a,b,a;
1675  addplaces(L); 
1676}
1677
1678proc sent2lplace(string s)
1679{
1680  // SENTence of words TO LetterPLACE
1681  list L =   stringpoly2lplace(s);
1682  int i; int ss = size(L);
1683  for(i=1; i<=ss; i++)
1684  {
1685    L[i] = str2lplace(L[i]);
1686  }
1687  return(L);
1688}
1689example
1690{
1691  "EXAMPLE:"; echo = 2;
1692  ring r = 0,(f2,f1),dp;
1693  string s = "f2*f1*f1 - 2*f1*f2*f1+ f1*f1*f2";
1694  sent2lplace(s); 
1695}
1696
1697proc testnumber(string s)
1698{
1699  string t;
1700  if (s[1]=="-")
1701  {
1702    // two situations: either there's a negative number
1703    t = s[2..size(s)];
1704    if (testnumber(t))
1705    {
1706      //a negative number
1707    }
1708    else
1709    {
1710      // a variable times -1
1711    }
1712    // or just a "-" for -1
1713  }
1714  t = "ring @r=(";
1715  t = t + charstr(basering)+"),";
1716  t = t + string(var(1))+",dp;";
1717  //  write(":w tstnum.tst",t);
1718  t = t+ "number @@Nn = " + s + ";"+"$";
1719  write(":w tstnum.tst",t);
1720  string runsing = system("Singular");
1721  int k;
1722  t = runsing+ " -teq <tstnum.tst >tstnum.out";
1723  k = system("sh",t);
1724  if (k!=0)
1725  {
1726    ERROR("Problems running Singular");
1727  }
1728  int i = system("sh", "grep error tstnum.out > /dev/NULL");
1729  if (i!=0)
1730  {
1731    // no error: s is a number
1732    i = 1;
1733  }
1734  k = system("sh","rm tstnum.tst tstnum.out > /dev/NULL");
1735  return(i);
1736}
1737example
1738{
1739  "EXAMPLE:"; echo = 2;
1740  ring r = (0,a),x,dp;
1741  string s = "a^2+7*a-2";
1742  testnumber(s); 
1743  s = "b+a";
1744  testnumber(s); 
1745}
1746
1747proc str2lplace(string s)
1748{
1749  // converts a word (monomial) with coeff into letter-place
1750  // string: coef*var1^exp1*var2^exp2*...varN^expN
1751  s = strpower2rep(s); // expand powers
1752  if (size(s)==0) { return(0); }
1753  int i,j,k,insC;
1754  string a,b,c,d,t;
1755  // 1. get coeff
1756  i = find(s,"*");
1757  if (i==0) { return(s); }
1758  list VN;
1759  c = s[1..i-1]; // incl. the case like (-a^2+1)
1760  int tn = testnumber(c);
1761  if (tn == 0)
1762  {
1763    // failed test
1764    if (c[1]=="-")
1765    {
1766      // two situations: either there's a negative number
1767      t = c[2..size(c)];
1768      if (testnumber(t))
1769      {
1770         //a negative number       
1771        // nop here
1772      }
1773      else
1774      {
1775         // a variable times -1
1776          c = "-1";
1777          j++; VN[j] = t; //string(c[2..size(c)]);
1778          insC = 1;
1779      }
1780    }
1781    else
1782    {
1783      // just a variable with coeff 1
1784          j++; VN[j] = string(c);
1785          c = "1";
1786          insC = 1;
1787    }
1788  }
1789 // get vars
1790  t = s;
1791  //  t = s[i+1..size(s)];
1792  k = size(t); //j = 0;
1793  while (k>0)
1794  {
1795    t = t[i+1..size(t)]; //next part
1796    i = find(t,"*"); // next *
1797    if (i==0)
1798    {
1799      // last monomial
1800      j++;
1801      VN[j] = t;
1802      k = size(t);
1803      break;
1804    }
1805    b = t[1..i-1];
1806    //    print(b);
1807    j++;
1808    VN[j] = b;
1809    k = size(t);
1810  }
1811  VN = addplaces(VN);
1812  VN[size(VN)+1] = string(c);
1813  return(VN);
1814}
1815example
1816{
1817  "EXAMPLE:"; echo = 2;
1818  ring r = (0,a),(f2,f1),dp;
1819  str2lplace("-2*f2^2*f1^2*f2"); 
1820  str2lplace("-f1*f2");
1821  str2lplace("(-a^2+7a)*f1*f2");
1822}
1823
1824proc strpower2rep(string s)
1825{
1826  // makes x*x*x*x out of x^4 ., rep statys for repetitions
1827  // looks for "-" problem
1828  // exception: "-" as coeff
1829  string ex,t;
1830  int i,j,k;
1831
1832  i = find(s,"^"); // first ^
1833  if (i==0) { return(s); } // no ^ signs
1834
1835  if (s[1] == "-")
1836  {
1837    // either -coef or -1
1838    // got the coeff:
1839    i = find(s,"*");
1840    if (i==0)
1841    {
1842      // no *'s   => coef == -1 or s == -23
1843      i = size(s)+1;
1844    }
1845    t = string(s[2..i-1]); // without "-"
1846    if ( testnumber(t) )
1847    {
1848      // a good number
1849      t = strpower2rep(string(s[2..size(s)]));
1850      t = "-"+t;
1851      return(t);
1852    }
1853    else
1854    {
1855      // a variable
1856      t = strpower2rep(string(s[2..size(s)]));
1857      t = "-1*"+ t;
1858      return(t);
1859    }
1860  }
1861  // the case when leadcoef is a number in ()
1862  if (s[1] == "(")
1863  {
1864    i = find(s,")",2);    // must be nonzero
1865    t = s[2..i-1];
1866    if ( testnumber(t) )
1867    {
1868      // a good number
1869    }
1870    else {"strpower2rep: bad number as coef";}
1871    ex = string(s[i+2..size(s)]); // 2 because of *
1872    ex =  strpower2rep(ex);
1873    t = "("+t+")*"+ex;
1874    return(t);
1875  }
1876
1877  i = find(s,"^"); // first ^
1878  j = find(s,"*",i+1); // next * == end of ^
1879  if (j==0)
1880  {
1881    ex = s[i+1..size(s)];
1882  }
1883  else
1884  {
1885    ex = s[i+1..j-1];
1886  }
1887  execute("int @exp = " + ex + ";"); //@exp = exponent
1888  // got varname
1889  for (k=i-1; k>0; k--)
1890  {
1891    if (s[k] == "*") break;
1892  }
1893  string varn = s[k+1..i-1];
1894  //  "varn:";  varn;
1895  string pref;
1896  if (k>0)
1897  {
1898    pref = s[1..k]; // with * on the k-th place 
1899  }
1900  //  "pref:";  pref;
1901  string suf;
1902  if ( (j>0) && (j+1 <= size(s)) )
1903  {
1904    suf = s[j+1..size(s)]; // without * on the 1st place
1905  }
1906  //  "suf:"; suf;
1907  string toins;
1908  for (k=1; k<=@exp; k++)
1909  {
1910    toins = toins + varn+"*";
1911  }
1912  //  "toins: ";  toins;
1913  if (size(suf) == 0)
1914  {
1915    toins = toins[1..size(toins)-1]; // get rid of trailing *
1916  }
1917  else
1918  {
1919    suf = strpower2rep(suf);
1920  }
1921  ex = pref + toins + suf;
1922  return(ex);
1923  //  return(strpower2rep(ex));
1924}
1925example
1926{
1927  "EXAMPLE:"; echo = 2;
1928  ring r = (0,a),(x,y,z,t),dp;
1929  strpower2rep("-x^4"); 
1930  strpower2rep("-2*x^4*y^3*z*t^2"); 
1931  strpower2rep("-a^2*x^4"); 
1932}
1933
1934proc Liebr(poly a, poly b, list #)
1935{
1936  // alias ppLiebr;
1937  //if int N is given compute [a,[...[a,b]]]] left normed bracket
1938  poly q;
1939  int N=1;
1940  if (size(#)>0)
1941  {
1942    if (typeof(#[1])=="int")
1943    {
1944      N = int(#[1]);
1945    }
1946  }
1947  if (N<=0) { return(q); }
1948  while (b!=0)
1949  {
1950    q = q + pmLiebr(a,lead(b));
1951    b = b - lead(b);
1952  }
1953  int i;
1954  if (N >1)
1955  {
1956    for(i=1; i<=N; i++)
1957    {
1958      q = Liebr(a,q);
1959    }
1960  }
1961  return(q);
1962}
1963example
1964{
1965  "EXAMPLE:"; echo = 2;
1966  ring r = 0,(x(1),y(1),x(2),y(2),x(3),y(3),x(4),y(4)),dp;
1967  poly a = x(1)*y(2); poly b = y(1);
1968  int uptodeg=4; int lV=2;
1969  export uptodeg; export lV;
1970  Liebr(a,b);
1971  Liebr(x(1),y(1),2);
1972}
1973
1974proc pmLiebr(poly a, poly b)
1975{
1976  //  a poly, b mono
1977  poly s;
1978  while (a!=0)
1979  {
1980    s = s + mmLiebr(lead(a),lead(b));
1981    a = a - lead(a);
1982  }
1983  return(s);
1984}
1985
1986//proc pshift(poly a, int i, int uptodeg, int lV)
1987proc pshift(poly a, int i)
1988{
1989  // shifts a monomial a by i
1990  // calls pLPshift(p,sh,uptodeg,lVblock);
1991  return(system("stest",a,i,uptodeg,lV));
1992}
1993
1994proc mmLiebr(poly a, poly b)
1995{
1996  // a,b, monomials
1997  a = lead(a);
1998  b = lead(b);
1999  int sa = deg(a); 
2000  int sb = deg(b); 
2001  poly v = a*pshift(b,sa) - b*pshift(a,sb);
2002  return(v);
2003}
2004
2005static proc test_shift()
2006{
2007  LIB "freegb.lib";
2008  ring r = 0,(a,b),dp;
2009  int d =5;
2010  def R = freegbRing(d);
2011  setring R;
2012  int uptodeg = d; export uptodeg;
2013  int lV = 2; export lV;
2014  poly p = mmLiebr(a(1),b(1));
2015  poly p = Liebr(a(1),b(1));
2016}
2017
2018proc Serre(intmat A, int zu)
2019{
2020  // zu = 1 -> with commutators [f_i,f_j]; zu == 0 without them
2021  // suppose that A is cartan matrix
2022  // then Serre's relations are
2023  // (ad f_j)^{1-A_{ij}} ( f_i)
2024  int ppl = printlevel-voice+2;
2025  int n = ncols(A); // hence n variables
2026  int i,j,k,l;
2027  poly p,q;
2028  ideal I;
2029  for (i=1; i<=n; i++)
2030  {
2031    for (j=1; j<=n; j++)
2032    {
2033      l = 1 - A[i,j];
2034      //     printf("i:%s, j: %s, l: %s",i,j,l);
2035      dbprint(ppl,"i, j, l: ",i,j,l);
2036      //      if ((i!=j) && (l >0))
2037      //      if ( (i!=j) &&  ( ((zu ==0) &&  (l >=2)) || ((zu ==1) &&  (l >=1)) ) )
2038      if ((i!=j) && (l >0))
2039      {
2040        q = Liebr(var(j),var(i));
2041        //        printf("first bracket: %s",q);
2042        dbprint(ppl,"first bracket: ",q);
2043        //        if (l >=2)
2044        //        {
2045          for (k=1; k<=l-1; k++)
2046          {
2047            q = Liebr(var(j),q);
2048            //            printf("further bracket: %s",q);
2049            dbprint(ppl,"further bracket:",q);
2050          }
2051          //        }
2052      }
2053      if (q!=0) { I = I,q; q=0;}
2054    }
2055  }
2056  I = simplify(I,2);
2057  return(I);
2058}
2059example
2060{
2061  "EXAMPLE:"; echo = 2;
2062  intmat A[2][2] = 2, -1, -1, 2; // sl_3 == A_2
2063  ring r = 0,(f1,f2),dp;
2064  int uptodeg = 3; int lV = 2;
2065  export uptodeg; export lV;
2066  def R = freegbRing(uptodeg);
2067  setring R;
2068  ideal I = Serre(A,1);
2069  I;
2070  Serre(A,0);
2071}
2072
2073proc lp2lstr(ideal K, def save)
2074"USAGE:  lp2lstr(K,save); K an ideal, save a ring
2075RETURN:  nothing (exports object LN into save)
2076PURPOSE: converts letter-place ideal to list of modules
2077EXAMPLE: example lp2lstr; shows examples
2078"
2079{
2080  def @R = basering;
2081  string err;
2082  int s = nvars(save);
2083  int i,j,k;
2084    // K contains vars x(1),...z(1) = images of originals
2085  // 5. go back to orig vars, produce strings/modules
2086  int sk = size(K);
2087  int sp, sx, a, b;
2088  intvec x;
2089  poly p,q;
2090  poly pn;
2091  // vars in 'save'
2092  setring save;
2093  module N;
2094  list LN;
2095  vector V;
2096  poly pn;
2097  // test and skip exponents >=2
2098  setring @R;
2099  for(i=1; i<=sk; i++)
2100  {
2101    p  = K[i];
2102    while (p!=0)
2103    {
2104      q  = lead(p);
2105      //      "processing q:";q;
2106      x  = leadexp(q);
2107      sx = size(x);
2108      for(k=1; k<=sx; k++)
2109      {
2110        if ( x[k] >= 2 )
2111        {
2112          err = "skip: the value x[k] is " + string(x[k]);
2113          dbprint(ppl,err);
2114          //        return(0);
2115          K[i] = 0;
2116          p    = 0;
2117          q    = 0;
2118          break;
2119        }
2120      }
2121      p  = p - q;
2122    }
2123  }
2124  K  = simplify(K,2);
2125  sk = size(K);
2126  for(i=1; i<=sk; i++)
2127  {
2128    //    setring save;
2129    //    V  = 0;
2130    setring @R;
2131    p  = K[i];
2132    while (p!=0)
2133    {
2134      q  = lead(p);
2135      err =  "processing q:" + string(q);
2136      dbprint(ppl,err);
2137      x  = leadexp(q);
2138      sx = size(x);
2139      pn = leadcoef(q);
2140      setring save;
2141      pn = imap(@R,pn);
2142      V  = V + leadcoef(pn)*gen(1);
2143      for(k=1; k<=sx; k++)
2144      {
2145        if (x[k] ==1)
2146        {
2147          a = k / s; // block number=a+1, a!=0
2148          b = k % s; // remainder
2149          //      printf("a: %s, b: %s",a,b);
2150          if (b == 0)
2151          {
2152            // that is it's the last var in the block
2153            b = s;
2154            a = a-1;
2155          }
2156          V = V + var(b)*gen(a+2);
2157        }
2158      }
2159      err = "V: " + string(V);
2160      dbprint(ppl,err);
2161      //      printf("V: %s", string(V));
2162      N = N,V;
2163      V  = 0;
2164      setring @R;
2165      p  = p - q;
2166      pn = 0;
2167    }
2168    setring save;
2169    LN[i] = simplify(N,2);
2170    N     = 0;
2171  }
2172  setring save;
2173  export LN;
2174  //  return(LN);
2175}
2176example
2177{
2178  "EXAMPLE:"; echo = 2;
2179  intmat A[2][2] = 2, -1, -1, 2; // sl_3 == A_2
2180  ring r = 0,(f1,f2),dp;
2181  int uptodeg = 3; int lV = 2;
2182  export uptodeg; export lV;
2183  def R = freegbRing(uptodeg);
2184  setring R;
2185  ideal I = Serre(A,1);
2186  lp2lstr(I,r);
2187  setring r;
2188  lst2str(LN,1);
2189  kill uptodeg; kill lV;
2190}
2191
2192proc strList2poly(list L)
2193{
2194  //  list L comes from sent2lplace (which takes a poly on the input)
2195  // each entry of L is a sublist with the coef on the last place
2196  int s = size(L); int t;
2197  int i,j;
2198  list M;
2199  poly p,q;
2200  string Q;
2201  for(i=1; i<=s; i++)
2202  {
2203    M = L[i];
2204    t = size(M);
2205    //    q = M[t]; // a constant
2206    Q = string(M[t]);
2207    for(j=1; j<t; j++)
2208    {
2209      //      q = q*M[j];
2210      Q = Q+"*"+string(M[j]);
2211    }
2212    execute("q="+Q+";");
2213    //    q;
2214    p = p + q;
2215  }
2216  kill Q;
2217  return(p);
2218}
2219example
2220{
2221  "EXAMPLE:"; echo = 2;
2222  ring r =0,(x,y,z,t),Dp;
2223  def A = freegbRing(4);
2224  setring A;
2225  string t = "-2*y*z*y*z + y*t*z*z - z*x*x*y  + 2*z*y*z*y";
2226  list L = sent2lplace(t);
2227  L;
2228  poly p = strList2poly(L);
2229  p;
2230}
2231
2232proc file2lplace(string fname)
2233{
2234  // format: from the usual string to letterplace
2235  string s = read(fname);
2236  // assume: file is a comma-sep list of polys
2237  // the vars are declared before
2238  // the file ends with ";"
2239  string t; int i;
2240  ideal I;
2241  list tst;
2242  while (s!="")
2243  {
2244    i = find(s,",");
2245    "i"; i;
2246    if (i==0)
2247    {
2248      i = find(s,";");
2249      if (i==0)
2250      {
2251        // no ; ??
2252         "no colon or semicolon found anymore";
2253         return(I);
2254      }
2255      // no "," but ";" on the i-th place
2256      t = s[1..i-1];
2257      s = "";
2258      "processing: "; t;
2259      tst = sent2lplace(t);
2260      tst;
2261      I = I, strList2poly(tst);
2262      return(I);
2263    }
2264    // here i !=0
2265    t = s[1..i-1];
2266    s = s[i+1..size(s)];
2267    "processing: "; t;
2268    tst = sent2lplace(t);
2269    tst;
2270    I = I, strList2poly(tst);
2271  }
2272  return(I);
2273}
2274example
2275{
2276  "EXAMPLE:"; echo = 2;
2277  ring r =0,(x,y,z,t),dp;
2278  def A = freegbRing(4);
2279  setring A;
2280  string fn = "myfile";
2281  string s1 = "z*y*y*y - 3*y*z*x*y  + 3*y*y*z*y - y*x*y*z,";
2282  string s2 = "-2*y*x*y*z + y*y*z*z - z*z*y*y + 2*z*y*z*y,";
2283  string s3 = "z*y*x*t - 2*y*z*y*t + y*y*z*t - t*z*y*y + 2*t*y*z*y - t*x*y*z;";
2284  write(":w "+fn,s1);  write(":a "+fn,s2);   write(":a "+fn,s3);
2285  read(fn);
2286  ideal I = file2lplace(fn);
2287  I;
2288}
2289
2290static proc get_ls3nilp()
2291{
2292//first app of file2lplace
2293  ring r =0,(x,y,z,t),dp;
2294  int d = 10;
2295  def A = freegbRing(d);
2296  setring A;
2297  ideal I = file2lplace("./ls3nilp.bg");
2298  // and now test the correctness: go back from lplace to strings
2299  lp2lstr(I,r);
2300  setring r;
2301  lst2str(LN,1); // agree!
2302}
2303
2304static proc doc_example
2305{
2306  LIB "freegb.lib";
2307  ring r = 0,(x,y,z),dp;
2308  int d =4; // degree bound
2309  def R = freegbRing(d);
2310  setring R;
2311  ideal I = x(1)*y(2) + y(1)*z(2), x(1)*x(2) + x(1)*y(2) - y(1)*x(2) - y(1)*y(2);
2312  option(redSB);option(redTail);
2313  ideal J = system("freegb",I,d,nvars(r));
2314  J;
2315  // visualization:
2316  lp2lstr(J,r); // export an object called LN to the ring r
2317  setring r;  // change to the ring r
2318  lst2str(LN,1); // output the strings
2319}
2320
2321
2322
2323// TODO:
2324// multiply two letterplace polynomials, lpMult
2325// reduction/ Normalform? needs kernel stuff
2326
Note: See TracBrowser for help on using the repository browser.