source: git/Singular/LIB/freegb.lib @ 3360fb

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