CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutSign UpSign In

Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.

| Download

GAP 4.8.9 installation with standard packages -- copy to your CoCalc project to get it

Views: 418346
#############################################################################
##
##  HomalgGenerators.gi         Modules package              Mohamed Barakat
##
##  Copyright 2007-2008 Lehrstuhl B für Mathematik, RWTH Aachen
##
##  Implementation stuff for a set of generators.
##
#############################################################################

##  <#GAPDoc Label="Generators:intro">
##  To present a left/right module it suffices to take a matrix <A>rel</A> and interpret its rows/columns
##  as relations among <M>n</M> <E>abstract</E> generators, where <M>n</M> is the number of columns/rows
##  of <A>rel</A>. Only that these abstract generators are useless when it comes to specific modules like
##  modules of homomorphisms, where one expects the generators to be maps between modules. For this
##  reason a presentation of a module in &homalg; is not merely a matrix of relations, but together with
##  a set of generators.
##  <P/>
##  In &homalg; a set of generators of a left/right module is given by a matrix <A>gen</A> with rows/columns
##  being interpreted as the generators.
##  <P/>
##  The data structure of a module in &homalg; is designed to contain not only one but several sets of generators
##  (together with their sets of relations (&see; Chapter <Ref Chap="Relations"/>)).
##  The different sets of generators are linked with so-called transition matrices (&see; Chapter <Ref Chap="Modules"/>).
##  <#/GAPDoc>

####################################
#
# representations:
#
####################################

##  <#GAPDoc Label="IsGeneratorsOfModuleRep">
##  <ManSection>
##    <Filt Type="Representation" Arg="rel" Name="IsGeneratorsOfModuleRep"/>
##    <Returns><C>true</C> or <C>false</C></Returns>
##    <Description>
##      The &GAP; representation of a finite set of generators of a &homalg; module. <P/>
##      (It is a representation of the &GAP; category <Ref Filt="IsHomalgGenerators"/>)
##    <Listing Type="Code"><![CDATA[
DeclareRepresentation( "IsGeneratorsOfModuleRep",
        IsHomalgGenerators,
        [ "generators" ] );
##  ]]></Listing>
##    </Description>
##  </ManSection>
##  <#/GAPDoc>

##  <#GAPDoc Label="IsGeneratorsOfFinitelyGeneratedModuleRep">
##  <ManSection>
##    <Filt Type="Representation" Arg="rel" Name="IsGeneratorsOfFinitelyGeneratedModuleRep"/>
##    <Returns><C>true</C> or <C>false</C></Returns>
##    <Description>
##      The &GAP; representation of a finite set of generators of a finitely generated &homalg; module. <P/>
##      (It is a representation of the &GAP; representation <Ref Filt="IsGeneratorsOfModuleRep"/>)
##    <Listing Type="Code"><![CDATA[
DeclareRepresentation( "IsGeneratorsOfFinitelyGeneratedModuleRep",
        IsGeneratorsOfModuleRep,
        [ "generators", "relations_of_hullmodule" ] );
##  ]]></Listing>
##    </Description>
##  </ManSection>
##  <#/GAPDoc>

####################################
#
# families and types:
#
####################################

# a new family:
BindGlobal( "TheFamilyOfHomalgGenerators",
        NewFamily( "TheFamilyOfHomalgGenerators" ) );

# four new types:
BindGlobal( "TheTypeHomalgGeneratorsOfLeftModule",
        NewType(  TheFamilyOfHomalgGenerators,
                IsGeneratorsOfModuleRep and IsHomalgGeneratorsOfLeftModule ) );

BindGlobal( "TheTypeHomalgGeneratorsOfRightModule",
        NewType(  TheFamilyOfHomalgGenerators,
                IsGeneratorsOfModuleRep and IsHomalgGeneratorsOfRightModule ) );

BindGlobal( "TheTypeHomalgGeneratorsOfFinitelyGeneratedLeftModule",
        NewType(  TheFamilyOfHomalgGenerators,
                IsGeneratorsOfFinitelyGeneratedModuleRep and IsHomalgGeneratorsOfLeftModule ) );

