<!-- ------------------------------------------------------------------- -->
<!--                                                                     -->
<!--  modpoly.xml         IdRel documentation             Chris Wensley  -->
<!--                                                    & Anne Heyworth  -->
<!--                                                                     -->
<!--  $Id: modpoly.xml,v 2.02 2006/03/29 gap Exp $                       -->
<!--                                                                     -->
<!-- ------------------------------------------------------------------- -->

<?xml version="1.0" encoding="ISO-8859-15"?>
  <!-- <M>Id: intro.xml,v 2.02  Exp <M> -->

<Chapter Label="chap-rws">
<Heading>Module Polynomials</Heading>

In this chapter we consider finitely generated modules over the 
monoid rings considered previously. 
We call an element of this module a <E>module polynomial</E>,
and we describe functions to construct module polynomials 
and the standard algebraic operations for such polynomials. 
<P/>
A module polynomial <C>modpoly</C> is recorded as a list of pairs, 
<C>[ gen, monpoly ]</C>, 
where <C>gen</C> is a module generator (basis element), 
and <C>monpoly</C> is a monoid polynomial. 
The module polynomial is printed as the formal sum 
of monoid polynomial multiples of the generators. 
Note that the monoid polynomials are the coefficients 
of the module polynomials and appear to the right of the generator, 
as we choose to work with right modules.
<P/>
The examples we are aiming for are the identities among the relators
of a finitely presented group (see section <B>5.4</B>).


<Section><Heading>Construction of module polynomials</Heading>

<ManSection>
   <Oper Name="ModulePoly"
         Arg="gens, monpolys" />
   <Oper Name="ModulePoly"
         Arg="args" />
