
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\Chapter{LiePRings in GAP}

This package introduces a new datastructure that allows to define and
compute with Lie $p$-rings in GAP. We first describe this datastructure
in the case of ordinary Lie $p$-rings; that is, Lie $p$-rings for a fixed
prime $p$ with given structure constants. Then we show how this datastructure
can also be used to define so-called 'generic' Lie $p$-rings; that is, 
Lie $p$-rings with indeterminate prime $p$.

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\Section{Ordinary Lie p-rings}

Let $p$ be a prime and let $L$ be a Lie $p$-ring of order $p^n$. Let 
$(l_1, \ldots, l_n)$ be a basis for $L$. Then there exist coefficients 
$c_{i,j,k} \in \{0, \ldots, p-1\}$ so that the following relations hold 
in $L$ for $1 \leq i,j \leq n$ with $i \neq j$:

$$ l_i \cdot l_j = \sum_{k=i+1}^n c_{i,j,k} l_k, $$
$$ p l_i = \sum_{k=i+1}^n c_{i,i,k} l_k. $$

These structure constants define the Lie $p$-ring $L$. As the multiplication 
in a Lie $p$-ring is anticommutative, it follows that $c_{i,j,k} = -c_{j,i,k}$ 
holds for each $k$ and each $i \neq j$. Thus the structure constants 
$c_{i,j,k}$ for $i \geq j$ are sufficient to define the Lie $p$-ring $L$.

This package contains the new datastructure <LiePRing> that allows to 
define Lie $p$-rings via their structure constants $c_{i,j,k}$. To use
this datastructure, we first collect all relevant information into a 
record as follows:
\beginitems
<dim> &
   the dimension $n$ of $L$;

<prime> &
   the prime $p$ of $L$;

<tab> &
   a list with structure constants 
   $[c_{1,1}, c_{2,1}, c_{2,2}, c_{3,1}, c_{3,2}, c_{3,3}, \ldots]$.
\enditems

Each entry $c_{i,j}$ in the list <tab> is a list $[k_1, c_{i,j,k_1}, k_2, 
c_{i,j,k_2}, \ldots]$ so that $k_1 \< k_2 \< \ldots$ and the entries 
$c_{i,j,k_1}, c_{i,j,k_2}, \ldots$ are the non-zero structure contants 
in the product $l_i \cdot l_j$. Thus if $l_i \cdot l_j = 0$, then $c_{i,j}$
is the empty list. If an entry in the list <tab> is not bound, then it is
assumed to be the empty list.

\> LiePRingBySCTable( SC )
\> LiePRingBySCTableNC( SC )

These functions create a <LiePRing> from the structure constants table
record $SC$. The first version checks that the multiplication defined by
<tab> is alternating and satisfies the Jacobi-identity, the second version
assumes that this is the case and omits these checks. These checks can
also be carried out independently via the following function.

\> CheckIsLiePRing( L )

This function takes as input an object <L> created via <LiePRingBySCTableNC>
and checks that the Jacobi identity holds in this ring.

The following example creates the Lie $2$-ring of order $8$ with trivial 
multiplication.  

\beginexample
gap> SC := rec( dim := 3, prime := 2, tab := [] );;
gap> L := LiePRingBySCTable(SC);
<LiePRing of dimension 3 over prime 2>
gap> l := BasisOfLiePRing(L);
[ l1, l2, l3 ]
gap> l[1]*l[2];
0
gap> 2*l[1];
0
gap> l[1] + l[2];
l1 + l2
\endexample

The next example creates a LiePRing of order $5^4$ with non-trivial 
multiplication.

\beginexample
gap> SC := rec( dim := 4, prime := 5, tab := [ [], [3, 1], [], [4, 1]]);;
gap> L := LiePRingBySCTableNC(SC);;
gap> ViewPCPresentation(L);
[l2,l1] = l3
[l3,l1] = l4
\endexample

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\Section{Generic Lie p-rings}