BindGlobal( "TheTypeHomalgGeneratorsOfFinitelyGeneratedRightModule",
        NewType(  TheFamilyOfHomalgGenerators,
                IsGeneratorsOfFinitelyGeneratedModuleRep and IsHomalgGeneratorsOfRightModule ) );

####################################
#
# methods for operations:
#
####################################

##
InstallMethod( MatrixOfGenerators,
        "for sets of generators of homalg modules",
        [ IsHomalgGenerators ],
        
  function( gen )
    
    return gen!.generators;
    
end );

##
InstallMethod( HomalgRing,
        "for sets of generators of homalg modules",
        [ IsHomalgGenerators ],
        
  function( gen )
    
    return HomalgRing( MatrixOfGenerators( gen ) );
    
end );

##
InstallMethod( GetGenerators,
        "for a set of homalg generators and a positive integer",
        [ IsGeneratorsOfFinitelyGeneratedModuleRep, IsPosInt ],
        
  function( gen, g )
    local AdjustedGenerators, mat, G, proc;
    
    if not IsBound( gen!.AdjustedGenerators ) then
        gen!.AdjustedGenerators := [ ];
    fi;
    
    AdjustedGenerators := gen!.AdjustedGenerators;
    
    if IsBound( AdjustedGenerators[g] ) then
        return AdjustedGenerators[g];
    fi;
    
    mat := MatrixOfGenerators( gen );
    
    if IsHomalgGeneratorsOfLeftModule( gen ) then
        G := CertainRows( mat, [ g ] );
    else
        G := CertainColumns( mat, [ g ] );
    fi;
    
    if HasProcedureToReadjustGenerators( gen ) then
        proc := ProcedureToReadjustGenerators( gen );
        G := CallFuncList( proc[1], Concatenation( [ G ], proc{[ 2 .. Length( proc ) ]} ) );
    fi;
    
    AdjustedGenerators[g] := G;
    
    return G;
    
end );

##
InstallMethod( GetGenerators,
        "for a set of homalg generators and a list of positive integer",
        [ IsGeneratorsOfFinitelyGeneratedModuleRep, IsList ],
        
  function( gen, g )
    
    return List( g, i -> GetGenerators( gen, i ) );
    
end );

##
InstallMethod( GetGenerators,
        "for homalg generators",
        [ IsGeneratorsOfFinitelyGeneratedModuleRep ],
        
  function( gen )
    
    return GetGenerators( gen, [ 1 .. NrGenerators( gen ) ] );
    
end );

##
InstallMethod( RelationsOfHullModule,
        "for sets of generators of homalg modules",
        [ IsHomalgGenerators ],
        
  function( gen )
    
    return gen!.relations_of_hullmodule;
    
end );

##
InstallMethod( HasNrRelations,
        "for sets of generators of homalg modules",
        [ IsHomalgGenerators ],
        
  function( gen )
    
    return HasNrRelations( RelationsOfHullModule( gen ) );
    
end );

##
InstallMethod( NrRelations,
        "for sets of generators of homalg modules",
        [ IsHomalgGenerators ],
        
  function( gen )
    
    return NrRelations( RelationsOfHullModule( gen ) );
    
end );

##
InstallMethod( MatrixOfRelations,
        "for sets of generators of homalg modules",
        [ IsHomalgGenerators ],
        
  function( gen )
    
    return EvaluatedMatrixOfRelations( RelationsOfHullModule( gen ) );
    
end );

##
InstallMethod( HasNrGenerators,
        "for sets of generators of homalg modules",
        [ IsHomalgGeneratorsOfRightModule ],
        
  function( gen )
    
    return HasNrColumns( MatrixOfGenerators( gen ) );
    
end );

##
InstallMethod( HasNrGenerators,
        "for sets of generators of homalg modules",
        [ IsHomalgGeneratorsOfLeftModule ],
        
  function( gen )
    
    return HasNrRows( MatrixOfGenerators( gen ) );
    
end );

