source: git/Singular/LIB/freegb.lib @ d2f488

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