In a generic Lie $p$-ring, $p$ is allowed to be an indeterminate and 
the structure constants are allowed to be rational functions over a 
polynomial ring in a finite set of 
commuting indeterminates. It is generally assumed that the indeterminate
with name <p> represents the prime, the indeterminate with name <w> 
represents the smallest primitive root modulo the prime and there are 
further predefined indeterminates with the names <x>, <y>, <z>, <t>, 
<j>, <k>, <m>, <n>, <r>, <s>, <u> and <v>. These indeterminates are used 
in the database of Lie $p$-rings and they can be obtained via

\> IndeterminateByName( string )

The structure constants records for generic Lie $p$-rings are similar to
those for ordinary Lie $p$-rings, but have the additional entry <param>
which is a list containing all indeterminates used in the considered Lie
$p$-ring. We exhibit an example.

\beginexample
gap> p := IndeterminateByName("p");;
gap> x := IndeterminateByName("x");;
gap> S := rec( dim := 5, 
>              param := [ x ], 
>              prime := p, 
>              tab := [ [ 4, 1 ], [ 3, 1 ], [ 5, x ], [ 4, 1 ], [ 5, 1 ] ] );;
gap> L := LiePRingBySCTable(S);
<LiePRing of dimension 5 over prime p with parameters [ x ]>
gap> ViewPCPresentation(L);
p*l1 = l4
p*l2 = x*l5
[l2,l1] = l3
[l3,l1] = l4
[l3,l2] = l5
gap> l := BasisOfLiePRing(L);
[ l1, l2, l3, l4, l5 ]
gap> p*l[1];
l4
gap> l[1]+l[2];
l1 + l2
gap> l[1]*l[2];
-1*l3
\endexample

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\Section{Specialising Lie $p$-rings}

A generic Lie $p$-ring defines a family of ordinary Lie $p$-rings by 
evaluating the parameters contained in its presentation. It is generally 
assumed that the indeterminate $p$ is evaluated to a rational prime $P$ 
and the indeterminate $w$ is evaluated to the smallest primitive root 
modulo $P$ (this can be determined via <PrimitiveRootMod(P)>). All other 
indeterminates can take arbitrary integer values (usually these values are
in $\{0, \ldots, P-1\}$, but other choices are possible as well). The 
following functions allow to evaluate the indeterminates.

\> SpecialiseLiePRing(L, P, para, vals)

takes as input a generic Lie $p$-ring <L>, a rational prime <P>, 
a list of indeterminates <para> and a corresponding list of values
<vals>. The function returns a new Lie $p$-ring in which the prime 
<p> is evaluated to <P>, the parameter <w> is evaluated to 
<PrimitiveRootMod(P)> and the parameters in <para> are evaluated
to <vals>. 

\> SpecialisePrimeOfLiePRing(L, P)

this is a shortcut for <SpecialiseLiePRing(L, P, [], [])>. We exhibit
a some example applications.

\beginexample
gap> p := IndeterminateByName("p");;
gap> w := IndeterminateByName("w");;
gap> x := IndeterminateByName("x");;
gap> y := IndeterminateByName("y");;
gap> S := rec( dim := 7, 
>              param := [ w, x, y ], 
>              prime := p, 
>              tab := [ [  ], [ 6, 1 ], [ 6, 1 ], [ 7, 1 ], [  ], 
>                       [ 6, x, 7, y ], [  ], [ 7, 1 ], [ 6, w ] ] );;
gap> L := LiePRingBySCTable(S);
<LiePRing of dimension 7 over prime p with parameters [ w, x, y ]>
gap> ViewPCPresentation(L);
p*l2 = l6
p*l3 = x*l6 + y*l7
[l2,l1] = l6
[l3,l1] = l7
[l4,l2] = l7
[l4,l3] = w*l6
gap> SpecialiseLiePRing(L, 7, [x, y], [0,0]);
<LiePRing of dimension 7 over prime 7>
gap> ViewPCPresentation(last);
7*l2 = l6
[l2,l1] = l6
[l3,l1] = l7
[l4,l2] = l7
[l4,l3] = 3*l6
gap> SpecialiseLiePRing(L, 11, [x, y], [0,10]);
<LiePRing of dimension 7 over prime 11>
gap> ViewPCPresentation(last);
11*l2 = l6
11*l3 = 10*l7
[l2,l1] = l6
[l3,l1] = l7
[l4,l2] = l7
[l4,l3] = 2*l6
gap> Cartesian([0,1],[0,1]);
[ [ 0, 0 ], [ 0, 1 ], [ 1, 0 ], [ 1, 1 ] ]
gap> List(last, v -> SpecialiseLiePRing(L, 2, [x,y], v));
[ <LiePRing of dimension 7 over prime 2>, 
  <LiePRing of dimension 7 over prime 2>, 
  <LiePRing of dimension 7 over prime 2>, 
  <LiePRing of dimension 7 over prime 2> ]