##
InstallMethod( NrGenerators,			### defines: NrGenerators (NumberOfGenerators)
        "for sets of generators of homalg modules",
        [ IsHomalgGeneratorsOfRightModule ],
        
  function( gen )
    
    return NrColumns( MatrixOfGenerators( gen ) );
    
end );

##
InstallMethod( NrGenerators,			### defines: NrGenerators (NumberOfGenerators)
        "for sets of generators of homalg modules",
        [ IsHomalgGeneratorsOfLeftModule ],
        
  function( gen )
    
    return NrRows( MatrixOfGenerators( gen ) );
    
end );

##
InstallMethod( CertainGenerators,
        "for sets of generators of homalg modules",
        [ IsHomalgGeneratorsOfRightModule, IsList ],
        
  function( gen, list )
    
    return CertainColumns( MatrixOfGenerators( gen ), list );
    
end );

##
InstallMethod( CertainGenerators,
        "for sets of generators of homalg modules",
        [ IsHomalgGeneratorsOfLeftModule, IsList ],
        
  function( gen, list )
    
    return CertainRows( MatrixOfGenerators( gen ), list );
    
end );

##
InstallMethod( CertainGenerator,
        "for sets of generators of homalg modules",
        [ IsHomalgGenerators, IsPosInt ],
        
  function( gen, pos )
    
    return CertainGenerators( gen, [ pos ] );
    
end );

##
InstallMethod( NewHomalgGenerators,
        "for sets of generators of homalg modules",
        [ IsHomalgMatrix, IsHomalgGenerators ],
        
  function( mat, gen )
    local relations_of_hullmodule, gen_new;
    
    relations_of_hullmodule := RelationsOfHullModule( gen );
    
    if IsHomalgGeneratorsOfLeftModule( gen ) then
        gen_new := HomalgGeneratorsForLeftModule( mat, relations_of_hullmodule );
    else
        gen_new := HomalgGeneratorsForRightModule( mat, relations_of_hullmodule );
    fi;
    
    if HasProcedureToReadjustGenerators( gen ) then
        SetProcedureToReadjustGenerators( gen_new, ProcedureToReadjustGenerators( gen ) );
    fi;
    
    if HasProcedureToNormalizeGenerators( gen ) then
        SetProcedureToNormalizeGenerators( gen_new, ProcedureToNormalizeGenerators( gen ) );
    fi;
    
    if IsBound( gen!.ring ) then
        gen_new!.ring := gen!.ring;
    fi;
    
    if IsBound( gen!.ConvertTransitionMatrix ) then
        gen_new!.ConvertTransitionMatrix := gen!.ConvertTransitionMatrix;
    fi;
    
    return gen_new;
    
end );

##
InstallMethod( UnionOfRelations,
        "for sets of generators of homalg modules",
        [ IsHomalgGenerators, IsHomalgRelations ],
        
  function( gen, rel )
    local gen_new, hull;
    
    gen_new := MatrixOfGenerators( gen );
    
    hull := RelationsOfHullModule( gen );
    
    hull := UnionOfRelations( hull, rel );
    
    if IsHomalgGeneratorsOfLeftModule( gen ) and IsHomalgRelationsOfLeftModule( rel ) then
        gen_new := HomalgGeneratorsForLeftModule( gen_new, hull );
    elif IsHomalgGeneratorsOfRightModule( gen ) and IsHomalgRelationsOfRightModule( rel ) then
        gen_new := HomalgGeneratorsForRightModule( gen_new, hull );
    else
        Error( "the set of generators and the set of relations must either be both left or both right\n" );
    fi;
    
    if HasProcedureToReadjustGenerators( gen ) then
        SetProcedureToReadjustGenerators( gen_new, ProcedureToReadjustGenerators( gen ) );
    fi;
    
    if HasProcedureToNormalizeGenerators( gen ) then
        SetProcedureToNormalizeGenerators( gen_new, ProcedureToNormalizeGenerators( gen ) );
    fi;
    
    if IsBound( gen!.ring ) then
        gen_new!.ring := gen!.ring;
    fi;
    
    if IsBound( gen!.ConvertTransitionMatrix ) then
        gen_new!.ConvertTransitionMatrix := gen!.ConvertTransitionMatrix;
    fi;
    
    return gen_new;
    
end );

