source: git/Singular/LIB/fpadim.lib @ 909b29

spielwiese
Last change on this file since 909b29 was 909b29, checked in by Karim Abou Zeid <karim23697@…>, 6 years ago
Apply changes from Levandovskyy
  • Property mode set to 100644
File size: 89.9 KB
Line 
1////////////////////////////////////////////////////////
2version="version fpadim.lib 4.1.1.0 Dec_2017 "; // $Id$
3category="Noncommutative";
4info="
5LIBRARY: fpadim.lib     Algorithms for quotient algebras in the letterplace case
6AUTHORS: Grischa Studzinski,       grischa.studzinski at rwth-aachen.de
7@*       Viktor Levandovskyy,      viktor.levandovskyy at math.rwth-aachen.de
8@*       Karim Abou Zeid,          karim.abou.zeid at rwth-aachen.de
9
10Support: Joint projects LE 2697/2-1 and KR 1907/3-1 of the Priority Programme SPP 1489:
11'Algorithmische und Experimentelle Methoden in Algebra, Geometrie und Zahlentheorie'
12of the German DFG
13and Project II.6 of the transregional collaborative research centre
14SFB-TRR 195 'Symbolic Tools in Mathematics and their Application' of the German DFG
15
16OVERVIEW: Given the free associative algebra A = K<x_1,...,x_n> and a (finite) Groebner basis
17      GB = {g_1,..,g_w}, one is interested in the K-dimension and in the
18      explicit K-basis of A/<GB>.
19      Therefore one is interested in the following data:
20      - the Ufnarovskij graph induced by GB
21      - the mistletoes of A/<GB> (special monomials in a basis)
22      - the K-dimension of A/<GB>
23      - the Hilbert series of A/<GB>
24
25@*      The Ufnarovskij graph is used to determine whether A/<GB> has finite
26@*      K-dimension. One has to check if the graph contains cycles.
27@*      For the whole theory we refer to [ufna]. Given a
28@*      reduced set of monomials GB one can define the basis tree, whose vertex
29@*      set V consists of all normal monomials w.r.t. GB. For every two
30@*      monomials m_1, m_2 in V there is a direct edge from m_1 to m_2, if and
31@*      only if there exists x_k in {x_1,..,x_n}, such that m_1*x_k = m_2. The
32@*      set M = {m in V | there is no edge from m to another monomial in V} is
33@*      called the set of mistletoes. As one can easily see it consists of
34@*      the endpoints of the graph. Since there is a unique path to every
35@*      monomial in V the whole graph can be described only from the knowledge
36@*      of the mistletoes. Note that V corresponds to a basis of A/<GB>, so
37@*      knowing the mistletoes we know a K-basis. The name mistletoes was given
38@*      to those points because of these miraculous value and the algorithm is
39@*      named sickle, because a sickle is the tool to harvest mistletoes.
40@*      For more details see [studzins]. This package uses the Letterplace
41@*      format introduced by [lls]. The algebra can either be represented as a
42@*      Letterplace ring or via integer vectors: Every variable will only be
43@*      represented by its number, so variable one is represented as 1,
44@*      variable two as 2 and so on. The monomial x_1*x_3*x_2 for example will
45@*      be stored as (1,3,2). Multiplication is concatenation. Note that the
46@*      approach in this library does not need an algorithm for computing the normal
47@*      form yet. Note that the name fpadim.lib is short for dimensions of
48@*      finite presented algebras.
49@*
50
51REFERENCES:
52
53@*   [ufna] Ufnarovskij: Combinatorical and asymptotic methods in algebra, 1990
54@*   [lls] Levandovskyy, La Scala: Letterplace ideals and non-commutative
55Groebner bases, 2009
56@*   [studzins] Studzinski: Dimension computations in non-commutative,
57associative algebras, Diploma thesis, RWTH Aachen, 2010
58
59NOTE:
60- basering is always a Letterplace ring
61- all intvecs correspond to Letterplace monomials
62- if you specify a different degree bound d, d <= attrib(basering,uptodeg) holds
63
64In the procedures below, 'iv' stands for intvec representation
65and 'lp' for the letterplace representation of monomials
66
67PROCEDURES:
68
69lpMis2Dim(M);              computes the K-dimension of the monomial factor algebra
70lpKDim(G[,d,n]);           computes the K-dimension of A/<G>
71lpDimCheck(G);             checks if the K-dimension of A/<G> is infinite
72lpMis2Base(M);             computes a K-basis of the factor algebra
73lpHilbert(G[,d,n]);        computes the Hilbert series of A/<G> in lp format
74lpDHilbert(G[,d,n]);       computes the K-dimension and Hilbert series of A/<G>
75lpDHilbertSickle(G[,d,n]); computes mistletoes, K-dimension and Hilbert series
76
77ivDHilbert(L,n[,d]);       computes the K-dimension and the Hilbert series
78ivDHilbertSickle(L,n[,d]); computes mistletoes, K-dimension and Hilbert series
79ivDimCheck(L,n);           checks if the K-dimension of A/<L> is infinite
80ivHilbert(L,n[,d]);        computes the Hilbert series of A/<L> in intvec format
81ivKDim(L,n[,d]);           computes the K-dimension of A/<L> in intvec format
82ivMis2Base(M);             computes a K-basis of the factor algebra
83ivMis2Dim(M);              computes the K-dimension of the factor algebra
84ivOrdMisLex(M);            orders a list of intvecs lexicographically
85ivSickle(L,n[,d]);         computes the mistletoes of A/<L> in intvec format
86ivSickleHil(L,n[,d]);      computes the mistletoes and Hilbert series of A/<L>
87ivSickleDim(L,n[,d]);      computes the mistletoes and the K-dimension of A/<L>
88lpOrdMisLex(M);            orders an ideal of lp-monomials lexicographically
89lpSickle(G[,d,n]);         computes the mistletoes of A/<G> in lp format
90lpSickleHil(G[,d,n]);      computes the mistletoes and Hilbert series of A/<G>
91lpSickleDim(G[,d,n]);      computes the mistletoes and the K-dimension of A/<G>
92sickle(G[,m,d,h]);         can be used to access all lp main procedures
93
94ivL2lpI(L);           transforms a list of intvecs into an ideal of lp monomials
95iv2lp(I);             transforms an intvec into the corresponding monomial
96iv2lpList(L);         transforms a list of intmats into an ideal of lp monomials
97iv2lpMat(M);          transforms an intmat into an ideal of lp monomials
98lp2iv(p);             transforms a polynomial into the corresponding intvec
99lp2ivId(G);           transforms an ideal into the corresponding list of intmats
100lpId2ivLi(G);         transforms a lp-ideal into the corresponding list of intvecs
101
102SEE ALSO: freegb_lib
103";
104
105LIB "freegb.lib"; //for letterplace rings
106LIB "general.lib";//for sorting mistletoes
107
108/////////////////////////////////////////////////////////
109
110
111//--------------- auxiliary procedures ------------------
112
113static proc allVars(list L, intvec P, int n)
114"USAGE: allVars(L,P,n); L a list of intmats, P an intvec, n an integer
115RETURN: int, 0 if all variables are contained in the quotient algebra, 1 otherwise
116"
117{int i,j,r;
118  intvec V;
119  for (i = 1; i <= size(P); i++) {if (P[i] == 1){ j = i; break;}}
120  V = L[j][1..nrows(L[j]),1];
121  for (i = 1; i <= n; i++) {if (isInVec(i,V) == 0) {r = 1; break;}}
122  if (r == 0) {return(1);}
123  else {return(0);}
124}
125
126static proc checkAssumptions(int d, list L)
127"PURPOSE: Checks, if all the Assumptions are holding
128"
129{if (typeof(attrib(basering,"isLetterplaceRing"))=="string") {ERROR("Basering is not a Letterplace ring!");}
130  if (d > attrib(basering,"uptodeg")) {ERROR("Specified degree bound exceeds ring parameter!");}
131  int i;
132  for (i = 1; i <= size(L); i++)
133  {if (entryViolation(L[i], attrib(basering,"lV")))
134    {ERROR("Not allowed monomial/intvec found!");}
135  }
136  return();
137}
138
139static proc createStartMat(int d, int n)
140"USAGE: createStartMat(d,n); d, n integers
141RETURN: intmat
142PURPOSE:Creating the intmat with all normal monomials in n variables and of degree d to start with
143NOTE:   d has to be > 0
144"
145{intmat M[(n^d)][d];
146  int i1,i2,i3,i4;
147  for (i1 = 1; i1 <= d; i1++)  //Spalten
148  {i2 = 1; //durchlaeuft Zeilen
149    while (i2 <= (n^d))
150    {for (i3 = 1; i3 <= n; i3++)
151      {for (i4 = 1; i4 <= (n^(i1-1)); i4++)
152        {M[i2,i1] = i3;
153          i2 = i2 + 1;
154        }
155      }
156    }
157  }
158  return(M);
159}
160
161static proc createStartMat1(int n, intmat M)
162"USAGE: createStartMat1(n,M); n an integer, M an intmat
163RETURN: intmat, with all variables except those in M
164"
165{int i;
166  intvec V,Vt;
167  V = M[(1..nrows(M)),1];
168  for (i = 1; i <= size(V); i++) {if (isInVec(i,V) == 0) {Vt = Vt,i;}}
169  if (Vt == 0) {intmat S; return(S);}
170  else {Vt = Vt[2..size(Vt)]; intmat S [size(Vt)][1]; S[1..size(Vt),1] = Vt; return(S);}
171}
172
173static proc entryViolation(intmat M, int n)
174"PURPOSE:checks, if all entries in M are variable-related
175"
176{int i,j;
177  for (i = 1; i <= nrows(M); i++)
178  {for (j = 1; j <= ncols(M); j++)
179    {if(!((1<=M[i,j])&&(M[i,j]<=n))) {return(1);}}
180  }
181  return(0);
182}
183
184static proc findDimen(intvec V, int n, list L, intvec P, list #)
185"USAGE: findDimen(V,n,L,P,degbound); V,P intvecs, n, an integer, L a list,
186@*      degbound an optional integer
187RETURN: int
188PURPOSE:Computing the K-dimension of the quotient algebra
189"
190{int degbound = 0;
191  if (size(#) > 0) {if (#[1] > 0) {degbound = #[1];}}
192  int dimen,i,j,w,it;
193  intvec Vt,Vt2;
194  module M;
195  if (degbound == 0)
196  {for (i = 1; i <= n; i++)
197    {Vt = V, i; w = 0;
198      for (j = 1; j<= size(P); j++)
199      {if (P[j] <= size(Vt))
200        {Vt2 = Vt[(size(Vt)-P[j]+1)..size(Vt)];
201          if (isInMat(Vt2,L[j]) > 0) {w = 1; break;}
202        }
203      }
204      if (w == 0)
205      {vector Vtt;
206        for (it = 1; it <= size(Vt); it++){Vtt = Vtt + Vt[it]*gen(it);}
207        M = M,Vtt;
208        kill Vtt;
209      }
210    }
211    if (size(M) == 0) {return(0);}
212    else
213    {M = simplify(M,2);
214      for (i = 1; i <= size(M); i++)
215      {kill Vt; intvec Vt;
216        for (j =1; j <= size(M[i]); j++){Vt[j] =  int(leadcoef(M[i][j]));}
217        dimen = dimen + 1 + findDimen(Vt,n,L,P);
218      }
219      return(dimen);
220    }
221  }
222  else
223  {if (size(V) > degbound) {ERROR("monomial exceeds degreebound");}
224    if (size(V) == degbound) {return(0);}
225    for (i = 1; i <= n; i++)
226    {Vt = V, i; w = 0;
227      for (j = 1; j<= size(P); j++)
228      {if (P[j] <= size(Vt))
229        {Vt2 = Vt[(size(Vt)-P[j]+1)..size(Vt)];
230          if (isInMat(Vt2,L[j]) > 0) {w = 1; break;}
231        }
232      }
233      if (w == 0) {vector Vtt;
234        for (it = 1; it <= size(Vt); it++){Vtt = Vtt + Vt[it]*gen(it);}
235        M = M,Vtt;
236        kill Vtt;
237      }
238    }
239    if (size(M) == 0) {return(0);}
240    else
241    {M = simplify(M,2);
242      for (i = 1; i <= size(M); i++)
243      {kill Vt; intvec Vt;
244        for (j =1; j <= size(M[i]); j++){Vt[j] =  int(leadcoef(M[i][j]));}
245        dimen = dimen + 1 + findDimen(Vt,n,L,P,degbound);
246      }
247      return(dimen);
248    }
249  }
250}
251
252static proc findCycle(intvec V, list L, intvec P, int n, int ld, module M)
253"USAGE:
254RETURN: int, 1 if Ufn-graph contains a cycle, or 0 otherwise
255PURPOSE:Searching the Ufnarovskij graph for cycles
256"
257{int i,j,w,r;intvec Vt,Vt2;
258  int it, it2;
259  if (size(V) < ld)
260  {for (i = 1; i <= n; i++)
261    {Vt = V,i; w = 0;
262      for (j = 1; j <= size(P); j++)
263      {if (P[j] <= size(Vt))
264        {Vt2 = Vt[(size(Vt)-P[j]+1)..size(Vt)];
265          if (isInMat(Vt2,L[j]) > 0)
266          {w = 1; break;}
267        }
268      }
269      if (w == 0) {r = findCycle(Vt,L,P,n,ld,M);}
270      if (r == 1) {break;}
271    }
272    return(r);
273  }
274  else
275  {j = size(M);
276    if (j > 0)
277    {
278      intmat Mt[j][nrows(M)];
279      for (it = 1; it <= j; it++)
280      { for(it2 = 1; it2 <= nrows(M);it2++)
281        {Mt[it,it2] = int(leadcoef(M[it2,it]));}
282      }
283      Vt = V[(size(V)-ld+1)..size(V)];
284      //Mt; type(Mt);Vt;type(Vt);
285      if (isInMat(Vt,Mt) > 0) {return(1);}
286      else
287      {vector Vtt;
288        for (it =1; it <= size(Vt); it++)
289        {Vtt = Vtt + Vt[it]*gen(it);}
290        M = M,Vtt;
291        kill Vtt;
292        for (i = 1; i <= n; i++)
293        {Vt = V,i; w = 0;
294          for (j = 1; j <= size(P); j++)
295          {if (P[j] <= size(Vt))
296            {Vt2 = Vt[(size(Vt)-P[j]+1)..size(Vt)];
297              //L[j]; type(L[j]);Vt2;type(Vt2);
298              if (isInMat(Vt2,L[j]) > 0)
299              {w = 1; break;}
300            }
301          }
302          if (w == 0) {r = findCycle(Vt,L,P,n,ld,M);}
303          if (r == 1) {break;}
304        }
305        return(r);
306      }
307    }
308    else
309    { Vt = V[(size(V)-ld+1)..size(V)];
310      vector Vtt;
311      for (it = 1; it <= size(Vt); it++)
312      {Vtt = Vtt + Vt[it]*gen(it);}
313      M = Vtt;
314      kill Vtt;
315      for (i = 1; i <= n; i++)
316      {Vt = V,i; w = 0;
317        for (j = 1; j <= size(P); j++)
318        {if (P[j] <= size(Vt))
319          {Vt2 = Vt[(size(Vt)-P[j]+1)..size(Vt)];
320            //L[j]; type(L[j]);Vt2;type(Vt2);
321            if (isInMat(Vt2,L[j]) > 0)
322            {w = 1; break;}
323          }
324        }
325        if (w == 0) {r = findCycle(Vt,L,P,n,ld,M);}
326        if (r == 1) {break;}
327      }
328      return(r);
329    }
330  }
331}
332
333
334static proc findCycleDFS(int i, intmat T, intvec V)
335"
336PURPOSE:
337this is a classical deep-first search for cycles contained in a graph given by an intmat
338"
339{
340  intvec rV;
341  int k,k1,t;
342  int j = V[size(V)];
343  if (T[j,i] > 0) {return(V);}
344  else
345  {
346    for (k = 1; k <= ncols(T); k++)
347    {
348      t = 0;
349      if (T[j,k] > 0)
350      {
351        for (k1 = 1; k1 <= size(V); k1++) {if (V[k1] == k) {t = 1; break;}}
352        if (t == 0)
353        {
354          rV = V;
355          rV[size(rV)+1] = k;
356          rV = findCycleDFS(i,T,rV);
357          if (rV[1] > -1) {return(rV);}
358        }
359      }
360    }
361  }
362  return(intvec(-1));
363}
364
365
366
367static proc findHCoeff(intvec V,int n,list L,intvec P,intvec H,list #)
368"USAGE: findHCoeff(V,n,L,P,H,degbound); L a list of intmats, degbound an integer
369RETURN: intvec
370PURPOSE:Computing the coefficient of the Hilbert series (upto degree degbound)
371NOTE:   Starting with a part of the Hilbert series we change the coefficient
372@*      depending on how many basis elements we found on the actual branch
373"
374{int degbound = 0;
375  if (size(#) > 0){if (#[1] > 0){degbound = #[1];}}
376  int i,w,j,it;
377  int h1 = 0;
378  intvec Vt,Vt2,H1;
379  module M;
380  if (degbound == 0)
381  {for (i = 1; i <= n; i++)
382    {Vt = V, i; w = 0;
383      for (j = 1; j<= size(P); j++)
384      {if (P[j] <= size(Vt))
385        {Vt2 = Vt[(size(Vt)-P[j]+1)..size(Vt)];
386          if (isInMat(Vt2,L[j]) > 0) {w = 1; break;}
387        }
388      }
389      if (w == 0)
390      {vector Vtt;
391        for (it = 1; it <= size(Vt); it++){Vtt = Vtt + Vt[it]*gen(it);}
392        M = M,Vtt;
393        kill Vtt;
394      }
395    }
396    if (size(M) == 0) {return(H);}
397    else
398    {M = simplify(M,2);
399      for (i = 1; i <= size(M); i++)
400      {kill Vt; intvec Vt;
401        for (j =1; j <= size(M[i]); j++) {Vt[j] =  int(leadcoef(M[i][j]));}
402        h1 = h1 + 1; H1 = findHCoeff(Vt,n,L,P,H1);
403      }
404      if (size(H1) < (size(V)+2)) {H1[(size(V)+2)] = h1;}
405      else {H1[(size(V)+2)] = H1[(size(V)+2)] + h1;}
406      H1 = H1 + H;
407      return(H1);
408    }
409  }
410  else
411  {if (size(V) > degbound) {ERROR("monomial exceeds degreebound");}
412    if (size(V) == degbound) {return(H);}
413    for (i = 1; i <= n; i++)
414    {Vt = V, i; w = 0;
415      for (j = 1; j<= size(P); j++)
416      {if (P[j] <= size(Vt))
417        {Vt2 = Vt[(size(Vt)-P[j]+1)..size(Vt)];
418          if (isInMat(Vt2,L[j]) > 0) {w = 1; break;}
419        }
420      }
421      if (w == 0)
422      {vector Vtt;
423        for (it = 1; it <= size(Vt); it++){Vtt = Vtt + Vt[it]*gen(it);}
424        M = M,Vtt;
425        kill Vtt;
426      }
427    }
428    if (size(M) == 0) {return(H);}
429    else
430    {M = simplify(M,2);
431      for (i = 1; i <= size(M); i++)
432      {kill Vt; intvec Vt;
433        for (j =1; j <= size(M[i]); j++)
434        {Vt[j] =  int(leadcoef(M[i][j]));}
435        h1 = h1 + 1; H1 = findHCoeff(Vt,n,L,P,H1,degbound);
436      }
437      if (size(H1) < (size(V)+2)) { H1[(size(V)+2)] = h1;}
438      else {H1[(size(V)+2)] = H1[(size(V)+2)] + h1;}
439      H1 = H1 + H;
440      return(H1);
441    }
442  }
443}
444
445static proc findHCoeffMis(intvec V, int n, list L, intvec P, list R,list #)
446"USAGE: findHCoeffMis(V,n,L,P,R,degbound); degbound an optional integer, L a
447@*      list of Intmats, R
448RETURN: list
449PURPOSE:Computing the coefficients of the Hilbert series and the Mistletoes all
450@*      at once
451"
452{int degbound = 0;
453  if (size(#) > 0) {if (#[1] > 0) {degbound = #[1];}}
454  int i,w,j,h1;
455  intvec Vt,Vt2,H1; int it;
456  module M;
457  if (degbound == 0)
458  {for (i = 1; i <= n; i++)
459    {Vt = V, i; w = 0;
460      for (j = 1; j<= size(P); j++)
461      {if (P[j] <= size(Vt))
462        {Vt2 = Vt[(size(Vt)-P[j]+1)..size(Vt)];
463          if (isInMat(Vt2,L[j]) > 0) {w = 1; break;}
464        }
465      }
466      if (w == 0)
467      {vector Vtt;
468        for (it = 1; it <= size(Vt); it++){Vtt = Vtt + Vt[it]*gen(it);}
469        M = M,Vtt;
470        kill Vtt;
471      }
472    }
473    if (size(M) == 0) {if (size(R) < 2){R[2] = list(V);} else {R[2] = R[2] + list(V);} return(R);}
474    else
475    {M = simplify(M,2);
476      for (i = 1; i <= size(M); i++)
477      {kill Vt; intvec Vt;
478        for (j =1; j <= size(M[i]); j++)
479        {Vt[j] =  int(leadcoef(M[i][j]));}
480        if (size(R[1]) < (size(V)+2)) { R[1][(size(V)+2)] = 1;}
481        else
482        {R[1][(size(V)+2)] = R[1][(size(V)+2)] + 1;}
483        R = findHCoeffMis(Vt,n,L,P,R);
484      }
485      return(R);
486    }
487  }
488  else
489  {if (size(V) > degbound) {ERROR("monomial exceeds degreebound");}
490    if (size(V) == degbound)
491    {if (size(R) < 2){R[2] = list (V);}
492      else{R[2] = R[2] + list (V);}
493      return(R);
494    }
495    for (i = 1; i <= n; i++)
496    {Vt = V, i; w = 0;
497      for (j = 1; j<= size(P); j++)
498      {if (P[j] <= size(Vt))
499        {Vt2 = Vt[(size(Vt)-P[j]+1)..size(Vt)];
500          if (isInMat(Vt2,L[j]) > 0) {w = 1; break;}
501        }
502      }
503      if (w == 0)
504      {vector Vtt;
505        for (it = 1; it <= size(Vt); it++){Vtt = Vtt + Vt[it]*gen(it);}
506        M = M,Vtt;
507        kill Vtt;
508      }
509    }
510    if (size(M) == 0) {if (size(R) < 2){R[2] = list(V);} else {R[2] = R[2] + list(V);} return(R);}
511    else
512    {M = simplify(M,2);
513      for (i = 1; i <= ncols(M); i++)
514      {kill Vt; intvec Vt;
515        for (j =1; j <= size(M[i]); j++)
516        {Vt[j] =  int(leadcoef(M[i][j]));}
517        if (size(R[1]) < (size(V)+2)) { R[1][(size(V)+2)] = 1;}
518        else
519        {R[1][(size(V)+2)] = R[1][(size(V)+2)] + 1;}
520        R = findHCoeffMis(Vt,n,L,P,R,degbound);
521      }
522      return(R);
523    }
524  }
525}
526
527
528static proc findMisDim(intvec V,int n,list L,intvec P,list R,list #)
529"USAGE:
530RETURN: list
531PURPOSE:Computing the K-dimension and the Mistletoes all at once
532"
533{int degbound = 0;
534  if (size(#) > 0) {if (#[1] > 0) {degbound = #[1];}}
535  int dimen,i,j,w;
536  intvec Vt,Vt2; int it;
537  module M;
538  if (degbound == 0)
539  {for (i = 1; i <= n; i++)
540    {Vt = V, i; w = 0;
541      for (j = 1; j<= size(P); j++)
542      {if (P[j] <= size(Vt))
543        {Vt2 = Vt[(size(Vt)-P[j]+1)..size(Vt)];
544          if (isInMat(Vt2,L[j]) > 0) {w = 1; break;}
545        }
546      }
547      if (w == 0)
548      {vector Vtt;
549        for (it = 1; it <= size(Vt); it++){Vtt = Vtt + Vt[it]*gen(it);}
550        M = M,Vtt;
551        kill Vtt;
552      }
553    }
554    if (size(M) == 0)
555    {if (size(R) < 2){R[2] = list (V);}
556      else{R[2] = R[2] + list(V);}
557      return(R);
558    }
559    else
560    {M = simplify(M,2);
561      for (i = 1; i <= size(M); i++)
562      {kill Vt; intvec Vt;
563        for (j =1; j <= size(M[i]); j++){Vt[j] =  int(leadcoef(M[i][j]));}
564        R[1] = R[1] + 1; R = findMisDim(Vt,n,L,P,R);
565      }
566      return(R);
567    }
568  }
569  else
570  {if (size(V) > degbound) {ERROR("monomial exceeds degreebound");}
571    if (size(V) == degbound)
572    {if (size(R) < 2){R[2] = list (V);}
573      else{R[2] = R[2] + list (V);}
574      return(R);
575    }
576    for (i = 1; i <= n; i++)
577    {Vt = V, i; w = 0;
578      for (j = 1; j<= size(P); j++)
579      {if (P[j] <= size(Vt))
580        {Vt2 = Vt[(size(Vt)-P[j]+1)..size(Vt)];
581          if (isInMat(Vt2,L[j]) > 0) {w = 1; break;}
582        }
583      }
584      if (w == 0)
585      {vector Vtt;
586        for (it = 1; it <= size(Vt); it++){Vtt = Vtt + Vt[it]*gen(it);}
587        M = M,Vtt;
588        kill Vtt;
589      }
590    }
591    if (size(M) == 0)
592    {if (size(R) < 2){R[2] = list (V);}
593      else{R[2] = R[2] + list(V);}
594      return(R);
595    }
596    else
597    {M = simplify(M,2);
598      for (i = 1; i <= size(M); i++)
599      {kill Vt; intvec Vt;
600        for (j =1; j <= size(M[i]); j++){Vt[j] =  int(leadcoef(M[i][j]));}
601        R[1] = R[1] + 1; R = findMisDim(Vt,n,L,P,R,degbound);
602      }
603      return(R);
604    }
605  }
606}
607
608
609static proc findmistletoes(intvec V, int n, list L, intvec P, list #)
610"USAGE: findmistletoes(V,n,L,P,degbound); V a normal word, n the number of
611@*      variables, L the GB, P the occuring degrees,
612@*      and degbound the (optional) degreebound
613RETURN:  list
614PURPOSE:Computing mistletoes starting in V
615NOTE:   V has to be normal w.r.t. L, it will not be checked for being so
616"
617{int degbound = 0;
618  if (size(#) > 0) {if (#[1] > 0) {degbound = #[1];}}
619  list R; intvec Vt,Vt2; int it;
620  int i,j;
621  module M;
622  if (degbound == 0)
623  {int w;
624    for (i = 1; i <= n; i++)
625    {Vt = V,i; w = 0;
626      for (j = 1; j <= size(P); j++)
627      {if (P[j] <= size(Vt))
628        {Vt2 = Vt[(size(Vt)-P[j]+1)..size(Vt)];
629          if (isInMat(Vt2,L[j]) > 0)
630          {w = 1; break;}
631        }
632      }
633      if (w == 0)
634      {vector Vtt;
635        for (it = 1; it <= size(Vt); it++){Vtt = Vtt + Vt[it]*gen(it);}
636        M = M,Vtt;
637        kill Vtt;
638      }
639    }
640    if (size(M)==0) {R = V; return(R);}
641    else
642    {M = simplify(M,2);
643      for (i = 1; i <= size(M); i++)
644      {kill Vt; intvec Vt;
645        for (j =1; j <= size(M[i]); j++){Vt[j] =  int(leadcoef(M[i][j]));}
646        R = R + findmistletoes(Vt,n,L,P);
647      }
648      return(R);
649    }
650  }
651  else
652  {if (size(V) > degbound) {ERROR("monomial exceeds degreebound");}
653    if (size(V) == degbound) {R = V; return(R);}
654    int w;
655    for (i = 1; i <= n; i++)
656    {Vt = V,i; w = 0;
657      for (j = 1; j <= size(P); j++)
658      {if (P[j] <= size(Vt))
659        {Vt2 = Vt[(size(Vt)-P[j]+1)..size(Vt)];
660          if (isInMat(Vt2,L[j]) > 0){w = 1; break;}
661        }
662      }
663      if (w == 0)
664      {vector Vtt;
665        for (it = 1; it <= size(Vt); it++){Vtt = Vtt + Vt[it]*gen(it);}
666        M = M,Vtt;
667        kill Vtt;
668      }
669    }
670    if (size(M) == 0) {R = V; return(R);}
671    else
672    {M = simplify(M,2);
673      for (i = 1; i <= ncols(M); i++)
674      {kill Vt; intvec Vt;
675        for (j =1; j <= size(M[i]); j++)
676        {Vt[j] =  int(leadcoef(M[i][j]));}
677        //Vt; typeof(Vt); size(Vt);
678        R = R + findmistletoes(Vt,n,L,P,degbound);
679      }
680      return(R);
681    }
682  }
683}
684
685static proc growthAlg(intmat T, list #)
686"
687real algorithm for checking the growth of an algebra
688"
689{
690  int s = 1;
691  if (size(#) > 0) { s = #[1];}
692  int j;
693  int n = ncols(T);
694  intvec NV,C; NV[n] = 0; int m,i;
695  intmat T2[n][n] = T[1..n,1..n]; intmat N[n][n];
696  if (T2 == N)
697  {
698    for (i = 1; i <= n; i++)
699    {
700      if (m <  T[n+1,i]) { m = T[n+1,i];}
701    }
702    return(m);
703  }
704
705  //first part: the diagonals
706  for (i = s; i <= n; i++)
707  {
708    if (T[i,i] > 0)
709    {
710      if ((T[i,i] >= 1) && (T[n+1,i] > 0)) {return(-1);}
711      if ((T[i,i] == 1) && (T[n+1,i] == 0))
712      {
713        T[i,i] = 0;
714        T[n+1,i] = 1;
715        return(growthAlg(T));
716      }
717    }
718  }
719
720  //second part: searching for the last but one vertices
721  T2 = T2*T2;
722  for (i = s; i <= n; i++)
723  {
724    if ((intvec(T[i,1..n]) <> intvec(0)) && (intvec(T2[i,1..n]) == intvec(0)))
725    {
726      for (j = 1; j <= n; j++)
727      {
728        if ((T[i,j] > 0) && (m < T[n+1,j])) {m = T[n+1,j];}
729      }
730      T[n+1,i] = T[n+1,i] + m;
731      T[i,1..n] = NV;
732      return(growthAlg(T));
733    }
734  }
735  m = 0;
736
737  //third part: searching for circles
738  for (i = s; i <= n; i++)
739  {
740    T2 = T[1..n,1..n];
741    C = findCycleDFS(i,T2, intvec(i));
742    if (C[1] > 0)
743    {
744      for (j = 2; j <= size(C); j++)
745      {
746        T[i,1..n] = T[i,1..n] + T[C[j],1..n];
747        T[C[j],1..n] = NV;
748      }
749      for (j = 2; j <= size(C); j++)
750      {
751        T[1..n,i] = T[1..n,i] + T[1..n,C[j]];
752        T[1..n,C[j]] = NV;
753      }
754      T[i,i] = T[i,i] - size(C) + 1;
755      m = 0;
756      for (j = 1; j <= size(C); j++)
757      {
758        m = m + T[n+1,C[j]];
759      }
760      for (j = 1; j <= size(C); j++)
761      {
762        T[n+1,C[j]] = m;
763      }
764      return(growthAlg(T,i));
765    }
766    else {ERROR("No Cycle found, something seems wrong! Please contact the authors.");}
767  }
768
769  m = 0;
770  for (i = 1; i <= n; i++)
771  {
772    if (m < T[n+1,i])
773    {
774      m = T[n+1,i];
775    }
776  }
777  return(m);
778}
779
780static proc GlDimSuffix(intvec v, intvec g)
781{
782  //Computes the shortest r such that g is a suffix for vr
783  //only valid for lex orderings?
784  intvec r,gt,vt,lt,g2;
785  int lg,lv,l,i,c,f;
786  lg = size(g); lv = size(v);
787  if (lg <= lv)
788  {
789    l = lv-lg;
790  }
791  else
792  {
793    l = 0; g2 = g[(lv+1)..lg];
794    g = g[1..lv]; lg = size(g);
795    c = 1;
796  }
797  while (l < lv)
798  {
799    vt = v[(l+1)..lv];
800    gt = g[1..(lv-l)];
801    lt = size(gt);
802    for (i = 1; i <= lt; i++)
803    {
804      if (vt[i]<>gt[i]) {l++; break;}
805    }
806    if (lt <=i ) { f = 1; break;}
807  }
808  if (f == 0) {return(g);}
809  r = g[(lv-l+1)..lg];
810  if (c == 1) {r = r,g2;}
811  return(r);
812}
813
814static proc isNormal(intvec V, list G)
815{
816  int i,j,k,l;
817  k = 0;
818  for (i = 1; i <= size(G); i++)
819  {
820    if ( size(G[i]) <= size(V) )
821    {
822      while ( size(G[i])+k <= size(V) )
823      {
824        if ( G[i] == V[(1+k)..size(V)] ) {return(1);}
825      }
826    }
827  }
828  return(0);
829}
830
831static proc findDChain(list L)
832{
833  list Li; int i,j;
834  for (i = 1; i <= size(L); i++) {Li[i] = size(L[i]);}
835  Li = sort(Li); Li = Li[1];
836  return(Li[size(Li)]);
837}
838
839static proc isInList(intvec V, list L)
840"USAGE: isInList(V,L); V an intvec, L a list of intvecs
841RETURN: int
842PURPOSE:Finding the position of V in L, returns 0, if V is not in M
843"
844{int i,n;
845  n = 0;
846  for (i = 1; i <= size(L); i++) {if (L[i] == V) {n = i; break;}}
847  return(n);
848}
849
850static proc isInMat(intvec V, intmat M)
851"USAGE: isInMat(V,M);V an intvec, M an intmat
852RETURN: int
853PURPOSE:Finding the position of V in M, returns 0, if V is not in M
854"
855{if (size(V) <> ncols(M)) {return(0);}
856  int i;
857  intvec Vt;
858  for (i = 1; i <= nrows(M); i++)
859  {Vt = M[i,1..ncols(M)];
860    if ((V-Vt) == 0){return(i);}
861  }
862  return(0);
863}
864
865static proc isInVec(int v,intvec V)
866"USAGE: isInVec(v,V); v an integer,V an intvec
867RETURN: int
868PURPOSE:Finding the position of v in V, returns 0, if v is not in V
869"
870{int i,n;
871  n = 0;
872  for (i = 1; i <= size(V); i++) {if (V[i] == v) {n = i; break;}}
873  return(n);
874}
875
876
877static proc isPF(intvec P, intvec I)
878"
879PURPOSE:
880checks, if a word P is a praefix of another word I
881"
882{
883  int n = size(P);
884  if (n <= 0 || P == 0) {return(1);}
885  if (size(I) < n) {return(0);}
886  intvec IP = I[1..n];
887  if (IP == P) {return(1);}
888  else {return(0);}
889}
890
891proc ivL2lpI(list L)
892"USAGE: ivL2lpI(L); L a list of intvecs
893RETURN: ideal
894PURPOSE:Transforming a list of intvecs into an ideal of Letterplace monomials
895ASSUME: - Intvec corresponds to a Letterplace monomial
896@*      - basering has to be a Letterplace ring
897NOTE:   - Assumptions will not be checked!
898EXAMPLE: example ivL2lpI; shows examples
899"
900{
901  int i; ideal G;
902  poly p;
903  for (i = 1; i <= size(L); i++)
904  {p = iv2lp(L[i]);
905    G[(size(G) + 1)] = p;
906  }
907  return(G);
908}
909example
910{
911  "EXAMPLE:"; echo = 2;
912  ring r = 0,(x,y,z),dp;
913  def R = makeLetterplaceRing(5);// constructs a Letterplace ring
914  setring R; //sets basering to Letterplace ring
915  intvec u = 1,1,2; intvec v = 2,1,3; intvec w = 3,1,1;
916  // u = x^2y, v = yxz, w = zx^2 in intvec representation
917  list L = u,v,w;
918  ivL2lpI(L);// invokes the procedure, returns the ideal containing u,v,w
919}
920
921proc iv2lp(intvec I)
922"USAGE: iv2lp(I); I an intvec
923RETURN: poly
924PURPOSE:Transforming an intvec into the corresponding Letterplace polynomial
925ASSUME: - Intvec corresponds to a Letterplace monomial
926@*      - basering has to be a Letterplace ring
927NOTE:   - Assumptions will not be checked!
928EXAMPLE: example iv2lp; shows examples
929"
930{if (I[1] == 0) {return(1);}
931  int i = size(I);
932  if (i > attrib(basering,"uptodeg")) {ERROR("polynomial exceeds degreebound");}
933  int j; poly p = 1;
934  for (j = 1; j <= i; j++) {if (I[j] > 0) { p = lpMult(p,var(I[j]));}} //ignore zeroes, because they correspond to 1
935  return(p);
936}
937example
938{
939  "EXAMPLE:"; echo = 2;
940  ring r = 0,(x,y,z),dp;
941  def R = makeLetterplaceRing(5); // constructs a Letterplace ring
942  setring R; //sets basering to Letterplace ring
943  intvec u = 1,1,2; intvec v = 2,1,3; intvec w = 3,1,1;
944  // u = x^2y, v = yxz, w = zx^2 in intvec representation
945  iv2lp(u); // invokes the procedure and returns the corresponding poly
946  iv2lp(v);
947  iv2lp(w);
948}
949
950proc iv2lpList(list L)
951"USAGE: iv2lpList(L); L a list of intmats
952RETURN: ideal
953PURPOSE:Converting a list of intmats into an ideal of corresponding monomials
954ASSUME: - The rows of each intmat in L must correspond to a Letterplace monomial
955@*      - basering has to be a Letterplace ring
956EXAMPLE: example iv2lpList; shows examples
957"
958{checkAssumptions(0,L);
959  ideal G;
960  int i;
961  for (i = 1; i <= size(L); i++){G = G + iv2lpMat(L[i]);}
962  return(G);
963}
964example
965{
966  "EXAMPLE:"; echo = 2;
967  ring r = 0,(x,y,z),dp;
968  def R = makeLetterplaceRing(5); // constructs a Letterplace ring
969  setring R; // sets basering to Letterplace ring
970  intmat u[3][1] = 1,1,2; intmat v[1][3] = 2,1,3; intmat w[2][3] = 3,1,1,2,3,1;
971  // defines intmats of different size containing intvec representations of
972  // monomials as rows
973  list L = u,v,w;
974  print(u); print(v); print(w); // shows the intmats contained in L
975  iv2lpList(L); // returns the corresponding monomials as an ideal
976}
977
978
979proc iv2lpMat(intmat M)
980"USAGE: iv2lpMat(M); M an intmat
981RETURN: ideal
982PURPOSE:Converting an intmat into an ideal of the corresponding monomials
983ASSUME: - The rows of M must correspond to Letterplace monomials
984@*      - basering has to be a Letterplace ring
985EXAMPLE: example iv2lpMat; shows examples
986"
987{list L = M;
988  checkAssumptions(0,L);
989  kill L;
990  ideal G; poly p;
991  int i; intvec I;
992  for (i = 1; i <= nrows(M); i++)
993  { I = M[i,1..ncols(M)];
994    p = iv2lp(I);
995    G[size(G)+1] = p;
996  }
997  return(G);
998}
999example
1000{
1001  "EXAMPLE:"; echo = 2;
1002  ring r = 0,(x,y,z),dp;
1003  def R = makeLetterplaceRing(5); // constructs a Letterplace ring
1004  setring R; // sets basering to Letterplace ring
1005  intmat u[3][1] = 1,1,2; intmat v[1][3] = 2,1,3; intmat w[2][3] = 3,1,1,2,3,1;
1006  // defines intmats of different size containing intvec representations of
1007  // monomials as rows
1008  iv2lpMat(u); // returns the monomials contained in u
1009  iv2lpMat(v); // returns the monomials contained in v
1010  iv2lpMat(w); // returns the monomials contained in w
1011}
1012
1013proc lpId2ivLi(ideal G)
1014"USAGE: lpId2ivLi(G); G an ideal
1015RETURN: list
1016PURPOSE:Transforming an ideal into the corresponding list of intvecs
1017ASSUME: - basering has to be a Letterplace ring
1018EXAMPLE: example lpId2ivLi; shows examples
1019"
1020{
1021  int i,j,k;
1022  list M;
1023  checkAssumptions(0,M);
1024  for (i = 1; i <= size(G); i++) {M[i] = lp2iv(G[i]);}
1025  return(M);
1026}
1027example
1028{
1029  "EXAMPLE:"; echo = 2;
1030  ring r = 0,(x,y),dp;
1031  def R = makeLetterplaceRing(5); // constructs a Letterplace ring
1032  setring R; // sets basering to Letterplace ring
1033  ideal L = x(1)*x(2),y(1)*y(2),x(1)*y(2)*x(3);
1034  lpId2ivLi(L); // returns the corresponding intvecs as a list
1035}
1036
1037proc lp2iv(poly p)
1038"USAGE: lp2iv(p); p a poly
1039RETURN: intvec
1040PURPOSE:Transforming a monomial into the corresponding intvec
1041ASSUME: - basering has to be a Letterplace ring
1042NOTE:   - Assumptions will not be checked!
1043EXAMPLE: example lp2iv; shows examples
1044"
1045{p = normalize(lead(p));
1046  intvec I;
1047  int i,j;
1048  if (deg(p) > attrib(basering,"uptodeg")) {ERROR("Monomial exceeds degreebound");}
1049  if (p == 1) {return(I);}
1050  if (p == 0) {ERROR("Monomial is not allowed to equal zero");}
1051  intvec lep = leadexp(p);
1052  for ( i = 1; i <= attrib(basering,"lV"); i++) {if (lep[i] == 1) {I = i; break;}}
1053  for (i = (attrib(basering,"lV")+1); i <= size(lep); i++)
1054  {if (lep[i] == 1)
1055    { j = (i mod attrib(basering,"lV"));
1056      if (j == 0) {I = I,attrib(basering,"lV");}
1057      else {I = I,j;}
1058    }
1059    else { if (lep[i] > 1) {ERROR("monomial has a not allowed multidegree");}}
1060  }
1061  if (I[1] == 0) {ERROR("monomial has a not allowed multidegree");}
1062
1063  return(I);
1064}
1065example
1066{
1067  "EXAMPLE:"; echo = 2;
1068  ring r = 0,(x,y,z),dp;
1069  def R = makeLetterplaceRing(5); // constructs a Letterplace ring
1070  setring R; // sets basering to Letterplace ring
1071  poly p = x(1)*x(2)*z(3); poly q = y(1)*y(2)*x(3)*x(4);
1072  poly w= z(1)*y(2)*x(3)*z(4)*z(5);
1073  // p,q,w are some polynomials we want to transform into their
1074  // intvec representation
1075  lp2iv(p); lp2iv(q); lp2iv(w);
1076}
1077
1078proc lp2ivId(ideal G)
1079"USAGE: lp2ivId(G); G an ideal
1080RETURN: list
1081PURPOSE:Converting an ideal into an list of intmats,
1082@*      the corresponding intvecs forming the rows
1083ASSUME: - basering has to be a Letterplace ring
1084EXAMPLE: example lp2ivId; shows examples
1085"
1086{G = normalize(lead(G));
1087  intvec I; list L;
1088  checkAssumptions(0,L);
1089  int i,md;
1090  for (i = 1; i <= size(G); i++) { if (md <= deg(G[i])) {md = deg(G[i]);}}
1091  while (size(G) > 0)
1092  {ideal Gt;
1093    for (i = 1; i <= ncols(G); i++) {if (md == deg(G[i])) {Gt = Gt + G[i]; G[i] = 0;}}
1094    if (size(Gt) > 0)
1095    {G = simplify(G,2);
1096      intmat M [size(Gt)][md];
1097      for (i = 1; i <= size(Gt); i++) {M[i,1..md] = lp2iv(Gt[i]);}
1098      L = insert(L,M);
1099      kill M; kill Gt;
1100      md = md - 1;
1101    }
1102    else {kill Gt; md = md - 1;}
1103  }
1104  return(L);
1105}
1106example
1107{
1108  "EXAMPLE:"; echo = 2;
1109  ring r = 0,(x,y,z),dp;
1110  def R = makeLetterplaceRing(5); // constructs a Letterplace ring
1111  setring R; // sets basering to Letterplace ring
1112  poly p = x(1)*x(2)*z(3); poly q = y(1)*y(2)*x(3)*x(4);
1113  poly w = z(1)*y(2)*x(3)*z(4);
1114  // p,q,w are some polynomials we want to transform into their
1115  // intvec representation
1116  ideal G = p,q,w;
1117  // define the ideal containing p,q and w
1118  lp2ivId(G); // and return the list of intmats for this ideal
1119}
1120
1121// -----------------main procedures----------------------
1122
1123static proc lpGraphOfNormalWords(ideal G)
1124"USAGE: lpGraphOfNormalWords(G); G a set of monomials in a letterplace ring
1125RETURN: intmat
1126PURPOSE: Constructs the graph of normal words induced by G
1127@*:      the adjacency matrix of the graph of normal words induced by G
1128ASSUME: - basering is a Letterplace ring
1129- G are the leading monomials of a Groebner basis
1130"
1131{
1132  // construct the Graph of normal words [Studzinski page 78]
1133  // construct set of vertices
1134  int v = attrib(basering,"lV"); int d = attrib(basering,"uptodeg");
1135  ideal V; poly p,q,w;
1136  ideal LG = lead(G);
1137  int i,j,k,b; intvec E,Et;
1138  for (i = 1; i <= v; i++){V = V, var(i);}
1139  for (i = 1; i <= size(LG); i++)
1140  {
1141    E = leadexp(LG[i]);
1142    if (E == intvec(0)) {V = V,monomial(intvec(0));}
1143    else
1144    {
1145      for (j = 1; j < d; j++)
1146      {
1147        Et = E[(j*v+1)..(d*v)];
1148        if (Et == intvec(0)) {break;}
1149        else {V = V, monomial(Et);}
1150      }
1151    }
1152  }
1153  V = simplify(V,2+4);
1154  printf("V = %p", V);
1155
1156
1157  // construct incidence matrix
1158
1159  list LV = lpId2ivLi(V);
1160  intvec Ip,Iw;
1161  int n = size(V);
1162  intmat T[n+1][n];
1163  for (i = 1; i <= n; i++)
1164  {
1165    // printf("for1 (i=%p, n=%p)", i, n);
1166    p = V[i]; Ip = lp2iv(p);
1167    for (j = 1; j <= n; j++)
1168    {
1169      // printf("for2 (j=%p, n=%p)", j, n);
1170      k = 1; b = 1;
1171      q = V[j];
1172      w = lpNF(lpMult(p,q),LG);
1173      if (w <> 0)
1174      {
1175        Iw = lp2iv(w);
1176        while (k <= n)
1177        {
1178          // printf("while (k=%p, n=%p)", k, n);
1179          if (isPF(LV[k],Iw) > 0)
1180          {if (isPF(LV[k],Ip) == 0) {b = 0; k = n+1;} else {k++;}
1181          }
1182          else {k++;}
1183        }
1184        T[i,j] = b;
1185        //  print("Incidence Matrix:");
1186        // print(T);
1187      }
1188    }
1189  }
1190  return(T);
1191}
1192
1193// This proc is deprecated, see lpGkDim() in fpaprops.lib
1194/* proc lpGkDim(ideal G) */
1195/* "USAGE: lpGkDim(G); G an ideal in a letterplace ring */
1196/* RETURN: int */
1197/* PURPOSE: Determines the Gelfand Kirillov dimension of A/<G> */
1198/* @*:     -1 means it is infinite */
1199/* ASSUME: - basering is a Letterplace ring */
1200/* - G is a Groebner basis */
1201/* NOTE: see fpaprops.lib for a faster and more up to date version of this method */
1202/* " */
1203/* { */
1204/*   return(growthAlg(lpGraphOfNormalWords(G))); */
1205/* } */
1206
1207proc ivDHilbert(list L, int n, list #)
1208"USAGE: ivDHilbert(L,n[,degbound]); L a list of intmats, n an integer,
1209@*      degbound an optional integer
1210RETURN: list
1211PURPOSE:Computing the K-dimension and the Hilbert series
1212ASSUME: - basering is a Letterplace ring
1213@*      - all rows of each intmat correspond to a Letterplace monomial
1214@*      - if you specify a different degree bound degbound,
1215@*        degbound <= attrib(basering,uptodeg) holds
1216NOTE: - If L is the list returned, then L[1] is an integer corresponding to the
1217@*      dimension, L[2] is an intvec which contains the coefficients of the
1218@*      Hilbert series
1219@*    - If degbound is set, there will be a degree bound added. By default there
1220@*      is no degree bound
1221@*    - n is the number of variables
1222@*    - If I = L[2] is the intvec returned, then I[k] is the (k-1)-th coefficient of
1223@*      the Hilbert series.
1224@*    - If the K-dimension is known to be infinite, a degree bound is needed
1225EXAMPLE: example ivDHilbert; shows examples
1226"
1227{int degbound = 0;
1228  if (size(#) > 0){if (typeof(#[1])=="int"){if (#[1] > 0){degbound = #[1];}}}
1229  checkAssumptions(degbound,L);
1230  intvec H; int i,dimen;
1231  H = ivHilbert(L,n,degbound);
1232  for (i = 1; i <= size(H); i++){dimen = dimen + H[i];}
1233  L = dimen,H;
1234  return(L);
1235}
1236example
1237{
1238  "EXAMPLE:"; echo = 2;
1239  ring r = 0,(x,y),dp;
1240  def R = makeLetterplaceRing(5); // constructs a Letterplace ring
1241  R;
1242  setring R; // sets basering to Letterplace ring
1243  //some intmats, which contain monomials in intvec representation as rows
1244  intmat I1 [2][2] = 1,1,2,2; intmat I2 [1][3]  = 1,2,1;
1245  intmat J1 [1][2] =  1,1; intmat J2 [2][3] = 2,1,2,1,2,1;
1246  print(I1);
1247  print(I2);
1248  print(J1);
1249  print(J2);
1250  list G = I1,I2; // ideal, which is already a Groebner basis
1251  list I = J1,J2; // ideal, which is already a Groebner basis
1252  //the procedure without a degree bound
1253  ivDHilbert(G,2);
1254  // the procedure with degree bound 5
1255  ivDHilbert(I,2,5);
1256}
1257
1258proc ivDHilbertSickle(list L, int n, list #)
1259"USAGE: ivDHilbertSickle(L,n[,degbound]); L a list of intmats, n an integer,
1260@*      degbound an optional integer
1261RETURN: list
1262PURPOSE:Computing K-dimension, Hilbert series and mistletoes
1263ASSUME: - basering is a Letterplace ring.
1264@*      - All rows of each intmat correspond to a Letterplace monomial.
1265@*      - If you specify a different degree bound degbound,
1266@*        degbound <= attrib(basering,uptodeg) holds.
1267NOTE: - If L is the list returned, then L[1] is an integer, L[2] is an intvec
1268@*      which contains the coefficients of the Hilbert series and L[3]
1269@*      is a list, containing the mistletoes as intvecs.
1270@*    - If degbound is set, a degree bound will be added. By default there
1271@*      is no degree bound.
1272@*    - n is the number of variables.
1273@*    - If I = L[2] is the intvec returned, then I[k] is the (k-1)-th
1274@*      coefficient of the Hilbert series.
1275@*    - If the K-dimension is known to be infinite, a degree bound is needed
1276EXAMPLE: example ivDHilbertSickle; shows examples
1277"
1278{int degbound = 0;
1279  if (size(#) > 0){if (typeof(#[1])=="int"){if (#[1] > 0){degbound = #[1];}}}
1280  checkAssumptions(degbound,L);
1281  int i,dimen; list R;
1282  R = ivSickleHil(L,n,degbound);
1283  for (i = 1; i <= size(R[1]); i++){dimen = dimen + R[1][i];}
1284  R[3] = R[2]; R[2] = R[1]; R[1] = dimen;
1285  return(R);
1286}
1287example
1288{
1289  "EXAMPLE:"; echo = 2;
1290  ring r = 0,(x,y),dp;
1291  def R = makeLetterplaceRing(5); // constructs a Letterplace ring
1292  R;
1293  setring R; // sets basering to Letterplace ring
1294  //some intmats, which contain monomials in intvec representation as rows
1295  intmat I1 [2][2] = 1,1,2,2; intmat I2 [1][3]  = 1,2,1;
1296  intmat J1 [1][2] =  1,1; intmat J2 [2][3] = 2,1,2,1,2,1;
1297  print(I1);
1298  print(I2);
1299  print(J1);
1300  print(J2);
1301  list G = I1,I2;// ideal, which is already a Groebner basis
1302  list I = J1,J2; // ideal, which is already a Groebner basis
1303  ivDHilbertSickle(G,2); // invokes the procedure without a degree bound
1304  ivDHilbertSickle(I,2,3); // invokes the procedure with degree bound 3
1305}
1306
1307proc ivDimCheck(list L, int n)
1308"USAGE: ivDimCheck(L,n); L a list of intmats, n an integer
1309RETURN: int, 0 if the dimension is finite, or 1 otherwise
1310PURPOSE:Decides, whether the K-dimension is finite or not
1311ASSUME: - basering is a Letterplace ring.
1312@*      - All rows of each intmat correspond to a Letterplace monomial.
1313NOTE:   - n is the number of variables.
1314EXAMPLE: example ivDimCheck; shows examples
1315"
1316{checkAssumptions(0,L);
1317  int i,r;
1318  intvec P,H;
1319  for (i = 1; i <= size(L); i++)
1320  {P[i] = ncols(L[i]);
1321    if (P[i] == 1) {if (isInMat(H,L[i]) > 0) {ERROR("Quotient algebra is trivial");}}
1322  }
1323  if (size(L) == 0) {ERROR("GB is empty, quotient algebra corresponds to free algebra");}
1324  kill H;
1325  intmat S; int sd,ld; intvec V;
1326  sd = P[1]; ld = P[1];
1327  for (i = 2; i <= size(P); i++)
1328  {if (P[i] < sd) {sd = P[i];}
1329    if (P[i] > ld) {ld = P[i];}
1330  }
1331  sd = (sd - 1); ld = ld - 1;
1332  if (ld == 0) { return(allVars(L,P,n));}
1333  if (sd == 0) { for (i = 1; i <= size(L); i++){if (ncols(L[i]) == 1){S = createStartMat1(n,L[i]); break;}}}
1334  else {S = createStartMat(sd,n);}
1335  module M;
1336  for (i = 1; i <= nrows(S); i++)
1337  {V = S[i,1..ncols(S)];
1338    if (findCycle(V,L,P,n,ld,M)) {r = 1; break;}
1339  }
1340  return(r);
1341}
1342example
1343{
1344  "EXAMPLE:"; echo = 2;
1345  ring r = 0,(x,y),dp;
1346  def R = makeLetterplaceRing(5); // constructs a Letterplace ring
1347  R;
1348  setring R; // sets basering to Letterplace ring
1349  //some intmats, which contain monomials in intvec representation as rows
1350  intmat I1 [2][2] = 1,1,2,2; intmat I2 [1][3]  = 1,2,1;
1351  intmat J1 [1][2] =  1,1; intmat J2 [2][3] = 2,1,2,1,2,1;
1352  print(I1);
1353  print(I2);
1354  print(J1);
1355  print(J2);
1356  list G = I1,I2;// ideal, which is already a Groebner basis
1357  list I = J1,J2; // ideal, which is already a Groebner basis and which
1358  ivDimCheck(G,2); // invokes the procedure, factor is of finite K-dimension
1359  ivDimCheck(I,2); // invokes the procedure, factor is not of finite K-dimension
1360}
1361
1362proc ivHilbert(list L, int n, list #)
1363"USAGE: ivHilbert(L,n[,degbound]); L a list of intmats, n an integer,
1364@*      degbound an optional integer
1365RETURN: intvec, containing the coefficients of the Hilbert series
1366PURPOSE:Computing the Hilbert series
1367ASSUME: - basering is a Letterplace ring.
1368@*      - all rows of each intmat correspond to a Letterplace monomial
1369@*      - if you specify a different degree bound degbound,
1370@*       degbound <= attrib(basering,uptodeg) holds.
1371NOTE: - If degbound is set, a degree bound  will be added. By default there
1372@*      is no degree bound.
1373@*    - n is the number of variables.
1374@*    - If I is returned, then I[k] is the (k-1)-th coefficient of the Hilbert
1375@*      series.
1376@*    - If the K-dimension is known to be infinite, a degree bound is needed
1377EXAMPLE: example ivHilbert; shows examples
1378"
1379{int degbound = 0;
1380  if (size(#) > 0) {if (typeof(#[1])=="int"){if (#[1] > 0) {degbound = #[1];}}}
1381  intvec P,H; int i;
1382  for (i = 1; i <= size(L); i++)
1383  {P[i] = ncols(L[i]);
1384    if (P[i] == 1) {if ( isInMat(H,L[i]) > 0) {ERROR("Quotient algebra is trivial");}}
1385  }
1386  if (size(L) == 0) {ERROR("GB is empty, quotient algebra corresponds to free algebra");}
1387  H[1] = 1;
1388  checkAssumptions(degbound,L);
1389  if (degbound == 0)
1390  {int sd;
1391    intmat S;
1392    sd = P[1];
1393    for (i = 2; i <= size(P); i++) {if (P[i] < sd) {sd = P[i];}}
1394    sd = (sd - 1);
1395    if (sd == 0) { for (i = 1; i <= size(L); i++){if (ncols(L[i]) == 1){S = createStartMat1(n,L[i]); break;}}}
1396    else {S = createStartMat(sd,n);}
1397    if (intvec(S) == 0) {return(H);}
1398    for (i = 1; i <= sd; i++) {H = H,(n^i);}
1399    for (i = 1; i <= nrows(S); i++)
1400    {intvec St = S[i,1..ncols(S)];
1401      H = findHCoeff(St,n,L,P,H);
1402      kill St;
1403    }
1404    return(H);
1405  }
1406  else
1407  {for (i = 1; i <= size(P); i++)
1408    {if (P[i] > degbound) {ERROR("degreebound is too small, GB contains elements of higher degree");}}
1409    int sd;
1410    intmat S;
1411    sd = P[1];
1412    for (i = 2; i <= size(P); i++) {if (P[i] < sd) {sd = P[i];}}
1413    sd = (sd - 1);
1414    if (sd == 0) { for (i = 1; i <= size(L); i++){if (ncols(L[i]) == 1){S = createStartMat1(n,L[i]); break;}}}
1415    else {S = createStartMat(sd,n);}
1416    if (intvec(S) == 0) {return(H);}
1417    for (i = 1; i <= sd; i++) {H = H,(n^i);}
1418    for (i = 1; i <= nrows(S); i++)
1419    {intvec St = S[i,1..ncols(S)];
1420      H = findHCoeff(St,n,L,P,H,degbound);
1421      kill St;
1422    }
1423    return(H);
1424  }
1425}
1426example
1427{
1428  "EXAMPLE:"; echo = 2;
1429  ring r = 0,(x,y),dp;
1430  def R = makeLetterplaceRing(5); // constructs a Letterplace ring
1431  R;
1432  setring R; // sets basering to Letterplace ring
1433  //some intmats, which contain monomials in intvec representation as rows
1434  intmat I1 [2][2] = 1,1,2,2; intmat I2 [1][3]  = 1,2,1;
1435  intmat J1 [1][2] =  1,1; intmat J2 [2][3] = 2,1,2,1,2,1;
1436  print(I1);
1437  print(I2);
1438  print(J1);
1439  print(J2);
1440  list G = I1,I2; // ideal, which is already a Groebner basis
1441  list I = J1,J2; // ideal, which is already a Groebner basis
1442  ivHilbert(G,2); // invokes the procedure without any degree bound
1443  ivHilbert(I,2,5); // invokes the procedure with degree bound 5
1444}
1445
1446
1447proc ivKDim(list L, int n, list #)
1448"USAGE: ivKDim(L,n[,degbound]); L a list of intmats,
1449@*      n an integer, degbound an optional integer
1450RETURN: int, the K-dimension of A/<L>
1451PURPOSE:Computing the K-dimension of A/<L>
1452ASSUME: - basering is a Letterplace ring.
1453@*      - all rows of each intmat correspond to a Letterplace monomial
1454@*      - if you specify a different degree bound degbound,
1455@*        degbound <= attrib(basering,uptodeg) holds.
1456NOTE: - If degbound is set, a degree bound will be added. By default there
1457@*      is no degree bound.
1458@*    - n is the number of variables.
1459@*    - If the K-dimension is known to be infinite, a degree bound is needed
1460EXAMPLE: example ivKDim; shows examples
1461"
1462{int degbound = 0;
1463  if (size(#) > 0) {if (typeof(#[1])=="int"){if (#[1] > 0) {degbound = #[1];}}}
1464  intvec P,H; int i;
1465  for (i = 1; i <= size(L); i++)
1466  {P[i] = ncols(L[i]);
1467    if (P[i] == 1) {if ( isInMat(H,L[i]) > 0) {ERROR("Quotient algebra is trivial");}}
1468  }
1469  if (size(L) == 0) {ERROR("GB is empty, quotient algebra corresponds to free algebra");}
1470  kill H;
1471  checkAssumptions(degbound,L);
1472  if (degbound == 0)
1473  {int sd; int dimen = 1;
1474    intmat S;
1475    sd = P[1];
1476    for (i = 2; i <= size(P); i++) {if (P[i] < sd) {sd = P[i];}}
1477    sd = (sd - 1);
1478    if (sd == 0) { for (i = 1; i <= size(L); i++){if (ncols(L[i]) == 1){S = createStartMat1(n,L[i]); break;}}}
1479    else {S = createStartMat(sd,n);}
1480    if (intvec(S) == 0) {return(dimen);}
1481    for (i = 1; i <= sd; i++) {dimen = dimen +(n^i);}
1482    for (i = 1; i <= nrows(S); i++)
1483    {intvec St = S[i,1..ncols(S)];
1484      dimen = dimen + findDimen(St,n,L,P);
1485      kill St;
1486    }
1487    return(dimen);
1488  }
1489  else
1490  {for (i = 1; i <= size(P); i++)
1491    {if (P[i] > degbound) {ERROR("degreebound is too small, GB contains elements of higher degree");}}
1492    int sd; int dimen = 1;
1493    intmat S;
1494    sd = P[1];
1495    for (i = 2; i <= size(P); i++) {if (P[i] < sd) {sd = P[i];}}
1496    sd = (sd - 1);
1497    if (sd == 0) { for (i = 1; i <= size(L); i++){if (ncols(L[i]) == 1){S = createStartMat1(n,L[i]); break;}}}
1498    else {S = createStartMat(sd,n);}
1499    if (intvec(S) == 0) {return(dimen);}
1500    for (i = 1; i <= sd; i++) {dimen = dimen +(n^i);}
1501    for (i = 1; i <= nrows(S); i++)
1502    {intvec St = S[i,1..ncols(S)];
1503      dimen = dimen + findDimen(St,n,L,P, degbound);
1504      kill St;
1505    }
1506    return(dimen);
1507  }
1508}
1509example
1510{
1511  "EXAMPLE:"; echo = 2;
1512  ring r = 0,(x,y),dp;
1513  def R = makeLetterplaceRing(5); // constructs a Letterplace ring
1514  R;
1515  setring R; // sets basering to Letterplace ring
1516  //some intmats, which contain monomials in intvec representation as rows
1517  intmat I1 [2][2] = 1,1,2,2; intmat I2 [1][3]  = 1,2,1;
1518  intmat J1 [1][2] =  1,1; intmat J2 [2][3] = 2,1,2,1,2,1;
1519  print(I1);
1520  print(I2);
1521  print(J1);
1522  print(J2);
1523  list G = I1,I2; // ideal, which is already a Groebner basis
1524  list I = J1,J2; // ideal, which is already a Groebner basis
1525  ivKDim(G,2); // invokes the procedure without any degree bound
1526  ivKDim(I,2,5); // invokes the procedure with degree bound 5
1527}
1528
1529proc ivMis2Base(list M)
1530"USAGE: ivMis2Base(M); M a list of intvecs
1531RETURN: ideal, a K-base of the given algebra
1532PURPOSE:Computing the K-base out of given mistletoes
1533ASSUME: - The mistletoes have to be ordered lexicographically -> OrdMisLex.
1534@*        Otherwise there might some elements missing.
1535@*      - basering is a Letterplace ring.
1536@*      - mistletoes are stored as intvecs, as described in the overview
1537EXAMPLE: example ivMis2Base; shows examples
1538"
1539{
1540  //checkAssumptions(0,M);
1541  intvec L,A;
1542  if (size(M) == 0){ERROR("There are no mistletoes, so it appears your dimension is infinite!");}
1543  if (isInList(L,M) > 0) {print("1 is a mistletoe, therefore 1 is the only basis element"); return(list(intvec(0)));}
1544  int i,j,d,s;
1545  list Rt;
1546  Rt[1] = intvec(0);
1547  L = M[1];
1548  for (i = size(L); 1 <= i; i--) {Rt = insert(Rt,intvec(L[1..i]));}
1549  for (i = 2; i <= size(M); i++)
1550  {A = M[i]; L = M[i-1];
1551    s = size(A);
1552    if (s > size(L))
1553    {d = size(L);
1554      for (j = s; j > d; j--) {Rt = insert(Rt,intvec(A[1..j]));}
1555      A = A[1..d];
1556    }
1557    if (size(L) > s){L = L[1..s];}
1558    while (A <> L)
1559    {Rt = insert(Rt, intvec(A));
1560      if (size(A) > 1)
1561      {A = A[1..(size(A)-1)];
1562        L = L[1..(size(L)-1)];
1563      }
1564      else {break;}
1565    }
1566  }
1567  return(Rt);
1568}
1569example
1570{
1571  "EXAMPLE:"; echo = 2;
1572  ring r = 0,(x,y),dp;
1573  def R = makeLetterplaceRing(5); // constructs a Letterplace ring
1574  R;
1575  setring R; // sets basering to Letterplace ring
1576  intvec i1 = 1,2; intvec i2 = 2,1,2;
1577  // the mistletoes are xy and yxy, which are already ordered lexicographically
1578  list L = i1,i2;
1579  ivMis2Base(L); // returns the basis of the factor algebra
1580}
1581
1582
1583proc ivMis2Dim(list M)
1584"USAGE: ivMis2Dim(M); M a list of intvecs
1585RETURN: int, the K-dimension of the given algebra
1586PURPOSE:Computing the K-dimension out of given mistletoes
1587ASSUME: - The mistletoes have to be ordered lexicographically -> OrdMisLex.
1588@*        Otherwise the returned value may differ from the K-dimension.
1589@*      - basering is a Letterplace ring.
1590EXAMPLE: example ivMis2Dim; shows examples
1591"
1592{checkAssumptions(0,M);
1593  intvec L;
1594  if (size(M) == 0){ERROR("There are no mistletoes, so it appears your dimension is infinite!");}
1595  if (isInList(L,M) > 0) {print("1 is a mistletoe, therefore dim = 1"); return(1);}
1596  int i,j,d,s;
1597  j = 1;
1598  d = 1 + size(M[1]);
1599  for (i = 1; i < size(M); i++)
1600  {s = size(M[i]); if (s > size(M[i+1])){s = size(M[i+1]);}
1601    while ((M[i][j] == M[i+1][j]) && (j <= s)){j = j + 1;}
1602    d = d + size(M[i+1])- j + 1;
1603  }
1604  return(d);
1605}
1606example
1607{
1608  "EXAMPLE:"; echo = 2;
1609  ring r = 0,(x,y),dp;
1610  def R = makeLetterplaceRing(5); // constructs a Letterplace ring
1611  R;
1612  setring R; // sets basering to Letterplace ring
1613  intvec i1 = 1,2; intvec i2 = 2,1,2;
1614  // the mistletoes are xy and yxy, which are already ordered lexicographically
1615  list L = i1,i2;
1616  ivMis2Dim(L); // returns the dimension of the factor algebra
1617}
1618
1619proc ivOrdMisLex(list M)
1620"USAGE: ivOrdMisLex(M); M a list of intvecs
1621RETURN: list, containing the ordered intvecs of M
1622PURPOSE:Orders a given set of mistletoes lexicographically
1623ASSUME: - basering is a Letterplace ring.
1624- intvecs correspond to monomials
1625NOTE:   - This is preprocessing, it's not needed if the mistletoes are returned
1626@*        from the sickle algorithm.
1627@*      - Each entry of the list returned is an intvec.
1628EXAMPLE: example ivOrdMisLex; shows examples
1629"
1630{checkAssumptions(0,M);
1631  return(sort(M)[1]);
1632}
1633example
1634{
1635  "EXAMPLE:"; echo = 2;
1636  ring r = 0,(x,y),dp;
1637  def R = makeLetterplaceRing(5); // constructs a Letterplace ring
1638  setring R; // sets basering to Letterplace ring
1639  intvec i1 = 1,2,1; intvec i2 = 2,2,1; intvec i3 = 1,1; intvec i4 = 2,1,1,1;
1640  // the corresponding monomials are xyx,y^2x,x^2,yx^3
1641  list M = i1,i2,i3,i4;
1642  M;
1643  ivOrdMisLex(M);// orders the list of monomials
1644}
1645
1646proc ivSickle(list L, int n, list #)
1647"USAGE: ivSickle(L,n,[degbound]); L a list of intmats, n an int, degbound an
1648@*      optional integer
1649RETURN: list, containing intvecs, the mistletoes of A/<L>
1650PURPOSE:Computing the mistletoes for a given Groebner basis L
1651ASSUME: - basering is a Letterplace ring.
1652@*      - all rows of each intmat correspond to a Letterplace monomial
1653@*      - if you specify a different degree bound degbound,
1654@*        degbound <= attrib(basering,uptodeg) holds.
1655NOTE: - If degbound is set, a degree bound will be added. By default there
1656@*      is no degree bound.
1657@*    - n is the number of variables.
1658@*    - If the K-dimension is known to be infinite, a degree bound is needed
1659EXAMPLE: example ivSickle; shows examples
1660"
1661{list M;
1662  int degbound = 0;
1663  if (size(#) > 0){if (typeof(#[1])=="int"){if (#[1] > 0){degbound = #[1];}}}
1664  int i;
1665  intvec P,H;
1666  for (i = 1; i <= size(L); i++)
1667  {P[i] = ncols(L[i]);
1668    if (P[i] == 1) {if (isInMat(H,L[i]) > 0) {ERROR("Quotient algebra is trivial");}}
1669  }
1670  if (size(L) == 0) {ERROR("GB is empty, quotient algebra corresponds to free algebra");}
1671  kill H;
1672  checkAssumptions(degbound,L);
1673  if (degbound == 0)
1674  {intmat S; int sd;
1675    sd = P[1];
1676    for (i = 2; i <= size(P); i++) {if (P[i] < sd) {sd = P[i];}}
1677    sd = (sd - 1);
1678    if (sd == 0) { for (i = 1; i <= size(L); i++){if (ncols(L[i]) == 1){S = createStartMat1(n,L[i]); break;}}}
1679    else {S = createStartMat(sd,n);}
1680    if (intvec(S) == 0) {return(list (intvec(0)));}
1681    for (i = 1; i <= nrows(S); i++)
1682    {intvec St = S[i,1..ncols(S)];
1683      M = M + findmistletoes(St,n,L,P);
1684      kill St;
1685    }
1686    return(M);
1687  }
1688  else
1689  {for (i = 1; i <= size(P); i++)
1690    {if (P[i] > degbound) {ERROR("degreebound is too small, GB contains elements of higher degree");}}
1691    intmat S; int sd;
1692    sd = P[1];
1693    for (i = 2; i <= size(P); i++) {if (P[i] < sd) {sd = P[i];}}
1694    sd = (sd - 1);
1695    if (sd == 0) { for (i = 1; i <= size(L); i++){if (ncols(L[i]) == 1){S = createStartMat1(n,L[i]); break;}}}
1696    else {S = createStartMat(sd,n);}
1697    if (intvec(S) == 0) {return(list (intvec(0)));}
1698    for (i = 1; i <= nrows(S); i++)
1699    {intvec St = S[i,1..ncols(S)];
1700      M = M + findmistletoes(St,n,L,P,degbound);
1701      kill St;
1702    }
1703    return(M);
1704  }
1705}
1706example
1707{
1708  "EXAMPLE:"; echo = 2;
1709  ring r = 0,(x,y),dp;
1710  def R = makeLetterplaceRing(5); // constructs a Letterplace ring
1711  setring R; // sets basering to Letterplace ring
1712  //some intmats, which contain monomials in intvec representation as rows
1713  intmat I1 [2][2] = 1,1,2,2; intmat I2 [1][3]  = 1,2,1;
1714  intmat J1 [1][2] =  1,1; intmat J2 [2][3] = 2,1,2,1,2,1;
1715  print(I1);
1716  print(I2);
1717  print(J1);
1718  print(J2);
1719  list G = I1,I2; // ideal, which is already a Groebner basis
1720  list I =  J1,J2; // ideal, which is already a Groebner basis
1721  ivSickle(G,2); // invokes the procedure without any degree bound
1722  ivSickle(I,2,5); // invokes the procedure with degree bound 5
1723}
1724
1725proc ivSickleDim(list L, int n, list #)
1726"USAGE: ivSickleDim(L,n[,degbound]); L a list of intmats, n an integer, degbound
1727@*      an optional integer
1728RETURN: list
1729PURPOSE:Computing mistletoes and the K-dimension
1730ASSUME: - basering is a Letterplace ring.
1731@*      - all rows of each intmat correspond to a Letterplace monomial
1732@*      - if you specify a different degree bound degbound,
1733@*        degbound <= attrib(basering,uptodeg) holds.
1734NOTE: - If L is the list returned, then L[1] is an integer, L[2] is a list,
1735@*      containing the mistletoes as intvecs.
1736@*    - If degbound is set, a degree bound will be added. By default there
1737@*      is no degree bound.
1738@*    - n is the number of variables.
1739@*    - If the K-dimension is known to be infinite, a degree bound is needed
1740EXAMPLE: example ivSickleDim; shows examples
1741"
1742{list M;
1743  int degbound = 0;
1744  if (size(#) > 0){if (typeof(#[1])=="int"){if (#[1] > 0){degbound = #[1];}}}
1745  int i,dimen; list R;
1746  intvec P,H;
1747  for (i = 1; i <= size(L); i++)
1748  {P[i] = ncols(L[i]);
1749    if (P[i] == 1) {if (isInMat(H,L[i]) > 0) {ERROR("Quotient algebra is trivial, dimension equals zero");}}
1750  }
1751  if (size(L) == 0) {ERROR("GB is empty, quotient algebra corresponds to free algebra");}
1752  kill H;
1753  checkAssumptions(degbound,L);
1754  if (degbound == 0)
1755  {int sd; dimen = 1;
1756    intmat S;
1757    sd = P[1];
1758    for (i = 2; i <= size(P); i++) {if (P[i] < sd) {sd = P[i];}}
1759    sd = (sd - 1);
1760    if (sd == 0) { for (i = 1; i <= size(L); i++){if (ncols(L[i]) == 1){S = createStartMat1(n,L[i]); break;}}}
1761    else {S = createStartMat(sd,n);}
1762    if (intvec(S) == 0) {return(list(dimen,list(intvec(0))));}
1763    for (i = 1; i <= sd; i++) {dimen = dimen +(n^i);}
1764    R[1] = dimen;
1765    for (i = 1; i <= nrows(S); i++)
1766    {intvec St = S[i,1..ncols(S)];
1767      R = findMisDim(St,n,L,P,R);
1768      kill St;
1769    }
1770    return(R);
1771  }
1772  else
1773  {for (i = 1; i <= size(P); i++)
1774    {if (P[i] > degbound) {ERROR("degreebound is too small, GB contains elements of higher degree");}}
1775    int sd; dimen = 1;
1776    intmat S;
1777    sd = P[1];
1778    for (i = 2; i <= size(P); i++) {if (P[i] < sd) {sd = P[i];}}
1779    sd = (sd - 1);
1780    if (sd == 0) { for (i = 1; i <= size(L); i++){if (ncols(L[i]) == 1){S = createStartMat1(n,L[i]); break;}}}
1781    else {S = createStartMat(sd,n);}
1782    if (intvec(S) == 0) {return(list(dimen,list(intvec(0))));}
1783    for (i = 1; i <= sd; i++) {dimen = dimen +(n^i);}
1784    R[1] = dimen;
1785    for (i = 1; i <= nrows(S); i++)
1786    {intvec St = S[i,1..ncols(S)];
1787      R = findMisDim(St,n,L,P,R,degbound);
1788      kill St;
1789    }
1790    return(R);
1791  }
1792}
1793example
1794{
1795  "EXAMPLE:"; echo = 2;
1796  ring r = 0,(x,y),dp;
1797  def R = makeLetterplaceRing(5); // constructs a Letterplace ring
1798  setring R; // sets basering to Letterplace ring
1799  //some intmats, which contain monomials in intvec representation as rows
1800  intmat I1 [2][2] = 1,1,2,2; intmat I2 [1][3]  = 1,2,1;
1801  intmat J1 [1][2] =  1,1; intmat J2 [2][3] = 2,1,2,1,2,1;
1802  print(I1);
1803  print(I2);
1804  print(J1);
1805  print(J2);
1806  list G = I1,I2;// ideal, which is already a Groebner basis
1807  list I =  J1,J2; // ideal, which is already a Groebner basis
1808  ivSickleDim(G,2); // invokes the procedure without any degree bound
1809  ivSickleDim(I,2,5); // invokes the procedure with degree bound 5
1810}
1811
1812proc ivSickleHil(list L, int n, list #)
1813"USAGE:ivSickleHil(L,n[,degbound]); L a list of intmats, n an integer,
1814@*     degbound an optional integer
1815RETURN: list
1816PURPOSE:Computing the mistletoes and the Hilbert series
1817ASSUME: - basering is a Letterplace ring.
1818@*      - all rows of each intmat correspond to a Letterplace monomial
1819@*      - if you specify a different degree bound degbound,
1820@*        degbound <= attrib(basering,uptodeg) holds.
1821NOTE: - If L is the list returned, then L[1] is an intvec, L[2] is a list,
1822@*      containing the mistletoes as intvecs.
1823@*    - If degbound is set, a degree bound will be added. By default there
1824@*      is no degree bound.
1825@*    - n is the number of variables.
1826@*    - If I = L[1] is the intvec returned, then I[k] is the (k-1)-th
1827@*      coefficient of the Hilbert series.
1828@*    - If the K-dimension is known to be infinite, a degree bound is needed
1829EXAMPLE: example ivSickleHil; shows examples
1830"
1831{int degbound = 0;
1832  if (size(#) > 0) {if (typeof(#[1])=="int"){if (#[1] > 0) {degbound = #[1];}}}
1833  intvec P,H; int i; list R;
1834  for (i = 1; i <= size(L); i++)
1835  {P[i] = ncols(L[i]);
1836    if (P[i] == 1) {if ( isInMat(H,L[i]) > 0) {ERROR("Quotient algebra is trivial");}}
1837  }
1838  if (size(L) == 0) {ERROR("GB is empty, quotient algebra corresponds to free algebra");}
1839  H[1] = 1;
1840  checkAssumptions(degbound,L);
1841  if (degbound == 0)
1842  {int sd;
1843    intmat S;
1844    sd = P[1];
1845    for (i = 2; i <= size(P); i++) {if (P[i] < sd) {sd = P[i];}}
1846    sd = (sd - 1);
1847    if (sd == 0) { for (i = 1; i <= size(L); i++){if (ncols(L[i]) == 1){S = createStartMat1(n,L[i]); break;}}}
1848    else {S = createStartMat(sd,n);}
1849    if (intvec(S) == 0) {return(list(H,list(intvec (0))));}
1850    for (i = 1; i <= sd; i++) {H = H,(n^i);}
1851    R[1] = H; kill H;
1852    for (i = 1; i <= nrows(S); i++)
1853    {intvec St = S[i,1..ncols(S)];
1854      R = findHCoeffMis(St,n,L,P,R);
1855      kill St;
1856    }
1857    return(R);
1858  }
1859  else
1860  {for (i = 1; i <= size(P); i++)
1861    {if (P[i] > degbound) {ERROR("degreebound is too small, GB contains elements of higher degree");}}
1862    int sd;
1863    intmat S;
1864    sd = P[1];
1865    for (i = 2; i <= size(P); i++) {if (P[i] < sd) {sd = P[i];}}
1866    sd = (sd - 1);
1867    if (sd == 0) { for (i = 1; i <= size(L); i++){if (ncols(L[i]) == 1){S = createStartMat1(n,L[i]); break;}}}
1868    else {S = createStartMat(sd,n);}
1869    if (intvec(S) == 0) {return(list(H,list(intvec(0))));}
1870    for (i = 1; i <= sd; i++) {H = H,(n^i);}
1871    R[1] = H; kill H;
1872    for (i = 1; i <= nrows(S); i++)
1873    {intvec St = S[i,1..ncols(S)];
1874      R = findHCoeffMis(St,n,L,P,R,degbound);
1875      kill St;
1876    }
1877    return(R);
1878  }
1879}
1880example
1881{
1882  "EXAMPLE:"; echo = 2;
1883  ring r = 0,(x,y),dp;
1884  def R = makeLetterplaceRing(5); // constructs a Letterplace ring
1885  setring R; // sets basering to Letterplace ring
1886  //some intmats, which contain monomials in intvec representation as rows
1887  intmat I1[2][2] = 1,1,2,2; intmat I2[1][3]  = 1,2,1;
1888  intmat J1[1][2] =  1,1; intmat J2[2][3] = 2,1,2,1,2,1;
1889  print(I1);
1890  print(I2);
1891  print(J1);
1892  print(J2);
1893  list G = I1,I2;// ideal, which is already a Groebner basis
1894  list I =  J1,J2; // ideal, which is already a Groebner basis
1895  ivSickleHil(G,2); // invokes the procedure without any degree bound
1896  ivSickleHil(I,2,5); // invokes the procedure with degree bound 5
1897}
1898
1899proc lpDHilbert(ideal G, list #)
1900"USAGE: lpDHilbert(G[,degbound,n]); G an ideal, degbound, n optional integers
1901RETURN: list
1902PURPOSE:Computing K-dimension and Hilbert series, starting with a lp-ideal
1903ASSUME: - basering is a Letterplace ring.
1904@*      - if you specify a different degree bound degbound,
1905@*        degbound <= attrib(basering,uptodeg) holds.
1906NOTE: - If L is the list returned, then L[1] is an integer corresponding to the
1907@*      dimension, L[2] is an intvec which contains the coefficients of the
1908@*      Hilbert series
1909@*    - If degbound is set, there will be a degree bound added. 0 means no
1910@*      degree bound. Default: attrib(basering,uptodeg).
1911@*    - n can be set to a different number of variables.
1912@*      Default: n = attrib(basering, lV).
1913@*    - If I = L[2] is the intvec returned, then I[k] is the (k-1)-th
1914@*      coefficient of the Hilbert series.
1915@*    - If the K-dimension is known to be infinite, a degree bound is needed
1916EXAMPLE: example lpDHilbert; shows examples
1917"
1918{int degbound = attrib(basering,"uptodeg");int n = attrib(basering, "lV");
1919  if (size(#) > 0){if (typeof(#[1])=="int"){if (#[1] >= 0){degbound = #[1];}}}
1920  if (size(#) > 1){if (typeof(#[1])=="int"){if (#[2] > 0){n = #[2];}}}
1921  list L;
1922  L = lp2ivId(normalize(lead(G)));
1923  return(ivDHilbert(L,n,degbound));
1924}
1925example
1926{
1927  "EXAMPLE:"; echo = 2;
1928  ring r = 0,(x,y),dp;
1929  def R = makeLetterplaceRing(5); // constructs a Letterplace ring
1930  setring R; // sets basering to Letterplace ring
1931  ideal G = x(1)*x(2), y(1)*y(2),x(1)*y(2)*x(3); // ideal G contains a
1932  //Groebner basis
1933  lpDHilbert(G,5,2); // invokes procedure with degree bound 5 and 2 variables
1934  // note that the optional parameters are not necessary, due to the finiteness
1935  // of the K-dimension of the factor algebra
1936  lpDHilbert(G); // procedure with ring parameters
1937  lpDHilbert(G,0); // procedure without degreebound
1938}
1939
1940proc lpDHilbertSickle(ideal G, list #)
1941"USAGE: lpDHilbertSickle(G[,degbound,n]); G an ideal, degbound, n optional
1942@*      integers
1943RETURN: list
1944PURPOSE:Computing K-dimension, Hilbert series and mistletoes at once
1945ASSUME: - basering is a Letterplace ring.
1946@*      - if you specify a different degree bound degbound,
1947@*        degbound <= attrib(basering,uptodeg) holds.
1948NOTE: - If L is the list returned, then L[1] is an integer, the K-dimension,
1949@*      L[2] is an intvec, the Hilbert series and L[3] is an ideal,
1950@*      the mistletoes
1951@*    - If degbound is set, there will be a degree bound added. 0 means no
1952@*      degree bound. Default: attrib(basering,uptodeg).
1953@*    - n can be set to a different number of variables.
1954@*      Default: n = attrib(basering, lV).
1955@*    - If I = L[1] is the intvec returned, then I[k] is the (k-1)-th
1956@*      coefficient of the Hilbert series.
1957@*    - If the K-dimension is known to be infinite, a degree bound is needed
1958EXAMPLE: example lpDHilbertSickle; shows examples
1959"
1960{int degbound = attrib(basering,"uptodeg");int n = attrib(basering, "lV");
1961  if (size(#) > 0){if (typeof(#[1])=="int"){if (#[1] >= 0){degbound = #[1];}}}
1962  if (size(#) > 1){if (typeof(#[1])=="int"){if (#[2] > 0){n = #[2];}}}
1963  list L;
1964  L = lp2ivId(normalize(lead(G)));
1965  L = ivDHilbertSickle(L,n,degbound);
1966  L[3] =  ivL2lpI(L[3]);
1967  return(L);
1968}
1969example
1970{
1971  "EXAMPLE:"; echo = 2;
1972  ring r = 0,(x,y),dp;
1973  def R = makeLetterplaceRing(5); // constructs a Letterplace ring
1974  setring R; // sets basering to Letterplace ring
1975  ideal G = x(1)*x(2), y(1)*y(2),x(1)*y(2)*x(3); // ideal G contains a
1976  //Groebner basis
1977  lpDHilbertSickle(G,5,2); //invokes procedure with degree bound 5 and 2 variables
1978  // note that the optional parameters are not necessary, due to the finiteness
1979  // of the K-dimension of the factor algebra
1980  lpDHilbertSickle(G); // procedure with ring parameters
1981  lpDHilbertSickle(G,0); // procedure without degreebound
1982}
1983
1984proc lpHilbert(ideal G, list #)
1985"USAGE: lpHilbert(G[,degbound,n]); G an ideal, degbound, n optional integers
1986RETURN: intvec, containing the coefficients of the Hilbert series
1987PURPOSE:Computing the Hilbert series
1988ASSUME: - basering is a Letterplace ring.
1989@*      - if you specify a different degree bound degbound,
1990@*        degbound <= attrib(basering,uptodeg) holds.
1991NOTE: - If degbound is set, there will be a degree bound added. 0 means no
1992@*      degree bound. Default: attrib(basering,uptodeg).
1993@*    - n is the number of variables, which can be set to a different number.
1994@*      Default: attrib(basering, lV).
1995@*    - If I is returned, then I[k] is the (k-1)-th coefficient of the Hilbert
1996@*      series.
1997@*    - If the K-dimension is known to be infinite, a degree bound is needed
1998EXAMPLE: example lpHilbert; shows examples
1999"
2000{int degbound = attrib(basering,"uptodeg");int n = attrib(basering, "lV");
2001  if (size(#) > 0){if (typeof(#[1])=="int"){if (#[1] >= 0){degbound = #[1];}}}
2002  if (size(#) > 1){if (typeof(#[1])=="int"){if (#[2] > 0){n = #[2];}}}
2003  list L;
2004  L = lp2ivId(normalize(lead(G)));
2005  return(ivHilbert(L,n,degbound));
2006}
2007example
2008{
2009  "EXAMPLE:"; echo = 2;
2010  ring r = 0,(x,y),dp;
2011  def R = makeLetterplaceRing(5); // constructs a Letterplace ring
2012  setring R; // sets basering to Letterplace ring
2013  ideal G = x(1)*x(2), y(1)*y(2),x(1)*y(2)*x(3); // ideal G contains a
2014  //Groebner basis
2015  lpHilbert(G,5,2); // invokes procedure with degree bound 5 and 2 variables
2016  // note that the optional parameters are not necessary, due to the finiteness
2017  // of the K-dimension of the factor algebra
2018  lpDHilbert(G); // procedure with ring parameters
2019  lpDHilbert(G,0); // procedure without degreebound
2020}
2021
2022proc lpDimCheck(ideal G)
2023"USAGE: lpDimCheck(G);
2024RETURN: int, 1 if K-dimension of the factor algebra is infinite, 0 otherwise
2025PURPOSE:Checking a factor algebra for finiteness of the K-dimension
2026ASSUME: - basering is a Letterplace ring.
2027EXAMPLE: example lpDimCheck; shows examples
2028"
2029{int n = attrib(basering,"lV");
2030  list L;
2031  ideal R;
2032  R = normalize(lead(G));
2033  L = lp2ivId(R);
2034  return(ivDimCheck(L,n));
2035}
2036example
2037{
2038  "EXAMPLE:"; echo = 2;
2039  ring r = 0,(x,y),dp;
2040  def R = makeLetterplaceRing(5); // constructs a Letterplace ring
2041  setring R; // sets basering to Letterplace ring
2042  ideal G = x(1)*x(2), y(1)*y(2),x(1)*y(2)*x(3);
2043  // Groebner basis
2044  ideal I = x(1)*x(2), y(1)*x(2)*y(3), x(1)*y(2)*x(3);
2045  // Groebner basis
2046  lpDimCheck(G); // invokes procedure, factor algebra is of finite K-dimension
2047  lpDimCheck(I); // invokes procedure, factor algebra is of infinite Kdimension
2048}
2049
2050proc lpKDim(ideal G, list #)
2051"USAGE: lpKDim(G[,degbound, n]); G an ideal, degbound, n optional integers
2052RETURN: int, the K-dimension of the factor algebra
2053PURPOSE:Computing the K-dimension of a factor algebra, given via an ideal
2054ASSUME: - basering is a Letterplace ring
2055@*      - if you specify a different degree bound degbound,
2056@*        degbound <= attrib(basering,uptodeg) holds.
2057NOTE: - If degbound is set, there will be a degree bound added. 0 means no
2058@*      degree bound. Default: attrib(basering, uptodeg).
2059@*    - n is the number of variables, which can be set to a different number.
2060@*      Default: attrib(basering, lV).
2061@*    - If the K-dimension is known to be infinite, a degree bound is needed
2062EXAMPLE: example lpKDim; shows examples
2063"
2064{int degbound = attrib(basering, "uptodeg");int n = attrib(basering, "lV");
2065  if (size(#) > 0){if (typeof(#[1])=="int"){if (#[1] >= 0){degbound = #[1];}}}
2066  if (size(#) > 1){if (typeof(#[1])=="int"){if (#[2] > 0){n = #[2];}}}
2067  list L;
2068  L = lp2ivId(normalize(lead(G)));
2069  return(ivKDim(L,n,degbound));
2070}
2071example
2072{
2073  "EXAMPLE:"; echo = 2;
2074  ring r = 0,(x,y),dp;
2075  def R = makeLetterplaceRing(5); // constructs a Letterplace ring
2076  setring R; // sets basering to Letterplace ring
2077  ideal G = x(1)*x(2), y(1)*y(2),x(1)*y(2)*x(3);
2078  // ideal G contains a Groebner basis
2079  lpKDim(G); //procedure invoked with ring parameters
2080  // the factor algebra is finite, so the degree bound given by the Letterplace
2081  // ring is not necessary
2082  lpKDim(G,0); // procedure without any degree bound
2083}
2084
2085proc lpMis2Base(ideal M)
2086"USAGE: lpMis2Base(M); M an ideal
2087RETURN: ideal, a K-basis of the factor algebra
2088PURPOSE:Computing a K-basis out of given mistletoes
2089ASSUME: - basering is a Letterplace ring. G is a Letterplace ideal.
2090@*      - M contains only monomials
2091NOTE:   - The mistletoes have to be ordered lexicographically -> OrdMisLex.
2092EXAMPLE: example lpMis2Base; shows examples
2093"
2094{list L;
2095  L = lpId2ivLi(M);
2096  return(ivL2lpI(ivMis2Base(L)));
2097}
2098example
2099{
2100  "EXAMPLE:"; echo = 2;
2101  ring r = 0,(x,y),dp;
2102  def R = makeLetterplaceRing(5); // constructs a Letterplace ring
2103  setring R; // sets basering to Letterplace ring
2104  ideal L = x(1)*y(2),y(1)*x(2)*y(3);
2105  // ideal containing the mistletoes
2106  lpMis2Base(L); // returns the K-basis of the factor algebra
2107}
2108
2109proc lpMis2Dim(ideal M)
2110"USAGE: lpMis2Dim(M); M an ideal
2111RETURN: int, the K-dimension of the factor algebra
2112PURPOSE:Computing the K-dimension out of given mistletoes
2113ASSUME: - basering is a Letterplace ring.
2114@*      - M contains only monomials
2115NOTE:   - The mistletoes have to be ordered lexicographically -> OrdMisLex.
2116EXAMPLE: example lpMis2Dim; shows examples
2117"
2118{list L;
2119  L = lpId2ivLi(M);
2120  return(ivMis2Dim(L));
2121}
2122example
2123{
2124  "EXAMPLE:"; echo = 2;
2125  ring r = 0,(x,y),dp;
2126  def R = makeLetterplaceRing(5); // constructs a Letterplace ring
2127  setring R; // sets basering to Letterplace ring
2128  ideal L = x(1)*y(2),y(1)*x(2)*y(3);
2129  // ideal containing the mistletoes
2130  lpMis2Dim(L); // returns the K-dimension of the factor algebra
2131}
2132
2133proc lpOrdMisLex(ideal M)
2134"USAGE: lpOrdMisLex(M); M an ideal of mistletoes
2135RETURN: ideal, containing the mistletoes, ordered lexicographically
2136PURPOSE:A given set of mistletoes is ordered lexicographically
2137ASSUME: - basering is a Letterplace ring.
2138NOTE:   This is preprocessing, it is not needed if the mistletoes are returned
2139@*      from the sickle algorithm.
2140EXAMPLE: example lpOrdMisLex; shows examples
2141"
2142{return(ivL2lpI(sort(lpId2ivLi(M))[1]));}
2143example
2144{
2145  "EXAMPLE:"; echo = 2;
2146  ring r = 0,(x,y),dp;
2147  def R = makeLetterplaceRing(5); // constructs a Letterplace ring
2148  setring R; // sets basering to Letterplace ring
2149  ideal M = x(1)*y(2)*x(3), y(1)*y(2)*x(3), x(1)*x(2), y(1)*x(2)*x(3)*x(4);
2150  // some monomials
2151  lpOrdMisLex(M); // orders the monomials lexicographically
2152}
2153
2154proc lpSickle(ideal G,  list #)
2155"USAGE: lpSickle(G[,degbound,n]); G an ideal, degbound, n optional integers
2156RETURN: ideal
2157PURPOSE:Computing the mistletoes of K[X]/<G>
2158ASSUME: - basering is a Letterplace ring.
2159@*      - if you specify a different degree bound degbound,
2160@*        degbound <= attrib(basering,uptodeg) holds.
2161NOTE: - If degbound is set, there will be a degree bound added. 0 means no
2162@*      degree bound. Default: attrib(basering,uptodeg).
2163@*    - n is the number of variables, which can be set to a different number.
2164@*      Default: attrib(basering, lV).
2165@*    - If the K-dimension is known to be infinite, a degree bound is needed
2166EXAMPLE: example lpSickle; shows examples
2167"
2168{int degbound = attrib(basering,"uptodeg"); int n = attrib(basering, "lV");
2169  if (size(#) > 0){if (typeof(#[1])=="int"){if (#[1] >= 0){degbound = #[1];}}}
2170  if (size(#) > 1){if (typeof(#[1])=="int"){if (#[2] > 0){n = #[2];}}}
2171  list L; ideal R;
2172  R = normalize(lead(G));
2173  L = lp2ivId(R);
2174  L = ivSickle(L,n,degbound);
2175  R = ivL2lpI(L);
2176  return(R);
2177}
2178example
2179{
2180  "EXAMPLE:"; echo = 2;
2181  ring r = 0,(x,y),dp;
2182  def R = makeLetterplaceRing(5); // constructs a Letterplace ring
2183  setring R; // sets basering to Letterplace ring
2184  ideal G = x(1)*x(2), y(1)*y(2),x(1)*y(2)*x(3); // ideal G contains a
2185  //Groebner basis
2186  lpSickle(G); //invokes the procedure with ring parameters
2187  // the factor algebra is finite, so the degree bound given by the Letterplace
2188  // ring is not necessary
2189  lpSickle(G,0); // procedure without any degree bound
2190}
2191
2192proc lpSickleDim(ideal G, list #)
2193"USAGE: lpSickleDim(G[,degbound,n]); G an ideal, degbound, n optional integers
2194RETURN: list
2195PURPOSE:Computing the K-dimension and the mistletoes
2196ASSUME: - basering is a Letterplace ring.
2197@*      - if you specify a different degree bound degbound,
2198@*        degbound <= attrib(basering,uptodeg) holds.
2199NOTE: - If L is the list returned, then L[1] is an integer, the K-dimension,
2200@*      L[2] is an ideal, the mistletoes.
2201@*    - If degbound is set, there will be a degree bound added. 0 means no
2202@*      degree bound. Default: attrib(basering,uptodeg).
2203@*    - n is the number of variables, which can be set to a different number.
2204@*      Default: attrib(basering, lV).
2205@*    - If the K-dimension is known to be infinite, a degree bound is needed
2206EXAMPLE: example lpSickleDim; shows examples
2207"
2208{int degbound = attrib(basering,"uptodeg");int n = attrib(basering, "lV");
2209  if (size(#) > 0){if (typeof(#[1])=="int"){if (#[1] >= 0){degbound = #[1];}}}
2210  if (size(#) > 1){if (typeof(#[1])=="int"){if (#[2] > 0){n = #[2];}}}
2211  list L;
2212  L = lp2ivId(normalize(lead(G)));
2213  L = ivSickleDim(L,n,degbound);
2214  L[2] = ivL2lpI(L[2]);
2215  return(L);
2216}
2217example
2218{
2219  "EXAMPLE:"; echo = 2;
2220  ring r = 0,(x,y),dp;
2221  def R = makeLetterplaceRing(5); // constructs a Letterplace ring
2222  setring R; // sets basering to Letterplace ring
2223  ideal G = x(1)*x(2), y(1)*y(2),x(1)*y(2)*x(3); // ideal G contains a
2224  //Groebner basis
2225  lpSickleDim(G); // invokes the procedure with ring parameters
2226  // the factor algebra is finite, so the degree bound given by the Letterplace
2227  // ring is not necessary
2228  lpSickleDim(G,0); // procedure without any degree bound
2229}
2230
2231proc lpSickleHil(ideal G, list #)
2232"USAGE: lpSickleHil(G);
2233RETURN: list
2234PURPOSE:Computing the Hilbert series and the mistletoes
2235ASSUME: - basering is a Letterplace ring.
2236@*      - if you specify a different degree bound degbound,
2237@*        degbound <= attrib(basering,uptodeg) holds.
2238NOTE: - If L is the list returned, then L[1] is an intvec, corresponding to the
2239@*      Hilbert series, L[2] is an ideal, the mistletoes.
2240@*    - If degbound is set, there will be a degree bound added. 0 means no
2241@*      degree bound. Default: attrib(basering,uptodeg).
2242@*    - n is the number of variables, which can be set to a different number.
2243@*      Default: attrib(basering, lV).
2244@*    - If I = L[1] is the intvec returned, then I[k] is the (k-1)-th
2245@*      coefficient of the Hilbert series.
2246@*    - If the K-dimension is known to be infinite, a degree bound is needed
2247EXAMPLE: example lpSickleHil; shows examples
2248"
2249{int degbound = attrib(basering,"uptodeg");int n = attrib(basering, "lV");
2250  if (size(#) > 0){if (typeof(#[1])=="int"){if (#[1] >= 0){degbound = #[1];}}}
2251  if (size(#) > 1){if (typeof(#[1])=="int"){if (#[2] > 0){n = #[2];}}}
2252  list L;
2253  L = lp2ivId(normalize(lead(G)));
2254  L = ivSickleHil(L,n,degbound);
2255  L[2] =  ivL2lpI(L[2]);
2256  return(L);
2257}
2258example
2259{
2260  "EXAMPLE:"; echo = 2;
2261  ring r = 0,(x,y),dp;
2262  def R = makeLetterplaceRing(5); // constructs a Letterplace ring
2263  setring R; // sets basering to Letterplace ring
2264  ideal G = x(1)*x(2), y(1)*y(2),x(1)*y(2)*x(3); // ideal G contains a
2265  //Groebner basis
2266  lpSickleHil(G); // invokes the procedure with ring parameters
2267  // the factor algebra is finite, so the degree bound given by the Letterplace
2268  // ring is not necessary
2269  lpSickleHil(G,0); // procedure without any degree bound
2270}
2271
2272proc sickle(ideal G, list #)
2273"USAGE: sickle(G[,m, d, h, degbound]); G an ideal; m,d,h,degbound optional
2274@*      integers
2275RETURN: list
2276PURPOSE:Allowing the user to access all procs with one command
2277ASSUME: - basering is a Letterplace ring.
2278@*      - if you specify a different degree bound degbound,
2279@*        degbound <= attrib(basering,uptodeg) holds.
2280NOTE:   The returned object will always be a list, but the entries of the
2281@*      returned list may be very different
2282@* case m=1,d=1,h=1: see lpDHilbertSickle
2283@* case m=1,d=1,h=0: see lpSickleDim
2284@* case m=1,d=0,h=1: see lpSickleHil
2285@* case m=1,d=0,h=0: see lpSickle (this is the default case)
2286@* case m=0,d=1,h=1: see lpDHilbert
2287@* case m=0,d=1,h=0: see lpKDim
2288@* case m=0,d=0,h=1: see lpHilbert
2289@* case m=0,d=0,h=0: returns an error
2290@*    - If degbound is set, there will be a degree bound added. 0 means no
2291@*      degree bound. Default: attrib(basering,uptodeg).
2292@*    - If the K-dimension is known to be infinite, a degree bound is needed
2293EXAMPLE: example sickle; shows examples
2294"
2295{int m,d,h,degbound;
2296  m = 1; d = 0; h = 0; degbound = attrib(basering,"uptodeg");
2297  if (size(#) > 0) {if (typeof(#[1])=="int"){if (#[1] < 1) {m = 0;}}}
2298  if (size(#) > 1) {if (typeof(#[1])=="int"){if (#[2] > 0) {d = 1;}}}
2299  if (size(#) > 2) {if (typeof(#[1])=="int"){if (#[3] > 0) {h = 1;}}}
2300  if (size(#) > 3) {if (typeof(#[1])=="int"){if (#[4] >= 0) {degbound = #[4];}}}
2301  if (m == 1)
2302  {if (d == 0)
2303    {if (h == 0) {return(lpSickle(G,degbound,attrib(basering,"lV")));}
2304      else        {return(lpSickleHil(G,degbound,attrib(basering,"lV")));}
2305    }
2306    else
2307    {if (h == 0) {return(lpSickleDim(G,degbound,attrib(basering,"lV")));}
2308      else {return(lpDHilbertSickle(G,degbound,attrib(basering,"lV")));}
2309    }
2310  }
2311  else
2312  {if (d == 0)
2313    {if (h == 0) {ERROR("You request to do nothing, so relax and do so");}
2314      else        {return(lpHilbert(G,degbound,attrib(basering,"lV")));}
2315    }
2316    else
2317    {if (h == 0) {return(lpKDim(G,degbound,attrib(basering,"lV")));}
2318      else {return(lpDHilbert(G,degbound,attrib(basering,"lV")));}
2319    }
2320  }
2321}
2322example
2323{
2324  "EXAMPLE:"; echo = 2;
2325  ring r = 0,(x,y),dp;
2326  def R = makeLetterplaceRing(5); // constructs a Letterplace ring
2327  setring R; // sets basering to Letterplace ring
2328  ideal G = x(1)*x(2), y(1)*y(2),x(1)*y(2)*x(3);
2329  // G contains a Groebner basis
2330  sickle(G,1,1,1); // computes mistletoes, K-dimension and the Hilbert series
2331  sickle(G,1,0,0); // computes mistletoes only
2332  sickle(G,0,1,0); // computes K-dimension only
2333  sickle(G,0,0,1); // computes Hilbert series only
2334}
2335
2336proc ivMaxIdeal(int l, int lonly)
2337  "USAGE: lpMaxIdeal(l, lonly); l an integer, lonly an integer
2338  RETURN: list
2339  PURPOSE: computes a list of free monomials in intvec presentation
2340  @*       with length <= l
2341  @*       if donly <> 0, only monomials of degree d are returned
2342  ASSUME: - basering is a Letterplace ring.
2343  NOTE: see also lpMaxIdeal()
2344  "
2345{
2346  if (l < 0) {
2347    ERROR("l must not be negative")
2348  }
2349  list words;
2350  if (l == 0) {
2351     words = 0;
2352     return (words);
2353  }
2354  int lV = attrib(basering, "lV"); // variable count
2355  list prevWords;
2356  if (l > 1) {
2357    prevWords = ivMaxIdeal(l - 1, lonly);
2358  } else {
2359    prevWords = 0;
2360  }
2361  for (int i = 1; i <= size(prevWords); i++) {
2362    if (size(prevWords[i]) >= l - 1) {
2363      for (int j = 1; j <= lV; j++) {
2364        intvec word = prevWords[i];
2365        word[l] = j;
2366        words = insert(words, word);
2367        kill word;
2368      } kill j;
2369    }
2370  } kill i;
2371  if (!lonly && l > 1) {
2372    words = prevWords + words;
2373  }
2374  return (words);
2375}
2376example {
2377  "EXAMPLE:"; echo = 2;
2378  ring r = 0,(a,b,c),dp;
2379  def R = makeLetterplaceRing(7); setring R;
2380  ivMaxIdeal(1,0);
2381  ivMaxIdeal(2,0);
2382  ivMaxIdeal(2,1);
2383  ivMaxIdeal(4,0);
2384  ivMaxIdeal(4,1);
2385}
2386
2387proc lpMaxIdeal(int d, int donly)
2388  "USAGE: lpMaxIdeal(d, donly); d an integer, donly an integer
2389  RETURN: ideal
2390  PURPOSE: computes a list of free monomials of degree at most d
2391  @*       if donly <> 0, only monomials of degree d are returned
2392  ASSUME: - basering is a Letterplace ring.
2393  @*      - d <= attrib(basering,uptodeg) holds.
2394  NOTE: analogous to maxideal(d) in the commutative case
2395  "
2396{
2397  ivL2lpI(ivMaxIdeal(d, donly));
2398}
2399example {
2400  "EXAMPLE:"; echo = 2;
2401  ring r = 0,(a,b,c),dp;
2402  def R = makeLetterplaceRing(7); setring R;
2403  lpMaxIdeal(1,0);
2404  lpMaxIdeal(2,0);
2405  lpMaxIdeal(2,1);
2406  lpMaxIdeal(4,0);
2407  lpMaxIdeal(4,1);
2408}
2409
2410proc monomialBasis(int d, int donly, ideal J)
2411  "USAGE: monomialBasis(d, donly, J); d, donly integers, J an ideal
2412  RETURN: ideal
2413  PURPOSE: computes a list of free monomials in a Letterplace
2414  @*       basering R of degree at most d and not contained in <LM(J)>
2415  @*       if donly <> 0, only monomials of degree d are returned
2416  ASSUME: - basering is a Letterplace ring.
2417  @*      - d <= attrib(basering,uptodeg) holds.
2418  @*      - J is a Groebner basis
2419  "
2420{
2421  int nv = attrib(basering,"uptodeg");
2422  if ((d>nv) || (d<0) )
2423  {
2424    ERROR("incorrect degree");
2425  }
2426  nv = attrib(basering,"lV"); // nvars
2427  if (d==0)
2428  {
2429    return(ideal(1));
2430  }
2431  /* from now on d>=1 */
2432  ideal I;
2433  if (size(J)==0)
2434  {
2435    I = lpMaxIdeal(d,donly);
2436    if (!donly)
2437    {
2438      // append 1 as the first element; d>=1
2439      I = 1, I;
2440    }
2441    return( I );
2442  }
2443  // ok, Sickle misbehaves: have to remove all
2444  // elts from J of degree >d
2445  ideal JJ;
2446  int j; int sj = ncols(J);
2447  int cnt=0;
2448  for(j=1;j<=sj;j++)
2449  {
2450    if (deg(J[j]) <= d)
2451    {
2452      cnt++;
2453      JJ[cnt]=lead(J[j]); // only LMs are needed
2454    }
2455  }
2456  if (cnt==0)
2457  {
2458    // there are no elements in J of degree <= d
2459    // return free stuff and the 1
2460    I = monomialBasis(d, donly, std(0));
2461    if (!donly)
2462    {
2463      I = 1, I;
2464    }
2465    return(I);
2466  }
2467  // from here on, Ibase is not zero
2468  ideal Ibase = lpMis2Base(lpSickle(JJ,d)); // the complete K-basis modulo J up to d
2469  if (!donly)
2470  {
2471    // for not donly, give everything back
2472    // sort by DP starting with smaller terms
2473    Ibase = sort(Ibase,"Dp")[1];
2474    return(Ibase);
2475  }
2476  /* !donly: pick out only monomials of degree d */
2477  int i; int si = ncols(Ibase);
2478  cnt=0;
2479  I=0;
2480  for(i=1;i<=si;i++)
2481  {
2482    if (deg(Ibase[i]) == d)
2483    {
2484      cnt++;
2485      I[cnt]=Ibase[i];
2486    }
2487  }
2488  kill Ibase;
2489  return(I);
2490}
2491example {
2492  "EXAMPLE:"; echo = 2;
2493  ring r = 0,(x,y),dp;
2494  def R = makeLetterplaceRing(7); setring R;
2495  ideal J = x(1)*y(2)*x(3) - y(1)*x(2)*y(3);
2496  option(redSB); option(redTail);
2497  J = letplaceGBasis(J);
2498  J;
2499  monomialBasis(2,1,std(0));
2500  monomialBasis(2,0,std(0));
2501  monomialBasis(3,1,J);
2502  monomialBasis(3,0,J);
2503}
2504
2505
2506///////////////////////////////////////////////////////////////////////////////
2507/* vl: stuff for conversion to Magma and to SD
2508todo: doc, example
2509 */
2510static proc extractVars(r)
2511{
2512  int i = 1;
2513  int j = 1;
2514  string candidate;
2515  list result = list();
2516  for (i = 1; i<=nvars(r);i++)
2517  {
2518    candidate = string(var(i))[1,find(string(var(i)),"(")-1];
2519    if (!inList(result, candidate))
2520    {
2521      result = insert(result,candidate,size(result));
2522    }
2523  }
2524  return(result);
2525}
2526
2527static proc letterPlacePoly2MagmaString(poly h)
2528{
2529  int pos;
2530  string s = string(h);
2531  while(find(s,"("))
2532  {
2533    pos = find(s,"(");
2534    while(s[pos]!=")")
2535    {
2536      s = s[1,pos-1]+s[pos+1,size(s)-pos];
2537    }
2538    if (size(s)!=pos)
2539    {
2540      s = s[1,pos-1]+s[pos+1,size(s)-pos]; // The last (")")
2541    }
2542    else
2543    {
2544      s = s[1,pos-1];
2545    }
2546  }
2547  return(s);
2548}
2549
2550static proc letterPlaceIdeal2SD(ideal I, int upToDeg)
2551{
2552  int i;
2553  print("Don't forget to fill in the formal Data in the file");
2554  string result = "<?xml version=\"1.0\"?>"+newline+"<FREEALGEBRA createdAt=\"\" createdBy=\"Singular\" id=\"FREEALGEBRA/\">"+newline;
2555  result = result + "<vars>"+string(extractVars(basering))+"</vars>"+newline;
2556  result = result + "<basis>"+newline;
2557  for (i = 1;i<=size(I);i++)
2558  {
2559    result = result + "<poly>"+letterPlacePoly2MagmaString(I[i])+"</poly>"+newline;
2560  }
2561  result = result + "</basis>"+newline;
2562  result = result + "<uptoDeg>"+ string(upToDeg)+"</uptoDeg>"+newline;
2563  result = result + "<Comment></Comment>"+newline;
2564  result = result + "<Version></Version>"+newline;
2565  result = result + "</FREEALGEBRA>";
2566  return(result);
2567}
2568
2569
2570///////////////////////////////////////////////////////////////////////////////
2571
2572
2573proc tst_fpadim()
2574{
2575  example ivDHilbert;
2576  example ivDHilbertSickle;
2577  example ivDimCheck;
2578  example ivHilbert;
2579  example ivKDim;
2580  example ivMis2Base;
2581  example ivMis2Dim;
2582  example ivOrdMisLex;
2583  example ivSickle;
2584  example ivSickleHil;
2585  example ivSickleDim;
2586  example lpDHilbert;
2587  example lpDHilbertSickle;
2588  example lpHilbert;
2589  example lpDimCheck;
2590  example lpKDim;
2591  example lpMis2Base;
2592  example lpMis2Dim;
2593  example lpOrdMisLex;
2594  example lpSickle;
2595  example lpSickleHil;
2596  example lpSickleDim;
2597  example sickle;
2598  example ivL2lpI;
2599  example iv2lp;
2600  example iv2lpList;
2601  example iv2lpMat;
2602  example lp2iv;
2603  example lp2ivId;
2604  example lpId2ivLi;
2605  example lpSubstitute;
2606}
2607
2608/*
2609   Here are some examples one may try. Just copy them into your console.
2610   These are relations for braid groups, up to degree d:
2611
2612   LIB "fpadim.lib";
2613   ring r = 0,(x,y,z),dp;
2614   int d =10; // degree
2615   def R = makeLetterplaceRing(d);
2616   setring R;
2617   ideal I = y(1)*x(2)*y(3) - z(1)*y(2)*z(3), x(1)*y(2)*x(3) - z(1)*x(2)*y(3),
2618   z(1)*x(2)*z(3) - y(1)*z(2)*x(3), x(1)*x(2)*x(3) + y(1)*y(2)*y(3) +
2619   z(1)*z(2)*z(3) + x(1)*y(2)*z(3);
2620   option(prot);
2621   option(redSB);option(redTail);option(mem);
2622   ideal J = system("freegb",I,d,3);
2623   lpDimCheck(J);
2624   sickle(J,1,1,1,d);//Computes mistletoes, K-dimension and the Hilbert series
2625
2626
2627
2628   LIB "fpadim.lib";
2629   ring r = 0,(x,y,z),dp;
2630   int d =11; // degree
2631   def R = makeLetterplaceRing(d);
2632   setring R;
2633   ideal I = y(1)*x(2)*y(3) - z(1)*y(2)*z(3), x(1)*y(2)*z(3) - z(1)*x(2)*y(3),
2634   z(1)*x(2)*z(3) - y(1)*z(2)*x(3), x(1)*x(2)*x(3) + y(1)*y(2)*y(3) +
2635   z(1)*z(2)*z(3) + x(1)*y(2)*z(3);
2636   option(prot);
2637   option(redSB);option(redTail);option(mem);
2638   ideal J = system("freegb",I,d,3);
2639   lpDimCheck(J);
2640   sickle(J,1,1,1,d);
2641
2642
2643
2644   LIB "fpadim.lib";
2645   ring r = 0,(x,y,z),dp;
2646   int d  = 6; // degree
2647   def R  = makeLetterplaceRing(d);
2648   setring R;
2649   ideal I = y(1)*x(2)*y(3) - z(1)*y(2)*z(3), x(1)*y(2)*x(3) - z(1)*x(2)*y(3),
2650   z(1)*x(2)*z(3) - y(1)*z(2)*x(3), x(1)*x(2)*x(3) -2*y(1)*y(2)*y(3) + 3*z(1)*z(2)*z(3) -4*x(1)*y(2)*z(3) + 5*x(1)*z(2)*z(3)- 6*x(1)*y(2)*y(3) +7*x(1)*x(2)*z(3) - 8*x(1)*x(2)*y(3);
2651   option(prot);
2652   option(redSB);option(redTail);option(mem);
2653   ideal J = system("freegb",I,d,3);
2654   lpDimCheck(J);
2655   sickle(J,1,1,1,d);
2656 */
2657
2658/*
2659   Here are some examples, which can also be found in [studzins]:
2660
2661// takes up to 880Mb of memory
2662LIB "fpadim.lib";
2663ring r = 0,(x,y,z),dp;
2664int d =10; // degree
2665def R = makeLetterplaceRing(d);
2666setring R;
2667ideal I =
2668z(1)*z(2)*z(3)*z(4) + y(1)*x(2)*y(3)*x(4) - x(1)*y(2)*y(3)*x(4) - 3*z(1)*y(2)*x(3)*z(4), x(1)*x(2)*x(3) + y(1)*x(2)*y(3) - x(1)*y(2)*x(3), z(1)*y(2)*x(3)-x(1)*y(2)*z(3) + z(1)*x(2)*z(3);
2669option(prot);
2670option(redSB);option(redTail);option(mem);
2671ideal J = system("freegb",I,d,nvars(r));
2672lpDimCheck(J);
2673sickle(J,1,1,1,d); // dimension is 24872
2674
2675
2676LIB "fpadim.lib";
2677ring r = 0,(x,y,z),dp;
2678int d =10; // degree
2679def R = makeLetterplaceRing(d);
2680setring R;
2681ideal I = x(1)*y(2) + y(1)*z(2), x(1)*x(2) + x(1)*y(2) - y(1)*x(2) - y(1)*y(2);
2682option(prot);
2683option(redSB);option(redTail);option(mem);
2684ideal J = system("freegb",I,d,3);
2685lpDimCheck(J);
2686sickle(J,1,1,1,d);
2687 */
2688
2689
2690/*
2691   Example for computing GK dimension:
2692   returns a ring which contains an ideal I
2693   run gkDim(I) inside this ring and it should return 2n (the GK dimension
2694   of n-th Weyl algebra including evaluation operators).
2695
2696   static proc createWeylEx(int n, int d)
2697   "
2698   "
2699   {
2700   int baseringdef;
2701   if (defined(basering)) // if a basering is defined, it should be saved for later use
2702   {
2703   def save = basering;
2704   baseringdef = 1;
2705   }
2706   ring r = 0,(d(1..n),x(1..n),e(1..n)),dp;
2707   def R = makeLetterplaceRing(d);
2708   setring R;
2709   ideal I; int i,j;
2710
2711   for (i = 1; i <= n; i++)
2712   {
2713   for (j = i+1; j<= n; j++)
2714   {
2715   I[size(I)+1] = lpMult(var(i),var(j));
2716   }
2717   }
2718
2719   for (i = 1; i <= n; i++)
2720   {
2721   for (j = i+1; j<= n; j++)
2722   {
2723   I[size(I)+1] = lpMult(var(n+i),var(n+j));
2724   }
2725   }
2726   for (i = 1; i <= n; i++)
2727   {
2728   for (j = 1; j<= n; j++)
2729   {
2730   I[size(I)+1] = lpMult(var(i),var(n+j));
2731   }
2732   }
2733   for (i = 1; i <= n; i++)
2734   {
2735   for (j = 1; j<= n; j++)
2736   {
2737   I[size(I)+1] = lpMult(var(i),var(2*n+j));
2738   }
2739   }
2740   for (i = 1; i <= n; i++)
2741   {
2742   for (j = 1; j<= n; j++)
2743   {
2744   I[size(I)+1] = lpMult(var(2*n+i),var(n+j));
2745   }
2746   }
2747   for (i = 1; i <= n; i++)
2748   {
2749   for (j = 1; j<= n; j++)
2750   {
2751   I[size(I)+1] = lpMult(var(2*n+i),var(2*n+j));
2752   }
2753   }
2754   I = simplify(I,2+4);
2755   I = letplaceGBasis(I);
2756   export(I);
2757   if (baseringdef == 1) {setring save;}
2758   return(R);
2759   }
2760
2761proc TestGKAuslander3()
2762{
2763  ring r = (0,q),(z,x,y),(dp(1),dp(2));
2764  def R = makeLetterplaceRing(5); // constructs a Letterplace ring
2765  R; setring R; // sets basering to Letterplace ring
2766  ideal I;
2767  I = q*x(1)*y(2) - y(1)*x(2), z(1)*y(2) - y(1)*z(2), z(1)*x(2) - x(1)*z(2);
2768  I = letplaceGBasis(I);
2769  lpGkDim(I); // must be 3
2770  I = x(1)*y(2)*z(3) - y(1)*x(2), z(1)*y(2) - y(1)*z(2), z(1)*x(2) - x(1)*z(2);//gkDim = 2
2771  I = letplaceGBasis(I); // not finite BUT contains a poly in x,y only
2772  lpGkDim(I); // must be 4
2773
2774  ring r = 0,(y,x,z),dp;
2775  def R = makeLetterplaceRing(10); // constructs a Letterplace ring
2776  R; setring R; // sets basering to Letterplace ring
2777  ideal I;
2778  I = x(1)*y(2)*z(3) - y(1)*x(2), z(1)*y(2) - y(1)*z(2), z(1)*x(2) - x(1)*z(2);//gkDim = 2
2779  I = letplaceGBasis(I); // computed as it would be homogenized; infinite
2780  poly p = x(1)*y(2)*y(3)*x(4)-y(1)*x(2)*x(3)*y(4);
2781  lpNF(p, I); // 0 as expected
2782
2783  // with inverse of z
2784  ring r = 0,(iz,z,x,y),dp;
2785  def R = makeLetterplaceRing(11); // constructs a Letterplace ring
2786  R; setring R; // sets basering to Letterplace ring
2787  ideal I;
2788  I = x(1)*y(2)*z(3) - y(1)*x(2), z(1)*y(2) - y(1)*z(2), z(1)*x(2) - x(1)*z(2),
2789    iz(1)*y(2) - y(1)*iz(2), iz(1)*x(2) - x(1)*iz(2), iz(1)*z(2)-1, z(1)*iz(2) -1;
2790  I = letplaceGBasis(I); //
2791  setring r;
2792  def R2 = makeLetterplaceRing(23); // constructs a Letterplace ring
2793  setring R2; // sets basering to Letterplace ring
2794  ideal I = imap(R,I);
2795  lpGkDim(I);
2796
2797
2798  ring r = 0,(t,z,x,y),(dp(2),dp(2));
2799  def R = makeLetterplaceRing(20); // constructs a Letterplace ring
2800  R; setring R; // sets basering to Letterplace ring
2801  ideal I;
2802  I = x(1)*y(2)*z(3) - y(1)*x(2)*t(3), z(1)*y(2) - y(1)*z(2), z(1)*x(2) - x(1)*z(2),
2803    t(1)*y(2) - y(1)*t(2), t(1)*x(2) - x(1)*t(2), t(1)*z(2) - z(1)*t(2);//gkDim = 2
2804  I = letplaceGBasis(I); // computed as it would be homogenized; infinite
2805  LIB "elim.lib";
2806  ideal Inoz = nselect(I,intvec(2,6,10,14,18,22,26,30));
2807  for(int i=1; i<=20; i++)
2808  {
2809    Inoz=subst(Inoz,t(i),1);
2810  }
2811  ideal J = x(1)*y(2)*y(3)*x(4)-y(1)*x(2)*x(3)*y(4);
2812  J = letplaceGBasis(J);
2813
2814  poly p = x(1)*y(2)*y(3)*x(4)-y(1)*x(2)*x(3)*y(4);
2815  lpNF(p, I); // 0 as expected
2816
2817  ring r2 = 0,(x,y),dp;
2818  def R2 = makeLetterplaceRing(50); // constructs a Letterplace ring
2819  setring R2;
2820  ideal J = x(1)*y(2)*y(3)*x(4)-y(1)*x(2)*x(3)*y(4);
2821  J = letplaceGBasis(J);
2822}
2823
2824*/
2825
2826
2827/*   more tests : downup algebra A
2828LIB "fpadim.lib";
2829ring r = (0,a,b,g),(x,y),Dp;
2830def R = makeLetterplaceRing(6); // constructs a Letterplace ring
2831setring R;
2832poly F1 = g*x(1);
2833poly F2 = g*y(1);
2834ideal J = x(1)*x(2)*y(3)-a*x(1)*y(2)*x(3) - b*y(1)*x(2)*x(3) - F1,
2835x(1)*y(2)*y(3)-a*y(1)*x(2)*y(3) - b*y(1)*y(2)*x(3) - F2;
2836J = letplaceGBasis(J);
2837lpGkDim(J); // 3 == correct
2838
2839// downup algebra B
2840LIB "fpadim.lib";
2841ring r = (0,a,b,g, p(1..7),q(1..7)),(x,y),Dp;
2842def R = makeLetterplaceRing(6); // constructs a Letterplace ring
2843setring R;
2844ideal imn = 1, y(1)*y(2)*y(3), x(1)*y(2), y(1)*x(2), x(1)*x(2), y(1)*y(2), x(1), y(1);
2845int i;
2846poly F1, F2;
2847for(i=1;i<=7;i++)
2848{
2849F1 = F1 + p(i)*imn[i];
2850F2 = F2 + q(i)*imn[i];
2851}
2852ideal J = x(1)*x(2)*y(3)-a*x(1)*y(2)*x(3) - b*y(1)*x(2)*x(3) - F1,
2853x(1)*y(2)*y(3)-a*y(1)*x(2)*y(3) - b*y(1)*y(2)*x(3) - F2;
2854J = letplaceGBasis(J);
2855lpGkDim(J); // 3 == correct
2856
2857 */
Note: See TracBrowser for help on using the repository browser.