source: git/Singular/LIB/fpadim.lib @ 7e51648

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