##
InstallMethod( DecideZero,
        "for sets of generators of homalg modules",
        [ IsHomalgGenerators ],
        
  function( gen )
    local gen_old, gen_new;
    
    if not IsBound( gen!.DecideZero ) then	## IsReduced is not set, otherwise the method below would apply
        gen_old := MatrixOfGenerators( gen );
        gen_new := DecideZero( gen_old, RelationsOfHullModule( gen ) );
        if gen_new = gen_old then
            gen!.DecideZero := gen_old;
            SetIsReduced( gen, true );
            return gen;
        fi;
        gen!.DecideZero := gen_new;
        SetIsReduced( gen, false );
    fi;
    
    gen_new := NewHomalgGenerators( gen!.DecideZero, gen );
    
    SetIsReduced( gen_new, true );
    
    return gen_new;
    
end );

##
InstallMethod( DecideZero,
        "for sets of generators of homalg modules",
        [ IsHomalgGenerators and IsReduced ],
        
  function( gen )
    
    return gen;
    
end );

##
InstallMethod( DecideZero,
        "for sets of generators of homalg modules",
        [ IsHomalgGenerators, IsHomalgRelations ],
        
  function( gen, rel )
    
    if not IsBound( gen!.DecideZero ) then
        gen!.DecideZero := DecideZero( MatrixOfGenerators( gen ), rel );
        SetIsReduced( gen, false );
    fi;
    
    return gen!.DecideZero;
    
end );

##
InstallMethod( GetRidOfZeroGenerators,	### defines: GetRidOfZeroGenerators (BetterBasis)
        "for sets of generators of homalg modules",
        [ IsHomalgGenerators ],
        
  function( _gen )
    local R, RP, gen, nonzero;
    
    R := HomalgRing( _gen );
    
    RP := homalgTable( R );
    
    #=====# begin of the core procedure #=====#
    
    gen := DecideZero( _gen );
    
    if IsHomalgGeneratorsOfLeftModule( gen ) then
        
        if IsBound(RP!.SimplifyBasisOfRows) then
            gen := RP!.SimplifyBasisOfRows( gen );
        else
            gen := MatrixOfGenerators( gen );
        fi;
        
        nonzero := NonZeroRows( gen );
        
        gen := CertainRows( gen, nonzero );
        
    else
        
        if IsBound(RP!.SimplifyBasisOfColumns) then
            gen := RP!.SimplifyBasisOfColumns( gen );
        else
            gen := MatrixOfGenerators( gen );
        fi;
        
        nonzero := NonZeroColumns( gen );
        
        gen := CertainColumns( gen, nonzero );
        
    fi;
    
    gen := NewHomalgGenerators( gen, _gen );
    
    return gen;
    
end );

##
InstallMethod( SyzygiesGenerators,
        "for sets of relations of homalg modules",
        [ IsHomalgGeneratorsOfRightModule, IsHomalgRelationsOfRightModule ],
        
  function( gen, rel )
    
    return HomalgRelationsForRightModule( SyzygiesGeneratorsOfColumns, [ MatrixOfGenerators( gen ), MatrixOfRelations( rel ) ] );
    
end );

##
InstallMethod( SyzygiesGenerators,
        "for sets of relations of homalg modules",
        [ IsHomalgGeneratorsOfLeftModule, IsHomalgRelationsOfLeftModule ],
        
  function( gen, rel )
    
    return HomalgRelationsForLeftModule( SyzygiesGeneratorsOfRows, [ MatrixOfGenerators( gen ), MatrixOfRelations( rel ) ] );
    
end );

##
InstallMethod( ReducedSyzygiesGenerators,
        "for sets of relations of homalg modules",
        [ IsHomalgGeneratorsOfRightModule, IsHomalgRelationsOfRightModule ],
        
  function( gen, rel )
    
    return ReducedSyzygiesGenerators( MatrixOfGenerators( gen ), rel );
    
end );

