  
  [1X3 [33X[0;0Y[22XFG[122X[101X[1X-modules[133X[101X
  
  [33X[0;0YLet [22XFG[122X be the group ring of the group [22XG[122X over the field [22XF[122X. In this package we
  only consider the case where [22XG[122X is a finite [22Xp[122X-groups and [22XF = F_p[122X is the field
  of [22Xp[122X elements. In addition, we only consider free [22XFG[122X-modules.[133X
  
  
  [1X3.1 [33X[0;0YThe [9XFpGModuleGF[109X[101X[1X datatype[133X[101X
  
  [33X[0;0YModules  and submodules of free [22XFG[122X-modules are represented in [5XHAPprime[105X using
  the  [9XFpGModuleGF[109X  datatype, where the `[10XGF[110X' stands for `Generator Form'. This
  defines  a  module using a group [22XG[122X and a set of [22XG[122X-generating vectors for the
  module's  vector space, together with a group action which operates on those
  vectors. A free [22XFG[122X-module [22XFG[122X can be considered as a vector space [22XF^|G|[122X whose
  basis  is  the  elements  of  [22XG[122X. An element of [22X(FG)^n[122X is the direct sum of [22Xn[122X
  copies  of  [22XFG[122X and, as an element of [9XFpGModuleGF[109X, is represented as a vector
  of  length  [22Xn|G|[122X with coefficients in [22XF[122X. Representing our [22XFG[122X-module elements
  as  vectors  is  ideal  for  our  purposes  since  [5XGAP[105X's  representation and
  manipulation  of  vectors  and  matrices  over  small  prime  fields is very
  efficient in both memory and computation time.[133X
  
  [33X[0;0YThe  [5XHAP[105X  package  defines a [9XFpGModule[109X object, which is similar but stores a
  vector  space  basis  rather than a [22XG[122X-generating set for the module's vector
  space.  Storing a [22XG[122X-generating set saves memory, both in passive storage and
  in allowing more efficient versions of some computation algorithms.[133X
  
  [33X[0;0YThere are a number of construction functions for [9XFpGModuleGF[109Xs: see [14X3.3-1[114X for
  details. A [22XFG[122X-module is defined by the following:[133X
  
  [30X    [33X[0;6Y[10Xgens[110X,  a list of [22XG[122X-generating vectors for the underlying vector space.
        These  do  not  need to be minimal - they could even be a vector space
        basis.  The  [10XMinimalGeneratorsModule[110X  functions ([14X3.5-9[114X) can be used to
        convert a module to one with a minimal set of generators.[133X
  
  [30X    [33X[0;6Y[10Xgroup[110X, the group [22XG[122X for the module[133X
  
  [30X    [33X[0;6Y[10Xaction[110X,  a  function  [10Xaction(g,  u)[110X that represents the module's group
        action  on  vectors.  It takes a group element [22Xg ∈ G[122X and a vector [10Xu[110X of
        length [10XactionBlockSize[110X and returns another vector [10Xv[110X of the same length
        that  is  the product [22Xv = gu[122X. If [10Xaction[110X is not provided, the canonical
        group  permutation  action  is  used.  If  the  vector [10Xu[110X is an integer
        multiple  of  [10XactionBlockSize[110X  in  length,  the  function  [10Xaction[110X acts
        block-wise on the vector.[133X
  
  [30X    [33X[0;6Y[10XactionBlockSize[110X,  the  length  of  vectors upon which [10Xaction[110X operates.
        This  is  usually  the  order  of  the group, [22X|G|[122X (for example for the
        canonical action), but it is possible to specify this to support other
        possible   group   actions   that   might   act   on  larger  vectors.
        [10XactionBlockSize[110X  will  always be equal to the ambient dimension of the
        module [22XFG^1[122X.[133X
  
  [33X[0;0YThe  group,  action  and  block size are internally wrapped up into a record
  [10XgroupAndAction[110X, with entries [10Xgroup[110X, [10Xaction[110X and [10XactionBlockSize[110X. This is used
  to simplify the passing of parameters to some functions.[133X
  
  [33X[0;0YSome  additional  information  is  sometimes  needed to construct particular
  classes of [9XFpGModuleGF[109X:[133X
  
  [30X    [33X[0;6Y[10XambientDimension[110X,  the  length of vectors in the generating set: for a
        module  [22X(FG)^n[122X,  this is equal to [22Xn×[122X[10XactionBlockSize[110X. This is needed in
        the case when the list of generating vectors is empty.[133X
  
  [30X    [33X[0;6Y[10Xform[110X,  a  string  detailing  whether  the  generators  are known to be
        minimal or not, and if so in which format. It can be one of [10X"unknown"[110X,
        [10X"fullcanonical"[110X,   [10X"minimal"[110X,   [10X"echelon"[110X   or   [10X"semiechelon"[110X.   Some
        algorithms   require   a  particular  form,  and  algorithms  such  as
        [2XEchelonModuleGenerators[102X  ([14X3.6-1[114X) that manipulate a module's generators
        to create these forms set this entry.[133X
  
  
  [1X3.2 [33X[0;0YImplementation details: Block echelon form[133X[101X
  
  
  [1X3.2-1 [33X[0;0YGenerating vectors and their block structure[133X[101X
  
  [33X[0;0YConsider  the  vector  representation of an element in the [22XFG[122X-module [22X(FG)^2[122X,
  where [22XG[122X is a group of order four:[133X
  
  
  [24X[33X[0;6Yv in (FG)^2 = (g_1 + g_3, g_1 + g_2 + g_4) = [1 0 1 0 | 1 1 0 1][133X
  
  [124X
  
  [33X[0;0YThe  first  block  of  four entries in the vector correspond to the first [22XFG[122X
  summand  and  the second block to the second summand (and the group elements
  are  numbered in the order provided by the [5XGAP[105X function [2XElements[102X ([14XReference:
  Elements[114X)).[133X
  
  [33X[0;0YGiven  a  [22XG[122X-generating  set for a [22XFG[122X-module, the usual group action permutes
  the  group  elements,  and  thus  the effect on the vector is to permute the
  equivalent vector elements. Each summand is independent, and so elements are
  permuted within the blocks (normally of size [22X|G|[122X) seen in the example above.
  A  consequence of this is that if any block (i.e. summand) in a generator is
  entirely zero, then it remains zero under group (or [22XF[122X) multiplication and so
  that  generator  contributes  nothing to that part of the vector space. This
  fact  enables  some  of  the  structure  of  the module's vector space to be
  inferred  from the [22XG[122X-generators, without needing a full vector space basis .
  A  desirable  set of [22XG[122X-generators is one that has many zero blocks, and what
  we call the `block echelon' form is one that has this property.[133X
  
  
  [1X3.2-2 [33X[0;0YMatrix echelon reduction and head elements[133X[101X
  
  [33X[0;0YThe  block  echelon  form  of a [22XFG[122X-module generating set is analagous to the
  echelon  form  of matrices, used as a first stage in many matrix algorithms,
  and  we  first  briefly  review matrix echelon form. In a (row) echelon-form
  matrix,  the  head  element  in  each  row (the first non-zero entry) is the
  identity, and is to the right of the head in the previous row. A consequence
  of  this  is that the values below each head are all zero. All zero rows are
  at  the  bottom  of  the  matrix  (or  are  removed).  [5XGAP[105X  also  defines  a
  semi-echelon form, in which it is guaranteed that all values below each head
  is zero, but not that each head is to the right of those above it.[133X
  
  [33X[0;0YMatrices  can  be  converted  into  (semi-)echelon  form  by  using Gaussian
  elimination   to  perform  row  reduction  (for  example  the  [5XGAP[105X  function
  [2XSemiEchelonMat[102X  ([14XReference:  SemiEchelonMat[114X)). A typical algorithm gradually
  builds  up a list of matrix rows with unique heads, which will eventually be
  an  echelon-form set of basis elements for the row space of the matrix. This
  set  is  initialised  with the first row of the matrix, and the algorithm is
  then  applied  to each subsequent row in turn. The basis rows in the current
  set  are  used to reduce the next row of the matrix: if, after reduction, it
  is  non-zero  then  it  will  have a unique head and is added to the list of
  basis  rows;  if it is zero then it may be removed. The final set of vectors
  will be a semi-echelon basis for the row space of the original matrix, which
  can then be permuted to give an echelon basis if required.[133X
  
  
  [1X3.2-3 [33X[0;0YEchelon block structure and minimal generators[133X[101X
  
  [33X[0;0YIn the same way that the echelon form is useful for vector space generators,
  we  can  convert  a  set of [22XFG[122X-module generators into echelon form. However,
  unlike  multiplication  by  a  field element, the group action on generating
  vectors  also permutes the vector elements, so a strict echelon form is less
  useful.  Instead,  we  define a `block echelon' form, treating the blocks in
  the  vector  (see  example  above)  as  the [22XFG[122X-elements to be converted into
  echelon form. In block-echelon form, the first non-zero block in each row is
  as  far  to  the right as possible. Often, the first non-zero block in a row
  will  be to the right of the first non-zero block in the row above, but when
  several  generating vectors are needed in a block, this may not be the case.
  The  following  example creates a random submodule of [22X(FG)^n[122X by picking five
  generating  vectors  at  random.  This  module  is  first displayed with the
  original generators, and then they are converted to block echelon form using
  the   the   [5XHAPprime[105X   function  [2XEchelonModuleGenerators[102X  ([14X3.6-1[114X).  The  two
  generating  sets  both span the same vector space (i.e. the same [22XFG[122X module),
  but the latter representation is much more useful.[133X
  
  [4X[32X  Example  [32X[104X
    [4X[25Xgap>[125X [27XM := FpGModuleGF(RandomMat(5, 32, GF(2)), DihedralGroup(8));;[127X[104X
    [4X[25Xgap>[125X [27XDisplay(M);[127X[104X
    [4X[28XModule over the group ring of Group( [ f1, f2, f3 ] )[128X[104X
    [4X[28X in characteristic 2 with 5 generators in FG^4.[128X[104X
    [4X[28X[.1..1.1.|.1....1.|1111.11.|11.1111.][128X[104X
    [4X[28X[11.1..1.|1....11.|1...111.|1...11..][128X[104X
    [4X[28X[11..1.1.|1.1.1...|11...1..|.11.11..][128X[104X
    [4X[28X[11111111|111...1.|.11...1.|.1..1111][128X[104X
    [4X[28X[.1111111|1.1.111.|..1..1..|1.111...][128X[104X
    [4X[25Xgap>[125X [27XechM := EchelonModuleGenerators(M);[127X[104X
    [4X[28Xrec( module := Module over the group ring of <pc group of size 8 with[128X[104X
    [4X[28X    3 generators> in characteristic 2 with 4 generators in FG^[128X[104X
    [4X[28X    4. Generators are in minimal echelon form., headblocks := [ 1, 2, 3, 4 ] )[128X[104X
    [4X[25Xgap>[125X [27XDisplay(echM.module);[127X[104X
    [4X[28XModule over the group ring of Group( [ f1, f2, f3 ] )[128X[104X
    [4X[28X in characteristic 2 with 4 generators in FG^4.[128X[104X
    [4X[28X[.1..1.1.|.1....1.|1111.11.|11.1111.][128X[104X
    [4X[28X[........|.1111..1|111.1...|.11.11.1][128X[104X
    [4X[28X[........|........|.1..1.1.|.1.1.111][128X[104X
    [4X[28X[........|........|........|..1111.1][128X[104X
    [4X[28XGenerators are in minimal echelon form.gap>[128X[104X
    [4X[25Xgap>[125X [27XM = echM.module;[127X[104X
    [4X[28Xtrue[128X[104X
  [4X[32X[104X
  
  [33X[0;0YThe  main  algorithm for converting a set of generators into echelon form is
  [2XSemiEchelonModuleGeneratorsDestructive[102X  ([14X3.6-1[114X).  The  generators for the [22XFG[122X
  module  are represented as rows of a matrix, and (with the canonical action)
  the first [22X|G|[122X columns of this matrix correspond to the first block, the next
  [22X|G|[122X columns to the second block, and so on. The first block of the matrix is
  taken  and  the  vector space [22XV_b[122X spanned by the rows of that block is found
  (which  will  be a a subspace of [22XF^|G|[122X). Taking the rows in the first block,
  find  (by  gradually  leaving out rows) a minimal subset that generates [22XV_b[122X.
  The  rows of the full matrix that correspond to this minimal subset form the
  first  rows of the block-echelon form generators. Taking those rows, and all
  [22XG[122X-multiples of them, now calculate a semi-echelon basis for the vector space
  that    they    generate    (using   [2XSemiEchelonMatDestructive[102X   ([14XReference:
  SemiEchelonMatDestructive[114X)).  This  is  used  to  reduce  all  of  the other
  generators. Since the rows we have chosen span the space of the first block,
  the  first  block  in all the other rows will be reduced to zero. We can now
  move on to the second block.[133X
  
  [33X[0;0YWe  now look at the rows of the matrix that start (have their first non-zero
  entry) in the second block. In addition, some of the generators used for the
  first  block might additionally give rise to vector space basis vectors with
  head  elements  in  the second blocks. The rows need to be stored during the
  first  stage  and reused here. We find a minimal set of the matrix rows with
  second-block  heads  that,  when  taken with any second-block heads from the
  first  stage,  generate  the  entire  space spanned by the second block. The
  vector-space basis from this new minimal set is then used to reduce the rest
  of  the  generating  rows  as before, reducing all of the other rows' second
  blocks  to  zero.  The  process  is  then repeated for each other block. Any
  generators  that  are  completely  zero  are  then removed. The algorithm is
  summarised in the following pseudocode:[133X
  
  Let X be the list of generators still to convert (initially all the generators)
  Let Xe = [] be the list of generators already in block-echelon form
  Define X{b} to represent the $b$th block from generators X
  Define V(X) to represent the vector space generated by generators X
  -------------------------------------------------------------------------------
  for b in [1..blocks] 
    1. Find a minimal set of generators Xm from X such that 
       V(Xm{b} + Xe{b}) = V(X{b} + Xe{b})
    2. Remove Xm from X and add them to Xe
    3. Find a semi-echelon basis for V(Xe) and use this to reduce the elements 
       of block b in remaining vectors of X to zero
  end for
        
  
  [33X[0;0YThe  result of this algorithm is a new generating set for the module that is
  minimal in the sense that no vector can be removed from the set and leave it
  still  spanning  the  same  vector  space.  In  the case of a [22XFG[122X-module with
  [22XF[122X=GF(2),  this  is  a globally minimal set: there is no possible alternative
  set with fewer generators.[133X
  
  
  [1X3.2-4 [33X[0;0YIntersection of two modules[133X[101X
  
  [33X[0;0YKnowing  the  block structure of the modules enables the intersection of two
  modules to be calculated more efficiently. Consider two modules [22XU[122X and [22XV[122X with
  the block structure as given in this example:[133X
  
  [4X[32X  Example  [32X[104X
    [4X[25Xgap>[125X [27XDisplayBlocks(U);[127X[104X
    [4X[28X[*..][128X[104X
    [4X[28X[**.][128X[104X
    [4X[28X[.*.][128X[104X
    [4X[25Xgap>[125X [27XDisplayBlocks(V);[127X[104X
    [4X[28X[.**][128X[104X
    [4X[28X[.**][128X[104X
    [4X[28X[..*][128X[104X
  [4X[32X[104X
  
  [33X[0;0YTo calculate the intersection of the two modules, it is normal to expand out
  the  two modules to find the vector space [22XU_F[122X and [22XV_F[122X of the two modules and
  calculate the intersection as a standard vector-space intersection. However,
  in  this  case,  since  [22XU[122X  has  no  elements in the last block, and [22XV[122X has no
  elements in the first block, the intersection must only have elements in the
  middle  block.  This  means  that  the  first  generator  of  [22XU[122X and the last
  generator  of  [22XV[122X  can  not be in the intersection and can be ignored for the
  purposes  of the intersection calculation. In general, rather than expanding
  the entirety of [22XU[122X and [22XV[122X into an [22XF[122X-basis to calculate their intersection, one
  can  expand  [22XU[122X and [22XV[122X more intelligently into [22XF[122X-bases [22XU'_F[122X and [22XV'_F[122X which are
  smaller than [22XU_F[122X and [22XV_F[122X but have the same intersection.[133X
  
  [33X[0;0YHaving  determined  (by  comparing the block structure of [22XU[122X and [22XV[122X) that only
  the  middle  block  in  our example contributes to the intersection, we only
  need  to  expand  out the rows of [22XU[122X and [22XV[122X that have heads in that block. The
  first  generator  of  [22XU[122X  generates  no  elements  in  the  middle block, and
  trivially  be  ignored. The second row of [22XU[122X may or may not contribute to the
  intersection: this will need expanding out and echelon reduced. The expanded
  rows  that don't have heads in the central block can then be discarded, with
  the  other  rows  forming  part  of  the  basis of [22XU'_F[122X. Likewise, the third
  generator of [22XU[122X is expanded and echelon reduced to give the rest of the basis
  for  [22XU'_F[122X. To find [22XV'_F[122X, the first two generators are expanded, semi-echelon
  reduced  and  the  rows  with  heads  in  the  middle  block kept. The third
  generator  can  be  ignored.  Finally, the intersection of [22XU'_F[122X and [22XV'_F[122X can
  found using, for example, [2XSumIntersectionMatDestructive[102X ([14X5.1-1[114X).[133X
  
  [33X[0;0YThis  algorithm,  implemented in the function [2XIntersectionModulesGF[102X ([14X3.7-3[114X),
  will (for modules whose generators have zero columns) use less memory than a
  full  vector-space  expansion,  and  in  the  case  where  [22XU[122X  and  [22XV[122X have no
  intersection,  may  need  to perform no expansion at all. In the worst case,
  both [22XU[122X and [22XV[122X will need a full expansion, using no more memory than the naive
  implementation.  Since  any  full expansion is done row-by-row, with echelon
  reduction  each time, it will in general still require less memory (but will
  be slower).[133X
  
  
  [1X3.3 [33X[0;0YConstruction functions[133X[101X
  
  
  [1X3.3-1 [33X[0;0YFpGModuleGF construction functions[133X[101X
  
  [33X[1;0Y[29X[2XFpGModuleGF[102X( [3Xgens[103X, [3XG[103X[, [3Xaction[103X, [3XactionBlockSize[103X] ) [32X operation[133X
  [33X[1;0Y[29X[2XFpGModuleGF[102X( [3Xgens[103X, [3XgroupAndAction[103X ) [32X operation[133X
  [33X[1;0Y[29X[2XFpGModuleGF[102X( [3XambientDimension[103X, [3XG[103X[, [3Xaction[103X, [3XactionBlockSize[103X] ) [32X operation[133X
  [33X[1;0Y[29X[2XFpGModuleGF[102X( [3XambientDimension[103X, [3XgroupAndAction[103X ) [32X operation[133X
  [33X[1;0Y[29X[2XFpGModuleGF[102X( [3XG[103X, [3Xn[103X ) [32X operation[133X
  [33X[1;0Y[29X[2XFpGModuleGF[102X( [3XgroupAndAction[103X, [3Xn[103X ) [32X operation[133X
  [33X[1;0Y[29X[2XFpGModuleGF[102X( [3XHAPmod[103X ) [32X operation[133X
  [33X[1;0Y[29X[2XFpGModuleGFNC[102X( [3Xgens[103X, [3XG[103X, [3Xform[103X, [3Xaction[103X, [3XactionBlockSize[103X ) [32X operation[133X
  [33X[1;0Y[29X[2XFpGModuleGFNC[102X( [3XambientDimension[103X, [3XG[103X, [3Xaction[103X, [3XactionBlockSize[103X ) [32X operation[133X
  [33X[1;0Y[29X[2XFpGModuleGFNC[102X( [3Xgens[103X, [3XgroupAndAction[103X[, [3Xform[103X] ) [32X operation[133X
  [6XReturns:[106X  [33X[0;10YFpGModuleGF[133X
  
  [33X[0;0YCreates  and  returns  a  [9XFpGModuleGF[109X  module object. The most commonly-used
  constructor  requires  a  list  of  generators [3Xgens[103X and a group [3XG[103X. The group
  action  and block size can be specified using the [3Xaction[103X and [3XactionBlockSize[103X
  parameters,  or  if  these are omitted then the canonical action is assumed.
  These  parameters  can  also  be  wrapped up in a [10XgroupAndAction[110X record (see
  [14X3.1[114X).[133X
  
  [33X[0;0YAn  empty  [9XFpGModuleGF[109X  can  be  constructed  by  specifying  a group and an
  [3XambientDimension[103X  instead  of  a set of generators. A module spanning [22X(FG)^n[122X
  with  canonical generators and action can be constructed by giving a group [3XG[103X
  and  a  rank  [3Xn[103X.  A [9XFpGModuleGF[109X can also be constructed from a [5XHAP[105X [9XFpGModule[109X
  [3XHAPmod[103X.[133X
  
  [33X[0;0YThe generators in a [9XFpGModuleGF[109X do not need to be a minimal set. If you wish
  to  create  a  module  with  minimal generators, construct the module from a
  non-minimal  set  [3Xgens[103X  and  then  use  one  of  the [10XMinimalGeneratorsModule[110X
  functions ([14X3.5-9[114X). When constructing a [9XFpGModuleGF[109X from a [9XFpGModule[109X, the [5XHAP[105X
  function  [2XGeneratorsOfFpGModule[102X  ([14XHAP:  GeneratorsOfFpGModule[114X)  is  used  to
  provide a set of generators, so in this case the generators will be minimal.[133X
  
  [33X[0;0YMost  of the forms of this function perform a few (cheap) tests to make sure
  that  the arguments are self-consistent. The [10XNC[110X versions of the constructors
  are  provided for internal use, or when you know what you are doing and wish
  to skip the tests. See Section [14X3.3-5[114X below for an example of usage.[133X
  
  [1X3.3-2 FpGModuleFromFpGModuleGF[101X
  
  [33X[1;0Y[29X[2XFpGModuleFromFpGModuleGF[102X( [3XM[103X ) [32X operation[133X
  [6XReturns:[106X  [33X[0;10YFpGModule[133X
  
  [33X[0;0YReturns  a  [5XHAP[105X [9XFpGModule[109X that represents the same module as the [9XFpGModuleGF[109X
  [3XM[103X.  This  uses [2XModuleVectorSpaceBasis[102X ([14X3.5-7[114X) to find the vector space basis
  for  [3XM[103X  and constructs a [9XFpGModule[109X with this vector space and the same group
  and action as [3XM[103X See Section [14X3.3-5[114X below for an example of usage.[133X
  
  [33X[0;0Y[13XTODO:  This  currently  constructs an FpGModule object explicitly. It should
  use a constructor once one is provided[113X[133X
  
  [1X3.3-3 MutableCopyModule[101X
  
  [33X[1;0Y[29X[2XMutableCopyModule[102X( [3XM[103X ) [32X operation[133X
  [6XReturns:[106X  [33X[0;10YFpGModuleGF[133X
  
  [33X[0;0YReturns  a  copy  of  the  module  [3XM[103X  where the generating vectors are fully
  mutable.  The group and action in the new module is identical to that in [3XM[103X -
  only  the  list of generators is copied and made mutable. (The assumption is
  that  this  function used in situations where you just want a new generating
  set.)[133X
  
  [1X3.3-4 CanonicalAction[101X
  
  [33X[1;0Y[29X[2XCanonicalAction[102X( [3XG[103X ) [32X attribute[133X
  [33X[1;0Y[29X[2XCanonicalActionOnRight[102X( [3XG[103X ) [32X attribute[133X
  [33X[1;0Y[29X[2XCanonicalGroupAndAction[102X( [3XG[103X ) [32X attribute[133X
  [6XReturns:[106X  [33X[0;10YFunction  [10Xaction(g,v)[110X  or  a  record with elements [10X(group, action,
            actionOnRight, actionBlockSize)[110X[133X
  
  [33X[0;0YReturns a function of the form [10Xaction(g,v)[110X that performs the canonical group
  action  of  an element [10Xg[110X of the group [3XG[103X on a vector [10Xv[110X (acting on the left by
  default,  or  on  the  right  with  the [10XOnRight[110X version). The [10XGroupAndAction[110X
  version  of  this function returns the actions in a record together with the
  group  and  the action block size. Under the canonical action, a free module
  [22XFG[122X is represented as a vector of length [22X|G|[122X over the field [22XF[122X, and the action
  is a permutation of the vector elements.[133X
  
  [33X[0;0YNote  that  these functions are attributes of a group, so that the canonical
  action  for  a  particular group object will always be an identical function
  (which is desirable for comparing and combining modules and submodules).[133X
  
  
  [1X3.3-5 [33X[0;0YExample: Constructing a [9XFpGModuleGF[109X[101X[1X[133X[101X
  
  [33X[0;0YThe  example  below  constructs  four  different  [22XFG[122X-modules, where [22XG[122X is the
  quaternion  group  of order eight, and the action is the canonical action in
  each case:[133X
  
  [31X1[131X   [33X[0;6Y[10XM[110X is the module [22X(FG)^3[122X[133X
  
  [31X2[131X   [33X[0;6Y[10XS[110X is the submodule of [22X(FG)^3[122X with elements only in the first summand[133X
  
  [31X3[131X   [33X[0;6Y[10XT[110X is a random submodule [10XM[110X generated by five elements[133X
  
  [31X4[131X   [33X[0;6Y[10XU[110X is the trivial (zero) submodule of [22X(FG)^4[122X[133X
  
  [33X[0;0YWe  check  whether  [10XS[110X, [10XT[110X and [10XU[110X are submodules of [10XM[110X, examine a random element
  from  [10XM[110X, and convert [10XS[110X into a [5XHAP[105X [9XFpGModule[109X. For the other functions used in
  this example, see Section [14X3.8[114X.[133X
  
  [4X[32X  Example  [32X[104X
    [4X[25Xgap>[125X [27XG := SmallGroup(8, 4);;[127X[104X
    [4X[25Xgap>[125X [27XM := FpGModuleGF(G, 3);[127X[104X
    [4X[28XFull canonical module FG^3 over the group ring of <pc group of size 8 with[128X[104X
    [4X[28X3 generators> in characteristic 2[128X[104X
    [4X[25Xgap>[125X [27Xgen := ListWithIdenticalEntries(24, Zero(GF(2)));;[127X[104X
    [4X[25Xgap>[125X [27Xgen[1] := One(GF(2));;[127X[104X
    [4X[25Xgap>[125X [27XS := FpGModuleGF([gen], G);[127X[104X
    [4X[28XModule over the group ring of <pc group of size 8 with[128X[104X
    [4X[28X3 generators> in characteristic 2 with 1 generator in FG^[128X[104X
    [4X[28X3. Generators are in minimal echelon form.[128X[104X
    [4X[25Xgap>[125X [27XT := RandomSubmodule(M, 5);[127X[104X
    [4X[28XModule over the group ring of <pc group of size 8 with[128X[104X
    [4X[28X3 generators> in characteristic 2 with 5 generators in FG^3.[128X[104X
    [4X[25Xgap>[125X [27XU := FpGModuleGF(32, CanonicalGroupAndAction(G));[127X[104X
    [4X[28XModule over the group ring of <pc group of size 8 with[128X[104X
    [4X[28X3 generators> in characteristic 2 with 0 generators in FG^[128X[104X
    [4X[28X4. Generators are in minimal echelon form.[128X[104X
    [4X[28Xgap>[128X[104X
    [4X[25Xgap>[125X [27XIsSubModule(M, S);[127X[104X
    [4X[28Xtrue[128X[104X
    [4X[25Xgap>[125X [27XIsSubModule(M, T);[127X[104X
    [4X[28Xtrue[128X[104X
    [4X[25Xgap>[125X [27XIsSubModule(M, U);[127X[104X
    [4X[28Xfalse[128X[104X
    [4X[28Xgap>[128X[104X
    [4X[25Xgap>[125X [27Xe := RandomElement(M);[127X[104X
    [4X[28X<a GF2 vector of length 24>[128X[104X
    [4X[25Xgap>[125X [27XDisplay([e]);[127X[104X
    [4X[28X . 1 1 . . 1 . . . . . 1 . . 1 1 . . 1 . 1 . . 1[128X[104X
    [4X[25Xgap>[125X [27XIsModuleElement(S, e);[127X[104X
    [4X[28Xfalse[128X[104X
    [4X[25Xgap>[125X [27XIsModuleElement(T, e);[127X[104X
    [4X[28Xtrue[128X[104X
    [4X[28Xgap>[128X[104X
    [4X[25Xgap>[125X [27XFpGModuleFromFpGModuleGF(S);[127X[104X
    [4X[28XModule of dimension 8 over the group ring of <pc group of size 8 with[128X[104X
    [4X[28X3 generators> in characteristic 2[128X[104X
    [4X[28X[128X[104X
  [4X[32X[104X
  
  
  [1X3.4 [33X[0;0YData access functions[133X[101X
  
  [1X3.4-1 ModuleGroup[101X
  
  [33X[1;0Y[29X[2XModuleGroup[102X( [3XM[103X ) [32X operation[133X
  [6XReturns:[106X  [33X[0;10YGroup[133X
  
  [33X[0;0YReturns  the  group of the module [3XM[103X. See Section [14X3.4-11[114X below for an example
  of usage.[133X
  
  [1X3.4-2 ModuleGroupOrder[101X
  
  [33X[1;0Y[29X[2XModuleGroupOrder[102X( [3XM[103X ) [32X operation[133X
  [6XReturns:[106X  [33X[0;10YInteger[133X
  
  [33X[0;0YReturns  the  order of the group of the module [3XM[103X. This function is identical
  to  [10XOrder(ModuleGroup(M))[110X,  and  is  provided  for  convenience. See Section
  [14X3.4-11[114X below for an example of usage.[133X
  
  [1X3.4-3 ModuleAction[101X
  
  [33X[1;0Y[29X[2XModuleAction[102X( [3XM[103X ) [32X operation[133X
  [6XReturns:[106X  [33X[0;10YFunction[133X
  
  [33X[0;0YReturns  the  group  action  function  of  the  module [3XM[103X. This is a function
  [10Xaction(g,  v)[110X  that  takes  a  group  element [10Xg[110X and a vector [10Xv[110X and returns a
  vector  [10Xw[110X  that  is  the  result  of [22Xw = gv[122X. See Section [14X3.4-11[114X below for an
  example of usage.[133X
  
  [1X3.4-4 ModuleActionBlockSize[101X
  
  [33X[1;0Y[29X[2XModuleActionBlockSize[102X( [3XM[103X ) [32X operation[133X
  [6XReturns:[106X  [33X[0;10YInteger[133X
  
  [33X[0;0YReturns  the  block  size  of  the group action of the module [3XM[103X. This is the
  length  of vectors (or the factor of the length) upon which the group action
  function acts. See Section [14X3.4-11[114X below for an example of usage.[133X
  
  [1X3.4-5 ModuleGroupAndAction[101X
  
  [33X[1;0Y[29X[2XModuleGroupAndAction[102X( [3XM[103X ) [32X operation[133X
  [6XReturns:[106X  [33X[0;10YRecord    with    elements    [10X(group,    action,    actionOnRight,
            actionBlockSize)[110X[133X
  
  [33X[0;0YReturns  details  of  the  module's  group  and  action in a record with the
  following elements:[133X
  
  [30X    [33X[0;6Y[10Xgroup[110X The module's group[133X
  
  [30X    [33X[0;6Y[10Xaction[110X  The module's group action, as a function of the form [10Xaction(g,
        v)[110X that takes a vector [10Xv[110X and returns the vector [22Xw = gv[122X[133X
  
  [30X    [33X[0;6Y[10XactionOnRight[110X The module's group action when acting on the right, as a
        function  of  the  form [10Xaction(g, v)[110X that takes a vector [10Xv[110X and returns
        the vector [22Xw = vg[122X[133X
  
  [30X    [33X[0;6Y[10XactionBlockSize[110X  The  module's  group  action  block size. This is the
        ambient dimension of vectors in the module [22XFG[122X[133X
  
  [33X[0;0YThis  function  is  provided  for  convenience,  and  is used by a number of
  internal functions. The canonical groups and action can be constructed using
  the  function  [2XCanonicalGroupAndAction[102X ([14X3.3-4[114X). See Section [14X3.4-11[114X below for
  an example of usage.[133X
  
  [1X3.4-6 ModuleCharacteristic[101X
  
  [33X[1;0Y[29X[2XModuleCharacteristic[102X( [3XM[103X ) [32X operation[133X
  [6XReturns:[106X  [33X[0;10YInteger[133X
  
  [33X[0;0YReturns  the  characteristic  of the field [22XF[122X of the [22XFG[122X-module [3XM[103X. See Section
  [14X3.4-11[114X below for an example of usage.[133X
  
  [1X3.4-7 ModuleField[101X
  
  [33X[1;0Y[29X[2XModuleField[102X( [3XM[103X ) [32X operation[133X
  [6XReturns:[106X  [33X[0;10YField[133X
  
  [33X[0;0YReturns  the  field  [22XF[122X  of  the [22XFG[122X-module [3XM[103X. See Section [14X3.4-11[114X below for an
  example of usage.[133X
  
  [1X3.4-8 ModuleAmbientDimension[101X
  
  [33X[1;0Y[29X[2XModuleAmbientDimension[102X( [3XM[103X ) [32X operation[133X
  [6XReturns:[106X  [33X[0;10YInteger[133X
  
  [33X[0;0YReturns  the  ambient dimension of the module [3XM[103X. The module [3XM[103X is represented
  as  a  submodule  of  [22XFG^n[122X using generating vectors for a vector space. This
  function  returns  the  dimension  of  this underlying vector space. This is
  equal  to  the length of each generating vector, and also [22Xn×[122X[10XactionBlockSize[110X.
  See Section [14X3.4-11[114X below for an example of usage.[133X
  
  [1X3.4-9 AmbientModuleDimension[101X
  
  [33X[1;0Y[29X[2XAmbientModuleDimension[102X( [3XM[103X ) [32X operation[133X
  [6XReturns:[106X  [33X[0;10YInteger[133X
  
  [33X[0;0YThe  module  [3XM[103X  is  represented  a submodule embedded within the free module
  [22XFG^n[122X.  This function returns [22Xn[122X, the dimension of the ambient module. This is
  the same as the number of blocks. See Section [14X3.4-11[114X below for an example of
  usage.[133X
  
  [1X3.4-10 DisplayBlocks[101X
  
  [33X[1;0Y[29X[2XDisplayBlocks[102X( [3XM[103X ) [32X operation[133X
  [6XReturns:[106X  [33X[0;10Ynothing[133X
  
  [33X[0;0YDisplays   the  structure  of  the  module  generators  [3Xgens[103X  in  a  compact
  human-readable  form.  Since the group action permutes generating vectors in
  blocks  of length [10XactionBlockSize[110X, any block that contains non-zero elements
  will  still  contain  non-zero  elements after the group action, but a block
  that  is  all  zero will remain all zero. This operation displays the module
  generators  in  a per-block form, with a [10X*[110X where the block is non-zero and [10X.[110X
  where the block is all zero.[133X
  
  [33X[0;0YThe  standard  [5XGAP[105X  methods [2XView[102X ([14XReference: View[114X), [2XPrint[102X ([14XReference: Print[114X)
  and  [2XDisplay[102X  ([14XReference:  Display[114X)  are  also available.) See Section [14X3.6-3[114X
  below for an example of usage.[133X
  
  
  [1X3.4-11 [33X[0;0YExample: Accessing data about a [9XFpGModuleGF[109X[101X[1X[133X[101X
  
  [33X[0;0YIn the following example, we construct three terms of a (minimal) resolution
  of  the  dihedral  group  of  order  eight,  which  is  a  chain  complex of
  [22XFG[122X-modules.[133X
  
  
  [24X[33X[0;6Y(FG)^3 -> (FG)^2 -> FG -> F -> 0[133X
  
  [124X
  
  [33X[0;0YWe  obtain  the  last  homomorphism  in this chain complex and calculate its
  kernel,  returning  this  as  a  [9XFpGModuleGF[109X.  We  can  use  the data access
  functions described above to extract information about this module.[133X
  
  [33X[0;0YSee  Chapters  [14X4[114X  and  [14X2[114X  respectively  for more information about [22XFG[122X-module
  homomorphisms and resolutions in [5XHAPprime[105X[133X
  
  [4X[32X  Example  [32X[104X
    [4X[25Xgap>[125X [27XR := ResolutionPrimePowerGroupRadical(DihedralGroup(8), 2);[127X[104X
    [4X[28XResolution of length 2 in characteristic 2 for <pc group of size 8 with[128X[104X
    [4X[28X3 generators> .[128X[104X
    [4X[28XNo contracting homotopy available.[128X[104X
    [4X[28XA partial contracting homotopy is available.[128X[104X
    [4X[28X[128X[104X
    [4X[25Xgap>[125X [27Xphi := BoundaryFpGModuleHomomorphismGF(R, 2);[127X[104X
    [4X[28X<Module homomorphism>[128X[104X
    [4X[28X[128X[104X
    [4X[25Xgap>[125X [27XM := KernelOfModuleHomomorphism(phi);[127X[104X
    [4X[28XModule over the group ring of <pc group of size 8 with[128X[104X
    [4X[28X3 generators> in characteristic 2 with 15 generators in FG^3.[128X[104X
    [4X[28X[128X[104X
    [4X[25Xgap>[125X [27X# Now find out things about this module M[127X[104X
    [4X[25Xgap>[125X [27XModuleGroup(M);[127X[104X
    [4X[28X<pc group of size 8 with 3 generators>[128X[104X
    [4X[25Xgap>[125X [27XModuleGroupOrder(M);[127X[104X
    [4X[28X8[128X[104X
    [4X[25Xgap>[125X [27XModuleAction(M);[127X[104X
    [4X[28Xfunction( g, v ) ... end[128X[104X
    [4X[25Xgap>[125X [27XModuleActionBlockSize(M);[127X[104X
    [4X[28X8[128X[104X
    [4X[25Xgap>[125X [27XModuleGroupAndAction(M);[127X[104X
    [4X[28Xrec( group := <pc group of size 8 with 3 generators>,[128X[104X
    [4X[28X  action := function( g, v ) ... end,[128X[104X
    [4X[28X  actionOnRight := function( g, v ) ... end, actionBlockSize := 8 )[128X[104X
    [4X[25Xgap>[125X [27XModuleCharacteristic(M);[127X[104X
    [4X[28X2[128X[104X
    [4X[25Xgap>[125X [27XModuleField(M);[127X[104X
    [4X[28XGF(2)[128X[104X
    [4X[25Xgap>[125X [27XModuleAmbientDimension(M);[127X[104X
    [4X[28X24[128X[104X
    [4X[25Xgap>[125X [27XAmbientModuleDimension(M);[127X[104X
    [4X[28X3[128X[104X
  [4X[32X[104X
  
  
  [1X3.5 [33X[0;0YGenerator and vector space functions[133X[101X
  
  [1X3.5-1 ModuleGenerators[101X
  
  [33X[1;0Y[29X[2XModuleGenerators[102X( [3XM[103X ) [32X operation[133X
  [6XReturns:[106X  [33X[0;10YList of vectors[133X
  
  [33X[0;0YReturns,  as  the  rows  of  a matrix, a list of the set of currently-stored
  generating  vectors for the vector space of the module [3XM[103X. Note that this set
  is  not necessarily minimal. The function [2XModuleGeneratorsAreMinimal[102X ([14X3.5-2[114X)
  will   return   [9Xtrue[109X   if   the   set  is  known  to  be  minimal,  and  the
  [10XMinimalGeneratorsModule[110X  functions  ([14X3.5-9[114X)  can be used to ensure a minimal
  set, if necessary. See Section [14X3.5-11[114X below for an example of usage.[133X
  
  [1X3.5-2 ModuleGeneratorsAreMinimal[101X
  
  [33X[1;0Y[29X[2XModuleGeneratorsAreMinimal[102X( [3XM[103X ) [32X operation[133X
  [6XReturns:[106X  [33X[0;10YBoolean[133X
  
  [33X[0;0YReturns  [10Xtrue[110X  if  the  module  generators are known to be minimal, or [10Xfalse[110X
  otherwise.   Generators   are  known  to  be  minimal  if  the  one  of  the
  [10XMinimalGeneratorsModule[110X  functions ([14X3.5-9[114X) have been previously used on this
  module,  or  if  the  module  was  created from a [5XHAP[105X [9XFpGModule[109X. See Section
  [14X3.5-11[114X below for an example of usage.[133X
  
  [1X3.5-3 ModuleGeneratorsAreEchelonForm[101X
  
  [33X[1;0Y[29X[2XModuleGeneratorsAreEchelonForm[102X( [3XM[103X ) [32X operation[133X
  [6XReturns:[106X  [33X[0;10YBoolean[133X
  
  [33X[0;0YReturn  [9Xtrue[109X  if  the  module generators are known to be in echelon form, or
  (i.e.  [2XEchelonModuleGenerators[102X  ([14X3.6-1[114X) has been called for this module), or
  [9Xfalse[109X  otherwise. Some algorithms work more efficiently if (or require that)
  the  generators of the module are in block-echelon form, i.e. each generator
  in  the module's list of generators has its first non-zero block in the same
  location  or  later  than  the  generator before it in the list. See Section
  [14X3.5-11[114X below for an example of usage.[133X
  
  [1X3.5-4 ModuleIsFullCanonical[101X
  
  [33X[1;0Y[29X[2XModuleIsFullCanonical[102X( [3XM[103X ) [32X operation[133X
  [6XReturns:[106X  [33X[0;10YBoolean[133X
  
  [33X[0;0YReturns  [9Xtrue[109X if the module is known to represent the full module [22XFG^n[122X, with
  canonical  generators and group action, or [9Xfalse[109X otherwise. A module is only
  known  to  be  canonical  if  it  was constructed using the canonical module
  [9XFpGModuleGF[109X  constructor  ([2XFpGModuleGF[102X ([14X3.3-1[114X)). If this is true, the module
  is  displayed  in  a  concise  form,  and  some  functions  have  a  trivial
  implementation. See Section [14X3.5-11[114X below for an example of usage.[133X
  
  [1X3.5-5 ModuleGeneratorsForm[101X
  
  [33X[1;0Y[29X[2XModuleGeneratorsForm[102X( [3XM[103X ) [32X operation[133X
  [6XReturns:[106X  [33X[0;10YString[133X
  
  [33X[0;0YReturns  a  string giving the form of the module generators. This may be one
  of the following:[133X
  
  [30X    [33X[0;6Y[10X"unknown"[110X The form is not known[133X
  
  [30X    [33X[0;6Y[10X"minimal"[110X  The  generators  are  known  to  be minimal, but not in any
        particular form[133X
  
  [30X    [33X[0;6Y[10X"fullcanonical"[110X   The  generators  are  the  canonical  (and  minimal)
        generators for [22XFG^n[122X[133X
  
  [30X    [33X[0;6Y[10X"semiechelon"[110X The generators are minimal and in semi-echelon form.[133X
  
  [30X    [33X[0;6Y[10X"echelon"[110X The generators are minimal and in echelon form[133X
  
  [33X[0;0YSee Section [14X3.5-11[114X below for an example of usage.[133X
  
  [1X3.5-6 ModuleRank[101X
  
  [33X[1;0Y[29X[2XModuleRank[102X( [3XM[103X ) [32X operation[133X
  [33X[1;0Y[29X[2XModuleRankDestructive[102X( [3XM[103X ) [32X operation[133X
  [6XReturns:[106X  [33X[0;10YInteger[133X
  
  [33X[0;0YReturns  the rank of the module [3XM[103X, i.e. the number of minimal generators. If
  the     module    is    already    in    minimal    form    (according    to
  [2XModuleGeneratorsAreMinimal[102X   ([14X3.5-2[114X))  then  the  number  of  generators  is
  returned  with  no calculation. Otherwise, [2XMinimalGeneratorsModuleGF[102X ([14X3.5-9[114X)
  or  [2XMinimalGeneratorsModuleGFDestructive[102X  ([14X3.5-9[114X)  respectively  are used to
  find a set of minimal generators. See Section [14X3.5-11[114X below for an example of
  usage.[133X
  
  [1X3.5-7 ModuleVectorSpaceBasis[101X
  
  [33X[1;0Y[29X[2XModuleVectorSpaceBasis[102X( [3XM[103X ) [32X operation[133X
  [6XReturns:[106X  [33X[0;10YList of vectors[133X
  
  [33X[0;0YReturns  a  matrix  whose  rows  are  a  basis  for  the vector space of the
  [9XFpGModuleGF[109X  module  [3XM[103X.  Since  [9XFpGModuleGF[109X  stores  modules  as  a  minimal
  [22XG[122X-generating  set,  this  function  has to calculate all [22XG[122X-multiples of this
  generating set and row-reduce this to find a basis. See Section [14X3.5-11[114X below
  for an example of usage.[133X
  
  [33X[0;0Y[13XTODO: A GF version of this one [113X[133X
  
  [1X3.5-8 ModuleVectorSpaceDimension[101X
  
  [33X[1;0Y[29X[2XModuleVectorSpaceDimension[102X( [3XM[103X ) [32X operation[133X
  [6XReturns:[106X  [33X[0;10YInteger[133X
  
  [33X[0;0YReturns the dimension of the vector space of the module [3XM[103X. Since [9XFpGModuleGF[109X
  stores modules as a minimal [22XG[122X-generating set, this function has to calculate
  all  [22XG[122X-multiples of this generating set and row-reduce this to find the size
  of the basis. See Section [14X3.5-11[114X below for an example of usage.[133X
  
  [33X[0;0Y[13XTODO: A GF version of this function [113X[133X
  
  
  [1X3.5-9 [33X[0;0YMinimalGeneratorsModule[133X[101X
  
  [33X[1;0Y[29X[2XMinimalGeneratorsModuleGF[102X( [3XM[103X ) [32X operation[133X
  [33X[1;0Y[29X[2XMinimalGeneratorsModuleGFDestructive[102X( [3XM[103X ) [32X operation[133X
  [33X[1;0Y[29X[2XMinimalGeneratorsModuleRadical[102X( [3XM[103X ) [32X operation[133X
  [6XReturns:[106X  [33X[0;10YFpGModuleGF[133X
  
  [33X[0;0YReturns  a module equal to the [9XFpGModuleGF[109X [3XM[103X, but which has a minimal set of
  generators. Two algorithms are provided:[133X
  
  [30X    [33X[0;6YThe   two   [10XGF[110X   versions   use  [2XEchelonModuleGenerators[102X  ([14X3.6-1[114X)  and
        [2XEchelonModuleGeneratorsDestructive[102X     ([14X3.6-1[114X)     respectively.    In
        characteristic  two, these return a set of minimal generators, and use
        less  memory  than  the  [10XRadical[110X  version,  but  take  longer.  If the
        characteristic    is    not    two,    these   functions   revert   to
        [2XMinimalGeneratorsModuleRadical[102X.[133X
  
  [30X    [33X[0;6YThe [10XRadical[110X version uses the radical of the module in a manner similar
        to  the  function [14XHAP: GeneratorsOfFpGModule[114X. This is much faster, but
        requires a considerable amount of temporary storage space.[133X
  
  [33X[0;0YSee Section [14X3.5-11[114X below for an example of usage.[133X
  
  [1X3.5-10 RadicalOfModule[101X
  
  [33X[1;0Y[29X[2XRadicalOfModule[102X( [3XM[103X ) [32X operation[133X
  [6XReturns:[106X  [33X[0;10YFpGModuleGF[133X
  
  [33X[0;0YReturns  radical  of  the  [9XFpGModuleGF[109X  module [3XM[103X as another [9XFpGModuleGF[109X. The
  radical  is the module generated by the vectors [22Xv-gv[122X for all [22Xv[122X in the set of
  generating  vectors  for [3XM[103X and all [22Xg[122X in a set of generators for the module's
  group.[133X
  
  [33X[0;0YThe  generators  for  the  returned  module will not be in minimal form: the
  [10XMinimalGeneratorsModule[110X  functions ([14X3.5-9[114X) can be used to convert the module
  to  a  minimal form if necessary. See Section [14X3.5-11[114X below for an example of
  usage.[133X
  
  
  [1X3.5-11 [33X[0;0YExample: Generators and basis vectors of a [9XFpGModuleGF[109X[101X[1X[133X[101X
  
  [33X[0;0YStarting with the same module as in the earlier example (Section [14X3.4-11[114X), we
  now  investigate  the generators of the module [10XM[110X. The generating vectors (of
  which  there  are  15)  returned  by the function [2XKernelOfModuleHomomorphism[102X
  ([14X4.6-3[114X)  are  not  a minimal set, but the function [2XMinimalGeneratorsModuleGF[102X
  ([14X3.5-9[114X)  creates  a  new object [10XN[110X representing the same module, but now with
  only  four  generators.  The vector space spanned by these generators has 15
  basis  vectors,  so representing the module by a [22XG[122X-generating set instead is
  much  more  efficient.  (The  original  generating  set  in [10XM[110X was in fact an
  [22XF[122X-basis, so the dimension of the vector space should come as no surprise.)[133X
  
  [33X[0;0YWe  can also find the radical of the module, and this is used internally for
  the faster, but more memory-hungry, [2XMinimalGeneratorsModuleRadical[102X ([14X3.5-9[114X).[133X
  
  [4X[32X  Example  [32X[104X
    [4X[25Xgap>[125X [27XR := ResolutionPrimePowerGroupRadical(DihedralGroup(8), 2);;[127X[104X
    [4X[25Xgap>[125X [27Xphi := BoundaryFpGModuleHomomorphismGF(R, 2);;[127X[104X
    [4X[25Xgap>[125X [27XM := KernelOfModuleHomomorphism(phi);;[127X[104X
    [4X[25Xgap>[125X [27X#[127X[104X
    [4X[25Xgap>[125X [27XModuleGenerators(M);[127X[104X
    [4X[28X[ <a GF2 vector of length 24>, <a GF2 vector of length 24>,[128X[104X
    [4X[28X  <a GF2 vector of length 24>, <a GF2 vector of length 24>,[128X[104X
    [4X[28X  <a GF2 vector of length 24>, <a GF2 vector of length 24>,[128X[104X
    [4X[28X  <a GF2 vector of length 24>, <a GF2 vector of length 24>,[128X[104X
    [4X[28X  <a GF2 vector of length 24>, <a GF2 vector of length 24>,[128X[104X
    [4X[28X  <a GF2 vector of length 24>, <a GF2 vector of length 24>,[128X[104X
    [4X[28X  <a GF2 vector of length 24>, <a GF2 vector of length 24>,[128X[104X
    [4X[28X  <a GF2 vector of length 24> ][128X[104X
    [4X[25Xgap>[125X [27XModuleGeneratorsAreMinimal(M);[127X[104X
    [4X[28Xfalse[128X[104X
    [4X[25Xgap>[125X [27XModuleGeneratorsForm(M);[127X[104X
    [4X[28X"unknown"[128X[104X
    [4X[25Xgap>[125X [27X#[127X[104X
    [4X[25Xgap>[125X [27XN := MinimalGeneratorsModuleGF(M);[127X[104X
    [4X[28XModule over the group ring of <pc group of size 8 with[128X[104X
    [4X[28X3 generators> in characteristic 2 with 4 generators in FG^[128X[104X
    [4X[28X3. Generators are in minimal echelon form.[128X[104X
    [4X[28X[128X[104X
    [4X[25Xgap>[125X [27XM = N;    # Check that the new module spans the same space[127X[104X
    [4X[28Xtrue[128X[104X
    [4X[25Xgap>[125X [27XModuleGeneratorsAreEchelonForm(N);[127X[104X
    [4X[28Xtrue[128X[104X
    [4X[25Xgap>[125X [27XModuleIsFullCanonical(N);[127X[104X
    [4X[28Xfalse[128X[104X
    [4X[25Xgap>[125X [27XM = N;[127X[104X
    [4X[28Xtrue[128X[104X
    [4X[25Xgap>[125X [27XModuleVectorSpaceBasis(N);[127X[104X
    [4X[28X[ <a GF2 vector of length 24>, <a GF2 vector of length 24>,[128X[104X
    [4X[28X  <a GF2 vector of length 24>, <a GF2 vector of length 24>,[128X[104X
    [4X[28X  <a GF2 vector of length 24>, <a GF2 vector of length 24>,[128X[104X
    [4X[28X  <a GF2 vector of length 24>, <a GF2 vector of length 24>,[128X[104X
    [4X[28X  <a GF2 vector of length 24>, <a GF2 vector of length 24>,[128X[104X
    [4X[28X  <a GF2 vector of length 24>, <a GF2 vector of length 24>,[128X[104X
    [4X[28X  <a GF2 vector of length 24>, <a GF2 vector of length 24>,[128X[104X
    [4X[28X  <a GF2 vector of length 24> ][128X[104X
    [4X[25Xgap>[125X [27XModuleVectorSpaceDimension(N);[127X[104X
    [4X[28X15[128X[104X
    [4X[25Xgap>[125X [27X#[127X[104X
    [4X[25Xgap>[125X [27XN2 := MinimalGeneratorsModuleRadical(M);[127X[104X
    [4X[28XModule over the group ring of <pc group of size 8 with[128X[104X
    [4X[28X3 generators> in characteristic 2 with 4 generators in FG^[128X[104X
    [4X[28X3. Generators are minimal.[128X[104X
    [4X[28X[128X[104X
    [4X[25Xgap>[125X [27X#[127X[104X
    [4X[25Xgap>[125X [27XR := RadicalOfModule(M);[127X[104X
    [4X[28XModule over the group ring of <pc group of size 8 with[128X[104X
    [4X[28X3 generators> in characteristic 2 with 120 generators in FG^3.[128X[104X
    [4X[28X[128X[104X
    [4X[25Xgap>[125X [27XN2 = N;[127X[104X
    [4X[28Xtrue[128X[104X
  [4X[32X[104X
  
  
  [1X3.6 [33X[0;0YBlock echelon functions[133X[101X
  
  [1X3.6-1 EchelonModuleGenerators[101X
  
  [33X[1;0Y[29X[2XEchelonModuleGenerators[102X( [3XM[103X ) [32X operation[133X
  [33X[1;0Y[29X[2XEchelonModuleGeneratorsDestructive[102X( [3XM[103X ) [32X operation[133X
  [33X[1;0Y[29X[2XSemiEchelonModuleGenerators[102X( [3XM[103X ) [32X operation[133X
  [33X[1;0Y[29X[2XSemiEchelonModuleGeneratorsDestructive[102X( [3XM[103X ) [32X operation[133X
  [33X[1;0Y[29X[2XEchelonModuleGeneratorsMinMem[102X( [3XM[103X ) [32X operation[133X
  [33X[1;0Y[29X[2XEchelonModuleGeneratorsMinMemDestructive[102X( [3XM[103X ) [32X operation[133X
  [33X[1;0Y[29X[2XSemiEchelonModuleGeneratorsMinMem[102X( [3XM[103X ) [32X operation[133X
  [33X[1;0Y[29X[2XSemiEchelonModuleGeneratorsMinMemDestructive[102X( [3XM[103X ) [32X operation[133X
  [6XReturns:[106X  [33X[0;10YRecord [10X(module, headblocks)[110X[133X
  
  [33X[0;0YReturns a record with two components:[133X
  
  [30X    [33X[0;6Y[9Xmodule[109X A module whose generators span the same vector space as that of
        the  input  module  [3XM[103X, but whose generators are in a block echelon (or
        semi-echelon) form[133X
  
  [30X    [33X[0;6Y[9Xheadblocks[109X  A  list giving, for each generating vector in [3XM[103X, the block
        in which the head for that generating row lies[133X
  
  [33X[0;0YIn  block-echelon  form. each generator is row-reduced using [22XG[122Xg-multiples of
  the other other generators to produce a new, equivalent generating set where
  the  first  non-zero  block  in  each  generator  is  as far to the right as
  possible.  The  resulting  form,  with  many  zero  blocks,  can  allow more
  memory-efficient  operations  on the module. See Section [14X3.2[114X for details. In
  addition,  the  standard  (non-[10XMinMem[110X)  form  guarantees  that  the  set  of
  generators  are  minimal  in the sense that no generator can be removed from
  the  set while leaving the spanned vector space the same. In the GF(2) case,
  this is the global minimum.[133X
  
  [33X[0;0YSeveral versions of this algorithm are provided. The [10XSemiEchelon[110X versions of
  these  functions do not guarantee a particular generator ordering, while the
  [10XEchelon[110X  versions  sort the generators into order of increasing initial zero
  blocks.  The  non-[10XDestructive[110X  versions of this function return a new module
  and  do  not  modify  the  input module; the [10XDestructive[110X versions change the
  generators  of  the  input  module  in-place,  and  return  this module. All
  versions  are  memory-efficient,  and do not need a full vector-space basis.
  The  [10XMinMem[110X  versions are guaranteed to expand at most two generators at any
  one time, while the standard version may, in the (unlikely) worst-case, need
  to  expand half of the generating set. As a result of this difference in the
  algorithm,  the  [10XMinMem[110X  version  is  likely  to  return a greater number of
  generators  (which will not be minimal), but those generators typically have
  a  greater  number  of  zero  blocks  after  the first non-zero block in the
  generator.  The  [10XMinMem[110X  operations are currently only implemented for GF(2)
  modules. See Section [14X3.6-3[114X below for an example of usage.[133X
  
  [1X3.6-2 ReverseEchelonModuleGenerators[101X
  
  [33X[1;0Y[29X[2XReverseEchelonModuleGenerators[102X( [3XM[103X ) [32X operation[133X
  [33X[1;0Y[29X[2XReverseEchelonModuleGeneratorsDestructive[102X( [3XM[103X ) [32X operation[133X
  [6XReturns:[106X  [33X[0;10YFpGModuleGF[133X
  
  [33X[0;0YReturns an [9XFpGModuleGF[109X module whose vector space spans the same space as the
  input  module  [3XM[103X, but whose generating vectors are modified to try to get as
  many  zero  blocks  as  possible  at  the  end of each vector. This function
  performs  echelon  reduction  of  generating  rows  in  a  manner similar to
  [2XEchelonModuleGenerators[102X  ([14X3.6-1[114X), but working from the bottom upwards. It is
  guaranteed  that  this function will not change the head block (the location
  of  the  first  non-zero  block)  in  each  generating row, and hence if the
  generators are already in an upper-triangular form (e.g. following a call to
  [2XEchelonModuleGenerators[102X  ([14X3.6-1[114X)) then it will not disturb that form and the
  resulting generators will be closer to a diagonal form.[133X
  
  [33X[0;0YThe  [10XDestructive[110X  version  of  this  function  modifies  the  input module's
  generators  in-place  and  then  returns  that  module;  the non-[10XDestructive[110X
  version  works  on  a  copy  of  the input module and so will not modify the
  original module.[133X
  
  [33X[0;0YThis  operation is currently only implemented for GF(2) modules. See Section
  [14X3.5-11[114X below for an example of usage.[133X
  
  
  [1X3.6-3 [33X[0;0YExample: Converting a [9XFpGModuleGF[109X[101X[1X to block echelon form[133X[101X
  
  [33X[0;0YWe  can  construct  a  larger  module than in the earlier examples (Sections
  [14X3.4-11[114X  and  [14X3.5-11[114X) by taking the kernel of the third boundary homomorphism
  of  a  minimal  resolution  of a group of order 32, which as returned by the
  function  [2XKernelOfModuleHomomorphism[102X  ([14X4.6-3[114X) has a generating set with many
  redundant  generators.  We  display the block structure of the generators of
  this module after applying various block echelon reduction functions.[133X
  
  [4X[32X  Example  [32X[104X
    [4X[25Xgap>[125X [27XR := ResolutionPrimePowerGroupRadical(SmallGroup(32, 10), 3);;[127X[104X
    [4X[25Xgap>[125X [27Xphi := BoundaryFpGModuleHomomorphismGF(R, 3);;[127X[104X
    [4X[25Xgap>[125X [27X#[127X[104X
    [4X[25Xgap>[125X [27XM := KernelOfModuleHomomorphism(phi);[127X[104X
    [4X[28XModule over the group ring of <pc group of size 32 with[128X[104X
    [4X[28X5 generators> in characteristic 2 with 65 generators in FG^4.[128X[104X
    [4X[28X[128X[104X
    [4X[25Xgap>[125X [27X#[127X[104X
    [4X[25Xgap>[125X [27XN := SemiEchelonModuleGenerators(M);[127X[104X
    [4X[28Xrec( module := Module over the group ring of <pc group of size 32 with[128X[104X
    [4X[28X    5 generators> in characteristic 2 with 5 generators in FG^[128X[104X
    [4X[28X    4. Generators are in minimal semi-echelon form.[128X[104X
    [4X[28X    , headblocks := [ 2, 3, 1, 1, 3 ] )[128X[104X
    [4X[25Xgap>[125X [27XDisplayBlocks(N.module);[127X[104X
    [4X[28XModule over the group ring of Group( [ f1, f2, f3, f4, f5 ] )[128X[104X
    [4X[28X in characteristic 2 with 5 generators in FG^4.[128X[104X
    [4X[28X[.*.*][128X[104X
    [4X[28X[..**][128X[104X
    [4X[28X[***.][128X[104X
    [4X[28X[****][128X[104X
    [4X[28X[..**][128X[104X
    [4X[28XGenerators are in minimal semi-echelon form.[128X[104X
    [4X[25Xgap>[125X [27XN2 := SemiEchelonModuleGeneratorsMinMem(M);[127X[104X
    [4X[28Xrec( module := Module over the group ring of <pc group of size 32 with[128X[104X
    [4X[28X    5 generators> in characteristic 2 with 9 generators in FG^4. [128X[104X
    [4X[28X    , headblocks := [ 2, 1, 3, 1, 1, 4, 1, 3, 4 ] )[128X[104X
    [4X[25Xgap>[125X [27XDisplayBlocks(N2.module);[127X[104X
    [4X[28XModule over the group ring of Group( [ f1, f2, f3, f4, f5 ] )[128X[104X
    [4X[28X in characteristic 2 with 9 generators in FG^4.[128X[104X
    [4X[28X[.*..][128X[104X
    [4X[28X[**..][128X[104X
    [4X[28X[..**][128X[104X
    [4X[28X[****][128X[104X
    [4X[28X[****][128X[104X
    [4X[28X[...*][128X[104X
    [4X[28X[****][128X[104X
    [4X[28X[..**][128X[104X
    [4X[28X[...*][128X[104X
    [4X[28X[128X[104X
    [4X[25Xgap>[125X [27X#[127X[104X
    [4X[25Xgap>[125X [27XEchelonModuleGeneratorsDestructive(M);;[127X[104X
    [4X[25Xgap>[125X [27XDisplayBlocks(M);[127X[104X
    [4X[28XModule over the group ring of Group( [ f1, f2, f3, f4, f5 ] )[128X[104X
    [4X[28X in characteristic 2 with 5 generators in FG^4.[128X[104X
    [4X[28X[***.][128X[104X
    [4X[28X[****][128X[104X
    [4X[28X[.*.*][128X[104X
    [4X[28X[..**][128X[104X
    [4X[28X[..**][128X[104X
    [4X[28XGenerators are in minimal echelon form.[128X[104X
    [4X[25Xgap>[125X [27XReverseEchelonModuleGeneratorsDestructive(M);[127X[104X
    [4X[28XModule over the group ring of <pc group of size 32 with[128X[104X
    [4X[28X5 generators> in characteristic 2 with 5 generators in FG^[128X[104X
    [4X[28X4. Generators are in minimal echelon form.[128X[104X
    [4X[28X[128X[104X
    [4X[25Xgap>[125X [27XDisplayBlocks(M);[127X[104X
    [4X[28XModule over the group ring of Group( [ f1, f2, f3, f4, f5 ] )[128X[104X
    [4X[28X in characteristic 2 with 5 generators in FG^4.[128X[104X
    [4X[28X[***.][128X[104X
    [4X[28X[****][128X[104X
    [4X[28X[.*..][128X[104X
    [4X[28X[..*.][128X[104X
    [4X[28X[..**][128X[104X
    [4X[28XGenerators are in minimal echelon form.[128X[104X
  [4X[32X[104X
  
  
  [1X3.7 [33X[0;0YSum and intersection functions[133X[101X
  
  
  [1X3.7-1 [33X[0;0YDirectSumOfModules[133X[101X
  
  [33X[1;0Y[29X[2XDirectSumOfModules[102X( [3XM[103X, [3XN[103X ) [32X operation[133X
  [33X[1;0Y[29X[2XDirectSumOfModules[102X( [3Xcoll[103X ) [32X operation[133X
  [33X[1;0Y[29X[2XDirectSumOfModules[102X( [3XM[103X, [3Xn[103X ) [32X operation[133X
  [6XReturns:[106X  [33X[0;10YFpGModule[133X
  
  [33X[0;0YReturns  the  [9XFpGModuleGF[109X  module  that  is  the direct sum of the specified
  modules (which must have a common group and action). The input can be either
  two modules [3XM[103X and [3XN[103X, a list of modules [3Xcoll[103X, or one module [3XM[103X and an exponent
  [3Xn[103X  specifying  the number of copies of [3XM[103X to sum. See Section [14X3.7-5[114X below for
  an example of usage.[133X
  
  [33X[0;0YIf  the  input  modules all have minimal generators and/or echelon form, the
  construction  of the direct sum guarantees that the output module will share
  the same form.[133X
  
  [1X3.7-2 DirectDecompositionOfModule[101X
  
  [33X[1;0Y[29X[2XDirectDecompositionOfModule[102X( [3XM[103X ) [32X operation[133X
  [33X[1;0Y[29X[2XDirectDecompositionOfModuleDestructive[102X( [3XM[103X ) [32X operation[133X
  [6XReturns:[106X  [33X[0;10YList of FpGModuleGFs[133X
  
  [33X[0;0YReturns  a  list  of  [9XFpGModuleGF[109Xs  whose  direct  sum is equal to the input
  [9XFpGModuleGF[109X  module  [3XM[103X.  The  list  may consist of one element: the original
  module.[133X
  
  [33X[0;0YThis function relies on the block structure of a set of generators that have
  been   converted   to   both   echelon   and   reverse-echelon   form   (see
  [2XEchelonModuleGenerators[102X ([14X3.6-1[114X) and [2XReverseEchelonModuleGenerators[102X ([14X3.6-2[114X)),
  and  calls  these functions if the module is not already in echelon form. In
  this  form,  it can be possible to trivially identify direct summands. There
  is no guarantee either that this function will return a decomposition if one
  is available, or that the modules returned in a decomposition are themselves
  indecomposable. See Section [14X3.7-5[114X below for an example of usage.[133X
  
  [33X[0;0YThe  [10XDestructive[110X  version  of this function uses the [10XDestructive[110X versions of
  the  echelon functions, and so modifies the input module and returns modules
  who  share  generating rows with the modified [3XM[103X. The non-[10XDestructive[110X version
  operates on a copy of [3XM[103X, and returns modules with unique rows.[133X
  
  [1X3.7-3 IntersectionModules[101X
  
  [33X[1;0Y[29X[2XIntersectionModules[102X( [3XM[103X, [3XN[103X ) [32X operation[133X
  [33X[1;0Y[29X[2XIntersectionModulesGF[102X( [3XM[103X, [3XN[103X ) [32X operation[133X
  [33X[1;0Y[29X[2XIntersectionModulesGFDestructive[102X( [3XM[103X, [3XN[103X ) [32X operation[133X
  [33X[1;0Y[29X[2XIntersectionModulesGF2[102X( [3XM[103X, [3XN[103X ) [32X operation[133X
  [6XReturns:[106X  [33X[0;10YFpGModuleGF[133X
  
  [33X[0;0YReturns the [9XFpGModuleGF[109X module that is the intersection of the modules [3XM[103X and
  [3XN[103X.  This  function  calculates  the  intersection using vector space methods
  (i.e.        [2XSumIntersectionMatDestructive[102X        ([14XHAPprime       Datatypes:
  SumIntersectionMatDestructive[114X)).  The standard version works on the complete
  vector  space bases of the input modules. The [10XGF[110X version considers the block
  structure  of  the generators of [3XM[103X and [3XN[103X and only expands the necessary rows
  and  blocks.  This  can  lead to a large saving and memory if [3XM[103X and [3XN[103X are in
  echelon  form  and have a small intersection. See Section [14X3.2-4[114X for details.
  See  Section  [14X3.7-5[114X  below for an example of usage. The [10XGF2[110X version computes
  the  intersection  by  a  [22XG[122X-version  of the standard vector space algorithm,
  using  [2XEchelonModuleGenerators[102X  ([14X3.6-1[114X)  to  perform echelon reduction on an
  augmented  set  of  generators. This is much slower than the [10XGF[110X version, but
  may use less memory.[133X
  
  [33X[0;0YThe  vector spaces in [9XFpGModuleGF[109Xs are assumed to all be with respect to the
  same  canonical  basis, so it is assumed that modules are compatible if they
  have the same group and the same ambient dimension.[133X
  
  [33X[0;0YThe  [10XDestructive[110X  version  of  the  [10XGF[110X  function  corrupts  or  permutes the
  generating  vectors  of  [3XM[103X  and  [3XN[103X,  leaving it invalid; the non-destructive
  version operates on copies of them, leaving the original modules unmodified.
  The  generating  vectors in the module returned by this function are in fact
  also  a  [13Xvector  space[113X  basis  for  the  module, so will not be minimal. The
  returned module can be converted to a set of minimal generators using one of
  the [10XMinimalGeneratorsModule[110X functions ([14X3.5-9[114X).[133X
  
  [33X[0;0YThis operation is currently only defined for GF(2).[133X
  
  [1X3.7-4 SumModules[101X
  
  [33X[1;0Y[29X[2XSumModules[102X( [3XM[103X, [3XN[103X ) [32X operation[133X
  [6XReturns:[106X  [33X[0;10YFpGModuleGF[133X
  
  [33X[0;0YReturns the [9XFpGModuleGF[109X module that is the sum of the input modules [3XM[103X and [3XN[103X.
  This  function simply concatenates the generating vectors of the two modules
  and  returns  the result. If a set of minimal generators are needed then use
  one  of  the  [10XMinimalGeneratorsModule[110X  functions  ([14X3.5-9[114X) on the result. See
  Section [14X3.7-5[114X below for an example of usage.[133X
  
  [33X[0;0YThe  vector  spaces in [9XFpGModuleGF[109X are assumed to all be with respect to the
  same  canonical  basis, so it is assumed that modules are compatible if they
  have the same group and the same ambient dimension.[133X
  
  
  [1X3.7-5 [33X[0;0YExample: Sum and intersection of [9XFpGModuleGF[109X[101X[1Xs[133X[101X
  
  [33X[0;0YWe  can construct the direct sum of [22XFG[122X-modules, and (attempt to) calculate a
  direct decomposition of a module. For example, we can show that[133X
  
  
  [24X[33X[0;6Y(FG)^2 (+) FG = FG (+) FG (+) FG[133X
  
  [124X
  
  [4X[32X  Example  [32X[104X
    [4X[25Xgap>[125X [27XG := CyclicGroup(64);;[127X[104X
    [4X[25Xgap>[125X [27XFG := FpGModuleGF(G, 1);[127X[104X
    [4X[28XFull canonical module FG^1 over the group ring of <pc group of size 64 with[128X[104X
    [4X[28X6 generators> in characteristic 2[128X[104X
    [4X[28X[128X[104X
    [4X[25Xgap>[125X [27XFG2 := FpGModuleGF(G, 2);[127X[104X
    [4X[28XFull canonical module FG^2 over the group ring of <pc group of size 64 with[128X[104X
    [4X[28X6 generators> in characteristic 2[128X[104X
    [4X[28X[128X[104X
    [4X[25Xgap>[125X [27XM := DirectSumOfModules(FG2, FG);[127X[104X
    [4X[28XFull canonical module FG^3 over the group ring of <pc group of size 64 with[128X[104X
    [4X[28X6 generators> in characteristic 2[128X[104X
    [4X[28X[128X[104X
    [4X[25Xgap>[125X [27XDirectDecompositionOfModule(M);[127X[104X
    [4X[28X[ Module over the group ring of <pc group of size 64 with[128X[104X
    [4X[28X    6 generators> in characteristic 2 with 1 generator in FG^[128X[104X
    [4X[28X    1. Generators are in minimal echelon form.[128X[104X
    [4X[28X    , Module over the group ring of <pc group of size 64 with[128X[104X
    [4X[28X    6 generators> in characteristic 2 with 1 generator in FG^[128X[104X
    [4X[28X    1. Generators are in minimal echelon form.[128X[104X
    [4X[28X    , Module over the group ring of <pc group of size 64 with[128X[104X
    [4X[28X    6 generators> in characteristic 2 with 1 generator in FG^[128X[104X
    [4X[28X    1. Generators are in minimal echelon form.[128X[104X
    [4X[28X     ][128X[104X
  [4X[32X[104X
  
  [33X[0;0YWe  can  also compute the sum and intersection of [22XFG[122X-modules. In the example
  below  we  construct  two submodules of [22XFG[122X, where [22XG[122X is the dihedral group of
  order  four:  [10XM[110X  is  the  submodule  generated  by  [22Xg_1  + g_2[122X, and [10XN[110X is the
  submodule  generated  by  [22Xg_1  + g_2 + g_3 + g_4[122X. We calculate their sum and
  intersection.  Since  [10XN[110X is in this case a submodule of [10XM[110X it is easy to check
  that the correct results are obtained.[133X
  
  [4X[32X  Example  [32X[104X
    [4X[25Xgap>[125X [27XG := DihedralGroup(4);;[127X[104X
    [4X[25Xgap>[125X [27XM := FpGModuleGF([[1,1,0,0]]*One(GF(2)), G);[127X[104X
    [4X[28XModule over the group ring of <pc group of size 4 with[128X[104X
    [4X[28X2 generators> in characteristic 2 with 1 generator in FG^[128X[104X
    [4X[28X1. Generators are in minimal echelon form.[128X[104X
    [4X[28X[128X[104X
    [4X[25Xgap>[125X [27XN := FpGModuleGF([[1,1,1,1]]*One(GF(2)), G);[127X[104X
    [4X[28XModule over the group ring of <pc group of size 4 with[128X[104X
    [4X[28X2 generators> in characteristic 2 with 1 generator in FG^[128X[104X
    [4X[28X1. Generators are in minimal echelon form.[128X[104X
    [4X[28X[128X[104X
    [4X[25Xgap>[125X [27X#[127X[104X
    [4X[25Xgap>[125X [27XS := SumModules(M,N);[127X[104X
    [4X[28XModule over the group ring of <pc group of size 4 with[128X[104X
    [4X[28X2 generators> in characteristic 2 with 2 generators in FG^1.[128X[104X
    [4X[28X[128X[104X
    [4X[25Xgap>[125X [27XI := IntersectionModules(M,N);[127X[104X
    [4X[28XModule over the group ring of <pc group of size 4 with[128X[104X
    [4X[28X2 generators> in characteristic 2 with 1 generator in FG^1.[128X[104X
    [4X[28X[128X[104X
    [4X[25Xgap>[125X [27X#[127X[104X
    [4X[25Xgap>[125X [27XS = M and I = N;[127X[104X
    [4X[28Xtrue[128X[104X
  [4X[32X[104X
  
  
  [1X3.8 [33X[0;0YMiscellaneous functions[133X[101X
  
  [1X3.8-1 =[101X
  
  [33X[1;0Y[29X[2X=[102X( [3XM[103X, [3XN[103X ) [32X operation[133X
  [6XReturns:[106X  [33X[0;10YBoolean[133X
  
  [33X[0;0YReturns [9Xtrue[109X if the modules are equal, [9Xfalse[109X otherwise. This checks that the
  groups  and  actions in each module are equal (i.e. identical), and that the
  vector  space spanned by the two modules are the same. (All vector spaces in
  [9XFpGModuleGF[109Xs of the same ambient dimension are assumed to be embedded in the
  same canonical basis.) See Section [14X3.5-11[114X above for an example of usage.[133X
  
  
  [1X3.8-2 [33X[0;0YIsModuleElement[133X[101X
  
  [33X[1;0Y[29X[2XIsModuleElement[102X( [3XM[103X, [3Xelm[103X ) [32X operation[133X
  [33X[1;0Y[29X[2XIsModuleElement[102X( [3XM[103X, [3Xcoll[103X ) [32X operation[133X
  [6XReturns:[106X  [33X[0;10YBoolean[133X
  
  [33X[0;0YReturns  [9Xtrue[109X  if  the  vector  [3Xelm[103X  can be interpreted as an element of the
  module  [3XM[103X,  or  [9Xfalse[109X otherwise. If a collection of elements is given as the
  second  argument  then a list of responses is returned, one for each element
  in the collection. See Section [14X3.3-5[114X above for an example of usage.[133X
  
  [1X3.8-3 IsSubModule[101X
  
  [33X[1;0Y[29X[2XIsSubModule[102X( [3XM[103X, [3XN[103X ) [32X operation[133X
  [6XReturns:[106X  [33X[0;10YBoolean[133X
  
  [33X[0;0YReturns  [9Xtrue[109X  if  the  module  [3XN[103X  is a submodule of [3XM[103X. This checks that the
  modules have the same group and action, and that the generators for module [3XN[103X
  are elements of the module [3XM[103X. (All vector spaces in [9XFpGModuleGF[109Xs of the same
  ambient  dimension  are assumed to be embedded in the same canonical basis.)
  See Section [14X3.3-5[114X above for an example of usage.[133X
  
  [1X3.8-4 RandomElement[101X
  
  [33X[1;0Y[29X[2XRandomElement[102X( [3XM[103X[, [3Xn[103X] ) [32X operation[133X
  [6XReturns:[106X  [33X[0;10YVector[133X
  
  [33X[0;0YReturns  a  vector  which is a random element from the module [3XM[103X. If a second
  argument,  [3Xn[103X  is  give,  then  a  list of [3Xn[103X random elements is returned. See
  Section [14X3.3-5[114X above for an example of usage.[133X
  
  
  [1X3.8-5 [33X[0;0YRandom Submodule[133X[101X
  
  [33X[1;0Y[29X[2XRandomSubmodule[102X( [3XM[103X, [3Xngens[103X ) [32X operation[133X
  [6XReturns:[106X  [33X[0;10Y[9XFpGModuleGF[109X[133X
  
  [33X[0;0YReturns a [9XFpGModuleGF[109X module that is a submodule of [3XM[103X, with [3Xngens[103X generators
  selected  at  random from elements of [3XM[103X. These generators are not guaranteed
  to be minimal, so the rank of the submodule will not necessarily be equal to
  [3Xngens[103X.   If   a   module   with   minimal   generators   is   required,  the
  [10XMinimalGeneratorsModule[110X  functions ([14X3.5-9[114X) can be used to convert the module
  to a minimal form See Section [14X3.3-5[114X above for an example of usage.[133X
  
