|
# SPDX-License-Identifier: GPL-2.0-or-later
# Modules: A homalg based package for the Abelian category of finitely presented modules over computable rings
#
# Implementations
#
## 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( \^,
"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 NumberColumns( gen ) <> NrGenerators( M ) then
Error( "the first argument is matrix with ", NumberColumns( gen )," columns while the second argument is a module on ", NrGenerators( M ), " generators\n" );
fi;
else
if NumberRows( gen ) <> NrGenerators( M ) then
Error( "the first argument is matrix with ", NumberRows( 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, NumberColumns( 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 * NumberRows( 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 := NumberRows( 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 := NumberColumns( 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 );
[ Dauer der Verarbeitung: 0.38 Sekunden
(vorverarbeitet)
]
|