##
InstallMethod( ReducedSyzygiesGenerators,
        "for sets of relations of homalg modules",
        [ IsHomalgGeneratorsOfLeftModule, IsHomalgRelationsOfLeftModule ],
        
  function( gen, rel )
    
    return ReducedSyzygiesGenerators( MatrixOfGenerators( gen ), rel );
    
end );

##
InstallMethod( \*,
        "for sets of generators of homalg modules",
        [ IsHomalgMatrix, IsHomalgGenerators ],
        
  function( TI, gen )
    local generators, R;
    
    generators := MatrixOfGenerators( gen );
    
    R := HomalgRing( generators );
    
    if not IsIdenticalObj( R, HomalgRing( TI ) ) then
        if IsBound( gen!.ConvertTransitionMatrix ) then
            TI := gen!.ConvertTransitionMatrix( TI );
        elif IsBound( gen!.ring ) and IsIdenticalObj( gen!.ring, HomalgRing( TI ) ) then
            TI := TI * R;
        fi;
    fi;
    
    if IsHomalgMatrix( TI ) then
        if IsHomalgGeneratorsOfLeftModule( gen ) then
            generators := NewHomalgGenerators( TI * generators, gen ); ## the hull relations remain unchanged :)
        else
            generators := NewHomalgGenerators( generators * TI, gen ); ## the hull relations remain unchanged :)
        fi;
    elif IsFunction( TI ) then
        generators := NewHomalgGenerators( TI( generators ), gen ); ## the hull relations remain unchanged :)
    else
        Error( "unknown type of transition operation\n" );
    fi;
    
    return generators;
    
end );

##
InstallMethod( \*,
        "for sets of generators of homalg modules",
        [ IsHomalgGenerators, IsHomalgGenerators ],
        
  function( gen1, gen2 )
    local gen;
    
    if not ( IsHomalgGeneratorsOfLeftModule( gen1 ) and IsHomalgGeneratorsOfLeftModule( gen2 ) )
       and not ( IsHomalgGeneratorsOfRightModule( gen1 ) and IsHomalgGeneratorsOfRightModule( gen2 ) ) then
        Error( "the two sets of generators must either be both left or both right\n" );
    fi;
    
    gen := MatrixOfGenerators( gen1 ) * gen2;
    
    return gen;
    
end );

##
InstallMethod( \*,
        "for sets of generators of homalg modules",
        [ IsHomalgRelations, IsHomalgGenerators ],
        
  function( rel, gen )
    local rel_mat, gen_mat, R;
    
    rel_mat := MatrixOfRelations( rel );
    
    gen_mat := MatrixOfGenerators( gen );
    
    R := HomalgRing( gen_mat );
    
    if not IsIdenticalObj( R, HomalgRing( rel_mat ) ) then
        if IsBound( gen!.ring ) and IsIdenticalObj( gen!.ring, HomalgRing( rel_mat ) ) then
            rel_mat := rel_mat * R;
        fi;
    fi;
    
    if IsBound( gen!.ConvertTransitionMatrix ) then
        rel_mat := gen!.ConvertTransitionMatrix( rel_mat );
    fi;
    
    if IsHomalgMatrix( rel_mat ) then
        if IsHomalgRelationsOfLeftModule( rel ) then
            if IsHomalgGeneratorsOfRightModule( gen ) then
                Error( "the set of generators and the set of relations must either be both left or both right\n" );
            fi;
            return HomalgRelationsForLeftModule( rel_mat * gen_mat );
        else
            if IsHomalgGeneratorsOfLeftModule( gen ) then
                Error( "the set of generators and the set of relations must either be both left or both right\n" );
            fi;
            return HomalgRelationsForRightModule( gen_mat * rel_mat );
        fi;
    elif IsFunction( rel_mat ) then
        if IsHomalgRelationsOfLeftModule( rel ) then
            return HomalgRelationsForLeftModule( rel_mat( gen_mat ) );
        else
            return HomalgRelationsForRightModule( rel_mat( gen_mat ) );
        fi;
    else
        Error( "unknown type of transition operation\n" );
    fi;
    
end );

