GAP 4.8.9 installation with standard packages -- copy to your CoCalc project to get it
############################################################################ ## ## HomalgSubmodule.gi Modules package ## ## Copyright 2007-2010 Mohamed Barakat, University of Kaiserslautern ## ## Implementations for homalg submodules. ## ############################################################################# #################################### # # families and types: # #################################### # two new types: BindGlobal( "TheTypeHomalgLeftFinitelyGeneratedSubmodule", NewType( TheFamilyOfHomalgModules, IsFinitelyPresentedSubmoduleRep and IsHomalgLeftObjectOrMorphismOfLeftObjects ) ); BindGlobal( "TheTypeHomalgRightFinitelyGeneratedSubmodule", NewType( TheFamilyOfHomalgModules, IsFinitelyPresentedSubmoduleRep and IsHomalgRightObjectOrMorphismOfRightObjects ) ); #################################### # # methods for operations: # #################################### ## InstallMethod( SetsOfGenerators, "for homalg submodules", [ IsFinitelyPresentedSubmoduleRep ], function( M ) return SetsOfGenerators( UnderlyingObject( M ) ); end ); ## InstallMethod( NrGenerators, "for homalg submodules", [ IsFinitelyPresentedSubmoduleRep ], function( M ) local phi, g; if HasEmbeddingInSuperObject( M ) then TryNextMethod( ); fi; phi := MorphismHavingSubobjectAsItsImage( M ); g := NrGenerators( Source( phi ) ); if g = 0 then SetIsZero( M, true ); elif IsFinitelyPresentedModuleOrSubmoduleRep( M ) and HasRankOfObject( M ) and RankOfObject( M ) = g then SetIsFree( M, true ); fi; return g; end ); ## InstallMethod( HasNrGenerators, "for homalg submodules", [ IsFinitelyPresentedSubmoduleRep ], function( M ) if HasEmbeddingInSuperObject( M ) then TryNextMethod( ); fi; return true; end ); ## InstallMethod( SetsOfRelations, "for homalg submodules", [ IsFinitelyPresentedSubmoduleRep ], function( M ) return SetsOfRelations( UnderlyingObject( M ) ); end ); ## InstallMethod( HasNrRelations, "for homalg submodules", [ IsFinitelyPresentedSubmoduleRep ], function( M ) if HasEmbeddingInSuperObject( M ) then TryNextMethod( ); fi; return fail; end ); ## InstallMethod( PositionOfTheDefaultPresentation, "for homalg submodules", [ IsFinitelyPresentedSubmoduleRep ], function( M ) return PositionOfTheDefaultPresentation( UnderlyingObject( M ) ); end ); ## InstallMethod( MatrixOfSubobjectGenerators, "for homalg submodules", [ IsStaticFinitelyPresentedSubobjectRep ], function( M ) return MatrixOfMap( MorphismHavingSubobjectAsItsImage( M ) ); end ); ## InstallMethod( DecideZero, "for homalg modules", [ IsHomalgMatrix, IsFinitelyPresentedSubmoduleRep and ConstructedAsAnIdeal ], function( mat, N ) return DecideZero( mat, MatrixOfGenerators( N ) ); end ); ## InstallMethod( DecideZero, "for homalg modules", [ IsRingElement, IsFinitelyPresentedSubmoduleRep and ConstructedAsAnIdeal ], function( r, N ) return DecideZero( r, MatrixOfGenerators( N ) ); end ); ## InstallMethod( OnBasisOfPresentation, "for homalg modules", [ IsFinitelyPresentedSubmoduleRep ], function( N ) local M, phi; M := SuperObject( N ); if not ( HasNrRelations( M ) and NrRelations( M ) = 0 ) then OnLessGenerators( UnderlyingObject( N ) ); return N; fi; ## the super object M is free and currently presented on free generators phi := MorphismHavingSubobjectAsItsImage( N ); phi := MatrixOfMap( phi ); if IsHomalgLeftObjectOrMorphismOfLeftObjects( N ) then phi := BasisOfRowModule( phi ); else phi := BasisOfColumnModule( phi ); fi; phi := HomalgMap( phi, "free", M ); if HasEmbeddingInSuperObject( N ) then phi := ImageObjectEmb( phi ); phi := phi / EmbeddingInSuperObject( N ); ## lift Assert( 4, IsEpimorphism( phi ) ); SetIsEpimorphism( phi, true ); ## this will have a side effect on Source( EmbeddingInSuperObject( N ) ) AsEpimorphicImage( phi ); else ## psssssss, noone saw that ;-) Add( N!.map_having_subobject_as_its_image_old, N!.map_having_subobject_as_its_image ); N!.map_having_subobject_as_its_image := phi; fi; return N; end ); ## InstallMethod( OnLessGenerators, "for homalg modules", [ IsFinitelyPresentedSubmoduleRep ], function( N ) local M, phi; M := SuperObject( N ); if not ( HasNrRelations( M ) and NrRelations( M ) = 0 ) then OnLessGenerators( UnderlyingObject( N ) ); return N; fi; ## the super object M is free and currently presented on free generators phi := MorphismHavingSubobjectAsItsImage( N ); phi := MatrixOfMap( phi ); if IsHomalgLeftObjectOrMorphismOfLeftObjects( N ) then phi := ReducedBasisOfRowModule( phi ); else phi := ReducedBasisOfColumnModule( phi ); fi; phi := HomalgMap( phi, "free", M ); if HasEmbeddingInSuperObject( N ) then phi := ImageObjectEmb( phi ); phi := phi / EmbeddingInSuperObject( N ); ## lift Assert( 4, IsEpimorphism( phi ) ); SetIsEpimorphism( phi, true ); ## this will have a side effect on Source( EmbeddingInSuperObject( N ) ) AsEpimorphicImage( phi ); else ## psssssss, noone saw that ;-) Add( N!.map_having_subobject_as_its_image_old, N!.map_having_subobject_as_its_image ); N!.map_having_subobject_as_its_image := phi; fi; return N; end ); ## InstallOtherMethod( \*, "for homalg submodules", [ IsFinitelyPresentedSubmoduleRep, IsFinitelyPresentedSubmoduleRep ], function( I, J ) local super, genI, genJ; super := SuperObject( I ); if not IsIdenticalObj( super, SuperObject( J ) ) then Error( "the super objects must coincide\n" ); elif not ( ConstructedAsAnIdeal( I ) and ConstructedAsAnIdeal( J ) ) then Error( "can only multiply ideals in a common ring\n" ); fi; genI := MatrixOfSubobjectGenerators( I ); genJ := MatrixOfSubobjectGenerators( J ); return Subobject( KroneckerMat( genI, genJ ), super ); end ); ## InstallOtherMethod( POW, "for homalg submodules", [ IsStaticFinitelyPresentedSubobjectRep, IsInt ], function( I, pow ) if pow < 0 then Error( "negative powers are not defined\n" ); elif pow = 0 then return FullSubobject( SuperObject( I ) ); elif pow = 1 then return I; else return Iterated( ListWithIdenticalEntries( pow, I ), \* ); fi; end ); ## InstallMethod( IsSubset, "for homalg submodules", [ IsHomalgModule, IsFinitelyPresentedSubmoduleRep ], function( K, J ) ## GAP-standard: is J a subset of K local M, mapJ, mapK, rel, red; M := SuperObject( J ); if not IsFinitelyPresentedSubmoduleRep( K ) then return IsIdenticalObj( M, K ); fi; if not IsIdenticalObj( M, SuperObject( K ) ) then Error( "the super objects must coincide\n" ); fi; mapJ := MatrixOfSubobjectGenerators( J ); mapK := MatrixOfSubobjectGenerators( K ); rel := MatrixOfRelations( M ); if IsHomalgLeftObjectOrMorphismOfLeftObjects( J ) then mapK := UnionOfRows( mapK, rel ); mapK := BasisOfRowModule( mapK ); red := DecideZeroRows( mapJ, mapK ); else mapK := UnionOfColumns( mapK, rel ); mapK := BasisOfColumnModule( mapK ); red := DecideZeroColumns( mapJ, mapK ); fi; return IsZero( red ); end ); ## InstallMethod( \+, "for homalg subobjects of static objects", [ IsStaticFinitelyPresentedSubobjectRep, IsStaticFinitelyPresentedSubobjectRep ], function( K, J ) local M, mapK, mapJ, sum; M := SuperObject( J ); if not IsIdenticalObj( M, SuperObject( K ) ) then Error( "the super objects must coincide\n" ); fi; mapK := MatrixOfSubobjectGenerators( K ); mapJ := MatrixOfSubobjectGenerators( J ); if IsHomalgLeftObjectOrMorphismOfLeftObjects( J ) then sum := UnionOfRows( mapK, mapJ ); else sum := UnionOfColumns( mapK, mapJ ); fi; return Subobject( sum, M ); end ); ## InstallMethod( MatchPropertiesAndAttributesOfSubobjectAndUnderlyingObject, "for a submodule and its underlying module", [ IsFinitelyPresentedSubmoduleRep, IsFinitelyPresentedModuleRep ], function( I, M ) ## we don't check if M is the underlying object of I ## to avoid infinite loops as EmbeddingInSuperObject ## will be invoked if ConstructedAsAnIdeal( I ) then MatchPropertiesAndAttributes( I, M, LIMOD.intrinsic_properties_shared_with_subobjects_and_ideals, LIMOD.intrinsic_attributes_shared_with_subobjects_and_ideals ); else MatchPropertiesAndAttributes( I, M, LIMOD.intrinsic_properties_shared_with_subobjects_which_are_not_ideals, LIMOD.intrinsic_attributes_shared_with_subobjects_which_are_not_ideals ); fi; end ); ## InstallMethod( \in, "for an element and an ideal", [ IsRingElement, IsStaticFinitelyPresentedSubobjectRep and ConstructedAsAnIdeal ], function( r, I ) r := HomalgMatrix( [ r ], 1, 1, HomalgRing( r ) ); r := Subobject( r, SuperObject( I ) ); return IsSubset( I, r ); end ); ## InstallMethod( RadicalIdealMembership, "for an element and an ideal", [ IsHomalgRingElement, IsFinitelyPresentedSubmoduleRep and ConstructedAsAnIdeal ], function( r, I ) local R, R_Rab, r_Rab, indets, Rabinovich_element, F, phi; R := HomalgRing( r ); if not ( IsIdenticalObj( 1 * R, SuperObject( I ) ) or IsIdenticalObj( R * 1, SuperObject( I ) ) ) then Error( "the element and the ideal are not in the same ring" ); fi; R_Rab := R * "RadicalTestVariable"; r_Rab := r / R_Rab; indets := Indeterminates( R_Rab ); Rabinovich_element := indets[ Length( indets ) ] * r_Rab - One( R_Rab ); F := R_Rab * SuperObject( I ); Rabinovich_element := HomalgMap( HomalgMatrix( [ Rabinovich_element ], 1, 1, R_Rab ), F, F ); phi := R_Rab * I!.map_having_subobject_as_its_image; phi := CoproductMorphism( phi, Rabinovich_element ); return IsZero( Cokernel( phi ) ); end ); #################################### # # constructor functions and methods: # #################################### ## InstallOtherMethod( \*, "for homalg submodules", [ IsHomalgRing, IsFinitelyPresentedSubmoduleRep ], 10001, function( R, M ) return ImageSubobject( R * OnAFreeSource( MorphismHavingSubobjectAsItsImage( M ) ) ); end ); ## <#GAPDoc Label="Subobject:matrix"> ## <ManSection> ## <Oper Arg="mat,M" Name="Subobject" Label="constructor for submodules using matrices"/> ## <Returns>a &homalg; submodule</Returns> ## <Description> ## This constructor returns the finitely generated left/right submodule of the &homalg; module <A>M</A> with generators given by the ## rows/columns of the &homalg; matrix <A>mat</A>. ## </Description> ## </ManSection> ## <#/GAPDoc> ## InstallMethod( Subobject, "constructor for homalg submodules", [ IsHomalgMatrix, IsFinitelyPresentedModuleRep ], function( gen, M ) local gen_map; if not IsIdenticalObj( HomalgRing( gen ), HomalgRing( M ) ) then Error( "the matrix and the module are not defined over identically the same ring\n" ); fi; if IsHomalgLeftObjectOrMorphismOfLeftObjects( M ) then if NrColumns( gen ) <> NrGenerators( M ) then Error( "the first argument is matrix with ", NrColumns( gen )," columns while the second argument is a module on ", NrGenerators( M ), " generators\n" ); fi; else if NrRows( gen ) <> NrGenerators( M ) then Error( "the first argument is matrix with ", NrRows( gen )," rows while the second argument is a module on ", NrGenerators( M ), " generators\n" ); fi; fi; gen_map := HomalgMap( gen, "free", M ); return ImageSubobject( gen_map ); end ); ## <#GAPDoc Label="Subobject:list"> ## <ManSection> ## <Oper Arg="gens,M" Name="Subobject" Label="constructor for submodules using a list of ring elements"/> ## <Returns>a &homalg; submodule</Returns> ## <Description> ## This constructor returns the finitely generated left/right submodule of the &homalg; cyclic left/right module <A>M</A> ## with generators given by the entries of the list <A>gens</A>. ## </Description> ## </ManSection> ## <#/GAPDoc> ## InstallMethod( Subobject, "constructor for homalg submodules", [ IsList, IsHomalgModule ], function( gens, M ) local l, R, mat; if NrGenerators( M ) <> 1 then Error( "the given module is either not cyclic or not presented on a cyclic generator\n" ); fi; l := Length( gens ); if l = 0 then return FullSubobject( M ); fi; if not ForAll( gens, IsRingElement ) then Error( "all entries of the list must be ring elements\n" ); fi; R := HomalgRing( M ); if IsHomalgLeftObjectOrMorphismOfLeftObjects( M ) then mat := HomalgMatrix( gens, l, 1, R ); else mat := HomalgMatrix( gens, 1, l, R ); fi; return Subobject( mat, M ); end ); ## InstallMethod( Subobject, ## in case the methods below do not apply "constructor for homalg submodules", [ IsHomalgRelations, IsFinitelyPresentedModuleRep ], function( rel, M ) Error( "the set of relations and the module should either be both left or both right\n" ); end ); ## InstallMethod( Subobject, "constructor for homalg submodules", [ IsHomalgRelations and IsHomalgRelationsOfRightModule, IsFinitelyPresentedModuleRep and IsHomalgRightObjectOrMorphismOfRightObjects ], function( rel, M ) return Subobject( MatrixOfRelations( rel ), M ); end ); ## InstallMethod( Subobject, "constructor for homalg submodules", [ IsHomalgRelations and IsHomalgRelationsOfLeftModule, IsFinitelyPresentedModuleRep and IsHomalgLeftObjectOrMorphismOfLeftObjects ], function( rel, M ) return Subobject( MatrixOfRelations( rel ), M ); end ); ## <#GAPDoc Label="LeftSubmodule"> ## <ManSection> ## <Oper Arg="mat" Name="LeftSubmodule" Label="constructor for left submodules"/> ## <Returns>a &homalg; submodule</Returns> ## <Description> ## This constructor returns the finitely generated left submodule with generators given by the ## rows of the &homalg; matrix <A>mat</A>. ## <Listing Type="Code"><![CDATA[ InstallMethod( LeftSubmodule, "constructor for homalg submodules", [ IsHomalgMatrix ], function( gen ) local R; R := HomalgRing( gen ); return Subobject( gen, NrColumns( gen ) * R ); end ); ## ]]></Listing> ## <Example><![CDATA[ ## gap> Z4 := HomalgRingOfIntegers( ) / 4; ## Z/( 4 ) ## gap> I := HomalgMatrix( "[ 2 ]", 1, 1, Z4 ); ## <A 1 x 1 matrix over a residue class ring> ## gap> I := LeftSubmodule( I ); ## <A principal torsion-free (left) ideal given by a cyclic generator> ## gap> IsFree( I ); ## false ## gap> I; ## <A principal reflexive non-projective (left) ideal given by a cyclic generator\ ## > ## ]]></Example> ## </Description> ## </ManSection> ## <#/GAPDoc> ## InstallMethod( LeftSubmodule, "constructor for homalg submodules", [ IsHomalgRing ], function( R ) return FullSubobject( 1 * R ); end ); ## InstallMethod( LeftSubmodule, "constructor for homalg ideals", [ IsList ], function( gen ) local R; if gen = [ ] then Error( "an empty list of ring elements\n" ); elif not ForAll( gen, IsRingElement ) then Error( "a list of ring elements is expected\n" ); fi; R := HomalgRing( gen[1] ); return LeftSubmodule( HomalgMatrix( gen, Length( gen ), 1, R ) ); end ); ## InstallMethod( LeftSubmodule, "constructor for homalg ideals", [ IsRingElement ], function( f ) if not IsBound( f!.LeftSubmodule ) then f!.LeftSubmodule := LeftSubmodule( [ f ] ); fi; return f!.LeftSubmodule; end ); ## InstallMethod( LeftSubmodule, "constructor for homalg ideals", [ IsList, IsHomalgRing ], function( gen, R ) local Gen; if gen = [ ] then return ZeroLeftSubmodule( R ); fi; Gen := List( gen, function( r ) if IsString( r ) then return HomalgRingElement( r, R ); elif IsRingElement( r ) then return r; else Error( r, " is neither a string nor a ring element\n" ); fi; end ); return LeftSubmodule( HomalgMatrix( Gen, Length( Gen ), 1, R ) ); end ); ## InstallMethod( LeftSubmodule, "constructor for homalg ideals", [ IsString, IsHomalgRing ], function( gen, R ) local Gen; if gen = [ ] then return ZeroLeftSubmodule( R ); fi; Gen := ShallowCopy( gen ); RemoveCharacters( Gen, "[]" ); return LeftSubmodule( SplitString( Gen, "," ), R ); end ); ## InstallMethod( ZeroLeftSubmodule, "constructor for homalg submodules", [ IsHomalgRing ], function( R ) return ZeroSubobject( 1 * R ); end ); ## <#GAPDoc Label="RightSubmodule"> ## <ManSection> ## <Oper Arg="mat" Name="RightSubmodule" Label="constructor for right submodules"/> ## <Returns>a &homalg; submodule</Returns> ## <Description> ## This constructor returns the finitely generated right submodule with generators given by the ## columns of the &homalg; matrix <A>mat</A>. ## <Listing Type="Code"><![CDATA[ InstallMethod( RightSubmodule, "constructor for homalg submodules", [ IsHomalgMatrix ], function( gen ) local R; R := HomalgRing( gen ); return Subobject( gen, R * NrRows( gen ) ); end ); ## ]]></Listing> ## <Example><![CDATA[ ## gap> Z4 := HomalgRingOfIntegers( ) / 4; ## Z/( 4 ) ## gap> I := HomalgMatrix( "[ 2 ]", 1, 1, Z4 ); ## <A 1 x 1 matrix over a residue class ring> ## gap> I := RightSubmodule( I ); ## <A principal torsion-free (right) ideal given by a cyclic generator> ## gap> IsFree( I ); ## false ## gap> I; ## <A principal reflexive non-projective (right) ideal given by a cyclic generato\ ## r> ## ]]></Example> ## </Description> ## </ManSection> ## <#/GAPDoc> ## InstallMethod( RightSubmodule, "constructor for homalg submodules", [ IsHomalgRing ], function( R ) return FullSubobject( R * 1 ); end ); ## InstallMethod( RightSubmodule, "constructor for homalg ideals", [ IsList ], function( gen ) local R; if gen = [ ] then Error( "an empty list of ring elements\n" ); elif not ForAll( gen, IsRingElement ) then Error( "a list of ring elements is expected\n" ); fi; R := HomalgRing( gen[1] ); return RightSubmodule( HomalgMatrix( gen, 1, Length( gen ), R ) ); end ); ## InstallMethod( RightSubmodule, "constructor for homalg ideals", [ IsRingElement ], function( f ) if not IsBound( f!.RightSubmodule ) then f!.RightSubmodule := RightSubmodule( [ f ] ); fi; return f!.RightSubmodule; end ); ## InstallMethod( RightSubmodule, "constructor for homalg ideals", [ IsList, IsHomalgRing ], function( gen, R ) local Gen; if gen = [ ] then return ZeroRightSubmodule( R ); fi; Gen := List( gen, function( r ) if IsString( r ) then return HomalgRingElement( r, R ); elif IsRingElement( r ) then return r; else Error( r, " is neither a string nor a ring element\n" ); fi; end ); return RightSubmodule( HomalgMatrix( Gen, 1, Length( Gen ), R ) ); end ); ## InstallMethod( RightSubmodule, "constructor for homalg ideals", [ IsString, IsHomalgRing ], function( gen, R ) local Gen; if gen = [ ] then return ZeroRightSubmodule( R ); fi; Gen := ShallowCopy( gen ); RemoveCharacters( Gen, "[]" ); return RightSubmodule( SplitString( Gen, "," ), R ); end ); ## InstallMethod( ZeroRightSubmodule, "constructor for homalg submodules", [ IsHomalgRing ], function( R ) return ZeroSubobject( R * 1 ); end ); ## InstallMethod( LeftIdealOfMinors, "constructor for homalg ideals", [ IsInt, IsHomalgMatrix ], function( d, M ) local minors, R; minors := Minors( d, M ); R := HomalgRing( M ); if minors = [ One( R ) ] then return LeftSubmodule( R ); elif minors = [ Zero( R ) ] then return ZeroLeftSubmodule( R ); fi; return LeftSubmodule( minors, R ); end ); ## InstallMethod( LeftIdealOfMaximalMinors, "constructor for homalg ideals", [ IsHomalgMatrix ], function( M ) local minors, R; minors := MaximalMinors( M ); R := HomalgRing( M ); if minors = [ One( R ) ] then return LeftSubmodule( R ); elif minors = [ Zero( R ) ] then return ZeroLeftSubmodule( R ); fi; return LeftSubmodule( minors, HomalgRing( M ) ); end ); ## InstallMethod( RightIdealOfMinors, "constructor for homalg ideals", [ IsInt, IsHomalgMatrix ], function( d, M ) local minors, R; minors := Minors( d, M ); R := HomalgRing( M ); if minors = [ One( R ) ] then return RightSubmodule( R ); elif minors = [ Zero( R ) ] then return ZeroRightSubmodule( R ); fi; return RightSubmodule( minors, HomalgRing( M ) ); end ); ## InstallMethod( RightIdealOfMaximalMinors, "constructor for homalg ideals", [ IsHomalgMatrix ], function( M ) local minors, R; minors := MaximalMinors( M ); R := HomalgRing( M ); if minors = [ One( R ) ] then return RightSubmodule( R ); elif minors = [ Zero( R ) ] then return ZeroRightSubmodule( R ); fi; return RightSubmodule( MaximalMinors( M ), HomalgRing( M ) ); end ); #################################### # # View, Print, and Display methods: # #################################### ## InstallMethod( ViewString, "for homalg submodules", [ IsFinitelyPresentedSubmoduleRep and IsFree ], 1001, ## since we don't use the filter IsHomalgLeftObjectOrMorphismOfLeftObjects it is good to set the ranks high function( J ) local s, R, vs, r, rk, l; s := ""; ## NrGenerators might set IsZero to true NrGenerators( J ); if HasIsZero( J ) and IsZero( J ) then return ViewString( J ); fi; R := HomalgRing( J ); vs := HasIsDivisionRingForHomalg( R ) and IsDivisionRingForHomalg( R ); if IsHomalgLeftObjectOrMorphismOfLeftObjects( J ) then if vs then if HasIsCommutative( R ) and IsCommutative( R ) then if IsBound( HOMALG.SuppressParityInViewObjForCommutativeStructureObjects ) and HOMALG.SuppressParityInViewObjForCommutativeStructureObjects = true then Append( s, " " ); else Append( s, " (left) " ); fi; else Append( s, " left " ); fi; Append( s, "vector subspace" ); elif ConstructedAsAnIdeal( J ) then Append( s, " principal " ); if HasIsCommutative( R ) and IsCommutative( R ) then if not ( IsBound( HOMALG.SuppressParityInViewObjForCommutativeStructureObjects ) and HOMALG.SuppressParityInViewObjForCommutativeStructureObjects = true ) then Append( s, "(left) " ); fi; else Append( s, "left " ); fi; Append( s, "ideal" ); else Append( s, " free left submodule" ); fi; else if vs then if HasIsCommutative( R ) and IsCommutative( R ) then if IsBound( HOMALG.SuppressParityInViewObjForCommutativeStructureObjects ) and HOMALG.SuppressParityInViewObjForCommutativeStructureObjects = true then Append( s, " " ); else Append( s, " (right) " ); fi; else Append( s, " right " ); fi; Append( s, "vector subspace" ); elif ConstructedAsAnIdeal( J ) then Append( s, " principal " ); if HasIsCommutative( R ) and IsCommutative( R ) then if not ( IsBound( HOMALG.SuppressParityInViewObjForCommutativeStructureObjects ) and HOMALG.SuppressParityInViewObjForCommutativeStructureObjects = true ) then Append( s, "(right) " ); fi; else Append( s, "right " ); fi; Append( s, "ideal" ); else Append( s, " free right submodule" ); fi; fi; r := NrGenerators( J ); if HasRankOfObject( J ) then rk := RankOfObject( J ); if vs then s := Concatenation( s, " of dimension " ); else s := Concatenation( s, " of rank " ); fi; s := Concatenation( s, String( rk ), " on " ); if r = rk then if r = 1 then Append( s, "a free generator" ); else Append( s, "free generators" ); fi; else ## => r > 1 s := Concatenation( s, String( r ), " non-free generators" ); if HasNrRelations( J ) = true then l := NrRelations( J ); Append( s, " satisfying " ); if l = 1 then Append( s, "a single relation" ); else s:= Concatenation( s, String( l ), " relations" ); fi; fi; fi; else if r = 1 then Append( s, " given by a cyclic generator" ); else s := Concatenation( s, " given by ", String( r ), " generators" ); fi; if HasNrRelations( J ) = true then l := NrRelations( J ); if l = 0 then SetRankOfObject( J, r ); return ViewString( J ); fi; Append( s, " satisfying " ); if l = 1 then Append( s, "a single relation" ); else s := Concatenation( s, String( l ), " relations" ); fi; fi; fi; return s; end ); ## InstallMethod( ViewString, "for homalg submodules", [ IsFinitelyPresentedSubmoduleRep and IsZero ], 1001, ## since we don't use the filter IsHomalgLeftObjectOrMorphismOfLeftObjects it is good to set the ranks high function( J ) local R, vs, s; R := HomalgRing( J ); vs := HasIsDivisionRingForHomalg( R ) and IsDivisionRingForHomalg( R ); s := " zero "; if not ( IsBound( HOMALG.SuppressParityInViewObjForCommutativeStructureObjects ) and HOMALG.SuppressParityInViewObjForCommutativeStructureObjects = true ) then if IsHomalgLeftObjectOrMorphismOfLeftObjects( J ) then Append( s, "(left) " ); else Append( s, "(right) " ); fi; fi; if vs then return Concatenation( s, "vector subspace" ); elif ConstructedAsAnIdeal( J ) then return Concatenation( s, "ideal" ); else return Concatenation( s, "submodule" ); fi; end ); ## InstallMethod( Display, "for homalg submodules", [ IsFinitelyPresentedSubmoduleRep ], function( M ) local R, gen, l; R := HomalgRing( M ); gen := MatrixOfSubobjectGenerators( M ); Display( gen ); Print( "\nA" ); if IsHomalgLeftObjectOrMorphismOfLeftObjects( M ) then l := NrRows( gen ); if ConstructedAsAnIdeal( M ) then if HasIsCommutative( R ) and IsCommutative( R ) then if IsBound( HOMALG.SuppressParityInViewObjForCommutativeStructureObjects ) and HOMALG.SuppressParityInViewObjForCommutativeStructureObjects = true then Print( "n" ); else Print( " (left)" ); fi; else Print( " left" ); fi; Print( " ideal generated by the " ); if l = 1 then Print( "entry" ); else Print( l, " entries" ); fi; else Print( " left submodule generated by the " ); if l = 1 then Print( "row" ); else Print( l, " rows" ); fi; fi; Print( " of the above matrix\n" ); else l := NrColumns( gen ); if ConstructedAsAnIdeal( M ) then if HasIsCommutative( R ) and IsCommutative( R ) then if IsBound( HOMALG.SuppressParityInViewObjForCommutativeStructureObjects ) and HOMALG.SuppressParityInViewObjForCommutativeStructureObjects = true then Print( "n" ); else Print( " (right)" ); fi; else Print( " right" ); fi; Print( " ideal generated by the " ); if l = 1 then Print( "entry" ); else Print( l, " entries" ); fi; else Print( " right submodule generated by the " ); if l = 1 then Print( "column" ); else Print( l, " columns" ); fi; fi; Print( " of the above matrix\n" ); fi; end );