\endexample

It is not necessary to specialise all parameters at once. In particular,
it is possible to leave the prime <p> as indeterminate and specialize only
some of the parameters. (Except for <w> which is linked to <p>.)

\beginexample
gap> SpecialiseLiePRing(L, p, [x], [0]);
<LiePRing of dimension 7 over prime p with parameters [ y, w ]>
gap> ViewPCPresentation(last);
p*l2 = l6
p*l3 = y*l7
[l2,l1] = l6
[l3,l1] = l7
[l4,l2] = l7
[l4,l3] = w*l6
gap> SpecialiseLiePRing(L, p, [y], [3]);
<LiePRing of dimension 7 over prime p with parameters [ x, w ]>
gap> ViewPCPresentation(last);
p*l2 = l6
p*l3 = x*l6 + 3*l7
[l2,l1] = l6
[l3,l1] = l7
[l4,l2] = l7
[l4,l3] = w*l6
\endexample

It is also possible to specialise the prime only, but leave all or
some of the parameters indeterminate. Note that specialising <p>
also specialises <w>. Again, we continue to use the generic Lie 
$p$-ring $L$ as above.

\beginexample
gap> SpecialisePrimeOfLiePRing(L, 29);
<LiePRing of dimension 7 over prime 29 with parameters [ y, x ]>
gap> ViewPCPresentation(last);
29*l2 = l6
29*l3 = x*l6 + y*l7
[l2,l1] = l6
[l3,l1] = l7
[l4,l2] = l7
[l4,l3] = 2*l6
\endexample

\> LiePValues(K)

if $K$ is obtained by specialising, then this attribute is set and 
contains the parameters that have been specialised and their values.

\beginexample
gap>  L := LiePRingsByLibrary(6)[14];
<LiePRing of dimension 6 over prime p with parameters [ x ]>
gap>  K := SpecialisePrimeOfLiePRing(L, 5);
<LiePRing of dimension 6 over prime 5 with parameters [ x ]>
gap> LiePValues(K);
[ [ p, w ], [ 5, 2 ] ]
\endexample

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\Section{Subrings of Lie p-rings}

Let $L$ be a Lie $p$-ring with basis $(l_1, \ldots, l_n)$ and let $U$ be a 
subring of $L$. Then $U$ is a Lie $p$-ring and thus also has a basis $(u_1, 
\ldots, u_m)$. For $1 \leq i \leq m$ we define the coefficients $a_{i,j} 
\in \{0, \ldots, p-1\}$ via 
$$ u_i = \sum_{j=1}^n a_{i,j} l_i $$
and we denote with $A$ the matrix with entries $a_{i,j}$. We say that the 
basis $(u_1, \ldots, u_m)$ is {\it induced} if $A$ is in upper triangular 
form. Further, the basis $(u_1, \ldots, u_m)$ is {\it canonical} if $A$ is 
in upper echelon form; that is, it is upper triangular, each row in $A$ has 
leading entry $1$ and there are $0$'s above the leading entry. Note that a
canonical basis is unique for the subring.

\> LiePSubring(L, gens)

