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

spielwiese
Last change on this file since fceb4e was fceb4e, checked in by Karim Abou Zeid <karim23697@…>, 5 years ago
Replace makeLetterplaceRing() with freeAlgebra() in LIBs
  • Property mode set to 100644
File size: 91.2 KB
Line 
1/////////////////////////////////////////////////////////////////////////////
2version="version freegb.lib 4.1.1.4 Oct_2018 "; // $Id$
3category="Noncommutative";
4info="
5LIBRARY: freegb.lib   Two-sided Groebner bases in free algebras and tools via Letterplace approach
6AUTHORS: Viktor Levandovskyy,   viktor.levandovskyy at math.rwth-aachen.de
7@*       Karim Abou Zeid,       karim.abou.zeid at rwth-aachen.de
8@*       Grischa Studzinski,    grischa.studzinski at math.rwth-aachen.de
9
10OVERVIEW: For the theory, see chapter 'Letterplace' in the Singular Manual.
11
12This library provides access to kernel functions and also contains legacy code (partially as
13 static procedures) for compatibility reasons.
14
15KEYWORDS: free associative algebra; tensor algebra; free noncommutative Groebner basis;
16Letterplace Groebner basis; finitely presented algebra
17
18Support: Joint projects LE 2697/2-1 and KR 1907/3-1 of the Priority Programme SPP 1489:
19'Algorithmische und Experimentelle Methoden in Algebra, Geometrie und Zahlentheorie'
20of the German DFG
21and Project II.6 of the transregional collaborative research centre
22SFB-TRR 195 'Symbolic Tools in Mathematics and their Application' of the German DFG
23
24PROCEDURES:
25freeAlgebra(r, d);               creates a Letterplace ring out of given data
26isFreeAlgebra(r);                check whether r is a letterplace ring (free algebra)
27lpDegBound(R);                   returns the degree bound of a letterplace ring
28lpVarBlockSize(R);               returns the size of the letterplace blocks
29
30letplaceGBasis(I);               (deprecated, use twostd) two-sided Groebner basis of a letterplace ideal I
31
32lpDivision(f,I);                 two-sided division with remainder
33lpGBPres2Poly(L,I);              reconstructs a polynomial from the output of lpDivision
34
35lieBracket(a,b[, N]);            Lie bracket ab-ba of two letterplace polynomials
36isOrderingShiftInvariant(i);     tests shift-invariance of the monomial ordering
37isVar(p);                        check whether p is a power of a single variable
38
39lpLmDivides(ideal I, poly p);    tests whether there exists q in I, such that LM(q)|LM(p)
40lpVarAt(poly p, int pos);        returns the variable (as a poly) at position pos of the poly p
41
42makeLetterplaceRing(d);          (deprecated, use freeAlgebra) creates a Letterplace ring out of given data
43setLetterplaceAttributes(R,d,b); (for testing purposes) supplies ring R with the letterplace structure
44
45SEE ALSO: fpadim_lib, fpaprops_lib, fpalgebras_lib, LETTERPLACE
46";
47
48// Remark Oct 2018: iv2lp, lp2iv etc are NOT IN HEADER because
49// they should not be used anymore
50
51/* more legacy:
52lpPrint(I, r); represents Letterplace ideal in the form of words (legacy routine)
53freeGBasis(L, n);  computes two-sided Groebner basis of an ideal, encoded via list L (legacy routine)
54lp2lstr(K, s);  convert a letterplace ideal into a list of modules
55lst2str(L[, n]); convert a list (of modules) into polynomials in free algebra via strings
56mod2str(M[, n]); convert a module into a polynomial in free algebra via strings
57vct2str(M[, n]);   convert a vector into a word in free algebra
58//also, there were
59shiftPoly;
60lpPower;
61*/
62
63LIB "qhmoduli.lib"; // for Max
64LIB "bfun.lib"; // for inForm
65LIB "fpadim.lib"; // for intvec conversion
66LIB "fpalgebras.lib"; // for compatibility
67
68/* very fast and cheap test of consistency and functionality
69  DO NOT make it static !
70  after adding the new proc, add it here */
71proc tstfreegb()
72{
73  example makeLetterplaceRing;
74  example letplaceGBasis;
75  example lpNF;
76  example lpDivision;
77  example lpGBPres2Poly;
78  example freeGBasis;
79  example setLetterplaceAttributes;
80  example isOrderingShiftInvariant;
81  /* secondary */
82  example lieBracket;
83  example lpPrint;
84  example isVar;
85
86  example lpLmDivides;
87  example lpVarAt;
88
89  example ivL2lpI;
90  example iv2lp;
91  example iv2lpList;
92  example iv2lpMat;
93  example lp2iv;
94  example lp2ivId;
95  example lpId2ivLi;
96}
97
98proc setLetterplaceAttributes(def R, int uptodeg, int lV)
99"USAGE: setLetterplaceAttributes(R, d, b); R a ring, b,d integers
100RETURN: ring with special attributes set
101PURPOSE: sets attributes for a letterplace ring:
102@*      'isLetterplaceRing' = true, 'uptodeg' = d, 'lV' = b, where
103@*      'uptodeg' stands for the degree bound,
104@*      'lV' for the number of variables in the block 0.
105NOTE: Activate the resulting ring by using @code{setring}
106"
107{
108  if (uptodeg*lV != nvars(R))
109  {
110    ERROR("uptodeg and lV do not agree on the basering!");
111  }
112
113  // Set letterplace-specific attributes for the output ring!
114  // a kind of dirty hack, getting the ringlist again
115  list RL = ringlist(R);
116  attrib(RL, "isLetterplaceRing", lV);
117  attrib(RL, "maxExp", 1);
118  def @R = ring(RL);
119  attrib(@R, "uptodeg", uptodeg); // no longer needed
120  attrib(@R, "isLetterplaceRing", lV);
121  return (@R);
122}
123example
124{
125  "EXAMPLE:"; echo = 2;
126  ring r = 0,(x(1),y(1),x(2),y(2),x(3),y(3),x(4),y(4)),dp;
127  def R = setLetterplaceAttributes(r, 4, 2); setring R;
128  lpVarBlockSize(R);
129  lieBracket(x(1),y(1),2);
130}
131
132
133static proc lst2str(list L, list #)
134"USAGE:  lst2str(L[,n]);  L a list of modules, n an optional integer
135RETURN:  list (of strings)
136PURPOSE: convert a list (of modules) into polynomials in free algebra
137EXAMPLE: example lst2str; shows examples
138NOTE: if an optional integer is not 0, stars signs are used in multiplication
139"
140{
141  // returns a list of strings
142  // being sentences in words built from L
143  // if #[1] = 1, use * between generators
144  int useStar = 0;
145  if ( size(#)>0 )
146  {
147    if ( typeof(#[1]) != "int")
148    {
149      ERROR("Second argument of type int expected");
150    }
151    if (#[1])
152    {
153      useStar = 1;
154    }
155  }
156  int i;
157  int s    = size(L);
158  if (s<1) { return(list(""));}
159  list N;
160  for(i=1; i<=s; i++)
161  {
162    if ((typeof(L[i]) == "module") || (typeof(L[i]) == "matrix") )
163    {
164      N[i] = mod2str(L[i],useStar);
165    }
166    else
167    {
168      "module or matrix expected in the list";
169      return(N);
170    }
171  }
172  return(N);
173}
174example
175{
176  "EXAMPLE:"; echo = 2;
177  ring r = 0,(x,y,z),(dp(1),dp(2));
178  module M = [-1,x,y],[-7,y,y],[3,x,x];
179  module N = [1,x,y,x,y],[-2,y,x,y,x],[6,x,y,y,x,y];
180  list L; L[1] = M; L[2] = N;
181  lst2str(L);
182  lst2str(L[1],1);
183}
184
185
186static proc mod2str(module M, list #)
187"USAGE:  mod2str(M[,n]);  M a module, n an optional integer
188RETURN:  string
189PURPOSE: convert a module into a polynomial in free algebra
190EXAMPLE: example mod2str; shows examples
191NOTE: if an optional integer is not 0, stars signs are used in multiplication
192"
193{
194  if (size(M)==0) { return(""); }
195  // returns a string
196  // a sentence in words built from M
197  // if #[1] = 1, use * between generators
198  int useStar = 0;
199  if ( size(#)>0 )
200  {
201    if ( typeof(#[1]) != "int")
202    {
203      ERROR("Second argument of type int expected");
204    }
205    if (#[1])
206    {
207      useStar = 1;
208    }
209  }
210  int i;
211  int s    = ncols(M);
212  string t;
213  string mp;
214  for(i=1; i<=s; i++)
215  {
216    mp = vct2str(M[i],useStar);
217    if (mp[1] == "-")
218    {
219      t = t + mp;
220    }
221    else
222    {
223      if (mp != "")
224      {
225         t = t + "+" + mp;
226      }
227    }
228  }
229  if (t[1]=="+")
230  {
231    t = t[2..size(t)]; // remove first "+"
232  }
233  return(t);
234}
235example
236{
237  "EXAMPLE:"; echo = 2;
238  ring r = 0,(x,y,z),(dp);
239  module M = [1,x,y,x,y],[-2,y,x,y,x],[6,x,y,y,x,y];
240  mod2str(M);
241  mod2str(M,1);
242}
243
244static proc vct2str(vector v, list #)
245"USAGE:  vct2str(v[,n]);  v a vector, n an optional integer
246RETURN:  string
247PURPOSE: convert a vector into a word in free algebra
248EXAMPLE: example vct2str; shows examples
249NOTE: if an optional integer is not 0, stars signs are used in multiplication
250"
251{
252  if (v==0) { return(""); }
253  // if #[1] = 1, use * between generators
254  int useStar = 0;
255  if ( size(#)>0 )
256  {
257    if (#[1])
258    {
259      useStar = 1;
260    }
261  }
262  int ppl = printlevel-voice+2;
263  // for a word, encoded by v
264  // produces a string for it
265  v = skip0(v);
266  if (v==0) { return(string(""));}
267  number cf = leadcoef(v[1]);
268  int s = size(v);
269  string vs,vv,vp,err;
270  int i,j,p,q;
271  for (i=1; i<=s-1; i++)
272  {
273    p     = isVar(v[i+1]);
274    if (p==0)
275    {
276      err = "Error: monomial expected at nonzero position " + string(i+1);
277      ERROR(err+" in vct2str");
278      //      dbprint(ppl,err);
279      //      return("_");
280    }
281    if (p==1)
282    {
283      if (useStar && (size(vs) >0))       {   vs = vs + "*"; }
284        vs = vs + string(v[i+1]);
285    }
286    else //power
287    {
288      vv = string(v[i+1]);
289      q = find(vv,"^");
290      if (q==0)
291      {
292        q = find(vv,string(p));
293        if (q==0)
294        {
295          err = "error in find for string "+vv;
296          dbprint(ppl,err);
297          return("_");
298        }
299      }
300      // q>0
301      vp = vv[1..q-1];
302      for(j=1;j<=p;j++)
303      {
304         if (useStar && (size(vs) >0))       {   vs = vs + "*"; }
305         vs = vs + vp;
306      }
307    }
308  }
309  string scf;
310  if (cf == -1)
311  {
312    scf = "-";
313  }
314  else
315  {
316    scf = string(cf);
317    if ( (cf == 1) && (size(vs)>0) )
318    {
319      scf = "";
320    }
321  }
322  if (useStar && (size(scf) >0) && (scf!="-") )       {   scf = scf + "*"; }
323  vs = scf + vs;
324  return(vs);
325}
326example
327{
328  "EXAMPLE:"; echo = 2;
329  ring r = (0,a),(x,y3,z(1)),dp;
330  vector v = [-7,x,y3^4,x2,z(1)^3];
331  vct2str(v);
332  vct2str(v,1);
333  vector w = [-7a^5+6a,x,y3,y3,x,z(1),z(1)];
334  vct2str(w);
335  vct2str(w,1);
336}
337
338proc isVar(poly p)
339"USAGE:  isVar(p);  poly p
340RETURN:  int
341PURPOSE: check, whether leading monomial of p is a power of a single variable
342@* from the basering. Returns the exponent or 0 if p is multivariate.
343EXAMPLE: example isVar; shows examples
344"
345{
346  // checks whether p is a variable indeed
347  // if it's a power of a variable, returns the power
348  if (p==0) {  return(0); } //"p=0";
349  poly q   = leadmonom(p);
350  if ( (p-lead(p)) !=0 ) { return(0); } // "p-lm(p)>0";
351  intvec v = leadexp(p);
352  int s = size(v);
353  int i=1;
354  int cnt = 0;
355  int pwr = 0;
356  for (i=1; i<=s; i++)
357  {
358    if (v[i] != 0)
359    {
360      cnt++;
361      pwr = v[i];
362    }
363  }
364  //  "cnt:";  cnt;
365  if (cnt==1) { return(pwr); }
366  else { return(0); }
367}
368example
369{
370  "EXAMPLE:"; echo = 2;
371  ring r = 0,(x,y),dp;
372  poly f = xy+1;
373  isVar(f);
374  poly g = y^3;
375  isVar(g);
376  poly h = 7*x^3;
377  isVar(h);
378  poly i = 1;
379  isVar(i);
380}
381
382proc lpLmDivides(ideal I, poly p)
383"USAGE: lpLmDivides(I); I an ideal
384RETURN: boolean
385ASSUME: basering is a Letterplace ring
386PURPOSE: tests if there is a polynomial q in I with LM(q)|LM(p)
387EXAMPLE: example lpLmDivides; shows examples
388"
389{
390  ERROR(" freegb.so not loaded");
391}
392example
393{
394  "EXAMPLE:"; echo = 2;
395  ring r = 0,(x,y),dp;
396  def R = freeAlgebra(r, 5);
397  setring R;
398  poly p = x*y*y;
399  lpLmDivides(y*y, p);
400  lpLmDivides(y*x, p);
401  lpLmDivides(ideal(y*y, y*x), p);
402}
403
404proc lpVarAt(poly p, int pos)
405"USAGE: lpVarAt(p, pos); p a poly, pos an int
406RETURN: poly
407ASSUME: basering is a Letterplace ring
408PURPOSE: returns the variable (as a poly) at position pos of the poly p
409EXAMPLE: example lpVarAt; shows examples
410"
411{
412  ERROR(" freegb.so not loaded");
413}
414example
415{
416  "EXAMPLE:"; echo = 2;
417  ring r = 0,(x,y),dp;
418  def R = freeAlgebra(r, 5);
419  setring R;
420  poly p = y*y*x;
421  lpVarAt(p, 3);
422}
423
424proc letplaceGBasis(def I)
425"USAGE: letplaceGBasis(I);  I an ideal/module
426RETURN: ideal/module
427ASSUME: basering is a Letterplace ring, input consists of Letterplace
428@*      polynomials
429PURPOSE: compute the two-sided Groebner basis of I via Letterplace
430@*       algorithm (legacy routine)
431NOTE: the degree bound for this computation is read off the letterplace
432@*    structure of basering
433EXAMPLE: example letplaceGBasis; shows examples
434"
435{
436  return(std(I));
437}
438example
439{
440  "EXAMPLE:"; echo = 2;
441  ring r = 0,(x,y,z),Dp;
442  int degree_bound = 5;
443  def R = freeAlgebra(r, 5);
444  setring R;
445  ideal I = -x*y-7*y*y+3*x*x, x*y*x-y*x*y;
446  ideal J = letplaceGBasis(I);
447  J;
448}
449
450/* // temporary name for testing */
451/* proc lpRightStd(ideal F, ideal Q) */
452/* { */
453/*   return (system("rightgb", F, Q)); */
454/* } */
455
456/*
457//// this was the part of example in the old good Letterplace
458  // now transfom letterplace polynomials into strings of words
459  lp2lstr(J,r); // export an object called @code{@LN} to the ring r
460  setring r;  // change to the ring r
461  lst2str(@LN,1);
462*/
463
464
465proc lieBracket(poly a, poly b, list #)
466"USAGE:  lieBracket(a,b[,N]); a,b letterplace polynomials, N an optional integer
467RETURN:  poly
468ASSUME: basering has a letterplace ring structure
469PURPOSE:compute the Lie bracket [a,b] = ab - ba between letterplace polynomials
470NOTE: if N>1 is specified, then the left normed bracket [a,[...[a,b]]]] is
471@*    computed.
472EXAMPLE: example lieBracket; shows examples
473"
474{
475  if (lpAssumeViolation())
476  {
477    //    ERROR("Either 'uptodeg' or 'lV' global variables are not set!");
478    ERROR("Incomplete Letterplace structure on the basering!");
479  }
480  // alias ppLiebr;
481  //if int N is given compute [a,[...[a,b]]]] left normed bracket
482  int N=1;
483  if (size(#)>0)
484  {
485    if (typeof(#[1])=="int")
486    {
487      N = int(#[1]);
488    }
489  }
490  if (N<=0) { return(q); }
491  poly q = a*b - b*a;
492  if (N >1)
493  {
494    for(int i=1; i<=N-1; i++)
495    {
496      q = lieBracket(a,q);
497    }
498  }
499  return(q);
500}
501example
502{
503  "EXAMPLE:"; echo = 2;
504  ring r = 0,(x,y),dp;
505  def R = freeAlgebra(r, 4,2); // R with letterplace structure
506  setring R;
507  poly a = x*y; poly b = y;
508  lieBracket(a,b);
509  lieBracket(x,y,2);
510}
511
512proc lpPrint(ideal I, def @r)
513"USAGE: lpPrint(I, r); I an ideal, r a ring
514RETURN: list of strings
515PURPOSE: represent Letterplace ideal in the form of words (legacy routine)
516ASSUME: - basering is a Letterplace ring, r is the commutative ring
517from which basering has been built
518EXAMPLE: example lpPrint; shows example
519"
520{
521  def save = basering;
522  lp2lstr(I,@r); // export an object called @code{@LN} to the ring r
523  setring @r;  // change to the ring r
524  list @L = lst2str(@LN,1);
525  export @L;
526  setring save;
527  list @@L = @L;
528  setring @r;
529  kill @L;
530  kill @LN;
531  setring save;
532  return(@@L);
533}
534example
535{
536 "EXAMPLE:"; echo = 2;
537 ring r = (0,a,b,g),(x,y),Dp;
538 def R = freeAlgebra(r, 4); // constructs a Letterplace ring
539 setring R; // downup algebra A
540 ideal J = x*x*y-a*x*y*x - b*y*x*x - g*x,
541 x*y*y-a*y*x*y - b*y*y*x - g*y;
542 list L = lpPrint(J,r);
543 L;
544}
545
546/* HISTORICAL STUFF from 2007
547// given the element -7xy^2x, it is represented as [-7,x,y^2,x] or as [-7,x,y,y,x]
548// use the orig ord on (x,y,z) and expand it blockwise to (x(i),y(i),z(i))
549
550// the correspondences:
551// monomial in K<x,y,z>    <<--->> vector in R
552// polynomial in K<x,y,z>  <<--->> list of vectors (matrix/module) in R
553// ideal in K<x,y,z>       <<--->> list of matrices/modules in R
554
555
556// 1. form a new ring
557// 2. NOP
558// 3. compute GB -> with the kernel stuff
559// 4. skip shifted elts (check that no such exist?)
560// 5. go back to orig vars, produce strings/modules
561// 6. return the result
562*/
563
564proc freeGBasis(list LM, int d)
565"USAGE:  freeGBasis(L, d);  L a list of modules, d an integer
566RETURN:  ring
567ASSUME: L has a special form. Namely, it is a list of modules, where
568
569 - each generator of every module stands for a monomial times coefficient in
570@* free algebra,
571
572 - in such a vector generator, the 1st entry is a nonzero coefficient from the
573@* ground field
574
575 - and each next entry hosts a variable from the basering.
576PURPOSE: compute the two-sided Groebner basis of an ideal, encoded by L
577@* in the free associative algebra, up to degree d
578NOTE: Apply @code{lst2str} to the output in order to obtain a better readable
579@*    presentation
580EXAMPLE: example freeGBasis; shows examples
581"
582{
583  // d = up to degree, will be shifted to d+1
584  if (d<1) {"bad d"; return(0);}
585
586  int ppl = printlevel-voice+2;
587  string err = "";
588
589  int i,j,s;
590  def save = basering;
591  // determine max no of places in the input
592  int slm = size(LM); // numbers of polys in the ideal
593  int sm;
594  intvec iv;
595  module M;
596  for (i=1; i<=slm; i++)
597  {
598    // modules, e.g. free polynomials
599    M  = LM[i];
600    sm = ncols(M);
601    for (j=1; j<=sm; j++)
602    {
603      //vectors, e.g. free monomials
604      iv = iv, size(M[j])-1; // 1 place is reserved by the coeff
605    }
606  }
607  int D = Max(iv); // max size of input words
608  if (d<D) {"bad d"; return(LM);}
609  D = D + d-1;
610  //  D = d;
611  list LR  = ringlist(save);
612  list L, tmp;
613  L[1] = LR[1]; // ground field
614  L[4] = LR[4]; // quotient ideal
615  tmp  = LR[2]; // varnames
616  s = size(LR[2]);
617  for (i=1; i<=D; i++)
618  {
619    for (j=1; j<=s; j++)
620    {
621      tmp[i*s+j] = tmp[j];
622    }
623  }
624  L[2] = tmp;
625  list OrigNames = LR[2];
626  // ordering: d blocks of the ord on r
627  // try to get whether the ord on r is blockord itself
628  s = size(LR[3]);
629  if (s==2)
630  {
631    // not a blockord, 1 block + module ord
632    tmp = LR[3][s]; // module ord
633    for (i=1; i<=D; i++)
634    {
635      LR[3][s-1+i] = LR[3][1];
636    }
637    LR[3][s+D] = tmp;
638  }
639  if (s>2)
640  {
641    // there are s-1 blocks
642    int nb = s-1;
643    tmp = LR[3][s]; // module ord
644    for (i=1; i<=D; i++)
645    {
646      for (j=1; j<=nb; j++)
647      {
648        LR[3][i*nb+j] = LR[3][j];
649      }
650    }
651    //    size(LR[3]);
652    LR[3][nb*(D+1)+1] = tmp;
653  }
654  L[3] = LR[3];
655  attrib(L,"isLetterplaceRing",s);
656  attrib(L, "maxExp", 1);
657  def @R = ring(L);
658  @R = setLetterplaceAttributes(@R, D+1, nvars(save));
659  setring @R;
660  ideal I;
661  poly @p;
662  s = size(OrigNames);
663  //  "s:";s;
664  // convert LM to canonical vectors (no powers)
665  setring save;
666  kill M; // M was defined earlier
667  module M;
668  slm = size(LM); // numbers of polys in the ideal
669  int sv,k,l;
670  vector v;
671  //  poly p;
672  string sp;
673  setring @R;
674  poly @@p=0;
675  setring save;
676  for (l=1; l<=slm; l++)
677  {
678    // modules, e.g. free polynomials
679    M  = LM[l];
680    sm = ncols(M); // in intvec iv the sizes are stored
681    // modules, e.g. free polynomials
682    for (j=1; j<=sm; j++)
683    {
684      //vectors, e.g. free monomials
685      v  = M[j];
686      sv = size(v);
687      //        "sv:";sv;
688      sp = "@@p = @@p + ";
689      for (k=2; k<=sv; k++)
690      {
691        sp = sp + string(v[k])+"*";
692      }
693      sp = sp + string(v[1])+";"; // coef;
694      setring @R;
695      execute(sp);
696      setring save;
697    }
698    setring @R;
699    //      "@@p:"; @@p;
700    I = I,@@p;
701    @@p = 0;
702    setring save;
703  }
704  kill sp;
705  // 3. compute GB
706  setring @R;
707  dbprint(ppl,"computing GB");
708  ideal J = std(I);
709  //  ideal J = slimgb(I);
710  dbprint(ppl,J);
711  // 4. skip shifted elts
712  attrib(@R, "isLetterplaceRing", 0); // select1 doesn't want to work with letterplace enabled
713  ideal K = select1(J,1..s); // s = size(OrigNames)
714  dbprint(ppl,K);
715  dbprint(ppl, "done with GB");
716  // K contains vars x(1),...z(1) = images of originals
717  // 5. go back to orig vars, produce strings/modules
718  if (K[1] == 0)
719  {
720    "no reasonable output, GB gives 0";
721    return(0);
722  }
723  int sk = size(K);
724  int sp, sx, a, b;
725  intvec x;
726  poly p,q;
727  poly pn;
728  // vars in 'save'
729  setring save;
730  module N;
731  list LN;
732  vector V;
733  poly pn;
734  // test and skip exponents >=2
735  setring @R;
736  for(i=1; i<=sk; i++)
737  {
738    p  = K[i];
739    while (p!=0)
740    {
741      q  = lead(p);
742      //      "processing q:";q;
743      x  = leadexp(q);
744      sx = size(x);
745      for(k=1; k<=sx; k++)
746      {
747        if ( x[k] >= 2 )
748        {
749          err = "skip: the value x[k] is " + string(x[k]);
750          dbprint(ppl,err);
751          //            return(0);
752          K[i] = 0;
753          p    = 0;
754          q    = 0;
755          break;
756        }
757      }
758      p  = p - q;
759    }
760  }
761  K  = simplify(K,2);
762  sk = size(K);
763  for(i=1; i<=sk; i++)
764  {
765    //    setring save;
766    //    V  = 0;
767    setring @R;
768    p  = K[i];
769    while (p!=0)
770    {
771      q  = lead(p);
772      err =  "processing q:" + string(q);
773      dbprint(ppl,err);
774      x  = leadexp(q);
775      sx = size(x);
776      pn = leadcoef(q);
777      setring save;
778      pn = imap(@R,pn);
779      V  = V + leadcoef(pn)*gen(1);
780      for(k=1; k<=sx; k++)
781      {
782        if (x[k] ==1)
783        {
784          a = k div s; // block number=a+1, a!=0
785          b = k % s; // remainder
786          //          printf("a: %s, b: %s",a,b);
787          if (b == 0)
788          {
789            // that is it's the last var in the block
790            b = s;
791            a = a-1;
792          }
793          V = V + var(b)*gen(a+2);
794        }
795//         else
796//         {
797//           printf("error: the value x[k] is %s", x[k]);
798//           return(0);
799//         }
800      }
801      err = "V: " + string(V);
802      dbprint(ppl,err);
803      //      printf("V: %s", string(V));
804      N = N,V;
805      V  = 0;
806      setring @R;
807      p  = p - q;
808      pn = 0;
809    }
810    setring save;
811    LN[i] = simplify(N,2);
812    N     = 0;
813  }
814  setring save;
815  return(LN);
816}
817example
818{
819  "EXAMPLE:"; echo = 2;
820  ring r = 0,(x,y,z),(dp(1),dp(2)); //  ring r = 0,(x,y,z),(a(3,0,2), dp(2));
821  module M = [-1,x,y],[-7,y,y],[3,x,x]; // stands for free poly -xy - 7yy - 3xx
822  module N = [1,x,y,x],[-1,y,x,y]; // stands for free poly xyx - yxy
823  list L; L[1] = M; L[2] = N; // list of modules stands for an ideal in free algebra
824  lst2str(L); // list to string conversion of input polynomials
825  def U = freeGBasis(L,5); // 5 is the degree bound
826  lst2str(U);
827}
828
829static proc crs(list LM, int d)
830"USAGE:  crs(L, d);  L a list of modules, d an integer
831RETURN:  ring
832PURPOSE: create a ring and shift the ideal
833EXAMPLE: example crs; shows examples
834"
835{
836  // d = up to degree, will be shifted to d+1
837  if (d<1) {"bad d"; return(0);}
838
839  int ppl = printlevel-voice+2;
840  string err = "";
841
842  int i,j,s;
843  def save = basering;
844  // determine max no of places in the input
845  int slm = size(LM); // numbers of polys in the ideal
846  int sm;
847  intvec iv;
848  module M;
849  for (i=1; i<=slm; i++)
850  {
851    // modules, e.g. free polynomials
852    M  = LM[i];
853    sm = ncols(M);
854    for (j=1; j<=sm; j++)
855    {
856      //vectors, e.g. free monomials
857      iv = iv, size(M[j])-1; // 1 place is reserved by the coeff
858    }
859  }
860  int D = Max(iv); // max size of input words
861  if (d<D) {"bad d"; return(LM);}
862  D = D + d-1;
863  //  D = d;
864  list LR  = ringlist(save);
865  list L, tmp;
866  L[1] = LR[1]; // ground field
867  L[4] = LR[4]; // quotient ideal
868  tmp  = LR[2]; // varnames
869  s = size(LR[2]);
870  for (i=1; i<=D; i++)
871  {
872    for (j=1; j<=s; j++)
873    {
874      tmp[i*s+j] = string(tmp[j])+"("+string(i)+")";
875    }
876  }
877  for (i=1; i<=s; i++)
878  {
879    tmp[i] = string(tmp[i])+"("+string(0)+")";
880  }
881  L[2] = tmp;
882  list OrigNames = LR[2];
883  // ordering: d blocks of the ord on r
884  // try to get whether the ord on r is blockord itself
885  s = size(LR[3]);
886  if (s==2)
887  {
888    // not a blockord, 1 block + module ord
889    tmp = LR[3][s]; // module ord
890    for (i=1; i<=D; i++)
891    {
892      LR[3][s-1+i] = LR[3][1];
893    }
894    LR[3][s+D] = tmp;
895  }
896  if (s>2)
897  {
898    // there are s-1 blocks
899    int nb = s-1;
900    tmp = LR[3][s]; // module ord
901    for (i=1; i<=D; i++)
902    {
903      for (j=1; j<=nb; j++)
904      {
905        LR[3][i*nb+j] = LR[3][j];
906      }
907    }
908    //    size(LR[3]);
909    LR[3][nb*(D+1)+1] = tmp;
910  }
911  L[3] = LR[3];
912  def @R = ring(L);
913  setring @R;
914  ideal I;
915  poly @p;
916  s = size(OrigNames);
917  //  "s:";s;
918  // convert LM to canonical vectors (no powers)
919  setring save;
920  kill M; // M was defined earlier
921  module M;
922  slm = size(LM); // numbers of polys in the ideal
923  int sv,k,l;
924  vector v;
925  //  poly p;
926  string sp;
927  setring @R;
928  poly @@p=0;
929  setring save;
930  for (l=1; l<=slm; l++)
931  {
932    // modules, e.g. free polynomials
933    M  = LM[l];
934    sm = ncols(M); // in intvec iv the sizes are stored
935    for (i=0; i<=d-iv[l]; i++)
936    {
937      // modules, e.g. free polynomials
938      for (j=1; j<=sm; j++)
939      {
940        //vectors, e.g. free monomials
941        v  = M[j];
942        sv = size(v);
943        //        "sv:";sv;
944        sp = "@@p = @@p + ";
945        for (k=2; k<=sv; k++)
946        {
947          sp = sp + string(v[k])+"("+string(k-2+i)+")*";
948        }
949        sp = sp + string(v[1])+";"; // coef;
950        setring @R;
951        execute(sp);
952        setring save;
953      }
954      setring @R;
955      //      "@@p:"; @@p;
956      I = I,@@p;
957      @@p = 0;
958      setring save;
959    }
960  }
961  setring @R;
962  export I;
963  return(@R);
964}
965example
966{
967  "EXAMPLE:"; echo = 2;
968  ring r = 0,(x,y,z),(dp(1),dp(2));
969  module M = [-1,x,y],[-7,y,y],[3,x,x];
970  module N = [1,x,y,x],[-1,y,x,y];
971  list L; L[1] = M; L[2] = N;
972  lst2str(L);
973  def U = crs(L,5);
974  setring U; U;
975  I;
976}
977
978static proc polylen(ideal I)
979{
980  // returns the ideal of length of polys
981  int i;
982  intvec J;
983  number s = 0;
984  for(i=1;i<=ncols(I);i++)
985  {
986    J[i] = size(I[i]);
987    s = s + J[i];
988  }
989  printf("the sum of length %s",s);
990  //  print(s);
991  return(J);
992}
993
994proc lpDegBound(def R)
995"USAGE:  lpDegBound(R); R a letterplace ring
996RETURN:  int
997PURPOSE: returns the degree bound of the letterplace ring
998EXAMPLE: example lpDegBound; shows examples
999"
1000{
1001  int lV = attrib(R, "isLetterplaceRing");
1002  if (lV < 1) {
1003    ERROR("not a letterplace ring");
1004  }
1005  return (nvars(R) div lV);
1006}
1007example
1008{
1009  "EXAMPLE:"; echo = 2;
1010  ring r = 0,(x,y,z),dp;
1011  def R = freeAlgebra(r, 7);
1012  lpDegBound(R);
1013}
1014
1015proc lpVarBlockSize(def R)
1016"USAGE:  lpVarBlockSize(R); R a letterplace ring
1017RETURN:  int
1018PURPOSE: returns the variable block size of the letterplace ring, that is the number of variables of the original ring.
1019EXAMPLE: example lpVarBlockSize; shows examples
1020"
1021{
1022  int lV = attrib(R, "isLetterplaceRing");
1023  if (lV < 1) {
1024    ERROR("not a letterplace ring");
1025  }
1026  return (lV);
1027}
1028example
1029{
1030  "EXAMPLE:"; echo = 2;
1031  ring r = 0,(x,y,z),dp;
1032  def R = freeAlgebra(r, 7);
1033  lpVarBlockSize(R);
1034}
1035
1036proc isFreeAlgebra(def r)
1037"USAGE:  isFreeAlgebra(r); r a ring
1038RETURN:  boolean
1039PURPOSE: check whether R is a letterplace ring (free algebra)
1040EXAMPLE: example isFreeAlgebra; shows examples
1041"
1042{
1043  int lV = attrib(r, "isLetterplaceRing");
1044  if (lV < 1) {
1045    return (0);
1046  }
1047  return (1);
1048}
1049example
1050{
1051  "EXAMPLE:"; echo = 2;
1052  ring r = 0,(x,y,z),dp;
1053  isFreeAlgebra(r);
1054  def R = freeAlgebra(r, 7);
1055  isFreeAlgebra(R);
1056}
1057
1058proc freeAlgebra(def r, int d)
1059"USAGE:  freeAlgebra(r, d); r a ring, d an integer
1060RETURN:  ring
1061PURPOSE: creates a letterplace ring with the ordering of r
1062EXAMPLE: example freeAlgebra; shows examples
1063"
1064{
1065  ERROR(" freegb.so not loaded");
1066}
1067example
1068{
1069  "EXAMPLE:"; echo = 2;
1070  ring r = 0,(x,y,z),dp;
1071  def R = freeAlgebra(r, 7);
1072  R;
1073  ring r2 = 0,(x,y,z),lp;
1074  def R2 = freeAlgebra(r2, 7);
1075  R2;
1076}
1077
1078// united all previous makes, including mLR1 (homog) and mLR2 (nonhomog)
1079proc makeLetterplaceRing(int d, list #)
1080"USAGE:  makeLetterplaceRing(d [,h]); d an integer, h an optional integer (deprecated, use freeAlgebra instead)
1081RETURN:  ring
1082PURPOSE: creates a ring with the ordering, used in letterplace computations
1083NOTE: h = -1 (default) : the ordering of the current ring will be used
1084h = 0 : Dp ordering will be used
1085h = 2 : weights 1 used for all the variables, a tie breaker is a list of block of original ring
1086h = 1 : the pure homogeneous letterplace block ordering (applicable in the situation of homogeneous input ideals) will be used.
1087EXAMPLE: example makeLetterplaceRing; shows examples
1088"
1089{
1090  int alternativeVersion = -1;
1091  if ( size(#)>0 )
1092  {
1093    if (typeof(#[1]) == "int")
1094    {
1095      alternativeVersion = #[1];
1096    }
1097  }
1098  if (alternativeVersion == 1)
1099  {
1100    def @A = makeLetterplaceRing1(d);
1101  }
1102  else {
1103    if (alternativeVersion == 2)
1104    {
1105      def @A = makeLetterplaceRing2(d);
1106    }
1107    else {
1108      if (alternativeVersion == 0)
1109      {
1110        def @A = makeLetterplaceRing4(d);
1111      }
1112      else {
1113        def @A = freeAlgebra(basering, d);
1114      }
1115    }
1116  }
1117  return(@A);
1118}
1119example
1120{
1121  "EXAMPLE:"; echo = 2;
1122  ring r = 0,(x,y,z),Dp;
1123  def A = makeLetterplaceRing(2); // same as  makeLetterplaceRing(2,0)
1124  setring A;  A;
1125  lpVarBlockSize(A);
1126  lpDegBound(A);  // degree bound
1127  setring r; def B = makeLetterplaceRing(2,1); // to compare:
1128  setring B;  B;
1129  lpVarBlockSize(B);
1130  lpDegBound(B);  // degree bound
1131  setring r; def C = makeLetterplaceRing(2,2); // to compare:
1132  setring C;  C;
1133  lpDegBound(C);
1134  lpDegBound(C);  // degree bound
1135}
1136
1137static proc makeLetterplaceRing1(int d)
1138"USAGE:  makeLetterplaceRing1(d); d an integer
1139RETURN:  ring
1140PURPOSE: creates a ring with a special ordering, suitable for
1141@* the use of homogeneous letterplace (d blocks of shifted original variables)
1142EXAMPLE: example makeLetterplaceRing1; shows examples
1143"
1144{
1145  // d = up to degree, will be shifted to d+1
1146  if (d<1) {"bad d"; return(0);}
1147
1148  int uptodeg = d; int lV = nvars(basering);
1149
1150  int ppl = printlevel-voice+2;
1151  string err = "";
1152
1153  int i,j,s;
1154  def save = basering;
1155  int D = d-1;
1156  list LR  = ringlist(save);
1157  list L, tmp;
1158  L[1] = LR[1]; // ground field
1159  L[4] = LR[4]; // quotient ideal
1160  tmp  = LR[2]; // varnames
1161  s = size(LR[2]);
1162  for (i=1; i<=D; i++)
1163  {
1164    for (j=1; j<=s; j++)
1165    {
1166      tmp[i*s+j] = tmp[j];
1167    }
1168  }
1169  L[2] = tmp;
1170  list OrigNames = LR[2];
1171  // ordering: d blocks of the ord on r
1172  // try to get whether the ord on r is blockord itself
1173  // TODO: make L(2) ordering! exponent is maximally 2
1174  s = size(LR[3]);
1175  if (s==2)
1176  {
1177    // not a blockord, 1 block + module ord
1178    tmp = LR[3][s]; // module ord
1179    for (i=1; i<=D; i++)
1180    {
1181      LR[3][s-1+i] = LR[3][1];
1182    }
1183    LR[3][s+D] = tmp;
1184  }
1185  if (s>2)
1186  {
1187    // there are s-1 blocks
1188    int nb = s-1;
1189    tmp = LR[3][s]; // module ord
1190    for (i=1; i<=D; i++)
1191    {
1192      for (j=1; j<=nb; j++)
1193      {
1194        LR[3][i*nb+j] = LR[3][j];
1195      }
1196    }
1197    //    size(LR[3]);
1198    LR[3][nb*(D+1)+1] = tmp;
1199  }
1200  L[3] = LR[3];
1201  attrib(L,"maxExp",1);
1202  attrib(L,"isLetterplaceRing",lV);
1203  def @R = ring(L);
1204  //  setring @R;
1205  //  int uptodeg = d; int lV = nvars(basering); // were defined before
1206  def @@R = setLetterplaceAttributes(@R,uptodeg,lV);
1207  return (@@R);
1208}
1209example
1210{
1211  "EXAMPLE:"; echo = 2;
1212  ring r = 0,(x,y,z),(dp(1),dp(2));
1213  def A = makeLetterplaceRing1(2);
1214  setring A;
1215  A;
1216  lpVarBlockSize(A);// number of variables in the main block
1217  lpDegBound(A);  // degree bound
1218}
1219
1220static proc makeLetterplaceRing2(int d)
1221"USAGE:  makeLetterplaceRing2(d); d an integer
1222RETURN:  ring
1223PURPOSE: creates a ring with a special ordering, suitable for
1224@* the use of non-homogeneous letterplace
1225NOTE: the matrix for the ordering looks as follows: first row is 1,1,...,1
1226@* then there come 'd' blocks of shifted original variables
1227EXAMPLE: example makeLetterplaceRing2; shows examples
1228"
1229{
1230
1231  // ToDo future: inherit positive weights in the orig ring
1232  // complain on nonpositive ones
1233
1234  // d = up to degree, will be shifted to d+1
1235  if (d<1) {"bad d"; return(0);}
1236
1237  int uptodeg = d; int lV = nvars(basering);
1238
1239  int ppl = printlevel-voice+2;
1240  string err = "";
1241
1242  int i,j,s;
1243  def save = basering;
1244  int D = d-1;
1245  list LR  = ringlist(save);
1246  list L, tmp, tmp2, tmp3;
1247  L[1] = LR[1]; // ground field
1248  L[4] = LR[4]; // quotient ideal
1249  tmp  = LR[2]; // varnames
1250  s = size(LR[2]);
1251  for (i=1; i<=D; i++)
1252  {
1253    for (j=1; j<=s; j++)
1254    {
1255      tmp[i*s+j] =tmp[j];
1256    }
1257  }
1258  L[2] = tmp;
1259  list OrigNames = LR[2];
1260  // ordering: one 1..1 a above
1261  // ordering: d blocks of the ord on r
1262  // try to get whether the ord on r is blockord itself
1263  // TODO: make L(2) ordering! exponent is maximally 2
1264  s = size(LR[3]);
1265  if (s==2)
1266  {
1267    // not a blockord, 1 block + module ord
1268    tmp = LR[3][s]; // module ord
1269    for (i=1; i<=d; i++)
1270    {
1271      LR[3][s-1+i] = LR[3][1];
1272    }
1273    //    LR[3][s+D] = tmp;
1274    LR[3][s+1+D] = tmp;
1275    LR[3][1] = list("a",intvec(1: int(d*lV))); // deg-ord
1276  }
1277  if (s>2)
1278  {
1279    // there are s-1 blocks
1280    int nb = s-1;
1281    tmp = LR[3][s]; // module ord to place at the very end
1282    tmp2 = LR[3]; tmp2 = tmp2[1..nb];
1283    tmp3[1] = list("a",intvec(1: int(d*lV))); // deg-ord, insert as the 1st
1284    for (i=1; i<=d; i++)
1285    {
1286      tmp3 = tmp3 + tmp2;
1287    }
1288    tmp3 = tmp3 + list(tmp);
1289    LR[3] = tmp3;
1290//     for (i=1; i<=d; i++)
1291//     {
1292//       for (j=1; j<=nb; j++)
1293//       {
1294//         //        LR[3][i*nb+j+1]= LR[3][j];
1295//         LR[3][i*nb+j+1]= tmp2[j];
1296//       }
1297//     }
1298//     //    size(LR[3]);
1299//     LR[3][(s-1)*d+2] = tmp;
1300//     LR[3] = list("a",intvec(1: int(d*lV))) + LR[3]; // deg-ord, insert as the 1st
1301    // remove everything behind nb*(D+1)+1 ?
1302    //    tmp = LR[3];
1303    //    LR[3] = tmp[1..size(tmp)-1];
1304  }
1305  L[3] = LR[3];
1306  attrib(L,"maxExp",1);
1307  attrib(L,"isLetterplaceRing",lV);
1308  def @R = ring(L);
1309  //  setring @R;
1310  //  int uptodeg = d; int lV = nvars(basering); // were defined before
1311  def @@R = setLetterplaceAttributes(@R,uptodeg,lV);
1312  return (@@R);
1313}
1314example
1315{
1316  "EXAMPLE:"; echo = 2;
1317  ring r = 0,(x,y,z),(dp(1),dp(2));
1318  def A = makeLetterplaceRing2(2);
1319  setring A;
1320  A;
1321  lpVarBlockSize(A); // number of variables in the main block
1322  lpDegBound(A);  // degree bound
1323}
1324
1325static proc makeLetterplaceRing4(int d)
1326"USAGE:  makeLetterplaceRing4(d); d an integer
1327RETURN:  ring
1328PURPOSE: creates a Letterplace ring with a Dp ordering, suitable for
1329@* the use of non-homogeneous letterplace
1330NOTE: the matrix for the ordering looks as follows: first row is 1,1,...,1
1331EXAMPLE: example makeLetterplaceRing4; shows examples
1332"
1333{
1334
1335  // ToDo future: inherit positive weights in the orig ring
1336  // complain on nonpositive ones
1337
1338  // d = up to degree, will be shifted to d+1
1339  if (d<1) {"bad d"; return(0);}
1340
1341  int uptodeg = d; int lV = nvars(basering);
1342
1343  int ppl = printlevel-voice+2;
1344  string err = "";
1345
1346  int i,j,s;
1347  def save = basering;
1348  int D = d-1;
1349  list LR  = ringlist(save);
1350  list L, tmp, tmp2, tmp3;
1351  L[1] = LR[1]; // ground field
1352  L[4] = LR[4]; // quotient ideal
1353  tmp  = LR[2]; // varnames
1354  s = size(LR[2]);
1355  for (i=1; i<=D; i++)
1356  {
1357    for (j=1; j<=s; j++)
1358    {
1359      tmp[i*s+j] =tmp[j];
1360    }
1361  }
1362  L[2] = tmp;
1363  list OrigNames = LR[2];
1364
1365  s = size(LR[3]);
1366  list ordering;
1367  ordering[1] = list("Dp",intvec(1: int(d*lV)));
1368  ordering[2] = LR[3][s]; // module ord to place at the very end
1369  LR[3] = ordering;
1370
1371  L[3] = LR[3];
1372  attrib(L,"maxExp",1);
1373  attrib(L,"isLetterplaceRing",lV);
1374  def @R = ring(L);
1375  def @@R = setLetterplaceAttributes(@R,uptodeg,lV);
1376  return (@@R);
1377}
1378example
1379{
1380  "EXAMPLE:"; echo = 2;
1381  ring r = 0,(x,y,z),(dp(1),dp(2));
1382  def A = makeLetterplaceRing4(2);
1383  setring A;
1384  A;
1385  lpVarBlockSize(A); // number of variables in the main block
1386  lpDegBound(A);  // degree bound
1387}
1388
1389// P[s;sigma] approach
1390static proc makeLetterplaceRing3(int d)
1391"USAGE:  makeLetterplaceRing3(d); d an integer
1392RETURN:  ring
1393PURPOSE: creates a ring with a special ordering, representing
1394@* the original P[s,sigma] (adds d blocks of shifted s)
1395ASSUME: basering is a letterplace ring
1396NOTE: experimental status
1397EXAMPLE: example makeLetterplaceRing3; shows examples
1398"
1399{
1400  // d = up to degree, will be shifted to d+1
1401  if (d<1) {"bad d"; return(0);}
1402
1403  int uptodeg = d; int lV = nvars(basering);
1404
1405  int ppl = printlevel-voice+2;
1406  string err = "";
1407
1408  int i,j,s;
1409  def save = basering;
1410  int D = d-1;
1411  list LR  = ringlist(save);
1412  list L, tmp;
1413  L[1] = LR[1]; // ground field
1414  L[4] = LR[4]; // quotient ideal
1415  tmp  = LR[2]; // varnames
1416  tmp[size(tmp)+1] = "s";
1417  // add s's
1418  //  string newSname = "@s";
1419  s = size(LR[2]);
1420  for (i=1; i<=D; i++)
1421  {
1422    for (j=1; j<=s; j++)
1423    {
1424      tmp[i*s+j] = tmp[j];
1425    }
1426  }
1427  // the final index is D*s+s = (D+1)*s = degBound*s
1428  L[2] = tmp;
1429  list OrigNames = LR[2];
1430  // ordering: d blocks of the MODIFIED ord on r
1431  // try to get whether the ord on r is blockord itself
1432  // TODO: make L(2) ordering! exponent is maximally 2
1433  s = size(LR[3]);
1434
1435  // assume: basering was a letterplace, so get its block
1436  tmp = LR[3][1]; // ASSUME: it's a nice block
1437  // modify it
1438  // add (0,..,0,1) ... as antiblock part
1439  intvec iv; list ttmp, tmp1;
1440  for (i=1; i<=d; i++)
1441  {
1442    // the position to hold 1:
1443    iv = intvec( gen( i*(lV+1)-1 ) );
1444    ttmp[1] = "a";
1445    ttmp[2] = iv;
1446    tmp1[i] = ttmp;
1447  }
1448  // finished: antiblock part //TOCONTINUE
1449
1450  if (s==2)
1451  {
1452    // not a blockord, 1 block + module ord
1453    tmp = LR[3][s]; // module ord
1454    for (i=1; i<=D; i++)
1455    {
1456      LR[3][s-1+i] = LR[3][1];
1457    }
1458    LR[3][s+D] = tmp;
1459  }
1460  if (s>2)
1461  {
1462    // there are s-1 blocks
1463    int nb = s-1;
1464    tmp = LR[3][s]; // module ord
1465    for (i=1; i<=D; i++)
1466    {
1467      for (j=1; j<=nb; j++)
1468      {
1469        LR[3][i*nb+j] = LR[3][j];
1470      }
1471    }
1472    //    size(LR[3]);
1473    LR[3][nb*(D+1)+1] = tmp;
1474  }
1475  L[3] = LR[3];
1476  attrib(L,"maxExp",1);
1477  attrib(L,"isLetterplaceRing",lV);
1478  def @R = ring(L);
1479  //  setring @R;
1480  //  int uptodeg = d; int lV = nvars(basering); // were defined before
1481  def @@R = setLetterplaceAttributes(@R,uptodeg,lV);
1482  return (@@R);
1483}
1484example
1485{
1486  "EXAMPLE:"; echo = 2;
1487  ring r = 0,(x,y,z),(dp(1),dp(2));
1488  def A = makeLetterplaceRing3(2);
1489  setring A;
1490  A;
1491  lpVarBlockSize(A); // number of variables in the main block
1492  lpDegBound(A);  // degree bound
1493}
1494
1495/* EXAMPLES:
1496
1497//static proc ex_shift()
1498{
1499  LIB "freegb.lib";
1500  ring r = 0,(x,y,z),(dp(1),dp(2));
1501  module M = [-1,x,y],[-7,y,y],[3,x,x];
1502  module N = [1,x,y,x],[-1,y,x,y];
1503  list L; L[1] = M; L[2] = N;
1504  lst2str(L);
1505  def U = crs(L,5);
1506  setring U; U;
1507  I;
1508  poly p = I[2]; // I[8];
1509  p;
1510  stest(p,7,7,3); // error -> the world is ok
1511  poly q1 = stest(p,1,7,3); //ok
1512  poly q6 = stest(p,6,7,3); //ok
1513  btest(p,3); //ok
1514  btest(q1,3); //ok
1515  btest(q6,3); //ok
1516}
1517
1518//static proc test_shrink()
1519{
1520  LIB "freegb.lib";
1521  ring r =0,(x,y,z),dp;
1522  int d = 5;
1523  def R = freeAlgebra(r, d);
1524  setring R;
1525  poly p1 = x(1)*y(2)*z(3);
1526  poly p2 = x(1)*y(4)*z(5);
1527  poly p3 = x(1)*y(1)*z(3);
1528  poly p4 = x(1)*y(2)*z(2);
1529  poly p5 = x(3)*z(5);
1530  poly p6 = x(1)*y(1)*x(3)*z(5);
1531  poly p7 = x(1)*y(2)*x(3)*y(4)*z(5);
1532  poly p8 = p1+p2+p3+p4+p5 + p6 + p7;
1533  p1; system("shrinktest",p1,3);
1534  p2; system("shrinktest",p2,3);
1535  p3; system("shrinktest",p3,3);
1536  p4; system("shrinktest",p4,3);
1537  p5; system("shrinktest",p5,3);
1538  p6; system("shrinktest",p6,3);
1539  p7; system("shrinktest",p7,3);
1540  p8; system("shrinktest",p8,3);
1541  poly p9 = p1 + 2*p2 + 5*p5 + 7*p7;
1542  p9; system("shrinktest",p9,3);
1543}
1544
1545//static proc ex2()
1546{
1547  option(prot);
1548  LIB "freegb.lib";
1549  ring r = 0,(x,y),dp;
1550  module M = [-1,x,y],[3,x,x]; // 3x^2 - xy
1551  def U = freegb(M,7);
1552  lst2str(U);
1553}
1554
1555//static proc ex_nonhomog()
1556{
1557  option(prot);
1558  LIB "freegb.lib";
1559  ring r = 0,(x,y,h),dp;
1560  list L;
1561  module M;
1562  M = [-1,y,y],[1,x,x,x];  // x3-y2
1563  L[1] = M;
1564  M = [1,x,h],[-1,h,x];  // xh-hx
1565  L[2] = M;
1566  M = [1,y,h],[-1,h,y];  // yh-hy
1567  L[3] = M;
1568  def U = freegb(L,4);
1569  lst2str(U);
1570  // strange elements in the basis
1571}
1572
1573//static proc ex_nonhomog_comm()
1574{
1575  option(prot);
1576  LIB "freegb.lib";
1577  ring r = 0,(x,y),dp;
1578  module M = [-1,y,y],[1,x,x,x];
1579  def U = freegb(M,5);
1580  lst2str(U);
1581}
1582
1583//static proc ex_nonhomog_h()
1584{
1585  option(prot);
1586  LIB "freegb.lib";
1587  ring r = 0,(x,y,h),(a(1,1),dp);
1588  module M = [-1,y,y,h],[1,x,x,x]; // x3 - y2h
1589  def U = freegb(M,6);
1590  lst2str(U);
1591}
1592
1593//static proc ex_nonhomog_h2()
1594{
1595  option(prot);
1596  LIB "freegb.lib";
1597  ring r = 0,(x,y,h),(dp);
1598  list L;
1599  module M;
1600  M = [-1,y,y,h],[1,x,x,x]; // x3 - y2h
1601  L[1] = M;
1602  M = [1,x,h],[-1,h,x]; // xh - hx
1603  L[2] = M;
1604  M = [1,y,h],[-1,h,y]; // yh - hy
1605  L[3] = M;
1606  def U = freeGBasis(L,3);
1607  lst2str(U);
1608  // strange answer CHECK
1609}
1610
1611//static proc ex_nonhomog_3()
1612{
1613  option(prot);
1614  LIB "./freegb.lib";
1615  ring r = 0,(x,y,z),(dp);
1616  list L;
1617  module M;
1618  M = [1,z,y],[-1,x]; // zy - x
1619  L[1] = M;
1620  M = [1,z,x],[-1,y]; // zx - y
1621  L[2] = M;
1622  M = [1,y,x],[-1,z]; // yx - z
1623  L[3] = M;
1624  lst2str(L);
1625  list U = freegb(L,4);
1626  lst2str(U);
1627  // strange answer CHECK
1628}
1629
1630//static proc ex_densep_2()
1631{
1632  option(prot);
1633  LIB "freegb.lib";
1634  ring r = (0,a,b,c),(x,y),(Dp); // deglex
1635  module M = [1,x,x], [a,x,y], [b,y,x], [c,y,y];
1636  lst2str(M);
1637  list U = freegb(M,5);
1638  lst2str(U);
1639  // a=b is important -> finite basis!!!
1640  module M = [1,x,x], [a,x,y], [a,y,x], [c,y,y];
1641  lst2str(M);
1642  list U = freegb(M,5);
1643  lst2str(U);
1644}
1645
1646// END COMMENTED EXAMPLES
1647
1648*/
1649
1650// 1. form a new ring
1651// 2. produce shifted generators
1652// 3. compute GB
1653// 4. skip shifted elts
1654// 5. go back to orig vars, produce strings/modules
1655// 6. return the result
1656
1657static proc freegbold(list LM, int d)
1658"USAGE:  freegbold(L, d);  L a list of modules, d an integer
1659RETURN:  ring
1660PURPOSE: compute the two-sided Groebner basis of an ideal, encoded by L in
1661the free associative algebra, up to degree d
1662EXAMPLE: example freegbold; shows examples
1663"
1664{
1665  // d = up to degree, will be shifted to d+1
1666  if (d<1) {"bad d"; return(0);}
1667
1668  int ppl = printlevel-voice+2;
1669  string err = "";
1670
1671  int i,j,s;
1672  def save = basering;
1673  // determine max no of places in the input
1674  int slm = size(LM); // numbers of polys in the ideal
1675  int sm;
1676  intvec iv;
1677  module M;
1678  for (i=1; i<=slm; i++)
1679  {
1680    // modules, e.g. free polynomials
1681    M  = LM[i];
1682    sm = ncols(M);
1683    for (j=1; j<=sm; j++)
1684    {
1685      //vectors, e.g. free monomials
1686      iv = iv, size(M[j])-1; // 1 place is reserved by the coeff
1687    }
1688  }
1689  int D = Max(iv); // max size of input words
1690  if (d<D) {"bad d"; return(LM);}
1691  D = D + d-1;
1692  //  D = d;
1693  list LR  = ringlist(save);
1694  list L, tmp;
1695  L[1] = LR[1]; // ground field
1696  L[4] = LR[4]; // quotient ideal
1697  tmp  = LR[2]; // varnames
1698  s = size(LR[2]);
1699  for (i=1; i<=D; i++)
1700  {
1701    for (j=1; j<=s; j++)
1702    {
1703      tmp[i*s+j] = tmp[j];
1704    }
1705  }
1706  L[2] = tmp;
1707  list OrigNames = LR[2];
1708  // ordering: d blocks of the ord on r
1709  // try to get whether the ord on r is blockord itself
1710  // TODO: make L(2) ordering! exponent is maximally 2
1711  s = size(LR[3]);
1712  if (s==2)
1713  {
1714    // not a blockord, 1 block + module ord
1715    tmp = LR[3][s]; // module ord
1716    for (i=1; i<=D; i++)
1717    {
1718      LR[3][s-1+i] = LR[3][1];
1719    }
1720    LR[3][s+D] = tmp;
1721  }
1722  if (s>2)
1723  {
1724    // there are s-1 blocks
1725    int nb = s-1;
1726    tmp = LR[3][s]; // module ord
1727    for (i=1; i<=D; i++)
1728    {
1729      for (j=1; j<=nb; j++)
1730      {
1731        LR[3][i*nb+j] = LR[3][j];
1732      }
1733    }
1734    //    size(LR[3]);
1735    LR[3][nb*(D+1)+1] = tmp;
1736  }
1737  L[3] = LR[3];
1738  attrib(L,"maxExp",1);
1739  attrib(L,"isLetterplaceRing",s);
1740  def @R = ring(L);
1741  setring @R;
1742  ideal I;
1743  poly @p;
1744  s = size(OrigNames);
1745  //  "s:";s;
1746  // convert LM to canonical vectors (no powers)
1747  setring save;
1748  kill M; // M was defined earlier
1749  module M;
1750  slm = size(LM); // numbers of polys in the ideal
1751  int sv,k,l;
1752  vector v;
1753  //  poly p;
1754  string sp;
1755  setring @R;
1756  poly @@p=0;
1757  setring save;
1758  for (l=1; l<=slm; l++)
1759  {
1760    // modules, e.g. free polynomials
1761    M  = LM[l];
1762    sm = ncols(M); // in intvec iv the sizes are stored
1763    for (i=0; i<=d-iv[l]; i++)
1764    {
1765      // modules, e.g. free polynomials
1766      for (j=1; j<=sm; j++)
1767      {
1768        //vectors, e.g. free monomials
1769        v  = M[j];
1770        sv = size(v);
1771        //        "sv:";sv;
1772        sp = "@@p = @@p + ";
1773        for (k=2; k<=sv; k++)
1774        {
1775          sp = sp + string(v[k])+")*";
1776        }
1777        sp = sp + string(v[1])+";"; // coef;
1778        setring @R;
1779        execute(sp);
1780        setring save;
1781      }
1782      setring @R;
1783      //      "@@p:"; @@p;
1784      I = I,@@p;
1785      @@p = 0;
1786      setring save;
1787    }
1788  }
1789  kill sp;
1790  // 3. compute GB
1791  setring @R;
1792  dbprint(ppl,"computing GB");
1793  //  ideal J = groebner(I);
1794  ideal J = slimgb(I);
1795  dbprint(ppl,J);
1796  // 4. skip shifted elts
1797  ideal K = select1(J,1..s); // s = size(OrigNames)
1798  dbprint(ppl,K);
1799  dbprint(ppl, "done with GB");
1800  // K contains vars x(1),...z(1) = images of originals
1801  // 5. go back to orig vars, produce strings/modules
1802  if (K[1] == 0)
1803  {
1804    "no reasonable output, GB gives 0";
1805    return(0);
1806  }
1807  int sk = size(K);
1808  int sp, sx, a, b;
1809  intvec x;
1810  poly p,q;
1811  poly pn;
1812  // vars in 'save'
1813  setring save;
1814  module N;
1815  list LN;
1816  vector V;
1817  poly pn;
1818  // test and skip exponents >=2
1819  setring @R;
1820  for(i=1; i<=sk; i++)
1821  {
1822    p  = K[i];
1823    while (p!=0)
1824    {
1825      q  = lead(p);
1826      //      "processing q:";q;
1827      x  = leadexp(q);
1828      sx = size(x);
1829      for(k=1; k<=sx; k++)
1830      {
1831        if ( x[k] >= 2 )
1832        {
1833          err = "skip: the value x[k] is " + string(x[k]);
1834          dbprint(ppl,err);
1835          //            return(0);
1836          K[i] = 0;
1837          p    = 0;
1838          q    = 0;
1839          break;
1840        }
1841      }
1842      p  = p - q;
1843    }
1844  }
1845  K  = simplify(K,2);
1846  sk = size(K);
1847  for(i=1; i<=sk; i++)
1848  {
1849    //    setring save;
1850    //    V  = 0;
1851    setring @R;
1852    p  = K[i];
1853    while (p!=0)
1854    {
1855      q  = lead(p);
1856      err =  "processing q:" + string(q);
1857      dbprint(ppl,err);
1858      x  = leadexp(q);
1859      sx = size(x);
1860      pn = leadcoef(q);
1861      setring save;
1862      pn = imap(@R,pn);
1863      V  = V + leadcoef(pn)*gen(1);
1864      for(k=1; k<=sx; k++)
1865      {
1866        if (x[k] ==1)
1867        {
1868          a = k div s; // block number=a+1, a!=0
1869          b = k % s; // remainder
1870          //          printf("a: %s, b: %s",a,b);
1871          if (b == 0)
1872          {
1873            // that is it's the last var in the block
1874            b = s;
1875            a = a-1;
1876          }
1877          V = V + var(b)*gen(a+2);
1878        }
1879//         else
1880//         {
1881//           printf("error: the value x[k] is %s", x[k]);
1882//           return(0);
1883//         }
1884      }
1885      err = "V: " + string(V);
1886      dbprint(ppl,err);
1887      //      printf("V: %s", string(V));
1888      N = N,V;
1889      V  = 0;
1890      setring @R;
1891      p  = p - q;
1892      pn = 0;
1893    }
1894    setring save;
1895    LN[i] = simplify(N,2);
1896    N     = 0;
1897  }
1898  setring save;
1899  return(LN);
1900}
1901example
1902{
1903  "EXAMPLE:"; echo = 2;
1904  ring r = 0,(x,y,z),(dp(1),dp(2));
1905  module M = [-1,x,y],[-7,y,y],[3,x,x];
1906  module N = [1,x,y,x],[-1,y,x,y];
1907  list L; L[1] = M; L[2] = N;
1908  lst2str(L);
1909  def U = freegbold(L,5);
1910  lst2str(U);
1911}
1912
1913/* begin older procs and tests
1914
1915static proc exHom1()
1916{
1917  // we start with
1918  // z*y - x, z*x - y, y*x - z
1919  LIB "freegb.lib";
1920  LIB "elim.lib";
1921  ring r = 0,(x,y,z,h),dp;
1922  list L;
1923  module M;
1924  M = [1,z,y],[-1,x,h]; // zy - xh
1925  L[1] = M;
1926  M = [1,z,x],[-1,y,h]; // zx - yh
1927  L[2] = M;
1928  M = [1,y,x],[-1,z,h]; // yx - zh
1929  L[3] = M;
1930  lst2str(L);
1931  def U = crs(L,4);
1932  setring U;
1933  I = I,
1934    y(2)*h(3)+z(2)*x(3),     y(3)*h(4)+z(3)*x(4),
1935    y(2)*x(3)-z(2)*h(3),     y(3)*x(4)-z(3)*h(4);
1936  I = simplify(I,2);
1937  ring r2 = 0,(x(0..4),y(0..4),z(0..4),h(0..4)),dp;
1938  ideal J = imap(U,I);
1939  //  ideal K = homog(J,h);
1940  option(redSB);
1941  option(redTail);
1942  ideal L = groebner(J); //(K);
1943  ideal LL = sat(L,ideal(h))[1];
1944  ideal M = subst(LL,h,1);
1945  M = simplify(M,2);
1946  setring U;
1947  ideal M = imap(r2,M);
1948  lst2str(U);
1949}
1950
1951static proc test1()
1952{
1953  LIB "freegb.lib";
1954  ring r = 0,(x,y),Dp;
1955  int d = 10; // degree
1956  def R = freeAlgebra(r, d);
1957  setring R;
1958  ideal I = x(1)*x(2) - y(1)*y(2);
1959  option(prot);
1960  option(teach);
1961  ideal J = system("freegb",I,d,2);
1962  J;
1963}
1964
1965static proc test2()
1966{
1967  LIB "freegb.lib";
1968  ring r = 0,(x,y),Dp;
1969  int d = 10; // degree
1970  def R = freeAlgebra(r, d);
1971  setring R;
1972  ideal I = x(1)*x(2) - x(1)*y(2);
1973  option(prot);
1974  option(teach);
1975  ideal J = system("freegb",I,d,2);
1976  J;
1977}
1978
1979static proc test3()
1980{
1981  LIB "freegb.lib";
1982  ring r = 0,(x,y,z),dp;
1983  int d =5; // degree
1984  def R = freeAlgebra(r, d);
1985  setring R;
1986  ideal I = x(1)*y(2), y(1)*x(2)+z(1)*z(2);
1987  option(prot);
1988  option(teach);
1989  ideal J = system("freegb",I,d,3);
1990}
1991
1992end older procs and tests */
1993
1994static proc stringpoly2lplace(string s)
1995{
1996  // decomposes sentence into terms
1997  s = replace(s,newline,""); // get rid of newlines
1998  s = replace(s," ",""); // get rid of empties
1999  //arith symbols: +,-
2000  // decompose into words with coeffs
2001  list LS;
2002  int i,j,ie,je,k,cnt;
2003  // s[1]="-" situation
2004  if (s[1]=="-")
2005  {
2006    LS = stringpoly2lplace(string(s[2..size(s)]));
2007    LS[1] = string("-"+string(LS[1]));
2008    return(LS);
2009  }
2010  i = find(s,"-",2);
2011  // i==1 might happen if the 1st symbol coeff is negative
2012  j = find(s,"+");
2013  list LL;
2014  if (i==j)
2015  {
2016    "return a monomial";
2017    // that is both are 0 -> s is a monomial
2018    LS[1] = s;
2019    return(LS);
2020  }
2021  if (i==0)
2022  {
2023    "i==0 situation";
2024    // no minuses at all => pluses only
2025    cnt++;
2026    LS[cnt] = string(s[1..j-1]);
2027    s = s[j+1..size(s)];
2028    while (s!= "")
2029    {
2030      j = find(s,"+");
2031      cnt++;
2032      if (j==0)
2033      {
2034        LS[cnt] = string(s);
2035        s = "";
2036      }
2037      else
2038      {
2039        LS[cnt] = string(s[1..j-1]);
2040        s = s[j+1..size(s)];
2041      }
2042    }
2043    return(LS);
2044  }
2045  if (j==0)
2046  {
2047    "j==0 situation";
2048    // no pluses at all except the lead coef => the rest are minuses only
2049    cnt++;
2050    LS[cnt] = string(s[1..i-1]);
2051    s = s[i..size(s)];
2052    while (s!= "")
2053    {
2054      i = find(s,"-",2);
2055      cnt++;
2056      if (i==0)
2057      {
2058        LS[cnt] = string(s);
2059        s = "";
2060      }
2061      else
2062      {
2063        LS[cnt] = string(s[1..i-1]);
2064        s = s[i..size(s)];
2065      }
2066    }
2067    return(LS);
2068  }
2069  // now i, j are nonzero
2070  if (i>j)
2071  {
2072    "i>j situation";
2073    // + comes first, at place j
2074    cnt++;
2075    //    "cnt:"; cnt; "j:"; j;
2076    LS[cnt] = string(s[1..j-1]);
2077    s = s[j+1..size(s)];
2078    LL = stringpoly2lplace(s);
2079    LS = LS + LL;
2080    kill LL;
2081    return(LS);
2082  }
2083  else
2084  {
2085    "j>i situation";
2086    // - might come first, at place i
2087    if (i>1)
2088    {
2089      cnt++;
2090      LS[cnt] = string(s[1..i-1]);
2091      s = s[i..size(s)];
2092    }
2093    else
2094    {
2095      // i==1->  minus at leadcoef
2096      ie = find(s,"-",i+1);
2097      je = find(s,"+",i+1);
2098      if (je == ie)
2099      {
2100         "ie=je situation";
2101        //monomial
2102        cnt++;
2103        LS[cnt] = s;
2104        return(LS);
2105      }
2106      if (je < ie)
2107      {
2108         "je<ie situation";
2109        // + comes first
2110        cnt++;
2111        LS[cnt] = s[1..je-1];
2112        s = s[je+1..size(s)];
2113      }
2114      else
2115      {
2116        // ie < je
2117         "ie<je situation";
2118        cnt++;
2119        LS[cnt] = s[1..ie-1];
2120        s = s[ie..size(s)];
2121      }
2122    }
2123    "going into recursion with "+s;
2124    LL = stringpoly2lplace(s);
2125    LS = LS + LL;
2126    return(LS);
2127  }
2128}
2129example
2130{
2131  "EXAMPLE:"; echo = 2;
2132  string s = "x*y+y*z+z*t"; // + only
2133  stringpoly2lplace(s);
2134  string s2 = "x*y - y*z-z*t*w*w"; // +1, - only
2135  stringpoly2lplace(s2);
2136  string s3 = "-x*y + y - 2*x +7*w*w*w";
2137  stringpoly2lplace(s3);
2138}
2139
2140static proc addplaces(list L)
2141{
2142  // adds places to the list of strings
2143  // according to their order in the list
2144  int s = size(L);
2145  int i;
2146  for (i=1; i<=s; i++)
2147  {
2148    if (typeof(L[i]) == "string")
2149    {
2150      L[i] = L[i] + "(" + string(i) + ")";
2151    }
2152    else
2153    {
2154      ERROR("entry of type string expected");
2155      return(0);
2156    }
2157  }
2158  return(L);
2159}
2160example
2161{
2162  "EXAMPLE:"; echo = 2;
2163  string a = "f1";   string b = "f2";
2164  list L = a,b,a;
2165  addplaces(L);
2166}
2167
2168static proc sent2lplace(string s)
2169{
2170  // SENTence of words TO LetterPLACE
2171  list L =   stringpoly2lplace(s);
2172  int i; int ss = size(L);
2173  for(i=1; i<=ss; i++)
2174  {
2175    L[i] = str2lplace(L[i]);
2176  }
2177  return(L);
2178}
2179example
2180{
2181  "EXAMPLE:"; echo = 2;
2182  ring r = 0,(f2,f1),dp;
2183  string s = "f2*f1*f1 - 2*f1*f2*f1+ f1*f1*f2";
2184  sent2lplace(s);
2185}
2186
2187static proc testnumber(string s)
2188{
2189  string t;
2190  if (s[1]=="-")
2191  {
2192    // two situations: either there's a negative number
2193    t = s[2..size(s)];
2194    if (testnumber(t))
2195    {
2196      //a negative number
2197    }
2198    else
2199    {
2200      // a variable times -1
2201    }
2202    // or just a "-" for -1
2203  }
2204  t = "ring @r=(";
2205  t = t + charstr(basering)+"),";
2206  t = t + string(var(1))+",dp;";
2207  //  write(":w tstnum.tst",t);
2208  t = t+ "number @@Nn = " + s + ";"+"$";
2209  write(":w tstnum.tst",t);
2210  string runsing = system("Singular");
2211  int k;
2212  t = runsing+ " -teq <tstnum.tst >tstnum.out";
2213  k = system("sh",t);
2214  if (k!=0)
2215  {
2216    ERROR("Problems running Singular");
2217  }
2218  int i = system("sh", "grep error tstnum.out > /dev/NULL");
2219  if (i!=0)
2220  {
2221    // no error: s is a number
2222    i = 1;
2223  }
2224  k = system("sh","rm tstnum.tst tstnum.out > /dev/NULL");
2225  return(i);
2226}
2227example
2228{
2229  "EXAMPLE:"; echo = 2;
2230  ring r = (0,a),x,dp;
2231  string s = "a^2+7*a-2";
2232  testnumber(s);
2233  s = "b+a";
2234  testnumber(s);
2235}
2236
2237static proc str2lplace(string s)
2238{
2239  // converts a word (monomial) with coeff into letter-place
2240  // string: coef*var1^exp1*var2^exp2*...varN^expN
2241  s = strpower2rep(s); // expand powers
2242  if (size(s)==0) { return(0); }
2243  int i,j,k,insC;
2244  string a,b,c,d,t;
2245  // 1. get coeff
2246  i = find(s,"*");
2247  if (i==0) { return(s); }
2248  list VN;
2249  c = s[1..i-1]; // incl. the case like (-a^2+1)
2250  int tn = testnumber(c);
2251  if (tn == 0)
2252  {
2253    // failed test
2254    if (c[1]=="-")
2255    {
2256      // two situations: either there's a negative number
2257      t = c[2..size(c)];
2258      if (testnumber(t))
2259      {
2260         //a negative number
2261        // nop here
2262      }
2263      else
2264      {
2265         // a variable times -1
2266          c = "-1";
2267          j++; VN[j] = t; //string(c[2..size(c)]);
2268          insC = 1;
2269      }
2270    }
2271    else
2272    {
2273      // just a variable with coeff 1
2274          j++; VN[j] = string(c);
2275          c = "1";
2276          insC = 1;
2277    }
2278  }
2279 // get vars
2280  t = s;
2281  //  t = s[i+1..size(s)];
2282  k = size(t); //j = 0;
2283  while (k>0)
2284  {
2285    t = t[i+1..size(t)]; //next part
2286    i = find(t,"*"); // next *
2287    if (i==0)
2288    {
2289      // last monomial
2290      j++;
2291      VN[j] = t;
2292      k = size(t);
2293      break;
2294    }
2295    b = t[1..i-1];
2296    //    print(b);
2297    j++;
2298    VN[j] = b;
2299    k = size(t);
2300  }
2301  VN = addplaces(VN);
2302  VN[size(VN)+1] = string(c);
2303  return(VN);
2304}
2305example
2306{
2307  "EXAMPLE:"; echo = 2;
2308  ring r = (0,a),(f2,f1),dp;
2309  str2lplace("-2*f2^2*f1^2*f2");
2310  str2lplace("-f1*f2");
2311  str2lplace("(-a^2+7a)*f1*f2");
2312}
2313
2314static proc strpower2rep(string s)
2315{
2316  // makes x*x*x*x out of x^4 ., rep statys for repetitions
2317  // looks for "-" problem
2318  // exception: "-" as coeff
2319  string ex,t;
2320  int i,j,k;
2321
2322  i = find(s,"^"); // first ^
2323  if (i==0) { return(s); } // no ^ signs
2324
2325  if (s[1] == "-")
2326  {
2327    // either -coef or -1
2328    // got the coeff:
2329    i = find(s,"*");
2330    if (i==0)
2331    {
2332      // no *'s   => coef == -1 or s == -23
2333      i = size(s)+1;
2334    }
2335    t = string(s[2..i-1]); // without "-"
2336    if ( testnumber(t) )
2337    {
2338      // a good number
2339      t = strpower2rep(string(s[2..size(s)]));
2340      t = "-"+t;
2341      return(t);
2342    }
2343    else
2344    {
2345      // a variable
2346      t = strpower2rep(string(s[2..size(s)]));
2347      t = "-1*"+ t;
2348      return(t);
2349    }
2350  }
2351  // the case when leadcoef is a number in ()
2352  if (s[1] == "(")
2353  {
2354    i = find(s,")",2);    // must be nonzero
2355    t = s[2..i-1];
2356    if ( testnumber(t) )
2357    {
2358      // a good number
2359    }
2360    else {"strpower2rep: bad number as coef";}
2361    ex = string(s[i+2..size(s)]); // 2 because of *
2362    ex =  strpower2rep(ex);
2363    t = "("+t+")*"+ex;
2364    return(t);
2365  }
2366
2367  i = find(s,"^"); // first ^
2368  j = find(s,"*",i+1); // next * == end of ^
2369  if (j==0)
2370  {
2371    ex = s[i+1..size(s)];
2372  }
2373  else
2374  {
2375    ex = s[i+1..j-1];
2376  }
2377  execute("int @exp = " + ex + ";"); //@exp = exponent
2378  // got varname
2379  for (k=i-1; k>0; k--)
2380  {
2381    if (s[k] == "*") break;
2382  }
2383  string varn = s[k+1..i-1];
2384  //  "varn:";  varn;
2385  string pref;
2386  if (k>0)
2387  {
2388    pref = s[1..k]; // with * on the k-th place
2389  }
2390  //  "pref:";  pref;
2391  string suf;
2392  if ( (j>0) && (j+1 <= size(s)) )
2393  {
2394    suf = s[j+1..size(s)]; // without * on the 1st place
2395  }
2396  //  "suf:"; suf;
2397  string toins;
2398  for (k=1; k<=@exp; k++)
2399  {
2400    toins = toins + varn+"*";
2401  }
2402  //  "toins: ";  toins;
2403  if (size(suf) == 0)
2404  {
2405    toins = toins[1..size(toins)-1]; // get rid of trailing *
2406  }
2407  else
2408  {
2409    suf = strpower2rep(suf);
2410  }
2411  ex = pref + toins + suf;
2412  return(ex);
2413  //  return(strpower2rep(ex));
2414}
2415example
2416{
2417  "EXAMPLE:"; echo = 2;
2418  ring r = (0,a),(x,y,z,t),dp;
2419  strpower2rep("-x^4");
2420  strpower2rep("-2*x^4*y^3*z*t^2");
2421  strpower2rep("-a^2*x^4");
2422}
2423
2424
2425
2426static proc shiftPoly(poly a, int i)
2427"USAGE:  shiftPoly(p,i); p letterplace poly, i int
2428RETURN: poly
2429ASSUME: basering has letterplace ring structure
2430PURPOSE: compute the i-th shift of letterplace polynomial p
2431EXAMPLE: example shiftPoly; shows examples
2432"
2433{
2434  // shifts a monomial a by i
2435  // calls pLPshift(p,sh,uptodeg,lVblock);
2436  if (lpAssumeViolation())
2437  {
2438    ERROR("Incomplete Letterplace structure on the basering!");
2439  }
2440  return(stest(a,i));
2441}
2442example
2443{
2444  "EXAMPLE:"; echo = 2;
2445  ring r = 0,(x,y,z),dp;
2446  int uptodeg = 5; int lV = 3;
2447  def R = freeAlgebra(r, uptodeg);
2448  setring R;
2449  poly f = x*z*y - 2*z*y + 3*x;
2450  shiftPoly(f,1);
2451  shiftPoly(f,2);
2452}
2453
2454static proc lastBlock(poly p)
2455"USAGE:  lastBlock(p); p letterplace poly
2456RETURN: int
2457ASSUME: basering has letterplace ring structure
2458PURPOSE: get the number of the last block occuring in the poly
2459EXAMPLE: example lastBlock; shows examples
2460"
2461{
2462  if (lpAssumeViolation())
2463  {
2464    ERROR("Incomplete Letterplace structure on the basering!");
2465  }
2466  // calls pLastVblock(p);
2467  return(btest(p));
2468}
2469example
2470{
2471  "EXAMPLE:"; echo = 2;
2472  ring r = 0,(x,y,z),dp;
2473  int uptodeg = 5;
2474  def R = freeAlgebra(r, uptodeg);
2475  setring R;
2476  poly f = x*z*y - 2*z*y + 3*x;
2477  lastBlock(f); // should be 3
2478}
2479
2480static proc test_shift()
2481{
2482  LIB "freegb.lib";
2483  ring r = 0,(a,b),dp;
2484  int d =5;
2485  def R = freeAlgebra(r, d);
2486  setring R;
2487  int uptodeg = d;
2488  int lV = 2;
2489  def R = setLetterplaceAttributes(r,uptodeg,2); // supply R with letterplace structure
2490  setring R;
2491  poly p = mmLiebr(a,b);
2492  poly p = lieBracket(a,b);
2493}
2494
2495proc lp2lstr(ideal K, def save)
2496"USAGE:  lp2lstr(K,s); K an ideal, s a ring name
2497RETURN:  nothing (exports object @LN into the ring named s)
2498ASSUME: basering has a letterplace ring structure
2499PURPOSE: converts letterplace ideal to list of modules
2500NOTE: useful as preprocessing to 'lst2str'
2501EXAMPLE: example lp2lstr; shows examples
2502"
2503{
2504  def @R = basering;
2505  string err;
2506  int s = nvars(save);
2507  int i,j,k;
2508    // K contains vars x(1),...z(1) = images of originals
2509  // 5. go back to orig vars, produce strings/modules
2510  int sk = size(K);
2511  int sp, sx, a, b;
2512  intvec x;
2513  poly p,q;
2514  poly pn;
2515  // vars in 'save'
2516  setring save;
2517  module N;
2518  list LN;
2519  vector V;
2520  poly pn;
2521  // test and skip exponents >=2
2522  setring @R;
2523  for(i=1; i<=sk; i++)
2524  {
2525    p  = K[i];
2526    while (p!=0)
2527    {
2528      q  = lead(p);
2529      //      "processing q:";q;
2530      x  = leadexp(q);
2531      sx = size(x);
2532      for(k=1; k<=sx; k++)
2533      {
2534        if ( x[k] >= 2 )
2535        {
2536          err = "skip: the value x[k] is " + string(x[k]);
2537          dbprint(ppl,err);
2538          //            return(0);
2539          K[i] = 0;
2540          p    = 0;
2541          q    = 0;
2542          break;
2543        }
2544      }
2545      p  = p - q;
2546    }
2547  }
2548  K  = simplify(K,2);
2549  sk = size(K);
2550  for(i=1; i<=sk; i++)
2551  {
2552    //    setring save;
2553    //    V  = 0;
2554    setring @R;
2555    p  = K[i];
2556    while (p!=0)
2557    {
2558      q  = lead(p);
2559      err =  "processing q:" + string(q);
2560      dbprint(ppl,err);
2561      x  = leadexp(q);
2562      sx = size(x);
2563      pn = leadcoef(q);
2564      setring save;
2565      pn = imap(@R,pn);
2566      V  = V + leadcoef(pn)*gen(1);
2567      for(k=1; k<=sx; k++)
2568      {
2569        if (x[k] ==1)
2570        {
2571          a = k div s; // block number=a+1, a!=0
2572          b = k % s; // remainder
2573          //          printf("a: %s, b: %s",a,b);
2574          if (b == 0)
2575          {
2576            // that is it's the last var in the block
2577            b = s;
2578            a = a-1;
2579          }
2580          V = V + var(b)*gen(a+2);
2581        }
2582      }
2583      err = "V: " + string(V);
2584      dbprint(ppl,err);
2585      //      printf("V: %s", string(V));
2586      N = N,V;
2587      V  = 0;
2588      setring @R;
2589      p  = p - q;
2590      pn = 0;
2591    }
2592    setring save;
2593    LN[i] = simplify(N,2);
2594    N     = 0;
2595  }
2596  setring save;
2597  list @LN = LN;
2598  export @LN;
2599  //  return(LN);
2600}
2601example
2602{
2603  "EXAMPLE:"; echo = 2;
2604  intmat A[2][2] = 2, -1, -1, 2; // sl_3 == A_2
2605  ring r = 0,(f1,f2),dp;
2606  def R = freeAlgebra(r, 3);
2607  setring R;
2608  ideal I = serreRelations(A,1);
2609  lp2lstr(I,r);
2610  setring r;
2611  lst2str(@LN,1);
2612}
2613
2614static proc strList2poly(list L)
2615{
2616  //  list L comes from sent2lplace (which takes a polynomial as input)
2617  // each entry of L is a sublist with the coef on the last place
2618  int s = size(L); int t;
2619  int i,j;
2620  list M;
2621  poly p,q;
2622  string Q;
2623  for(i=1; i<=s; i++)
2624  {
2625    M = L[i];
2626    t = size(M);
2627    //    q = M[t]; // a constant
2628    Q = string(M[t]);
2629    for(j=1; j<t; j++)
2630    {
2631      //      q = q*M[j];
2632      Q = Q+"*"+string(M[j]);
2633    }
2634    execute("q="+Q+";");
2635    //    q;
2636    p = p + q;
2637  }
2638  kill Q;
2639  return(p);
2640}
2641example
2642{
2643  "EXAMPLE:"; echo = 2;
2644  ring r =0,(x,y,z,t),Dp;
2645  def A = freeAlgebra(r, 4);
2646  setring A;
2647  string t = "-2*y*z*y*z + y*t*z*z - z*x*x*y  + 2*z*y*z*y";
2648  list L = sent2lplace(t);
2649  L;
2650  poly p = strList2poly(L);
2651  p;
2652}
2653
2654static proc file2lplace(string fname)
2655"USAGE:  file2lplace(fnm);  fnm a string
2656RETURN:  ideal
2657PURPOSE: convert the contents of the file fnm into ideal of polynomials in free algebra
2658EXAMPLE: example file2lplace; shows examples
2659"
2660{
2661  // format: from the usual string to letterplace
2662  string s = read(fname);
2663  // assume: file is a comma-sep list of polys
2664  // the vars are declared before
2665  // the file ends with ";"
2666  string t; int i;
2667  ideal I;
2668  list tst;
2669  while (s!="")
2670  {
2671    i = find(s,",");
2672    "i"; i;
2673    if (i==0)
2674    {
2675      i = find(s,";");
2676      if (i==0)
2677      {
2678        // no ; ??
2679         "no colon or semicolon found anymore";
2680         return(I);
2681      }
2682      // no "," but ";" on the i-th place
2683      t = s[1..i-1];
2684      s = "";
2685      "processing: "; t;
2686      tst = sent2lplace(t);
2687      tst;
2688      I = I, strList2poly(tst);
2689      return(I);
2690    }
2691    // here i !=0
2692    t = s[1..i-1];
2693    s = s[i+1..size(s)];
2694    "processing: "; t;
2695    tst = sent2lplace(t);
2696    tst;
2697    I = I, strList2poly(tst);
2698  }
2699  return(I);
2700}
2701example
2702{
2703  "EXAMPLE:"; echo = 2;
2704  ring r =0,(x,y,z,t),dp;
2705  def A = freeAlgebra(r, 4);
2706  setring A;
2707  string fn = "myfile";
2708  string s1 = "z*y*y*y - 3*y*z*x*y  + 3*y*y*z*y - y*x*y*z,";
2709  string s2 = "-2*y*x*y*z + y*y*z*z - z*z*y*y + 2*z*y*z*y,";
2710  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;";
2711  write(":w "+fn,s1);  write(":a "+fn,s2);   write(":a "+fn,s3);
2712  read(fn);
2713  ideal I = file2lplace(fn);
2714  I;
2715}
2716
2717/* EXAMPLES AGAIN:
2718//static proc get_ls3nilp()
2719{
2720//first app of file2lplace
2721  ring r =0,(x,y,z,t),dp;
2722  int d = 10;
2723  def A = freeAlgebra(r, d);
2724  setring A;
2725  ideal I = file2lplace("./ls3nilp.bg");
2726  // and now test the correctness: go back from lplace to strings
2727  lp2lstr(I,r);
2728  setring r;
2729  lst2str(@LN,1); // agree!
2730}
2731
2732*/
2733
2734// static proc lpMultX(poly f, poly g)
2735// {
2736//   /* multiplies two polys in a very general setting correctly */
2737//   /* alternative to lpMult, possibly better at non-positive orderings */
2738//
2739//   if (lpAssumeViolation())
2740//   {
2741//     ERROR("Incomplete Letterplace structure on the basering!");
2742//   }
2743//   // decompose f,g into graded pieces with inForm: need dmodapp.lib
2744//   int b = attrib(basering,"isLetterplaceRing");  // the length of the block
2745//   intvec w; // inherit the graded on the oridinal ring
2746//   int i;
2747//   for(i=1; i<=b; i++)
2748//   {
2749//     w[i] = deg(var(i));
2750//   }
2751//   intvec v = w;
2752//   for(i=1; i< lpDegBound(basering); i++)
2753//   {
2754//     v = v,w;
2755//   }
2756//   w = v;
2757//   poly p,q,s, result;
2758//   s = g;
2759//   while (f!=0)
2760//   {
2761//     p = inForm(f,w)[1];
2762//     f = f - p;
2763//     s = g;
2764//     while (s!=0)
2765//     {
2766//       q = inForm(s,w)[1];
2767//       s = s - q;
2768//       result = result + lpMult(p,q);
2769//     }
2770//   }
2771//   // shrinking
2772//   //  result;
2773//   return( system("shrinktest",result,attrib(basering, "isLetterplaceRing")) );
2774// }
2775// example
2776// {
2777//   "EXAMPLE:"; echo = 2;
2778//   // define a ring in letterplace form as follows:
2779//   ring r = 0,(x(1),y(1),x(2),y(2),x(3),y(3),x(4),y(4)),dp;
2780//   def R = setLetterplaceAttributes(r,4,2); // supply R with letterplace structure
2781//   setring R;
2782//   poly a = x(1)*y(2)+x(1)+y(1); poly b = y(1)+3;
2783//   lpMultX(b,a);
2784//   lpMultX(a,b);
2785// }
2786//
2787// // multiply two letterplace polynomials, lpMult: done
2788// // reduction/ Normalform? needs kernel stuff
2789//
2790//
2791// proc lpMult(poly f, poly g)
2792// "USAGE:  lpMult(f,g); f,g letterplace polynomials
2793// RETURN:  poly
2794// ASSUME: basering has a letterplace ring structure
2795// PURPOSE: compute the letterplace form of f*g
2796// EXAMPLE: example lpMult; shows examples
2797// "
2798// {
2799//
2800//   // changelog:
2801//   // VL oct 2010: deg -> deg(_,w) for the length
2802//   // shrink the result => don't need to decompose polys
2803//   // since the shift is big enough
2804//
2805//   // indeed it's better to have that
2806//   // ASSUME: both f and g are quasi-homogeneous
2807//
2808//   if (lpAssumeViolation())
2809//   {
2810//     ERROR("Incomplete Letterplace structure on the basering!");
2811//   }
2812//   intvec w = 1:nvars(basering);
2813//   int sf = deg(f,w); // VL Oct 2010: we need rather length than degree
2814//   int sg = deg(g,w); // esp. in the case of weighted ordering
2815//   int uptodeg = attrib(basering, "uptodeg");
2816//   if (sf+sg > uptodeg)
2817//   {
2818//     ERROR("degree bound violated by the product!");
2819//   }
2820//   //  if (sf>1) { sf = sf -1; }
2821//   poly v = f*shiftPoly(g,sf);
2822//   // bug, reported by Simon King: in nonhomog case [solved]
2823//   // we need to shrink
2824//   return( system("shrinktest",v,attrib(basering, "isLetterplaceRing")) );
2825// }
2826// example
2827// {
2828//   "EXAMPLE:"; echo = 2;
2829//   // define a ring in letterplace form as follows:
2830//   ring r = 0,(x(1),y(1),x(2),y(2),x(3),y(3),x(4),y(4)),dp;
2831//   def R = setLetterplaceAttributes(r,4,2); // supply R with letterplace structure
2832//   setring R;
2833//   poly a = x(1)*y(2)+x(1)+y(1); poly b = y(1)+3;
2834//   lpMult(b,a);
2835//   lpMult(a,b);
2836// }
2837
2838static proc lpPower(poly f, int n)
2839"USAGE:  lpPower(f,n); f letterplace polynomial, int n
2840RETURN:  poly
2841ASSUME: basering has a letterplace ring structure
2842PURPOSE: compute the letterplace form of f^n
2843EXAMPLE: example lpPower; shows examples
2844"
2845{
2846  if (n<0) { ERROR("the power must be a natural number!"); }
2847  if (n==0) { return(poly(1)); }
2848  if (n==1) { return(f); }
2849  poly p = 1;
2850  for(int i = 1; i <= n; i++)
2851  {
2852    p = p*f;
2853  }
2854  return(p);
2855}
2856example
2857{
2858  "EXAMPLE:"; echo = 2;
2859  // define a ring in letterplace form as follows:
2860  ring r = 0,(x,y),dp;
2861  def R = freeAlgebra(r, 4,2); // supply R with letterplace structure
2862  setring R;
2863  poly a = x*y + y; poly b = y - 1;
2864  lpPower(a,2);
2865  lpPower(b,4);
2866}
2867
2868//Main normal form procedure for the user
2869// TODO Oct 18: replace by legacy call to the kernel function
2870proc lpNF(poly p, ideal G)
2871"USAGE: lpNF(p,G); poly p, ideal G (deprecated in favor of reduce(). will be removed soon)
2872RETURN: poly
2873PURPOSE: computation of the normal form of p with respect to G
2874ASSUME: p is a Letterplace polynomial, G is a set Letterplace polynomials,
2875being a Letterplace Groebner basis (no check for this will be done)
2876NOTE: Strategy: take the smallest monomial wrt ordering for reduction
2877-     For homogenous ideals the shift does not matter
2878-     For non-homogenous ideals the first shift will be the smallest monomial
2879EXAMPLE: example lpNF; shows examples
2880"
2881{if ((p==0) || (size(G) == 0)){return(p);}
2882 checkAssumptions(p,G);
2883 G = sort(G)[1];
2884 list L = makeDVecI(G);
2885 return(lpNormalForm2(p,G,L));
2886}
2887example
2888{
2889  "EXAMPLE:"; echo = 2;
2890  ring r = 0,(x,y),dp;
2891  def R = freeAlgebra(r, 4); setring R;
2892  ideal I = x*x + y*y - 1; // 2D sphere
2893  ideal J = letplaceGBasis(I); // compute a Letterplace Groebner basis
2894  J; // it is finite and nice
2895  poly f = lieBracket(x,y); f;
2896  lpNF(f,J);
2897  poly g = lieBracket(x,y*y); g;
2898  lpNF(g,J);
2899}
2900/* old and more complicated example
2901{
2902  "EXAMPLE:"; echo = 2;
2903ring r = 0,(x,y,z),dp;
2904int d =5; // degree
2905def R = freeAlgebra(r, d);
2906setring R;
2907ideal I = y*x*y - z*y*z, x*y*x - z*x*y, z*x*z - y*z*x, x*x*x + y*y*y + z*z*z + x*y*z;
2908ideal J = letplaceGBasis(I); // compute a Letterplace Groebner basis
2909poly p = y*x*y*z*y - y*z*z*y + z*y*z;
2910poly q = z*x*z*y*z - y*z*x*y*z;
2911lpNF(p,J);
2912lpNF(q,J);
2913}
2914*/
2915// analog of division(); but the output HAS different structure
2916proc lpDivision(poly p, ideal I)
2917"USAGE: lpDivision(p,G); poly p, ideal G
2918PURPOSE: compute a two-sided division with remainder of p wrt G; two-sided noncommutative analogue of the procedure division
2919ASSUME: G = {g1,...,gN} is a Groebner basis, the original ring of the Letterplace ring has the name 'r' and no variable is called 'tag_i' for i in 1...N
2920RETURN: list L
2921NOTE: - L[1] is NF(p,I)
2922      - L[2] is the list of expressions [i,l_(ij),r_(ij)] with \sum_(i,j) l_(ij) g_i r_(ij) = p - NF(p,I)
2923      - procedure lpGBPres2Poly, applied to L, reconstructs p
2924EXAMPLE: example lpDivision; shows examples
2925"
2926{
2927 if (p == 0 || size(I) == 0) {
2928    list L = 0;
2929    list empty;
2930    L[2] = empty;
2931    return (L);
2932  }
2933  poly pNF = lpNF(p,I);
2934  p = p - pNF;
2935
2936  // make new ring
2937  def save = basering;
2938  int norigvars = lpVarBlockSize(save);
2939  def Rtagged; def temp = save;
2940  for (int i = 1; i <= size(I); i++) {
2941     Rtagged = temp + ("tag_" + string(i));
2942     temp = Rtagged;
2943  } kill i;
2944  // currently R + "var" doesn't preserve uptodeg
2945  Rtagged = setLetterplaceAttributes(Rtagged, lpVarBlockSize(Rtagged), lpDegBound(save));
2946  setring Rtagged;
2947
2948  // restore vars
2949  poly p = imap(save, p);
2950  poly pNF = imap(save, pNF);
2951  ideal I = imap(save, I);
2952  for (int i = 1; i <= size(I); i++) {
2953    I[i] = I[i] - var(norigvars + i);
2954  } kill i;
2955
2956  list summands;
2957  list L = pNF;
2958  poly pTaggedNF = lpNF(p,I);
2959  for (int i = 1; i <= size(pTaggedNF); i++) {
2960    intvec iv = lp2iv(pTaggedNF[i]);
2961    for (int j = 1; j <= size(iv); j++) {
2962      if (iv[j] > norigvars) {
2963        intvec left;
2964        intvec right;
2965        if (j > 1) {
2966          left = iv[1..(j-1)];
2967        }
2968        if (j < size(iv)) {
2969          right = iv[(j+1)..size(iv)];
2970        }
2971        list summand = (iv[j] - norigvars), leadcoef(pTaggedNF[i])*iv2lp(left), iv2lp(right);
2972        summands = insert(summands, summand, size(summands));
2973
2974        kill left;
2975        kill right;
2976        kill summand;
2977        break;
2978      }
2979    } kill j;
2980    kill iv;
2981  } kill i;
2982
2983  L[2] = summands;
2984
2985  setring save;
2986  list L = imap(Rtagged,L);
2987  return (L);
2988}
2989example
2990{
2991  "EXAMPLE:"; echo = 2;
2992  ring r = 0,(x,y),dp;
2993  def R = freeAlgebra(r, 4); setring R;
2994  ideal I = x*x + y*y - 1; // 2D sphere
2995  ideal J = letplaceGBasis(I); // compute a Letterplace Groebner basis
2996  J; // it is finite and nice
2997  poly h = x*x*y-y*x*x+x*y;
2998  lpDivision(h,J); // what means that the NF of h wrt J is x*y
2999  h - lpNF(h,J); // and this poly has the folowing two-sided Groebner presentation:
3000  -y*J[1] + J[1]*y;
3001}
3002
3003proc lpGBPres2Poly(list L, ideal I)
3004"USAGE: lpGBPres2Poly(p,G); poly p, ideal G
3005ASSUME: L is a valid Groebner presentation like the result of lpDivision
3006RETURN: poly
3007NOTE: assembles p = \sum_(i,j) l_(ij) g_i r_(ij) + NF(p,I) = \sum_(i) L[2][i][2] I[L[2][i][1]] L[2][i][3] + L[1]
3008EXAMPLE: example lpGBPres2Poly; shows examples
3009"
3010{
3011  poly p;
3012  for (int i = 1; i <= size(L[2]); i++) {
3013    p = p + L[2][i][2] * I[L[2][i][1]] * L[2][i][3];
3014  }
3015  p = p + L[1];
3016  return (p);
3017}
3018example
3019{
3020  "EXAMPLE:"; echo = 2;
3021  ring r = 0,(x,y),dp;
3022  def R = freeAlgebra(r, 4); setring R;
3023  ideal I = x*x + y*y - 1; // 2D sphere
3024  ideal J = letplaceGBasis(I); // compute a Letterplace Groebner basis
3025  J; // it is finite and nice
3026  poly h = x*x*y-y*x*x+x*y;
3027  list L = lpDivision(h,J); // what means that the NF of h wrt J is x*y
3028  lpGBPres2Poly(L,J); // we see, that it is equal to h from above
3029}
3030
3031
3032
3033
3034//procedures to convert monomials into the DVec representation, all static
3035////////////////////////////////////////////////////////
3036
3037
3038static proc getExpVecs(ideal G)
3039"USUAGE: getExpVecs(G);
3040RETURN: list of intvecs
3041PURPOSE: convert G into a list of intvecs, corresponding to the exponent vector
3042 of the leading monomials of G
3043"
3044{int i; list L;
3045 for (i = 1; i <= size(G); i++) {L[i] = leadexp(G[i]); }
3046 return(L);
3047}
3048
3049static proc delSupZero(intvec I)
3050"USUAGE:delSupZero(I);
3051RETURN: intvec
3052PURPOSE: Deletes superfluous zero blocks of an exponent vector
3053ASSUME: Intvec is an exponent vector of a letterplace monomial contained in V'
3054"
3055{if (I==intvec(0)) {return(intvec(0));}
3056 int j,k,l;
3057 int n = lpVarBlockSize(basering); int d = lpDegBound(basering);
3058 intvec w; j = 1;
3059 while (j <= d)
3060 {w = I[1..n];
3061  if (w<>intvec(0)){break;}
3062   else {I = I[(n+1)..(n*d)]; d = d-1; j++;}
3063 }
3064 for (j = 1; j <= d; j++)
3065  {l=(j-1)*n+1; k= j*n;
3066   w = I[l..k];
3067   if (w==intvec(0)){w = I[1..(l-1)]; return(w);}//if a zero block is found there are only zero blocks left,
3068                                                 //otherwise there would be a hole in the monomial
3069                                                 // shrink should take care that this will not happen
3070  }
3071 return(I);
3072}
3073
3074static proc delSupZeroList(list L)
3075"USUAGE:delSupZeroList(L); L a list, containing intvecs
3076RETURN: list, containing intvecs
3077PURPOSE: Deletes all superfluous zero blocks for a list of exponent vectors
3078ASSUME: All intvecs are exponent vectors of letterplace monomials contained in V'
3079"
3080{int i;
3081 for (i = size(L); 0 < i; i--){L[i] = delSupZero(L[i]);}
3082 return(L);
3083}
3084
3085
3086static proc makeDVec(intvec V)
3087"USUAGE:makeDVec(V);
3088RETURN: intvec
3089PURPOSE: Converts an modified exponent vector into an Dvec
3090NOTE: Superfluos zero blocks must have been deleted befor using this procedure
3091"
3092{int i,j,k,r1,r2; intvec D;
3093 int n = lpVarBlockSize(basering);
3094 k = size(V) div n; r1 = 0; r2 = 0;
3095 for (i=1; i<= k; i++)
3096  {for (j=(1+((i-1)*n)); j <= (i*n); j++)
3097   {if (V[j]>0){r2 = j - ((i-1)*n); j = (j mod n); break;}
3098   }
3099   D[size(D)+1] = r1+r2;
3100   if (j == 0) {r1 = 0;} else{r1= n-j;}
3101  }
3102 D = D[2..size(D)];
3103 return(D);
3104}
3105
3106static proc makeDVecL(list L)
3107"USUAGE:makeDVecL(L); L, a list containing intvecs
3108RETURN: list, containing intvecs
3109ASSUME:
3110"
3111{int i; list R;
3112 for (i=1; i <= size(L); i++) {R[i] = makeDVec(L[i]);}
3113 return(R);
3114}
3115
3116static proc makeDVecI(ideal G)
3117"USUAGE:makeDVecI(G);
3118RETURN:list, containing intvecs
3119PURPOSE:computing the DVec representation for lead(G)
3120ASSUME:
3121"
3122{list L = delSupZeroList(getExpVecs(G));
3123 return(makeDVecL(L));
3124}
3125
3126
3127//procedures, which are dealing with the DVec representation, all static
3128
3129static proc dShiftDiv(intvec V, intvec W)
3130"USUAGE: dShiftDiv(V,W);
3131RETURN: a list,containing integers, or -1, if no shift of W divides V
3132PURPOSE: find all possible shifts s, such that s.W|V
3133ASSUME: V,W are DVecs of monomials contained in V'
3134"
3135{if(size(V)<size(W)){return(list(-1));}
3136
3137 int i,j,r; intvec T; list R;
3138 int n = lpVarBlockSize(basering);
3139 int k = size(V) - size(W) + 1;
3140 if (intvec(V[1..size(W)])-W == 0){R[1]=0;}
3141 for (i =2; i <=k; i++)
3142 {r = 0; kill T; intvec T;
3143  for (j =1; j <= i; j++) {r = r + V[j];}
3144  //if (i==1) {T[1] = r-(i-1)*n;} else
3145  T[1] = r-(i-1)*n; if (size(W)>1) {T[2..size(W)] = V[(i+1)..(size(W)+i-1)];}
3146  if (T-W == 0) {R[size(R)+1] = i-1;}
3147 }
3148 if (size(R)>0) {return(R);}
3149 else {return(list(-1));}
3150}
3151
3152//the first normal form procedure, if a user want not to presort the ideal, just make it not static
3153static proc lpNormalForm1(poly p, ideal G, list L)
3154"USUAGE:lpNormalForm1(p,G);
3155RETURN:poly
3156PURPOSE:computation of the normalform of p w.r.t. G
3157ASSUME: p is a Letterplace polynomial, G is a set of Letterplace polynomials
3158NOTE: Taking the first possible reduction
3159"
3160{
3161 if (deg(p) <1) {return(p);}
3162 else
3163  {
3164  int i; int s;
3165  intvec V = makeDVec(delSupZero(leadexp(p)));
3166  for (i = 1; i <= size(L); i++)
3167  {s = dShiftDiv(V, L[i])[1];
3168   if (s <> -1)
3169   {p = lpReduce(p,G[i],s);
3170    p = lpNormalForm1(p,G,L);
3171    break;
3172   }
3173  }
3174  p = p[1] + lpNormalForm1(p-p[1],G,L);
3175  return(p);
3176 }
3177}
3178
3179// VL; called from lpNF
3180static proc lpNormalForm2(poly pp, ideal G, list L)
3181"USUAGE:lpNormalForm2(p,G);
3182RETURN:poly
3183PURPOSE:computation of the normal form of p w.r.t. G
3184ASSUME: p is a Letterplace polynomial, G is a set of Letterplace polynomials
3185NOTE: Taking the first possible reduction
3186"
3187{
3188 poly one = 1;
3189 if ( (pp == 0) || (leadmonom(pp) == one) ) { return(pp); }
3190 poly p = pp; poly q;
3191 int i; int s; intvec V;
3192 while ( (p != 0) && (leadmonom(p) != one) )
3193 {
3194   //"entered while with p="; p;
3195   V = makeDVec(delSupZero(leadexp(p)));
3196   i = 0;
3197   s = -1;
3198   //"look for divisor";
3199   while ( (s == -1) && (i<size(L)) )
3200   {
3201     i = i+1;
3202     s = dShiftDiv(V, L[i])[1];
3203   }
3204 // now, out of here: either i=size(L) and s==-1 => no reduction
3205 // otherwise: i<=size(L) and s!= -1 => reduction
3206    //"out of divisor search: s="; s; "i="; i;
3207    if (s != -1)
3208    {
3209    //"start reducing with G[i]:";
3210      p = lpReduce(p,G[i],s); // lm-reduction
3211      //"reduced to p="; p;
3212    }
3213    else
3214    {
3215      // ie no lm-reduction possible; proceed with the tail reduction
3216      q = p-lead(p);
3217      p = lead(p);
3218      if (q!=0)
3219      {
3220        p = p + lpNormalForm2(q,G,L);
3221      }
3222      return(p);
3223    }
3224 }
3225 // out of while when p==0 or p == const
3226 return(p);
3227}
3228
3229proc isOrderingShiftInvariant(int withHoles)
3230"USAGE: isOrderingShiftInvariant(b); b an integer interpreted as a boolean
3231RETURN: int
3232NOTE: Tests whether the ordering of the current ring is shift invariant, which is the case, when LM(p) > LM(p') for all p and p' where p' is p shifted by any number of places.
3233@*      If withHoles != 0 even Letterplace polynomials with holes (eg. x(1)*y(4)) are considered.
3234ASSUME: - basering is a Letterplace ring.
3235"
3236{
3237  int shiftInvariant = 1;
3238
3239  int d = lpDegBound(basering);
3240
3241  ideal monomials;
3242  if (withHoles) {
3243    monomials = delete(lpMonomialsWithHoles(d-1), 1); // ignore the first element (1)
3244  } else {
3245    monomials = maxideal(1);
3246    for (int i = 2; i <= d-1; i++) {
3247      monomials = monomials, maxideal(i);
3248    } kill i;
3249  }
3250
3251  for (int i = 1; i <= size(monomials); i++) {
3252    poly monom = monomials[i];
3253    int lastblock = lastBlock(monom);
3254    for (int s = 1; s <= d - lastblock; s++) {
3255      for (int s2 = 0; s2 < s; s2++) { // paranoid, check every pair
3256        poly first = shiftPoly(monom,s2);
3257        poly second = shiftPoly(monom,s);
3258        if (!(first > second)) {
3259          if (printlevel >= voice) { // otherwise string() is always evaluated
3260            dbprint(string(first) + " <= " + string(second));
3261          }
3262          shiftInvariant = 0;
3263        }
3264        kill first; kill second;
3265      } kill s2;
3266    } kill s;
3267    kill monom; kill lastblock;
3268  } kill i;
3269
3270  return(shiftInvariant);
3271}
3272example
3273{
3274  "EXAMPLE:"; echo = 2;
3275  ring r = 0,(x,y,z),dp;
3276  def R = freeAlgebra(r, 5);
3277  setring R;
3278  isOrderingShiftInvariant(0);// should be 1
3279
3280  ring r = 0,(x,y,z),dp;
3281  def R = freeAlgebra(r, 5);
3282  list RL = ringlist(R);
3283  RL[3][1][1] = "wp";
3284  intvec weights = 1,1,1,1,1,1,1,2,3,1,1,1,1,1,1;
3285  RL[3][1][2] = weights;
3286  attrib(RL,"isLetterplaceRing",3);
3287  attrib(RL,"maxExp",1);
3288  def Rw = setLetterplaceAttributes(ring(RL),5,3);
3289  setring Rw;
3290  /* printlevel = voice + 1; */
3291  isOrderingShiftInvariant(0);
3292  isOrderingShiftInvariant(1);
3293}
3294
3295static proc lpMonomialsWithHoles(int d)
3296{
3297  if (d < 0) {
3298    ERROR("d must not be negative")
3299  }
3300
3301  ideal monomials = 1;
3302  if (d == 0) {
3303     return (monomials);
3304  }
3305
3306  int lV = lpVarBlockSize(basering); // variable count
3307  ideal prevMonomials = lpMonomialsWithHoles(d - 1);
3308
3309  for (int i = 1; i <= size(prevMonomials); i++) {
3310    /* if (deg(prevMonomials[i]) >= d - 1) { */
3311      for (int j = 1; j <= lV; j++) {
3312        poly m = prevMonomials[i];
3313        m = m * var(j + (d-1)*lV);
3314        monomials = monomials, m;
3315        kill m;
3316      } kill j;
3317    /* } */
3318  } kill i;
3319
3320  if (d > 1) {
3321    // removes the 1
3322    monomials[1] = 0;
3323    monomials = simplify(monomials,2);
3324
3325    monomials = prevMonomials, monomials;
3326  }
3327  return (monomials);
3328}
3329
3330static proc getlpCoeffs(poly q, poly p)
3331{list R; intvec cq,t,lv,rv,bla;
3332 int n = lpVarBlockSize(basering); int d = lpDegBound(basering);
3333 int i;
3334 cq = leadexp(p)-leadexp(q); /* p/q */
3335 for (i = 1; i<= d; i++)
3336 {bla = cq[((i-1)*n+1)..(i*n)];
3337  if (bla == 0) {lv = cq[1..i*n]; cq = cq[(i*n+1)..(d*n)]; break;}
3338 }
3339
3340 d = size(cq) div n;
3341 for (i = 1; i<= d; i++)
3342 {bla = cq[((i-1)*n+1)..(i*n)];
3343  if (bla <> 0){rv = cq[((i-1)*n+1)..(d*n)]; break;}
3344 }
3345 return(list(monomial(lv),monomial(rv)));
3346}
3347
3348static proc lpReduce(poly p, poly g, int s)
3349"NOTE: shift can not exceed the degree bound, because s*g | p
3350"
3351{poly l,r,qt; int i;
3352 list K = getlpCoeffs(lead(shiftPoly(g,s)), lead(p));
3353 l = K[1]; r = K[2];
3354 kill K;
3355 for (i = 1; i <= size(g); i++)
3356 {
3357   qt = qt + l*g[i]*r;
3358 }
3359 return(p - leadcoef(p)*normalize(qt));
3360}
3361
3362static proc entryViolation(intmat M, int n)
3363"PURPOSE:checks, if all entries in M are variable-related
3364"
3365{int i,j;
3366  for (i = 1; i <= nrows(M); i++)
3367  {for (j = 1; j <= ncols(M); j++)
3368    {if(!((1<=M[i,j])&&(M[i,j]<=n))) {return(1);}}
3369  }
3370  return(0);
3371}
3372
3373static proc checkAssumptionsLPIV(int d, list L)
3374"PURPOSE: Checks, if all the Assumptions are holding
3375"
3376{if (!isFreeAlgebra(basering)) {ERROR("Basering is not a Letterplace ring!");}
3377  if (d > lpDegBound(basering)) {ERROR("Specified degree bound exceeds ring parameter!");}
3378  int i;
3379  for (i = 1; i <= size(L); i++)
3380  {if (entryViolation(L[i], lpVarBlockSize(basering)))
3381    {ERROR("Not allowed monomial/intvec found!");}
3382  }
3383  return();
3384}
3385
3386static proc checkAssumptions(poly p, ideal G)
3387"
3388"
3389{checkLPRing();
3390 checkAssumptionPoly(p);
3391 checkAssumptionIdeal(G);
3392 return();
3393}
3394
3395static proc checkLPRing();
3396"
3397"
3398{if (!isFreeAlgebra(basering)) {ERROR("Basering is not a Letterplace ring!");}
3399 return();
3400}
3401
3402static proc checkAssumptionIdeal(ideal G)
3403"PURPOSE:Check if all elements of ideal are elements of V'
3404"
3405{ideal L = lead(normalize(G));
3406 int i;
3407 for (i = 1; i <= ncols(G); i++) {if (!isContainedInVp(G[i])) {ERROR("Ideal containes elements not contained in V'");}}
3408 return();
3409}
3410
3411static proc checkAssumptionPoly(poly p)
3412"PURPOSE:Check if p is an element of V'
3413"
3414{poly l = lead(normalize(p));
3415 if (!isContainedInVp(l)) {ERROR("Polynomial is not contained in V'");}
3416 return();
3417}
3418
3419static proc isContainedInVp(poly p)
3420"PURPOSE: Check monomial for holes in the places
3421"
3422{int r = 0; intvec w;
3423 intvec l = leadexp(p);
3424 int n = lpVarBlockSize(basering); int d = lpDegBound(basering);
3425 int i,j,c,c1;
3426 while (1 <= d)
3427 {
3428   w = l[1..n];
3429   if (w<>(0:n)) {break;}
3430   else
3431   {
3432     if (size(w)==size(l)) break;
3433     l = l[(n+1)..(n*d)];
3434     d = d-1;
3435   }
3436 }
3437
3438 while (1 <= d)
3439  {for (j = 1; j <= n; j++)
3440   {if (l[j]<>0)
3441    {if (c1<>0){return(0);}
3442     if (c<>0){return(0);}
3443     if (l[j]<>1){return(0);}
3444     c=1;
3445    }
3446   }
3447   if (c == 0){c1=1;if (1 < d){l = l[(n+1)..(n*d)]; d = d-1;} else {d = d -1;}}
3448    else {c = 0; if (1 < d){l = l[(n+1)..(n*d)]; d = d-1;} else {d = d -1;}}
3449  }
3450 return(1);
3451}
3452
3453static proc extractLinearPart(module M)
3454{
3455  /* returns vectors from a module whose max leadexp is 1 */
3456  /* does not take nonlinearity into account yet */
3457  /* use rather kernel function isinV to get really nonlinear things */
3458  int i; int s = ncols(M);
3459  int answer = 1;
3460  vector v; module Ret;
3461  for(i=1; i<=s; i++)
3462  {
3463    if ( isLinearVector(M[i]) )
3464    {
3465      Ret = Ret, M[i];
3466    }
3467  }
3468  Ret = simplify(Ret,2);
3469  return(Ret);
3470}
3471
3472static proc isLinearVector(vector v)
3473{
3474  /* vector v consists of polynomials */
3475  /* returns true iff max leadexp is 1 */
3476  int i,j,k;
3477  intvec w;
3478  int s = size(v);
3479  poly p;
3480  int answer = 1;
3481  for(i=1; i<=s; i++)
3482  {
3483    p = v[i];
3484    while (p != 0)
3485    {
3486      w = leadexp(p);
3487      j = Max(w);
3488      if (j >=2)
3489      {
3490        answer = 0;
3491        return(answer);
3492      }
3493      p = p-lead(p);
3494    }
3495  }
3496  return(answer);
3497}
3498
3499
3500// // the following is to determine a shift of a mono/poly from the
3501// // interface
3502
3503// static proc whichshift(poly p, int numvars)
3504// {
3505// // numvars = number of vars of the orig free algebra
3506// // assume: we are in the letterplace ring
3507// // takes  monomial on the input
3508// poly q = lead(p);
3509// intvec v = leadexp(v);
3510// if (v==0) { return(int(0)); }
3511// int sv = size(v);
3512// int i=1;
3513// while ( (v[i]==0) && (i<sv) ) { i++; }
3514// i = sv div i;
3515// return(i);
3516// }
3517
3518
3519// LIB "qhmoduli.lib";
3520// static proc polyshift(poly p,  int numvars)
3521// {
3522//   poly q = p; int i = 0;
3523//   while (q!=0)
3524//   {
3525//     i = Max(i, whichshift(q,numvars));
3526//     q = q - lead(q);
3527//   }
3528//   return(q);
3529// }
3530
3531static proc lpAssumeViolation()
3532{
3533  // checks whether the global vars
3534  // uptodeg and lV are defined
3535  // returns Boolean : yes/no [for assume violation]
3536  def uptodeg = lpDegBound(basering);
3537  if ( typeof(uptodeg)!="int" )
3538  {
3539    return(1);
3540  }
3541  return (!isFreeAlgebra(basering))
3542}
3543
3544// obsolete
3545static proc lshift(module M, int s, string varing, def lpring)
3546{
3547  // FINALLY IMPLEMENTED AS A PART OT THE C CODE
3548  // shifts a polynomial from the ring R to s positions
3549  // M lives in varing, the result in lpring
3550  // to be run from varing
3551  int i, j, k, sm, sv;
3552  vector v;
3553  //  execute("setring "+lpring);
3554  setring lpring;
3555  poly @@p;
3556  ideal I;
3557  execute("setring "+varing);
3558  sm = ncols(M);
3559  for (i=1; i<=s; i++)
3560  {
3561    // modules, e.g. free polynomials
3562    for (j=1; j<=sm; j++)
3563    {
3564      //vectors, e.g. free monomials
3565      v  = M[j];
3566      sv = size(v);
3567      sp = "@@p = @@p + ";
3568      for (k=2; k<=sv; k++)
3569      {
3570        sp = sp + string(v[k])+"("+string(k-1+s)+")*";
3571      }
3572      sp = sp + string(v[1])+";"; // coef;
3573      setring lpring;
3574      //      execute("setring "+lpring);
3575      execute(sp);
3576      execute("setring "+varing);
3577    }
3578    setring lpring;
3579    //    execute("setring "+lpring);
3580    I = I,@@p;
3581    @@p = 0;
3582  }
3583  setring lpring;
3584  //execute("setring "+lpring);
3585  export(I);
3586  //  setring varing;
3587  execute("setring "+varing);
3588}
3589
3590static proc skip0(vector v)
3591{
3592  // skips zeros in a vector, producing another vector
3593  if ( (v[1]==0) || (v==0) ) { return(vector(0)); }
3594  int sv = nrows(v);
3595  int sw = size(v);
3596  if (sv == sw)
3597  {
3598    return(v);
3599  }
3600  int i;
3601  int j=1;
3602  vector w;
3603  for (i=1; i<=sv; i++)
3604  {
3605    if (v[i] != 0)
3606    {
3607      w = w + v[i]*gen(j);
3608      j++;
3609    }
3610  }
3611  return(w);
3612}
3613
3614// static proc bugSKing()
3615// {
3616//   LIB "freegb.lib";
3617//   ring r=0,(a,b),dp;
3618//   def R = freeAlgebra(r, 5);
3619//   setring R;
3620//   poly p = a(1);
3621//   poly q = b(1);
3622//   poly p2 = lpPower(p,2);
3623//   lpMult(p2+q,q)-lpMult(p2,q)-lpMult(q,q); // now its 0
3624// }
3625//
3626// static proc bugRucker()
3627// {
3628//   // needs unstatic lpMultX
3629//   LIB "freegb.lib";
3630//   ring r=0,(a,b,c,d,p,q,r,s,t,u,v,w),(a(7,1,1,7),dp);
3631//   def R=freeAlgebra(r, 20,1);
3632//   setring R;
3633//   option(redSB); option(redTail);
3634//   ideal I=a(1)*b(2)*c(3)-p(1)*q(2)*r(3)*s(4)*t(5)*u(6),b(1)*c(2)*d(3)-v(1)*w(2);
3635//   poly ttt = a(1)*v(2)*w(3)-p(1)*q(2)*r(3)*s(4)*t(5)*u(6)*d(7);
3636//   // with lpMult
3637//   lpMult(I[1],d(1)) - lpMult(a(1),I[2]); // spoly; has been incorrect before
3638//   _ - ttt;
3639//   // with lpMultX
3640//   lpMultX(I[1],d(1)) - lpMultX(a(1),I[2]); // spoly; has been incorrect before
3641//   _ - ttt;
3642// }
3643//
3644// static proc checkWeightedExampleLP()
3645// {
3646//   ring r = 0,(x(1),y(1),x(2),y(2),x(3),y(3),x(4),y(4)),wp(2,1,2,1,2,1,2,1);
3647//   def R = setLetterplaceAttributes(r,4,2); // supply R with letterplace structure
3648//   setring R;
3649//   poly a = x(1)*y(2)+x(1)+y(1); poly b = y(1)+3;
3650//   lpMultX(b,a);
3651//   lpMultX(a,b); // seems to work properly
3652// }
3653
3654// ----------------- iv2lp and lp2iv ----------------------
3655proc ivL2lpI(list L)
3656"USAGE: ivL2lpI(L); L a list of intvecs (deprecated, will be removed soon)
3657RETURN: ideal
3658PURPOSE:Transforming a list of intvecs into an ideal of Letterplace monomials
3659ASSUME: - Intvec corresponds to a Letterplace monomial
3660@*      - basering has to be a Letterplace ring
3661NOTE:   - Assumptions will not be checked!
3662EXAMPLE: example ivL2lpI; shows examples
3663"
3664{
3665  int i; ideal G;
3666  poly p;
3667  for (i = 1; i <= size(L); i++)
3668  {
3669    p = iv2lp(L[i]);
3670    G[(size(G) + 1)] = p;
3671  }
3672  return(G);
3673}
3674example
3675{
3676  "EXAMPLE:"; echo = 2;
3677  ring r = 0,(x,y,z),dp;
3678  def R = freeAlgebra(r, 5);// constructs a Letterplace ring
3679  setring R; //sets basering to Letterplace ring
3680  intvec u = 1,1,2; intvec v = 2,1,3; intvec w = 3,1,1;
3681  // u = x^2y, v = yxz, w = zx^2 in intvec representation
3682  list L = u,v,w;
3683  ivL2lpI(L);// invokes the procedure, returns the ideal containing u,v,w
3684}
3685
3686proc iv2lp(intvec I)
3687"USAGE: iv2lp(I); I an intvec (deprecated, will be removed soon)
3688RETURN: poly
3689PURPOSE:Transforming an intvec into the corresponding Letterplace polynomial
3690ASSUME: - Intvec corresponds to a Letterplace monomial
3691@*      - basering has to be a Letterplace ring
3692NOTE:   - Assumptions will not be checked!
3693EXAMPLE: example iv2lp; shows examples
3694"
3695{if (I[1] == 0) {return(1);}
3696  int i = size(I);
3697  if (i > lpDegBound(basering)) {ERROR("polynomial exceeds degreebound");}
3698  int j; poly p = 1;
3699  for (j = 1; j <= i; j++) {if (I[j] > 0) { p = p*var(I[j]);}} //ignore zeroes, because they correspond to 1
3700  return(p);
3701}
3702example
3703{
3704  "EXAMPLE:"; echo = 2;
3705  ring r = 0,(x,y,z),dp;
3706  def R = freeAlgebra(r, 5); // constructs a Letterplace ring
3707  setring R; //sets basering to Letterplace ring
3708  // u = x^2y, v = yxz, w = zx^2 in intvec representation
3709  intvec u = 1,1,2;
3710  iv2lp(u); // invokes the procedure and returns the corresponding poly
3711  intvec v = 2,1,3;
3712  iv2lp(v);
3713  intvec w = 3,1,1;
3714  iv2lp(w);
3715}
3716
3717proc iv2lpList(list L)
3718"USAGE: iv2lpList(L); L a list of intmats (deprecated, will be removed soon)
3719RETURN: ideal
3720PURPOSE:Converting a list of intmats into an ideal of corresponding monomials
3721ASSUME: - The rows of each intmat in L must correspond to a Letterplace monomial
3722@*      - basering has to be a Letterplace ring
3723EXAMPLE: example iv2lpList; shows examples
3724"
3725{checkAssumptionsLPIV(0,L);
3726  ideal G;
3727  int i;
3728  for (i = 1; i <= size(L); i++){G = G + iv2lpMat(L[i]);}
3729  return(G);
3730}
3731example
3732{
3733  "EXAMPLE:"; echo = 2;
3734  ring r = 0,(x,y,z),dp;
3735  def R = freeAlgebra(r, 5); // constructs a Letterplace ring
3736  setring R; // sets basering to Letterplace ring
3737  intmat u[3][1] = 1,1,2; intmat v[1][3] = 2,1,3; intmat w[2][3] = 3,1,1,2,3,1;
3738  // defines intmats of different size containing intvec representations of
3739  // monomials as rows
3740  list L = u,v,w;
3741  print(u); print(v); print(w); // shows the intmats contained in L
3742  iv2lpList(L); // returns the corresponding monomials as an ideal
3743}
3744
3745
3746proc iv2lpMat(intmat M)
3747"USAGE: iv2lpMat(M); M an intmat (deprecated, will be removed soon)
3748RETURN: ideal
3749PURPOSE:Converting an intmat into an ideal of the corresponding monomials
3750ASSUME: - The rows of M must correspond to Letterplace monomials
3751@*      - basering has to be a Letterplace ring
3752EXAMPLE: example iv2lpMat; shows examples
3753"
3754{list L = M;
3755  checkAssumptionsLPIV(0,L);
3756  kill L;
3757  ideal G; poly p;
3758  int i; intvec I;
3759  for (i = 1; i <= nrows(M); i++)
3760  { I = M[i,1..ncols(M)];
3761    p = iv2lp(I);
3762    G[size(G)+1] = p;
3763  }
3764  return(G);
3765}
3766example
3767{
3768  "EXAMPLE:"; echo = 2;
3769  ring r = 0,(x,y,z),dp;
3770  def R = freeAlgebra(r, 5); // constructs a Letterplace ring
3771  setring R; // sets basering to Letterplace ring
3772  intmat u[3][1] = 1,1,2; intmat v[1][3] = 2,1,3; intmat w[2][3] = 3,1,1,2,3,1;
3773  // defines intmats of different size containing intvec representations of
3774  // monomials as rows
3775  iv2lpMat(u); // returns the monomials contained in u
3776  iv2lpMat(v); // returns the monomials contained in v
3777  iv2lpMat(w); // returns the monomials contained in w
3778}
3779
3780proc lpId2ivLi(ideal G)
3781"USAGE: lpId2ivLi(G); G an ideal (deprecated, will be removed soon)
3782RETURN: list
3783PURPOSE:Transforming an ideal into the corresponding list of intvecs
3784ASSUME: - basering has to be a Letterplace ring
3785EXAMPLE: example lpId2ivLi; shows examples
3786"
3787{
3788  int i,j,k;
3789  list M;
3790  checkAssumptionsLPIV(0,M);
3791  for (i = 1; i <= size(G); i++) {M[i] = lp2iv(G[i]);}
3792  return(M);
3793}
3794example
3795{
3796  "EXAMPLE:"; echo = 2;
3797  ring r = 0,(x,y),dp;
3798  def R = freeAlgebra(r, 5); // constructs a Letterplace ring
3799  setring R; // sets basering to Letterplace ring
3800  ideal L = x*x,y*y,x*y*x;
3801  lpId2ivLi(L); // returns the corresponding intvecs as a list
3802}
3803
3804proc lp2iv(poly p)
3805"USAGE: lp2iv(p); p a poly (deprecated, will be removed soon)
3806RETURN: intvec
3807PURPOSE: Transforming a monomial into the corresponding intvec
3808ASSUME: - basering has to be a Letterplace ring
3809NOTE:   - Assumptions will not be checked!
3810EXAMPLE: example lp2iv; shows examples
3811"
3812{p = normalize(lead(p));
3813  intvec I;
3814  int i,j;
3815  if (deg(p) > lpDegBound(basering)) {ERROR("Monomial exceeds degreebound");}
3816  if (p == 1) {return(I);}
3817  if (p == 0) {ERROR("Monomial is not allowed to equal zero");}
3818  intvec lep = leadexp(p);
3819  for ( i = 1; i <= lpVarBlockSize(basering); i++) {if (lep[i] == 1) {I = i; break;}}
3820  for (i = (lpVarBlockSize(basering)+1); i <= size(lep); i++)
3821  {if (lep[i] == 1)
3822    { j = (i mod lpVarBlockSize(basering));
3823      if (j == 0) {I = I,lpVarBlockSize(basering);}
3824      else {I = I,j;}
3825    }
3826    else { if (lep[i] > 1) {ERROR("monomial has a not allowed multidegree");}}
3827  }
3828  if (I[1] == 0) {ERROR("monomial has a not allowed multidegree");}
3829  return(I);
3830}
3831example
3832{
3833  "EXAMPLE:"; echo = 2;
3834  ring r = 0,(x,y,z),dp;
3835  def R = freeAlgebra(r, 5); // constructs a Letterplace ring
3836  setring R; // sets basering to Letterplace ring
3837  poly p = x*x*z;
3838  lp2iv(p); // transforms p into the intvec representation
3839  lp2iv(y*y*x*x);
3840  lp2iv(z*y*x*z*z);
3841}
3842
3843proc lp2ivId(ideal G)
3844"USAGE: lp2ivId(G); G an ideal (deprecated, will be removed soon)
3845RETURN: list
3846PURPOSE:Converting an ideal into an list of intmats,
3847@*      the corresponding intvecs forming the rows
3848ASSUME: - basering has to be a Letterplace ring
3849EXAMPLE: example lp2ivId; shows examples
3850"
3851{G = normalize(lead(G));
3852  intvec I; list L;
3853  checkAssumptionsLPIV(0,L);
3854  int i,md;
3855  for (i = 1; i <= size(G); i++) { if (md <= deg(G[i])) {md = deg(G[i]);}}
3856  while (size(G) > 0)
3857  {ideal Gt;
3858    for (i = 1; i <= ncols(G); i++) {if (md == deg(G[i])) {Gt = Gt + G[i]; G[i] = 0;}}
3859    if (size(Gt) > 0)
3860    {G = simplify(G,2);
3861      intmat M [size(Gt)][md];
3862      for (i = 1; i <= size(Gt); i++) {M[i,1..md] = lp2iv(Gt[i]);}
3863      L = insert(L,M);
3864      kill M; kill Gt;
3865      md = md - 1;
3866    }
3867    else {kill Gt; md = md - 1;}
3868  }
3869  return(L);
3870}
3871example
3872{
3873  "EXAMPLE:"; echo = 2;
3874  ring r = 0,(x,y,z),dp;
3875  def R = freeAlgebra(r, 5); // constructs a Letterplace ring
3876  setring R; // sets basering to Letterplace ring
3877  poly p = x*x*z;
3878  poly q = y*y*x*x;
3879  poly w = z*y*x*z;
3880  // p,q,w are some polynomials we want to transform into their
3881  // intvec representation
3882  ideal G = p,q,w;
3883  lp2ivId(G); // returns the list of intmats for this ideal
3884}
3885
3886static proc mod_init()
3887{
3888  LIB"freegb.so";
3889}
Note: See TracBrowser for help on using the repository browser.