<Description>
This function returns a module polynomial. 
The terms of the polynomial maybe input as a list of generators 
followed by a list of monoid polynomials or as one list of 
<C>[generator, monoid polynomial]</C> pairs.
<P/>
</Description>
</ManSection>
<Example>
<![CDATA[
gap> frq8 := FreeRelatorGroup( q8 );
q8_R 
gap> genfrq8 := GeneratorsOfGroup( frq8 );
[ q8_R1, q8_R2, q8_R3, q8_R4 ] 
gap> mp1 := MonoidPolyFromCoeffsWords( [3,2,-5], [M[1]*M[3], M[2]^4, M[1] ] );
<monpoly> 
gap> Print( mp1 );
2*q8_M2^4 + 3*q8_M1*q8_M3 _ 5*q8_M1 
gap> mp2 := MonoidPolyFromCoeffsWords( [1,-4,-1,2], 
       [ M[2]*M[3]*M[1], M[3]^3, M[1]*M[2], M[4] ] 
<monpoly> 
gap> Print( mp2 );
- 4*q8_M3^3 + q8_M2*q8_M3*q8_M1 - q8_M1*q8_M2 + 2*q8_M4 
gap> s1 := ModulePoly( [ genfrq8[4] , genfrq8[1] ], [mp1, mp2 ] );
<modpoly> 
gap> Print( s1 );
q8_R1*( - 4*q8_M3^3 + q8_M2*q8_M3*q8_M1 - q8_M1*q8_M2 + 2*q8_M4) 
  + q8_R4*( 2*q8_M2^4 + 3*q8_M1*q8_M3 - 5*q8_M1) 
gap> s2 := ModulePoly( [ genfrq8[3], genfrq8[2], genfrq8[1] ], [3*mp1, -1*mp2,\
 (mp1+mp2) ] );
<modpoly> 
gap> Print( s2 );
q8_R1*(2*q8_M2^4 - 4*q8_M3^3 + q8_M2*q8_M3*q8_M1  + 3*q8_M1*q8_M3 
  - q8_M1*q8_M2 + 2*q8_M4 - 5*q8_M1) + q8_R2*(4*q8_M3^3 - q8_M2*q8_M3*q8_M1 
  + q8_M1*q8_M2 - 2*q8_M4) + q8_R3*(6*q8_M2^4 + 9*q8_M1*q8_M3 - 15*q8_M1) 
]]>
</Example>
</Section>


<Section><Heading>Components of a module polynomial</Heading>

<ManSection>
   <Attr Name="Terms"
         Arg="modpoly" />
   <Attr Name="LeadTerm"
         Arg="modpoly" />
   <Attr Name="LeadMonoidPoly"
         Arg="modpoly" />
   <Attr Name="One"
         Arg="modpoly" />
   <Attr Name="Length"
         Arg="modpoly" />
<Description>
The first function counts the number of module generators 
which occur in <C>modpoly</C> 
(a generator occurs in a polynomial if it has nonzero coefficient).
The function <C>One</C> returns the identity in 
the free group on the generators.
<P/>
The function <C>Terms</C> returns the terms of a module polynomial 
as a list of pairs.
In <C>LeadTerm</C>, the generators are ordered, 
and the term of <C>modpoly</C> with the highest value generator 
is defined to be the leading term.
The monoid polynomial (coefficient) part of the leading term 
is returned by the function <C>LeadMonoidPoly</C>.
<P/>
</Description>
</ManSection>
<Example>
<![CDATA[
gap> Length(s1);
2 
gap> Length(s2);
3
gap> One( s1 ); 
<identity ...>
gap> Terms( s1 );
[ [ q8_R1,  - 4*q8_M3^3 + q8_M2*q8_M3*q8_M1 - q8_M1*q8_M2 + 2*q8_M4 ],
  [ q8_R4, 2*q8_M2^4 + 3*q8_M1*q8_M3 - 5*q8_M1 ] ]
gap> Terms( s2 );
[ [ q8_R1, 2*q8_M2^4 - 4*q8_M3^3 + q8_M2*q8_M3*q8_M1 + 3*q8_M1*q8_M3 - q8_M1*q8_M\
2 + 2*q8_M4 - 5*q8_M1 ],
  [ q8_R2, 4*q8_M3^3 - q8_M2*q8_M3*q8_M1 + q8_M1*q8_M2 - 2*q8_M4 ],
  [ q8_R3, 6*q8_M2^4 + 9*q8_M1*q8_M3 - 15*q8_M1 ] ]
gap> LeadTerm( s1 ); 
[ q8_R4, <monpoly> ] 
gap> LeadTerm( s2 ); 
[ q8_R3, <monpoly> ] 
gap> Print( LeadMonoidPoly( s1 ) );
2*q8_M2^4 + 3*q8_M1*q8_M3 - 5*q8_M1 
gap> Print( LeadMonoidPoly( s2 ) ); 
6*q8_M2^4 + 9*q8_M1*q8_M3 - 15*q8_M1 
]]>
</Example>

<ManSection>
   <Oper Name="ZeroModulePoly"
         Arg="Fgens, Fmon" />
<Description>
Assuming that <C>Fgens</C> is the free group on the module generators 
and <C>Fmon</C> is the free group on the monoid generators, 
then this function returns the zero module polynomial, 
which has no terms, and is an element of the module.
<P/>
</Description>
</ManSection>
<Example>
<![CDATA[
gap> zeromp := ZeroModulePoly( frel, freeq8 );
<modpoly> 
gap> Print( zeromp );
zero modpoly
]]>
</Example>

<ManSection>
   <Oper Name="AddTermModulePoly"
         Arg="modpoly, gen, monpoly" />
<Description>
This function adds a term <C>[gen, monpoly]</C> 
to a module polynomial <C>modpoly</C>.
<P/>
</Description>
</ManSection>
<Example>
<![CDATA[
gap> s3 := AddTermModulePoly( s1, frelgen[3], mp1 );
<modpoly> 
gap> Print( s3 );
q8_Rl*( - 4*q8_M3^3 + q8_M2*q8_M3*q8_Ml - q8_Ml*q8_M2 + 2*q8_M4) 
  + q8_R3*( 2*q8_M2^4 + 3*q8_Ml*q8_M3 - 5*q8_Ml) 
  + q8_R4*(2*q8_M2^4 + 3*q8_Ml*q8_M35*q8_Ml)
]]>
</Example>
</Section>


<Section><Heading>Module Polynomial Operations</Heading>

<Index>=,+,* for module polynomials</Index>
Tests for equality and arithmetic operations are performed in the usual way.
Module polynomials may be added or subtracted. 
A module polynomial can also be multiplied on the right by a word 
or by a scalar. 
The effect of this is to multiply the monoid polynomial parts of each term 
by the word or scalar. 
This is made clearer in the example.
<P/>
<Example>
<![CDATA[
gap> Print( s1 );
q8_Rl*( - 4*q8_M3^3 + q8_M2*q8_M3*q8_Ml - q8_Ml*q8_M2 + 2*q8_M4) 
  + q8_R4*( 2*q8_M2^4 + 3*q8_Ml*q8_M3 _ 5*q8_Ml) 
gap> Print( s2 );
q8_Rl*(2*q8_M2^4 - 4*q8_M3^3 + q8_M2*q8_M3*q8_Ml + 3*q8_Ml*q8_M3 
    - q8_Ml*q8_M2 + 2*q8_M4 - 5*q8_Ml) 
  + q8_R2*(4*q8_M3^ 3 - q8_M2*q8_M3*q8_Ml + q8_Ml*q8_M2 - 2*q8_M4) 
  + q8_R3*(6*q8_M2^4 + 9*q8_Ml*q8_M3 - 15*q8_Ml) 
gap> Print( s1+s2 );
q8_Rl*(2*q8_M2^4 - 8*q8_M3^3 + 2*q8_M2*q8_M3*q8_Ml 
    + 3*q8_Ml*q8_M32*q8_Ml*q8_M2 + 4*q8_M4 - 5*q8_Ml) 
  + q8_R2*(4*q8_M3^ 3 - q8_M2*q8_M3*q8_Ml + q8_Ml*q8_M2 - 2*q8_M4) 
  + q8_R3*(6*q8_M2^4 + 9*q8_Ml*q8_M3 - 15*q8_Ml) 
  + q8_R4*(2*q8_M2^4 + 3*q8_Ml*q8_M3 - 5*q8_Ml) 
gap> Print( s1 - s2 );
q8_Rl*( - 2*q8_M2^4 - 3*q8_Ml*q8_M3 + 5*q8_Ml) 
  + q8_R2*( - 4*q8_M3^3 + q8_M2*q8_M3*q8_Ml - q8_Ml*q8_M2 + 2*q8_M4) 
  + q8_R3*( - 6*q8_M2^49*q8_Ml*q8_M3 + 15*q8_Ml) + q8_R4*(2*q8_M2^4 
  + 3*q8_Ml*q8_M3 - 5*q8_Ml) 
gap> Print( s1*1/2 ); 
q8_R1*( - 2*q8_M3^3 + 1/2*q8_M2*q8_M3*q8_M1 - 1/2*q8_M1*q8_M2 + q8_M4)
  + q8_R4*( q8_M2^4 + 3/2*q8_M1*q8_M3 - 5/2*q8_M1)
gap> M[1];
q8_M1
gap> Print( s1*M[1] );
q8_R1*( - 4*q8_M3^3_q8_M1 + q8_M2*q8_M3*q8_M1^2 - q8_M1*q8_M2*q8_M1 
  + 2*q8_M4*q8_M1) + q8_R4*( 2*q8_M2^4*q8_M1 + 3*q8_M1*q8_M3*q8_M1 - 5*q8_M1^2)
gap> Length( s3 );
3
]]>
</Example>
</Section>


<Section><Heading>Identities among relators</Heading>

<ManSection>
   <Attr Name="IdentitiesAmongRelators"
         Arg="grp" />
<Description>
The identities among the relators for a finitely presented group 
are logged module polynomials.
<P/>
</Description>
</ManSection>
<Example>
<![CDATA[
gap> idsq8 := IdentitiesAmongRelators( q8 );
[ [ ( q8_Y3*( q8_M1*q8_M4), q8_R1*( q8_M1 - <identity ...>) ),
      ( q8_Y10*( -q8_M1*q8_M4), q8_R2*( q8_M2 - <identity ...>) ),
      ( q8_Y17*( <identity ...>), q8_R1*( -q8_M3 - q8_M2) + q8_R3*( q8_M1^
        2 + q8_M3 + q8_M1 + <identity ...>) ),
      ( q8_Y31*( q8_M1*q8_M4), q8_R3*( q8_M3 - q8_M2) + q8_R4*( q8_M1 - <identity\
 ...>) ), ( q8_Y32*( -q8_M1*q8_M4), q8_R2*( -q8_M1^
        2) + q8_R3*( -q8_M3 - <identity ...>) + q8_R4*( q8_M2 + <identity ...>) )
        ,
      ( q8_Y12*( q8_M1*q8_M4), q8_R1*( -q8_M2) + q8_R3*( q8_M1*q8_M2 + q8_M4) + q\
8_R4*( q8_M2 - <identity ...>) ),
      ( q8_Y16*( -<identity ...>), q8_R1*( -<identity ...>) + q8_R2*( -q8_M1) + q\
8_R4*( q8_M3 + q8_M1) ) ],
  [ ( q8_Y3*( q8_M1*q8_M4), q8_R1*( q8_M1 - <identity ...>) ),
      ( q8_Y10*( -q8_M1*q8_M4), q8_R2*( q8_M2 - <identity ...>) ),
      ( q8_Y3*( -q8_M1*q8_M4*q8_M3) + q8_Y17*( <identity ...>), q8_R1*( -q8_M2 - \
<identity ...>) + q8_R3*( q8_M1^2 + q8_M3 + q8_M1 + <identity ...>) ),
      ( q8_Y31*( q8_M1*q8_M4), q8_R3*( q8_M3 - q8_M2) + q8_R4*( q8_M1 - <identity\
 ...>) ),
      ( q8_Y10*( -q8_M1*q8_M4*q8_M2 - q8_M1*q8_M4) + q8_Y32*( -q8_M1*q8_M4), q8_R\
2*( -<identity ...>) + q8_R3*( -q8_M3 - <identity ...>) + q8_R4*( q8_M2 + <identi\
ty ...>) ),
      ( q8_Y12*( q8_M1*q8_M4), q8_R1*( -q8_M2) + q8_R3*( q8_M1*q8_M2 + q8_M4) + q\
8_R4*( q8_M2 - <identity ...>) ),
      ( q8_Y16*( -<identity ...>), q8_R1*( -<identity ...>) + q8_R2*( -q8_M1) + q\
8_R4*( q8_M3 + q8_M1) ) ] ]
gap> RootIdentities( q8 );
[ ( q8_Y3*( q8_M1*q8_M4), q8_R1*( q8_M1 - <identity ...>) ),
  ( q8_Y3*( q8_M1*q8_M4), q8_R1*( q8_M1 - <identity ...>) ) ]
]]>
</Example>

<ManSection>
   <Attr Name="RootIdentities"
         Arg="grp" />
<Description>
The <E>root identities</E> are identities of the form 
<M>r^wr^{-1}</M> where <M>r = w^n</M> is a relator and <M>n>1</M>.
<P/>
</Description>
</ManSection>
<Example>
<![CDATA[
gap> RootIdentities( q8 );
[ ( q8_Y3*( q8_M1*q8_M4), q8_R1*( q8_M1 - <identity ...>) ),
  ( q8_Y3*( q8_M1*q8_M4), q8_R1*( q8_M1 - <identity ...>) ) ]
]]>
</Example>
</Section>
</Chapter>