####################################
#
# constructor functions and methods:
#
####################################

##
InstallGlobalFunction( HomalgGeneratorsForLeftModule,
  function( arg )
    local nargs, ar, R, generators, relations_of_hullmodule, gen;
    
    nargs := Length( arg );
    
    for ar in arg{ [ 2 .. nargs ] } do
        if IsHomalgRing( ar ) then
            R := ar;
            break;
        fi;
    od;
    
    if IsHomalgMatrix( arg[1] ) then
        ResetFilterObj( arg[1], IsMutable );
        generators := arg[1];
    elif IsBound( R ) then
        generators := HomalgMatrix( arg[1], R );
    else
        Error( "if the first argument isn't of type IsHomalgMatrix, then the last argument must be of type IsHomalgRing\n" );
    fi;
    
    if not IsBound( R ) then
        R := HomalgRing( generators );
    fi;
    
    for ar in arg{ [ 2 .. nargs ] } do
        if IsHomalgRelations( ar ) then
            if not IsHomalgRelationsOfLeftModule( ar ) then
                Error( "the set of relations of the hull module of the generators is not a set of relations of a left module\n" );
            fi;
            relations_of_hullmodule := ar;
            break;
        elif IsHomalgMatrix( ar ) then
            relations_of_hullmodule := HomalgRelationsForLeftModule( ar );
            break;
        elif IsList( ar ) and not IsStringRep( ar ) and IsBound( R ) then
            relations_of_hullmodule := HomalgRelationsForLeftModule( ar, R );
            break;
        elif nargs > 2 then
            if IsBound( R ) then
                relations_of_hullmodule := HomalgRelationsForLeftModule( ar, R );
                break;
            else
                Error( "if more than two arguments are provided and the second argument is neither of type IsHomalgRelations nor of type IsHomalgMatrix, then the last argument must be of type IsHomalgRing\n" );
            fi;
        fi;
    od;
    
    if not IsBound( relations_of_hullmodule ) then
        relations_of_hullmodule :=
          HomalgRelationsForLeftModule( HomalgZeroMatrix( 0, NrColumns( generators ), R ) );
    fi;
    
    gen := rec( generators := generators,
                relations_of_hullmodule := relations_of_hullmodule );
    
    ## Objectify:
    Objectify( TheTypeHomalgGeneratorsOfFinitelyGeneratedLeftModule, gen );
    
    return gen;
    
end );

##
InstallGlobalFunction( HomalgGeneratorsForRightModule,
  function( arg )
    local nargs, ar, R, generators, relations_of_hullmodule, gen;
    
    nargs := Length( arg );
    
    for ar in arg{ [ 2 .. nargs ] } do
        if IsHomalgRing( ar ) then
            R := ar;
            break;
        fi;
    od;
    
    if IsHomalgMatrix( arg[1] ) then
        ResetFilterObj( arg[1], IsMutable );
        generators := arg[1];
    elif IsBound( R ) then
        generators := HomalgMatrix( arg[1], R );
    else
        Error( "if the first argument isn't of type IsHomalgMatrix, then the last argument must be of type IsHomalgRing\n" );
    fi;
    
    if not IsBound( R ) then
        R := HomalgRing( generators );
    fi;
    
    for ar in arg{ [ 2 .. nargs ] } do
        if IsHomalgRelations( ar ) then
            if not IsHomalgRelationsOfRightModule( ar ) then
                Error( "the set of relations of the hull module of the generators is not a set of relations of a right module\n" );
            fi;
            relations_of_hullmodule := ar;
            break;
        elif IsHomalgMatrix( ar ) then
            relations_of_hullmodule := HomalgRelationsForRightModule( ar );
            break;
        elif IsList( ar ) and not IsStringRep( ar ) and IsBound( R ) then
            relations_of_hullmodule := HomalgRelationsForRightModule( ar, R );
            break;
        elif nargs > 2 then
            if IsBound( R ) then
                relations_of_hullmodule := HomalgRelationsForRightModule( ar, R );
                break;
            else
                Error( "if more than two arguments are provided and the second argument is neither of type IsHomalgRelations nor of type IsHomalgMatrix, then the last argument must be of type IsHomalgRing\n" );
            fi;
        fi;
    od;
    
    if not IsBound( relations_of_hullmodule ) then
        relations_of_hullmodule :=
          HomalgRelationsForRightModule( HomalgZeroMatrix( NrRows( generators ), 0, R ) );
    fi;
    
    gen := rec( generators := generators,
                relations_of_hullmodule := relations_of_hullmodule );
    
    ## Objectify:
    Objectify( TheTypeHomalgGeneratorsOfFinitelyGeneratedRightModule, gen );
    
    return gen;
    
end );