Let <L> be a (generic or ordinary) Lie $p$-ring and let <gens> be a set of 
elements in <L>. This function determines a canonical basis for the subring
generated by <gens> in <L> and returns the LiePSubring of <L> generated by
<gens>. Note that this function may have strange effects for generic Lie
$p$-rings as the following example shows.

\beginexample
gap> L := LiePRingsByLibrary(6)[100];
<LiePRing of dimension 6 over prime p>
gap> l := BasisOfLiePRing(L);
[ l1, l2, l3, l4, l5, l6 ]
gap> U := LiePSubring(L, [5*l[1]]);
<LiePRing of dimension 3 over prime p>
gap> BasisOfLiePRing(U);
[ l1, l4, l6 ]
gap>  K := SpecialisePrimeOfLiePRing(L, 5);
<LiePRing of dimension 6 over prime 5>
gap>  b := BasisOfLiePRing(K);
[ l1, l2, l3, l4, l5, l6 ]
gap> LiePSubring(K, [5*b[1]]);
<LiePRing of dimension 2 over prime 5>
gap>  BasisOfLiePRing(last);
[ l4, l6 ]
gap> K := SpecialisePrimeOfLiePRing(L, 7);
<LiePRing of dimension 6 over prime 7>
gap> b := BasisOfLiePRing(K);
[ l1, l2, l3, l4, l5, l6 ]
gap> U := LiePSubring(K, [5*b[1]]);
<LiePRing of dimension 3 over prime 7>
gap> BasisOfLiePRing(U);
[ l1, l4, l6 ]
\endexample

\> LiePIdeal(L, gens)

return the ideal of $L$ generated by $gens$. This function computes a
an induced basis for the ideal.

\beginexample
gap> LiePIdeal(L, [l[1]]);
<LiePRing of dimension 5 over prime p>
gap> BasisOfLiePRing(last);
[ l1, l3, l4, l5, l6 ]
\endexample

\> LiePQuotient(L, U)

return a Lie $p$-ring isomorphic to $L/U$ where $U$ must be an ideal of
$L$. This function requires that $L$ is an ordinary Lie $p$-ring.

\beginexample
gap> LiePIdeal(K, [b[1]]);
<LiePRing of dimension 5 over prime 7>
gap> LiePIdeal(K, [b[2]]);
<LiePRing of dimension 4 over prime 7>
gap> LiePQuotient(K,last);
<LiePRing of dimension 2 over prime 7>
\endexample

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\Section{Elementary functions}

The functions described in this section work for ordinary and generic
Lie $p$-rings and their subrings.

\> PrimeOfLiePRing(L)

returns the underlying prime. This can either be an integer or an
indeterminate.

\> BasisOfLiePRing(L)

returns a basis for $L$.

\> DimensionOfLiePRing(L)

returns the dimension of <L>.

\> ParametersOfLiePRing(L)

returns the list of indeterminates involved in $L$. If $L$ is a subring
of a Lie $p$-ring defined by structure constants, then the parameters of
the parent are returned. 

\> ViewPCPresentation(L)

prints the presentation for $L$ with respect to its basis. 

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\Section{Series of subrings}

Let <L> be a generic or ordinary Lie $p$-ring or a subring of such such
a Lie $p$-ring. 

\> LiePLowerCentralSeries(L)

returns the lower central series of $L$. 

\> LiePLowerPCentralSeries(L)

returns the lower exponent-$p$ central series of $L$.

\> LiePDerivedSeries(L)

returns the derived series of $L$.

\> LiePMinimalGeneratingSet(L)

returns a minimal generating set of $L$; that is, a generating set of
smallest possible size.

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\Section{The Lazard correspondence}

The following function has been implemented by Willem de Graaf. It uses
the Baker-Campbell-Hausdorff formula as described in \cite{CGV12} and it 
is based on the Liering package \cite{CdG10}.

\> PGroupByLiePRing(L)

Let <L> be an ordinary Lie $p$-ring with $cl(L) \< p$. Then this function 
returns the $p$-group $G$ obtained from $L$ via the Lazard correspondence. 


