  
  [1X6 FG-module homomorphisms[0X
  
  
  [1X6.1 The [9XFpGModuleHomomorphismGF[1X datatype[0X
  
  Linear  homomorphisms  between free FG-modules (as [9XFpGModuleGF[0m objects - see
  Chapter  [14X5[0m)  are  represented  in [5XHAPprime[0m using the [9XFpGModuleHomomorphismGF[0m
  datatype.  This  represents  module  homomorphisms  in  a  similar manner to
  FG-modules,  using  a  set  of generating vectors, in this case vectors that
  generate  the  images  in  the target module of the generators of the source
  module.
  
  Three    items   need   to   be   passed   to   the   constructor   function
  [2XFpGModuleHomomorphismGF[0m ([14X6.4-1[0m):
  
  --    [10Xsource[0m the source [9XFpGModuleGF[0m module for the homomorphism
  
  --    [10Xtarget[0m the target [9XFpGModuleGF[0m module for the homomorphism
  
  --    [10Xgens[0m  a  list  of  vectors  that  are the images (in [10Xtarget[0m) under the
        homomorphisms of each of the generators stored in [10Xsource[0m
  
  
  [1X6.2  Calculating  the kernel of a FG-module homorphism by splitting into two[0X
  [1Xhomomorphisms[0X
  
  [5XHAPprime[0m  represents  a  homomorphism  between  two  FG-modules as a list of
  generators  for the image of the homomorphism. Each generator is given as an
  element  in the target module, represented as a vector in the same manner as
  used  in  the  [9XFpGModuleGF[0m  datatype  (see  Chapter  [14X5[0m). Given a set of such
  generating  vectors,  an  F-generating set for the image of the homomorphism
  (as  elements  of  the  target module's vector space) is given by taking all
  G-multiples of the generators. Writing the vectors in this expanded set as a
  matrix,  the kernel of the boundary homomorphism is the (left) null-space of
  this  matrix.  As  with  [9XFpGModuleGF[0ms, the block structure of the generating
  vectors  (see Section [14X5.2-1[0m) allows this null-space to be calculated without
  necessarily expanding the whole matrix.
  
  This   basic   algorithm   is   implemented   in   the   [5XHAPprime[0m   function
  [2XKernelOfModuleHomomorphismSplit[0m ([14X6.6-3[0m). The generating vectors for a module
  homomorphism  H  are divided in half, with the homomorphism generated by the
  first  half  of the generating vectors being called U and that by the second
  half being called V. Given this partition the kernel of H can be defined as
  
  
       ker(H) = intersection of preim_U(I) with [-preim_V(I)]
  
  
  where
  
  --    I  =  im(U)  cap  im(V)  is  the intersection of the images of the two
        homomorphisms U and V
  
  --    preim_U(I) the set of all preimages of I under U
  
  --    preim_V(I) the set of all preimages of I under V
  
  Rather   than   computing   the  complete  set  of  preimages,  instead  the
  implementation  takes  a preimage representative of each generator for I and
  adds  the  kernel  of  the  homomorphisms U and V. The means that instead of
  calculating  the  null-space of the full expanded matrix, we can compute the
  answer   by   calculating  the  kernels  of  two  homomorphisms  with  fewer
  generators,  as  well  as the intersection of two modules, and some preimage
  representatives.  Each  of these operations takes less memory than the naive
  null-space  calculation. The intersection of two FG-modules can be compactly
  calculated  using the generators' block structure (see Section [14X5.2-4[0m), while
  the  kernels  of  U  and  V  can  be  computed  recursively using these same
  algorithm.  The  block  structure can also help in calculating the preimage,
  but  at  a  considerable cost in time, so this is not done. However, since U
  and V have fewer generators than the original homomorphism H, a space saving
  is still made.
  
  In  the case where the problem is seperable, i.e. a U and V can be found for
  which  there  is no intersection, this approach can give a large saving. The
  separable  components of the homomorphism can be readily identified from the
  block  structure  of the generators (they are the rows which share no blocks
  or  heads  with  other  rows),  and  the  kernels of these can be calculated
  independently,  with  no intersection to worry about. This is implemented in
  the    alternative    algorithm   [2XKernelOfModuleHomomorphismIndependentSplit[0m
  ([14X6.6-3[0m).
  
  
  [1X6.3 Calculating the kernel of a FG-module homorphism by column reduction and[0X
  [1Xpartitioning[0X
  
  The  list  of  generators  of  the  image of a FG-module homomorphism can be
  interpreted  as  the  rows  of a matrix A with elements in FG, and it is the
  kernel  of  this  matrix which must be found (i.e. the solutions to xA=0. If
  column  reduction  is  performed  on  this matrix (by adding FG-multiples of
  other  columns  to a column), the kernel is left unchanged, and this process
  can  be  performed to enable the kernel to be found by a recursive algorithm
  similar to standard back substitution methods.
  
  Given  the  matrix A = (a_ij), take the FG-module generated by the first row
  (a_1j)  and  find  a  minimal (or small) subset of elements a_1j_j in J that
  generate  this  module.  Without  altering  the  kernel,  we can permute the
  columns  of  A  such  that  J  =  1 ... t. Taking F and G-multiples of these
  columns  from  the  remaining columns, the first row of these columns can be
  reduced  to  zero, giving a new matrix A'. This matrix can be partitioned as
  follows:
  
  
       [ B 0 ] [ C D ]
  
  
  where  B  is 1x t, C is (m-1)x t and D is (m-1)x (n-t). It is assumed that B
  and  C  are  `small'  and  operations  on these can can be easily handled in
  memory using standard linear algebra, while D may still be large.
  
  Taking  the FG-module generated by the t columns which form the BC partition
  of  the  matrix, we compute E, a set of minimal generators for the submodule
  of  this  which  is zero in the first row. These are added as columns at the
  end of A', giving a matrix
  
  
       [ B 0 0 ] [ C D E ]
  
  
  The kernel of this matrix can be shown to be
  
  
       [ ker(B) 0 ] [ L ker(DE) ]
  
  
  where
  
  
       L = preim_B((\ker (DE)) C)
  
  
  The  augmentation  of  D with E guarantees that this preimage always exists.
  Since  B  and C are small, both ker B and L are easy to compute using linear
  algebra, while ker (DE) can be computed by recursion.
  
  Unfortunately,  E  can be large, and the accumulated increase of size of the
  matrix  over  many  recursions  negates the time and memory saving that this
  algorithm  might be expected to give. Testing indicates that it is currently
  no  faster than the [2XKernelOfModuleHomomorphismSplit[0m ([14X6.6-3[0m) method, and does
  not  save  much  memory  over  the  full  expansion using linear algebra. An
  improved  version of this algorithm would reduce E by D before augmentation,
  thus  adding  a  smaller  set of generators and restricting the explosion in
  size. If D were already in echelon form, this would also be time-efficient.
  
  
  [1X6.4 Construction functions[0X
  
  
  [1X6.4-1 FpGModuleHomomorphismGF construction functions[0X
  
  [2X> FpGModuleHomomorphismGF( [0X[3XS, T, gens[0X[2X ) ___________________________[0Xoperation
  [2X> FpGModuleHomomorphismGFNC( [0X[3XS, T, gens[0X[2X ) _________________________[0Xoperation
  [6XReturns:[0X  [9XFpGModuleHomomorphismGF[0m
  
  Creates  and  returns an [9XFpGModuleHomomorphismGF[0m module homomorphism object.
  This  represents  the  homomorphism from the module [3XS[0m to the module [3XT[0m with a
  list  of vectors [3Xgens[0m whose rows are the images in [3XT[0m of the generators of [3XS[0m.
  The modules must (currently) be over the same group.
  
  The standard constructor checks that the homomorphism is compatible with the
  modules,  i.e.  that the vectors in [3Xgens[0m have the correct dimension and that
  they  lie  within the target module [3XT[0m. It also checks whether the generators
  of  [3XS[0m  are minimal. If they are not, then the homomorphism is created with a
  copy  of [3XS[0m that has minimal generators (using [2XMinimalGeneratorsModuleRadical[0m
  ([14X5.5-9[0m)),  and  [3Xgens[0m is also copied and converted to agree with the new form
  of  [3XS[0m.  If  you  wish  to  skip these checks then use the [10XNC[0m version of this
  function.
  
  IMPORTANT: The generators of the module [3XS[0m and the generator matrix [3Xgens[0m must
  be  remain  consistent  for  the  lifetime  of  this  homomorphism.  If  the
  homomorphism  is  constructed  with  a  mutable  source  module or generator
  matrix,  then  you must be careful not to modify them while the homomorphism
  is needed.
  
  
  [1X6.4-2 Example: Constructing a [9XFpGModuleHomomorphismGF[1X[0X
  
  In this example we construct the module homomorphism phi: (FG)^2 -> FG which
  maps both generators of (FG)^2 to the generator of FG
  
  [4X---------------------------  Example  ----------------------------[0X
    [4Xgap> G := SmallGroup(8, 4);;[0X
    [4Xgap> im := [1,0,0,0,0,0,0,0]*One(GF(2));[0X
    [4X[ Z(2)^0, 0*Z(2), 0*Z(2), 0*Z(2), 0*Z(2), 0*Z(2), 0*Z(2), 0*Z(2) ][0X
    [4Xgap> phi := FpGModuleHomomorphismGF([0X
    [4X>              FpGModuleGF(G, 2),[0X
    [4X>              FpGModuleGF(G, 1),[0X
    [4X>              [im, im]);[0X
    [4X<Module homomorphism>[0X
  [4X------------------------------------------------------------------[0X
  
  
  [1X6.5 Data access functions[0X
  
  [1X6.5-1 SourceModule[0m
  
  [2X> SourceModule( [0X[3Xphi[0X[2X ) _____________________________________________[0Xoperation
  [6XReturns:[0X  [9XFpGModuleGF[0m
  
  Returns the source module for the homomorphism [3Xphi[0m, as an [9XFpGModuleGF[0m.
  
  [1X6.5-2 TargetModule[0m
  
  [2X> TargetModule( [0X[3Xphi[0X[2X ) _____________________________________________[0Xoperation
  [6XReturns:[0X  FpGModuleGF
  
  Returns the targetmodule for the homomorphism [3Xphi[0m, as an [9XFpGModuleGF[0m.
  
  [1X6.5-3 ModuleHomomorphismGeneratorMatrix[0m
  
  [2X> ModuleHomomorphismGeneratorMatrix( [0X[3Xphi[0X[2X ) ________________________[0Xoperation
  [6XReturns:[0X  List of vectors
  
  Returns   the   generating   vectors  [10Xgens[0m  of  the  representation  of  the
  homomorphism  [3Xphi[0m.  These vectors are the images in the target module of the
  generators of the source module.
  
  [1X6.5-4 DisplayBlocks[0m
  
  [2X> DisplayBlocks( [0X[3Xphi[0X[2X ) _______________________________________________[0Xmethod
  [6XReturns:[0X  nothing
  
  Prints a detailed description of the module in human-readable form, with the
  module generators and generator matrix shown in block form. The standard [5XGAP[0m
  methods  [2XView[0m  ([14XReference:  View[0m),  [2XPrint[0m  ([14XReference:  Print[0m)  and  [2XDisplay[0m
  ([14XReference: Display[0m) are also available.)
  
  [1X6.5-5 DisplayModuleHomomorphismGeneratorMatrix[0m
  
  [2X> DisplayModuleHomomorphismGeneratorMatrix( [0X[3Xphi[0X[2X ) ____________________[0Xmethod
  [6XReturns:[0X  nothing
  
  Prints  a detailed description of the module homomorphism generating vectors
  [10Xgens[0m  in human-readable form. This is the display method used in the [2XDisplay[0m
  ([14XReference: Display[0m) method for this datatype.
  
  [1X6.5-6 DisplayModuleHomomorphismGeneratorMatrixBlocks[0m
  
  [2X> DisplayModuleHomomorphismGeneratorMatrixBlocks( [0X[3Xphi[0X[2X ) ______________[0Xmethod
  [6XReturns:[0X  nothing
  
  Prints  a detailed description of the module homomorphism generating vectors
  [10Xgens[0m  in human-readable form. This is the function used in the [2XDisplayBlocks[0m
  ([14X6.5-4[0m) method.
  
  
  [1X6.5-7 Example: Accessing data about a [9XFpGModuleHomomorphismGF[1X[0X
  
  A free FG resolution is a chain complex of FG-modules and homomorphisms, and
  the  homomorphisms  in a [9XHAPResolution[0m (see Chapter [14X2[0m) can be extracted as a
  [9XFpGModuleHomomorphismGF[0m  using  the function [2XBoundaryFpGModuleHomomorphismGF[0m
  ([14X2.4-6[0m).  We  construct a resolution [10XR[0m and then examine the third resolution
  in  the  chain  complex,  which  is a FG-module homomorphism d_3 : (FG)^7 ->
  (FG)^5.
  
  [4X---------------------------  Example  ----------------------------[0X
    [4Xgap> R := ResolutionPrimePowerGroupRadical(SmallGroup(64, 141), 3);;[0X
    [4X#I  Dimension 2: rank 5[0X
    [4X#I  Dimension 3: rank 7[0X
    [4Xgap> d3 := BoundaryFpGModuleHomomorphismGF(R, 3);;[0X
    [4Xgap> SourceModule(d3);[0X
    [4XFull canonical module FG^7 over the group ring of <pc group of size 64 with[0X
    [4X6 generators> in characteristic 2[0X
    [4X[0X
    [4Xgap> TargetModule(d3);[0X
    [4XFull canonical module FG^5 over the group ring of <pc group of size 64 with[0X
    [4X6 generators> in characteristic 2[0X
    [4X[0X
    [4Xgap> ModuleHomomorphismGeneratorMatrix(d3);[0X
    [4X<an immutable 7x320 matrix over GF2>[0X
    [4Xgap> DisplayBlocks(d3);[0X
    [4XModule homomorphism with source:[0X
    [4XFull canonical module FG^7 over the group ring of Group([0X
    [4X[ f1, f2, f3, f4, f5, f6 ] )[0X
    [4X in characteristic 2[0X
    [4X[0X
    [4Xand target:[0X
    [4XFull canonical module FG^5 over the group ring of Group([0X
    [4X[ f1, f2, f3, f4, f5, f6 ] )[0X
    [4X in characteristic 2[0X
    [4X[0X
    [4Xand generator matrix:[0X
    [4X[*.*.*][0X
    [4X[*****][0X
    [4X[.**..][0X
    [4X[.**..][0X
    [4X[..**.][0X
    [4X[...**][0X
    [4X[...*.][0X
    [4X[0X
  [4X------------------------------------------------------------------[0X
  
  Note  that  the  module  homomorphism  generating  vectors  in  a resolution
  calculated  using [5XHAPprime[0m are in block-echelon form (see Section [14X5.2[0m). This
  makes  it  efficient  to  compute  the  kernel  of  this  homomorphism using
  [2XKernelOfModuleHomomorphismSplit[0m  ([14X6.6-3[0m), as described in Section [14X6.2[0m, since
  there  is  only a small intersection between the images generated by the top
  and bottom halves of the generating vectors.
  
  
  [1X6.6 Image and kernel functions[0X
  
  
  [1X6.6-1 ImageOfModuleHomomorphism[0X
  
  [2X> ImageOfModuleHomomorphism( [0X[3Xphi[0X[2X ) ________________________________[0Xoperation
  [2X> ImageOfModuleHomomorphism( [0X[3Xphi, M[0X[2X ) _____________________________[0Xoperation
  [2X> ImageOfModuleHomomorphism( [0X[3Xphi, elm[0X[2X ) ___________________________[0Xoperation
  [2X> ImageOfModuleHomomorphism( [0X[3Xphi, coll[0X[2X ) __________________________[0Xoperation
  [2X> ImageOfModuleHomomorphismDestructive( [0X[3Xphi, elm[0X[2X ) ________________[0Xoperation
  [2X> ImageOfModuleHomomorphismDestructive( [0X[3Xphi, coll[0X[2X ) _______________[0Xoperation
  [6XReturns:[0X  [9XFpGModuleGF[0m, vector or list of vectors depending on argument
  
  For  a module homomorphism [3Xphi[0m, the one-argument function returns the module
  that  is  the  image  of  the  homomorphism, while the two-argument versions
  return  the  result  of  mapping  of  an [10XFpGModuleGF[0m [3XM[0m, a module element [3Xelm[0m
  (given  as  a  vector),  or a collection of module elements [3Xcoll[0m through the
  homomorphism.  This  uses  standard  linear  algebra  to  find  the image of
  elements from the source module.
  
  The  [10XDestructive[0m versions of the function will corrupt the second parameter,
  which  must  be  mutable  as  a  result.  The version of this operation that
  returns a module does not guarantee that the module will be in minimal form,
  and  one  of the [10XMinimalGeneratorsModule[0m functions ([14X5.5-9[0m) should be used on
  the result if a minimal set of generators is needed.
  
  
  [1X6.6-2 PreImageRepresentativeOfModuleHomomorphism[0X
  
  [2X> PreImageRepresentativeOfModuleHomomorphism( [0X[3Xphi, elm[0X[2X ) __________[0Xoperation
  [2X> PreImageRepresentativeOfModuleHomomorphism( [0X[3Xphi, coll[0X[2X ) _________[0Xoperation
  [2X> PreImageRepresentativeOfModuleHomomorphism( [0X[3Xphi, M[0X[2X ) ____________[0Xoperation
  [2X> PreImageRepresentativeOfModuleHomomorphismGF( [0X[3Xphi, elm[0X[2X ) ________[0Xoperation
  [2X> PreImageRepresentativeOfModuleHomomorphismGF( [0X[3Xphi, coll[0X[2X ) _______[0Xoperation
  
  For an element [3Xelm[0m in the image of [3Xphi[0m, this returns a representative of the
  set  of  preimages of [3Xelm[0m under [3Xphi[0m, otherwise it returns [10Xfail[0m. If a list of
  vectors  [3Xcoll[0m  is  provided  then  the  function  returns a list of preimage
  representatives,  one  for  each  element in the list (the returned list can
  contain  [10Xfail[0m  entries  if  there  are  vectors  with  no  solution). For an
  [9XFpGModuleGF[0m  module  [3XM[0m, this returns a module whose image under [3Xphi[0m is [3XM[0m (or
  [10Xfail[0m). The module returned will not necessarily have minimal generators, and
  one  of  the [10XMinimalGeneratorsModule[0m functions ([14X5.5-9[0m) should be used on the
  result if a minimal set of generators is needed.
  
  The  standard  functions  use linear algebra, expanding the generator matrix
  into  a  full  matrix  and  using  [2XSolutionMat[0m  ([14XReference:  SolutionMat[0m) to
  calculate  a  preimage  of  [3Xelm[0m.  In  the  case  where  a list of vectors is
  provided,  the  matrix  decomposition is only performed once, which can save
  significant time.
  
  The  [10XGF[0m  versions  of  the functions can give a large memory saving when the
  generators of the homomorphism [3Xphi[0m are in echelon form, and operate by doing
  back-substitution using the generator form of the matrices.
  
  [1X6.6-3 KernelOfModuleHomomorphism[0m
  
  [2X> KernelOfModuleHomomorphism( [0X[3Xphi[0X[2X ) _______________________________[0Xoperation
  [2X> KernelOfModuleHomomorphismSplit( [0X[3Xphi[0X[2X ) __________________________[0Xoperation
  [2X> KernelOfModuleHomomorphismIndependentSplit( [0X[3Xphi[0X[2X ) _______________[0Xoperation
  [2X> KernelOfModuleHomomorphismGF( [0X[3Xphi[0X[2X ) _____________________________[0Xoperation
  [6XReturns:[0X  [9XFpGModuleGF[0m
  
  Returns the kernel of the module homomorphism [3Xphi[0m, as an [9XFpGModuleGF[0m module.
  There   are   three  independent  algorithms  for  calculating  the  kernel,
  represented by different versions of this function:
  
  --    The standard version calculates the kernel by the obvious vector-space
        method.  The  homomorphism's  generators  are  expanded  into  a  full
        vector-space basis and the kernel of that vector space homomorphism is
        found.  The  generators  of  the  returned module are in fact a vector
        space basis for the kernel module.
  
  --    The  [10XSplit[0m  version divides the homomorphism into two (using the first
        half  and  the  second  half  of the generating vectors), and uses the
        preimage  of  the  intersection  of  the  images  of the two halves to
        calculate  the kernel (see Section [14X6.2[0m). If the generating vectors for
        [3Xphi[0m  are  in  block echelon form (see Section [14X5.2[0m), then this approach
        provides a considerable memory saving over the standard approach.
  
  --    The  [10XIndependentSplit[0m  version splits the generating vectors into sets
        that generate vector spaces which have no intersection, and calculates
        the kernel as the sum of the kernels of those independent rows. If the
        generating  vectors  can  be  decomposed  in this manner (i.e. the the
        generator  matrix  is  in  a  diagonal form), this will provide a very
        large memory saving over the standard approach.
  
  --    The  [10XGF[0m  version  performs  column  reduction  and partitioning of the
        generator  matrix  to  enable  a  recursive  approach to computing the
        kernel (see Section [14X6.3[0m). The level of partitioning is governed by the
        option  [10XMaxFGExpansionSize[0m,  which  defaults  to  10^9, allowing about
        128Mb  of  memory  to  be  used  for  standard  linear  algebra before
        partitioning  starts.  See  [14X'Reference:  Options Stack'[0m for details of
        using options in [5XGAP[0m
  
  None  of these basis versions of the functions guarantee to return a minimal
  set  of generators, and one of the [10XMinimalGeneratorsModule[0m functions ([14X5.5-9[0m)
  should  be  used on the result if a minimal set of generators is needed. All
  of the functions leave the input homomorphism [3Xphi[0m unchanged.
  
  
  [1X6.6-4 Example: Kernel and Image of a [9XFpGModuleHomomorphismGF[1X[0X
  
  A   free   FG-resolution  of  a  module  is  an  exact  sequence  of  module
  homomorphisms.     In     this     example     we    use    the    functions
  [2XImageOfModuleHomomorphism[0m  ([14X6.6-1[0m) and [2XKernelOfModuleHomomorphism[0m ([14X6.6-3[0m) to
  check  that  one of the sequences in a resolution is exact, i.e. that in the
  sequence
  
  
       M_3 -> M_2 -> M_1
  
  
  the  image  of  the  first homomorphism d_3: M_3 -> M_2 is the kernel of the
  second homomorphism d_2: M_2 -> M_1
  
  We  also  demonstrate  that  we  can  find  the image and preimage of module
  elements  under  our  module  homomorphisms. We take an element [10Xe[0m of M_2, in
  this  case  by taking the first generating element of the kernel of d_2, and
  map it up to M_3 and back.
  
  Finally,  we compute the kernel using the other available methods, and check
  that the results are the same.
  
  [4X---------------------------  Example  ----------------------------[0X
    [4Xgap> R := ResolutionPrimePowerGroupRadical(SmallGroup(8, 3), 3);;[0X
    [4Xgap> d2 := BoundaryFpGModuleHomomorphismGF(R, 2);;[0X
    [4Xgap> d3 := BoundaryFpGModuleHomomorphismGF(R, 3);;[0X
    [4Xgap> #[0X
    [4Xgap> I := ImageOfModuleHomomorphism(d3);[0X
    [4XModule over the group ring of <pc group of size 8 with[0X
    [4X3 generators> in characteristic 2 with 4 generators in FG^3.[0X
    [4X[0X
    [4Xgap> K := KernelOfModuleHomomorphism(d2);[0X
    [4XModule over the group ring of <pc group of size 8 with[0X
    [4X3 generators> in characteristic 2 with 15 generators in FG^3.[0X
    [4X[0X
    [4Xgap> I = K;[0X
    [4Xtrue[0X
    [4Xgap> #[0X
    [4Xgap> e := ModuleGenerators(K)[1];;[0X
    [4Xgap> PreImageRepresentativeOfModuleHomomorphism(d3, e);[0X
    [4X<a GF2 vector of length 32>[0X
    [4Xgap> f := PreImageRepresentativeOfModuleHomomorphism(d3, e);[0X
    [4X<a GF2 vector of length 32>[0X
    [4Xgap> ImageOfModuleHomomorphism(d3, f);[0X
    [4X<a GF2 vector of length 24>[0X
    [4Xgap> last = e;[0X
    [4Xtrue[0X
    [4Xgap> #[0X
    [4Xgap> L := KernelOfModuleHomomorphismSplit(d2);[0X
    [4XModule over the group ring of <pc group of size 8 with[0X
    [4X3 generators> in characteristic 2 with 5 generators in FG^3.[0X
    [4X[0X
    [4Xgap> K = L;[0X
    [4Xtrue[0X
    [4Xgap> M := KernelOfModuleHomomorphismGF(d2);[0X
    [4XModule over the group ring of <pc group of size 8 with[0X
    [4X3 generators> in characteristic 2 with 4 generators in FG^[0X
    [4X3. Generators are minimal.[0X
    [4X[0X
    [4Xgap> K = M;[0X
    [4Xtrue[0X
  [4X------------------------------------------------------------------[0X
  