##
InstallMethod( RingMap,
        "for homalg rings",
        [ IsHomalgGenerators, IsHomalgRing, IsHomalgRing ],
        
  function( images, S, T )
    local R, psi;
    
    if IsIdenticalObj( HomalgRing( images ), T ) then
        psi := RingMap( MatrixOfGenerators( images ), S, T );
    else
        psi := RingMap( T * MatrixOfGenerators( images ), S, T );
    fi;
    
    if IsHomalgGeneratorsOfLeftModule( images ) then
        psi!.left := true;
    else
        psi!.left := false;
    fi;
    
    return psi;
    
end );

####################################
#
# View, Print, and Display methods:
#
####################################

InstallMethod( ViewObj,
        "for homalg generators",
        [ IsHomalgGenerators ], 100,
        
  function( o )
    local g;
    
    g := NrGenerators( o );
    
    if g = 0 then
        Print( "<An empty set of generators " );
    elif g = 1 then
        Print( "<A set consisting of a single generator " );
    else
        Print( "<A set of ", g, " generators " );
    fi;
    
    Print( "of a homalg " );
    
    if IsHomalgGeneratorsOfLeftModule( o ) then
        Print( "left " );
    else
        Print( "right " );
    fi;
    
    Print( "module>" );
    
end );

InstallMethod( Display,
        "for homalg generators",
        [ IsHomalgGenerators ], 100000,
        
  function( o )
    local g;
    
    g := NrGenerators( o );
    
    if g = 0 then
        Print( "an empty set of generators\n" );
    else
        Display( MatrixOfGenerators( o ) );
        
        Print( "\na set " );
        
        if g = 1 then
            Print( "consisting of a single generator given by (the" );
        else
            Print( "of ", g, " generators given by the" );
        fi;
        
        if IsHomalgGeneratorsOfLeftModule( o ) then
            Print( " row" );
        else
            Print( " column" );
        fi;
        
        if g = 1 then
            Print( " of)" );
        else
            Print( "s of" );
        fi;
        
        Print( " the above matrix\n" );
    fi;
    
end );

InstallMethod( Display,
        "for homalg generators",
        [ IsHomalgGenerators and HasProcedureToReadjustGenerators ], 100000,
        
  function( o )
    local g, mat, proc, l, i;
    
    g := NrGenerators( o );
    
    if g = 0 then
        Print( "an empty set of generators\n" );
    else
        mat := MatrixOfGenerators( o );
        
        proc := ProcedureToReadjustGenerators( o );
        l := Length( proc );
    
        if IsHomalgGeneratorsOfLeftModule( o ) then
            for i in [ 1 .. NrGenerators( o ) ] do
                Display( CallFuncList( proc[1], Concatenation( [ CertainRows( mat, [ i ] ) ], proc{[ 2 .. l ]} ) ) ); Print( "\n" );
            od;
        else
            for i in [ 1 .. NrGenerators( o ) ] do
                Display( CallFuncList( proc[1], Concatenation( [ CertainColumns( mat, [ i ] ) ], proc{[ 2 .. l ]} ) ) ); Print( "\n" );
            od;
        fi;
        
        Print( "a set " );
        
        if g = 1 then
            Print( "consisting of a single generator" );
        else
            Print( "of ", g, " generators" );
        fi;
        
        Print( " given by the the above " );
        
        if g = 1 then
            Print( "matrix\n" );
        else
            Print( "matrices\n" );
        fi;
    fi;
    
end );