source: git/Singular/LIB/fpadim.lib @ 61fbaf

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