GAP 4.8.9 installation with standard packages -- copy to your CoCalc project to get it
#############################################################################
##
## GradedModule.gi GradedModules package
##
## Copyright 2007-2010, Mohamed Barakat, University of Kaiserslautern
## Markus Lange-Hegermann, RWTH Aachen
##
## Implementations for graded homalg modules.
##
#############################################################################
####################################
#
# global variables:
#
####################################
# a central place for configuration variables:
InstallValue( HOMALG_GRADED_MODULES,
rec(
category := rec(
description := "f.p. graded modules and their maps over computable graded rings",
short_description := "_for_fp_graded_modules",
TryPostDivideWithoutAids := true, # see homalg/ToolFunctors.gi
MorphismConstructor := GradedMap,
TypeOfElements := TheTypeHomalgModuleElement,
InternalHom := GradedHom,
InternalExt := GradedExt,
),
ModulesSave := [ ],
MorphismsSave := [ ],
# this sets the bound at which modules are cut of when computing ModuleOfGlobalSections.
# it should be zero to ensure that global sections sets the correct transformation
LowerTruncationBound := 0
)
);
####################################
#
# representations:
#
####################################
DeclareRepresentation( "IsGradedModuleOrGradedSubmoduleRep",
IsHomalgGradedModule and
IsStaticFinitelyPresentedObjectOrSubobjectRep and
IsHomalgGradedRingOrGradedModuleRep,
[ ] );
DeclareRepresentation( "IsGradedModuleRep",
IsGradedModuleOrGradedSubmoduleRep and
IsStaticFinitelyPresentedObjectRep,
[ "UnderlyingModule", "SetOfDegreesOfGenerators" ] );
##
DeclareRepresentation( "IsCategoryOfFinitelyPresentedGradedLeftModulesRep",
IsHomalgCategoryOfLeftObjectsRep and
IsCategoryOfGradedModules,
[ ] );
##
DeclareRepresentation( "IsCategoryOfFinitelyPresentedGradedRightModulesRep",
IsHomalgCategoryOfRightObjectsRep and
IsCategoryOfGradedModules,
[ ] );
####################################
#
# families and types:
#
####################################
# a new family:
BindGlobal( "TheFamilyOfHomalgGradedModules",
NewFamily( "TheFamilyOfHomalgGradedModules" ) );
# two new types:
BindGlobal( "TheTypeHomalgGradedLeftModule",
NewType( TheFamilyOfHomalgGradedModules, IsHomalgLeftObjectOrMorphismOfLeftObjects and IsGradedModuleRep )
);
BindGlobal( "TheTypeHomalgGradedRightModule",
NewType( TheFamilyOfHomalgGradedModules, IsHomalgRightObjectOrMorphismOfRightObjects and IsGradedModuleRep )
);
# two new types:
BindGlobal( "TheTypeCategoryOfFinitelyPresentedGradedLeftModules",
NewType( TheFamilyOfHomalgCategories,
IsCategoryOfFinitelyPresentedGradedLeftModulesRep ) );
BindGlobal( "TheTypeCategoryOfFinitelyPresentedGradedRightModules",
NewType( TheFamilyOfHomalgCategories,
IsCategoryOfFinitelyPresentedGradedRightModulesRep ) );
####################################
#
# methods for operations:
#
####################################
##
InstallMethod( MapHavingCertainGeneratorsAsItsImage,
"for two homalg modules, submodules, or maps",
[ IsGradedModuleRep, IsList ],
function( M, l )
local n, certain_part, mat;
return GradedMap( MapHavingCertainGeneratorsAsItsImage( UnderlyingModule( M ), l ), "create", M );
end );
##
InstallMethod( LockObjectOnCertainPresentation,
"for homalg graded modules",
[ IsGradedModuleRep, IsInt ],
function( M, p )
## first save the current setting
M!.LockObjectOnCertainPresentation := PositionOfTheDefaultPresentation( M );
SetPositionOfTheDefaultPresentation( M, p );
LockObjectOnCertainPresentation( UnderlyingModule( M ), p );
end );
##
InstallMethod( LockObjectOnCertainPresentation,
"for homalg graded modules",
[ IsGradedModuleRep ],
function( M )
LockObjectOnCertainPresentation( M, PositionOfTheDefaultPresentation( M ) );
end );
##
InstallMethod( UnlockObject,
"for homalg graded modules",
[ IsGradedModuleRep ],
function( M )
UnlockObject( UnderlyingModule( M ) );
## first restore the saved settings
if IsBound( M!.LockObjectOnCertainPresentation ) then
SetPositionOfTheDefaultPresentation( M, M!.LockObjectOnCertainPresentation );
Unbind( M!.LockObjectOnCertainPresentation );
fi;
end );
##
InstallMethod( UnderlyingModule,
"for homalg graded modules",
[ IsGradedModuleRep ],
function( M )
return M!.UnderlyingModule;
end );
##
InstallMethod( SetOfDegreesOfGenerators,
"for homalg graded modules",
[ IsGradedModuleRep ],
function( M )
return M!.SetOfDegreesOfGenerators;
end );
##
InstallMethod( AnyParametrization,
"for homalg graded modules",
[ IsGradedModuleRep ],
function( M )
local par;
par := AnyParametrization( UnderlyingModule( M ) );
par := GradedMap( par, M, "create", HomalgRing( M ) );
Assert( 4, IsMorphism );
SetIsMorphism( par, true );
return par;
end );
##
InstallMethod( MinimalParametrization,
"for homalg graded modules",
[ IsGradedModuleRep ],
function( M )
local par;
par := MinimalParametrization( UnderlyingModule( M ) );
par := GradedMap( par, M, "create", HomalgRing( M ) );
Assert( 4, IsMorphism );
SetIsMorphism( par, true );
return par;
end );
##
InstallMethod( CurrentResolution,
"for graded modules",
[ IsInt, IsGradedModuleRep ],
function( q, M )
local S, res, degrees, deg, len, CEpi, d_j, F_j, graded_res, j;
S := HomalgRing( M );
res := Resolution( q, UnderlyingModule( M ) );
degrees := ObjectDegreesOfComplex( res );
len := Length( degrees );
if HasCurrentResolution( M ) then
graded_res := CurrentResolution( M );
deg := ObjectDegreesOfComplex( graded_res );
j := Length( deg );
j := deg[j];
d_j := CertainMorphism( graded_res, j );
else
j := res!.degrees[2];
CEpi := GradedMap( CokernelEpi( res!.(j) ), "create", M );
Assert( 3, IsMorphism( CEpi ) );
SetIsMorphism( CEpi, true );
d_j := GradedMap( res!.(j), "create", Source( CEpi ), S );
Assert( 3, IsMorphism( d_j ) );
SetIsMorphism( d_j, true );
SetCokernelEpi( d_j, CEpi );
graded_res := HomalgComplex( d_j );
SetCurrentResolution( M, graded_res );
fi;
F_j := Source( d_j );
if len >= j+2 then
for j in [ res!.degrees[j+2] .. res!.degrees[len] ] do
if IsIdenticalObj( F_j, 0 * S ) or IsIdenticalObj( F_j, S * 0 ) then
# take care not to create the graded zero morphism between distinguished zero modules again each step
d_j := TheZeroMorphism( F_j, F_j );
Add( graded_res, d_j );
# no need for resetting F_j, since all other modules will be zero, too
else
d_j := GradedMap( res!.(j), "create", F_j, S );
Assert( 3, IsMorphism( d_j ) );
SetIsMorphism( d_j, true );
Add( graded_res, d_j );
F_j := Source( d_j );
fi;
od;
fi;
if HasIsAcyclic( res ) and IsAcyclic( res ) then
SetIsAcyclic( graded_res, true );
fi;
if HasIsRightAcyclic( res ) and HasIsRightAcyclic( res ) then
SetIsRightAcyclic( graded_res, true );
fi;
if IsBound( res!.LengthOfResolution ) then
graded_res!.LengthOfResolution := res!.LengthOfResolution;
fi;
return graded_res;
end );
##
InstallMethod( PresentationMorphism,
"for homalg modules",
[ IsGradedModuleRep, IsPosInt ],
function( M, pos )
local rel, pres, epi;
if IsBound(M!.PresentationMorphisms.( pos )) then
return M!.PresentationMorphisms.( pos );
fi;
pres := PresentationMorphism( UnderlyingModule( M ), pos );
epi := GradedMap( CokernelEpi( pres ), "create", M );
Assert( 4, IsMorphism( epi ) );
SetIsMorphism( epi, true );
pres := GradedMap( pres, "create", Source( epi ) );
Assert( 4, IsMorphism( pres ) );
SetIsMorphism( pres, true );
SetCokernelEpi( pres, epi );
M!.PresentationMorphisms.( pos ) := pres;
return pres;
end );
## <#GAPDoc Label="MonomialMap">
## <ManSection>
## <Oper Arg="d, M" Name="MonomialMap"/>
## <Returns>a &homalg; map</Returns>
## <Description>
## The map from a free graded module onto all degree <A>d</A> monomial generators
## of the finitely generated &homalg; module <A>M</A>.
## <#Include Label="MonomialMap:example">
## </Description>
## </ManSection>
## <#/GAPDoc>
InstallMethod( MonomialMap,
"for homalg modules",
[ IsInt, IsGradedModuleRep ],
function( d, M )
local S, degrees, mon, i, result;
S := HomalgRing( M );
degrees := DegreesOfGenerators( M );
degrees := List( degrees, HomalgElementToInteger );
mon := rec( );
for i in Set( degrees ) do
mon.(String( d - i )) := MonomialMatrix( d - i, S );
od;
mon := List( degrees, i -> mon.(String(d - i)) );
if IsHomalgRightObjectOrMorphismOfRightObjects( M ) then
mon := List( mon, Involution );
fi;
if mon <> [ ] then
mon := DiagMat( mon );
else
mon := HomalgZeroMatrix( 0, 0, UnderlyingNonGradedRing( S ) );
fi;
mon := MatrixOverGradedRing( mon, S );
result:= GradedMap( mon, "free", M );
Assert( 4, IsMorphism( result ) );
SetIsMorphism( result, true );
return result;
end );
##
InstallMethod( MonomialMap,
"for homalg modules",
[ IsHomalgElement, IsGradedModuleRep ],
function( d, M )
return MonomialMap( HomalgElementToInteger( d ), M );
end );
## <#GAPDoc Label="RandomMatrix">
## <ManSection>
## <Oper Arg="S,T" Name="RandomMatrix"/>
## <Returns>a &homalg; matrix</Returns>
## <Description>
## A random matrix between the graded source module <A>S</A> and the graded target module <A>T</A>.
## <#Include Label="RandomMatrix:example">
## </Description>
## </ManSection>
## <#/GAPDoc>
##
InstallMethod( RandomMatrix,
"for homalg modules",
[ IsHomalgGradedModule, IsHomalgGradedModule ],
function( S, T )
local left, degreesS, degreesT, R;
left := IsHomalgLeftObjectOrMorphismOfLeftObjects( S );
if IsHomalgLeftObjectOrMorphismOfLeftObjects( T ) <> left then
Error( "both modules must either be left or either be right modules" );
fi;
degreesS := DegreesOfGenerators( S );
degreesT := DegreesOfGenerators( T );
R := HomalgRing( S );
if left then
return RandomMatrixBetweenGradedFreeLeftModules( degreesS, degreesT, R );
else
return RandomMatrixBetweenGradedFreeRightModules( degreesT, degreesS, R );
fi;
end );
##
InstallMethod( \/, ### defines: / (SubfactorModule)
"for a homalg matrix and a graded module",
[ IsHomalgMatrix, IsGradedModuleOrGradedSubmoduleRep ], 10000,
function( mat, M )
# local B, N, gen, S, SF;
local mat2, res;
if IsHomalgMatrixOverGradedRingRep( mat ) then
mat2 := UnderlyingMatrixOverNonGradedRing( mat );
else
mat2 := mat;
fi;
res := mat2 / UnderlyingModule( M );
return GradedModule( res, HomalgRing( M ) );
end );
##
InstallMethod( \/, ## needed by _Functor_Kernel_OnObjects since SyzygiesGenerators returns a set of relations
"for a set of homalg relations and a graded module",
[ IsHomalgRelations, IsGradedModuleOrGradedSubmoduleRep ], 10000,
function( rel, M )
return MatrixOfRelations( rel ) / M;
end );
##
InstallMethod( Annihilator,
"for homalg relations",
[ IsHomalgMatrixOverGradedRingRep, IsHomalgRelations ],
function( mat, rel )
return GradedModule( Annihilator( UnderlyingMatrixOverNonGradedRing( mat ), rel ), HomalgRing( mat ) );
end );
##
InstallMethod( CompleteComplexByLinearResolution,
"for homalg cocomplexes",
[ IsInt, IsCocomplexOfFinitelyPresentedObjectsRep ],
function( n, C )
local i, phi, S;
for i in [ 1 .. n ] do
phi := LowestDegreeMorphism( C );
S := Source( phi );
phi := MatrixOfMap( phi );
if IsHomalgLeftObjectOrMorphismOfLeftObjects( C ) then
phi := LinearSyzygiesGeneratorsOfRows( phi );
else
phi := LinearSyzygiesGeneratorsOfColumns( phi );
fi;
phi := GradedMap( phi, "free", S );
Assert( 4, IsMorphism( phi ) );
SetIsMorphism( phi, true );
Add( phi, C );
od;
return C;
end );
##
InstallMethod( FittingIdeal,
"for homalg graded modules",
[ IsInt, IsGradedModuleRep ],
function( i, M )
local Fitt, Fitt_i;
if not IsBound( M!.FittingIdeals ) then
M!.FittingIdeals := rec( );
fi;
Fitt := M!.FittingIdeals;
if IsBound( Fitt.(String( i )) ) then
return Fitt.(String( i ));
fi;
Fitt_i := FittingIdeal( i, UnderlyingModule( M ) );
Fitt_i := GradedModule( Fitt_i, HomalgRing( M ) );
Fitt.(String( i )) := Fitt_i;
return Fitt_i;
end );
####################################
#
# constructors:
#
####################################
##
InstallMethod( HomalgCategory,
"constructor for module categories",
[ IsHomalgGradedRing, IsString ],
function( R, parity )
local A;
if parity = "right" and IsBound( R!.category_of_fp_graded_right_modules ) then
return R!.category_of_fp_graded_right_modules;
elif IsBound( R!.category_of_fp_graded_left_modules ) then
return R!.category_of_fp_graded_left_modules;
fi;
A := ShallowCopy( HOMALG_GRADED_MODULES.category );
A.containers := rec( );
A.ring := R;
if parity = "right" then
Objectify( TheTypeCategoryOfFinitelyPresentedGradedRightModules, A );
R!.category_of_fp_graded_right_modules := A;
else
Objectify( TheTypeCategoryOfFinitelyPresentedGradedLeftModules, A );
R!.category_of_fp_graded_left_modules := A;
fi;
return A;
end );
##
InstallMethod( GradedModule,
"for a homalg module",
[ IsFinitelyPresentedModuleRep, IsList, IsHomalgGradedRingRep ],
function( module, degrees, S )
local degree_group, weights, i, GradedModule, setofdegrees, type, ring;
if IsGradedModuleRep( module ) then
return module;
fi;
# if not Length( degrees ) = 0 then
#
# if not IsHomalgElement( degrees[ 1 ] ) and not Set( degrees ) = [ 0 ] then
#
# weights := GeneratingElements( DegreeGroup( S ) );
#
# if not IsInt( degrees[ 1 ] ) then
#
# if not Length( weights ) = Length( degrees[ 1 ] ) then
# Error(" number of generators of DegreeGroup does not match length of degrees.");
# fi;
#
# fi;
#
# for i in [ 1 .. Length( weights ) ] do
#
# degrees[ i ] := degrees[ i ] * weights[ i ];
#
# od;
#
# degrees := Flat( degrees );
#
# fi;
#
# fi;
degree_group := DegreeGroup( S );
if not Length( degrees ) = 0 then
weights := GeneratingElements( degree_group );
if IsInt( degrees[ 1 ] ) then
if Set( degrees ) = [ 0 ] then
degrees := ListWithIdenticalEntries( Length( degrees ), TheZeroElement( degree_group ) );
elif Length( weights ) = 1 then
degrees := List( degrees, HomalgElementToInteger );
degrees := List( degrees, i -> i * weights[ 1 ] );
else
Error( "input weights do not match generators of degree group" );
fi;
elif IsList( degrees[ 1 ] ) then
if Length( degrees[ 1 ] ) = Length( weights ) then
degrees := List( degrees, i -> HomalgModuleElement( i, degree_group ) );
else
Error( "something went terribly wrong" );
fi;
elif not IsHomalgElement( degrees[ 1 ] ) then
Error( "wrong input degrees" );
fi;
fi;
if IsBound( module!.GradedVersions ) then
for i in module!.GradedVersions do
if IsIdenticalObj( HomalgRing( i ), S ) and degrees = DegreesOfGenerators( i ) then
return i;
fi;
od;
fi;
if not IsIdenticalObj( UnderlyingNonGradedRing( S ), HomalgRing( module ) ) and
not IsIdenticalObj( S, HomalgRing( module ) ) then
Error( "Underlying rings do not match" );
fi;
if not ( Length( degrees ) = NrGenerators( module ) ) then
Error( "The number of degrees ", Length( degrees ),
" has to equal the number of Generators ", NrGenerators( module ), "\n" );
fi;
if IsBound( module!.distinguished ) and module!.distinguished and HasIsZero( module ) and IsZero( module ) then
if IsHomalgLeftObjectOrMorphismOfLeftObjects( module ) then
if IsBound( S!.ZeroLeftModule ) then
return S!.ZeroLeftModule;
fi;
else
if IsBound( S!.ZeroRightModule ) then
return S!.ZeroRightModule;
fi;
fi;
fi;
setofdegrees := CreateSetOfDegreesOfGenerators( degrees, PositionOfTheDefaultPresentation( module ) );
GradedModule := rec(
adjective := "graded",
string := "module",
string_plural := "modules",
ring := S,
Resolutions := rec( ),
PresentationMorphisms := rec(),
SetOfDegreesOfGenerators := setofdegrees
);
if IsHomalgLeftObjectOrMorphismOfLeftObjects( module ) then
type := TheTypeHomalgGradedLeftModule;
ring := LeftActingDomain;
GradedModule.category := HomalgCategory( S, "left" );
else
type := TheTypeHomalgGradedRightModule;
ring := RightActingDomain;
GradedModule.category := HomalgCategory( S, "right" );
fi;
## Objectify:
ObjectifyWithAttributes(
GradedModule, type,
UnderlyingModule, module,
ring, S
);
if IsBound( module!.distinguished ) and module!.distinguished and HasIsZero( module ) and IsZero( module ) then
if IsHomalgLeftObjectOrMorphismOfLeftObjects( module ) then
GradedModule!.distinguished := true;
S!.ZeroLeftModule := GradedModule;
else
GradedModule!.distinguished := true;
S!.ZeroRightModule := GradedModule;
fi;
fi;
MatchPropertiesAndAttributes( GradedModule, module, LIGrMOD.exchangeable_properties, LIGrMOD.exchangeable_attributes );
# if AssertionLevel() >= 10 then
# for i in [ 1 .. Length( HOMALG_GRADED_MODULES.ModulesSave ) ] do
# Assert( 10,
# not IsIdenticalObj( UnderlyingModule( HOMALG_GRADED_MODULES.ModulesSave[i] ), UnderlyingModule( GradedModule ) )
# or IsIdenticalObj( HOMALG_GRADED_MODULES.ModulesSave[i], GradedModule ),
# "a module is about to be graded (at least) twice. This might be intentionally. Set AssertionLevel to 11 to get an error message" );
# Assert( 11,
# not IsIdenticalObj( UnderlyingModule( HOMALG_GRADED_MODULES.ModulesSave[i] ), UnderlyingModule( GradedModule ) )
# or IsIdenticalObj( HOMALG_GRADED_MODULES.ModulesSave[i], GradedModule ) );
# od;
# Add( HOMALG_GRADED_MODULES.ModulesSave, GradedModule );
# fi;
if not IsBound( module!.GradedVersions ) then
module!.GradedVersions := [ GradedModule ];
else
Add( module!.GradedVersions, GradedModule );
fi;
return GradedModule;
end );
##
InstallMethod( GradedModule,
"for a homalg module",
[ IsFinitelyPresentedModuleRep, IsInt, IsHomalgGradedRingRep ],
function( module, d, S )
local gens;
gens := GeneratingElements( DegreeGroup( S ) );
if Length( gens ) > 0 then
gens := gens[ 1 ];
else
gens := TheZeroElement( DegreeGroup( S ) );
fi;
return GradedModule( module, ListWithIdenticalEntries( NrGenerators( module ), d * gens ), S );
end );
##
InstallMethod( GradedModule,
"for a homalg module",
[ IsFinitelyPresentedModuleRep, IsHomalgElement, IsHomalgGradedRingRep ],
function( module, d, S )
## User should take care that d is element in the DegreeGroup of s.
return GradedModule( module, ListWithIdenticalEntries( NrGenerators( module ), d ), S );
end );
##
InstallMethod( GradedModule,
"for a homalg module",
[ IsFinitelyPresentedModuleRep, IsHomalgGradedRingRep ],
function( module, S )
return GradedModule( module, TheZeroElement( DegreeGroup( S ) ), S );
end );
##
InstallMethod( GradedModule,
"for a homalg submodule",
[ IsFinitelyPresentedSubmoduleRep, IsHomalgGradedRingRep ],
function( J, S )
local map;
map := MorphismHavingSubobjectAsItsImage( J );
map := GradedMap( map, "create", ListWithIdenticalEntries( NrGenerators( Range( map ) ), TheZeroElement( DegreeGroup( S ) ) ), S );
return ImageSubobject( map );
end );
##
InstallMethod( LeftPresentationWithDegrees,
"constructor for homalg graded modules",
[ IsHomalgMatrix, IsList, IsHomalgGradedRingRep ],
function( mat, degrees, S )
local M;
if Length( degrees ) <> NrColumns( mat ) then
Error( "the number of degrees must coincide with the number of columns\n" );
fi;
if IsHomalgMatrixOverGradedRingRep( mat ) then
M := LeftPresentation( UnderlyingMatrixOverNonGradedRing( mat ) );
else
M := LeftPresentation( mat );
fi;
return GradedModule( M, degrees, S );
end );
##
InstallMethod( LeftPresentationWithDegrees,
"constructor for homalg graded modules",
[ IsHomalgMatrixOverGradedRingRep, IsList ],
function( mat, degrees )
return LeftPresentationWithDegrees( mat, degrees, HomalgRing( mat ) );
end );
##
InstallMethod( LeftPresentationWithDegrees,
"constructor for homalg graded modules",
[ IsHomalgMatrix, IsInt, IsHomalgGradedRingRep ],
function( mat, degree, S )
local gens;
gens := GeneratingElements( DegreeGroup( S ) );
if Length( gens ) > 0 then
gens := gens[ 1 ];
else
gens := TheZeroElement( DegreeGroup( S ) );
fi;
return LeftPresentationWithDegrees( mat, ListWithIdenticalEntries( NrColumns( mat ), degree * gens ), S );
end );
##
InstallMethod( LeftPresentationWithDegrees,
"constructor for homalg graded modules",
[ IsHomalgMatrix, IsHomalgElement, IsHomalgGradedRingRep ],
function( mat, degree, S )
return LeftPresentationWithDegrees( mat, ListWithIdenticalEntries( NrColumns( mat ), degree ), S );
end );
##
InstallMethod( LeftPresentationWithDegrees,
"constructor for homalg graded modules",
[ IsHomalgMatrixOverGradedRingRep, IsInt ],
function( mat, degree )
local ring, gens;
ring := HomalgRing( mat );
gens := GeneratingElements( DegreeGroup( ring ) );
if Length( gens ) > 0 then
gens := gens[ 1 ];
else
gens := TheZeroElement( DegreeGroup( ring ) );
fi;
return LeftPresentationWithDegrees( mat, degree * gens, ring );
end );
##
InstallMethod( LeftPresentationWithDegrees,
"constructor for homalg graded modules",
[ IsHomalgMatrixOverGradedRingRep, IsHomalgElement ],
function( mat, degree )
return LeftPresentationWithDegrees( mat, degree, HomalgRing( mat ) );
end );
##
InstallMethod( LeftPresentationWithDegrees,
"constructor for homalg graded modules",
[ IsHomalgMatrix, IsHomalgGradedRingRep ],
function( mat, S )
return LeftPresentationWithDegrees( mat, ListWithIdenticalEntries( NrColumns( mat ), TheZeroElement( DegreeGroup( S ) ) ), S );
end );
##
InstallMethod( LeftPresentationWithDegrees,
"constructor for homalg graded modules",
[ IsHomalgMatrixOverGradedRingRep ],
function( mat )
return LeftPresentationWithDegrees( mat, HomalgRing( mat ) );
end );
##
InstallMethod( RightPresentationWithDegrees,
"constructor for homalg graded modules",
[ IsHomalgMatrix, IsList, IsHomalgGradedRingRep ],
function( mat, degrees, S )
local M;
if Length( degrees ) <> NrRows( mat ) then
Error( "the number of degrees must coincide with the number of rows\n" );
fi;
if IsHomalgMatrixOverGradedRingRep( mat ) then
M := RightPresentation( UnderlyingMatrixOverNonGradedRing( mat ) );
else
M := RightPresentation( mat );
fi;
return GradedModule( M, degrees, S );
end );
##
InstallMethod( RightPresentationWithDegrees,
"constructor for homalg graded modules",
[ IsHomalgMatrixOverGradedRingRep, IsList ],
function( mat, degrees )
return RightPresentationWithDegrees( mat, degrees, HomalgRing( mat ) );
end );
##
InstallMethod( RightPresentationWithDegrees,
"constructor for homalg graded modules",
[ IsHomalgMatrix, IsInt, IsHomalgGradedRingRep ],
function( mat, degree, S )
local gens;
gens := GeneratingElements( DegreeGroup( S ) );
if Length( gens ) > 0 then
gens := gens[ 1 ];
else
gens := TheZeroElement( DegreeGroup( S ) );
fi;
return RightPresentationWithDegrees( mat, ListWithIdenticalEntries( NrRows( mat ), degree * gens ), S );
end );
##
InstallMethod( RightPresentationWithDegrees,
"constructor for homalg graded modules",
[ IsHomalgMatrix, IsHomalgElement, IsHomalgGradedRingRep ],
function( mat, degree, S )
return RightPresentationWithDegrees( mat, ListWithIdenticalEntries( NrRows( mat ), degree ), S );
end );
##
InstallMethod( RightPresentationWithDegrees,
"constructor for homalg graded modules",
[ IsHomalgMatrixOverGradedRingRep, IsInt ],
function( mat, degree )
return RightPresentationWithDegrees( mat, degree, HomalgRing( mat ) );
end );
##
InstallMethod( RightPresentationWithDegrees,
"constructor for homalg graded modules",
[ IsHomalgMatrix, IsHomalgGradedRingRep ],
function( mat, S )
return RightPresentationWithDegrees( mat, ListWithIdenticalEntries( NrRows( mat ), TheZeroElement( DegreeGroup( S ) ) ), S );
end );
##
InstallMethod( RightPresentationWithDegrees,
"constructor for homalg graded modules",
[ IsHomalgMatrixOverGradedRingRep ],
function( mat )
return RightPresentationWithDegrees( mat, HomalgRing( mat ) );
end );
##
InstallMethod( FreeLeftModuleWithDegrees,
"constructor for homalg graded free modules",
[ IsHomalgGradedRingRep, IsList ],
function( S, degrees )
return GradedModule( HomalgFreeLeftModule( Length( degrees ), UnderlyingNonGradedRing( S ) ), degrees, S );
end );
##
InstallMethod( FreeLeftModuleWithDegrees,
"constructor for homalg graded free modules",
[ IsList, IsHomalgGradedRingRep ],
function( degrees, S )
return GradedModule( HomalgFreeLeftModule( Length( degrees ), UnderlyingNonGradedRing( S ) ), degrees, S );
end );
##
InstallMethod( FreeLeftModuleWithDegrees,
"constructor for homalg graded free modules",
[ IsHomalgRing, IsList ],
function( S, degrees )
return LeftPresentationWithDegrees( HomalgZeroMatrix( 0, Length( degrees ), S ), degrees );
end );
##
InstallMethod( FreeLeftModuleWithDegrees,
"constructor for homalg graded free modules",
[ IsInt, IsHomalgRing, IsInt ],
function( rank, S, degree )
return FreeLeftModuleWithDegrees( S, ListWithIdenticalEntries( rank, degree ) );
end );
InstallMethod( FreeLeftModuleWithDegrees,
"constructor for homalg graded free modules",
[ IsInt, IsHomalgRing, IsHomalgElement ],
function( rank, S, degree )
return FreeLeftModuleWithDegrees( S, ListWithIdenticalEntries( rank, degree ) );
end );
##
InstallMethod( FreeLeftModuleWithDegrees,
"constructor for homalg graded free modules",
[ IsInt, IsHomalgRing ],
function( rank, S )
return FreeLeftModuleWithDegrees( rank, S, 0 );
end );
##
InstallMethod( FreeRightModuleWithDegrees,
"constructor for homalg graded free modules",
[ IsHomalgGradedRingRep, IsList ],
function( S, degrees )
return GradedModule( HomalgFreeRightModule( Length( degrees ), UnderlyingNonGradedRing( S ) ), degrees, S );
end );
##
InstallMethod( FreeRightModuleWithDegrees,
"constructor for homalg graded free modules",
[ IsList, IsHomalgGradedRingRep ],
function( degrees, S )
return GradedModule( HomalgFreeRightModule( Length( degrees ), UnderlyingNonGradedRing( S ) ), degrees, S );
end );
##
InstallMethod( FreeRightModuleWithDegrees,
"constructor for homalg graded free modules",
[ IsHomalgRing, IsList ],
function( S, degrees )
return RightPresentationWithDegrees( HomalgZeroMatrix( Length( degrees ), 0, S ), degrees );
end );
##
InstallMethod( FreeRightModuleWithDegrees,
"constructor for homalg graded free modules",
[ IsInt, IsHomalgRing, IsInt ],
function( rank, S, degree )
return FreeRightModuleWithDegrees( S, ListWithIdenticalEntries( rank, degree ) );
end );
InstallMethod( FreeRightModuleWithDegrees,
"constructor for homalg graded free modules",
[ IsInt, IsHomalgRing, IsHomalgElement ],
function( rank, S, degree )
return FreeRightModuleWithDegrees( S, ListWithIdenticalEntries( rank, degree ) );
end );
##
InstallMethod( FreeRightModuleWithDegrees,
"constructor for homalg graded free modules",
[ IsInt, IsHomalgRing ],
function( rank, S )
return FreeRightModuleWithDegrees( rank, S, 0 );
end );
##
InstallMethod( ZeroLeftModule,
"for homalg rings",
[ IsHomalgGradedRingRep ],
function( S )
if IsBound(S!.ZeroLeftModule) then
return S!.ZeroLeftModule;
fi;
return GradedModule( 0 * UnderlyingNonGradedRing( S ), S );
end );
##
InstallMethod( ZeroRightModule,
"for homalg rings",
[ IsHomalgGradedRingRep ],
function( S )
if IsBound(S!.ZeroRightModule) then
return S!.ZeroRightModule;
fi;
return GradedModule( UnderlyingNonGradedRing( S ) * 0, S );
end );
##
InstallMethod( PresentationWithDegrees,
"constructor for homalg graded modules",
[ IsGeneratorsOfFinitelyGeneratedModuleRep,
IsRelationsOfFinitelyPresentedModuleRep,
IsList,
IsHomalgGradedRingRep ],
function( gen, rel, degrees, S )
local module;
module := Presentation( gen, rel );
return GradedModule( module, degrees, S );
end );
##
InstallMethod( PresentationWithDegrees,
"constructor for homalg graded modules",
[ IsGeneratorsOfFinitelyGeneratedModuleRep,
IsRelationsOfFinitelyPresentedModuleRep,
IsInt,
IsHomalgGradedRingRep ],
function( gen, rel, degree, S )
local module, degree_group;
degree_group := DegreeGroup( S );
module := Presentation( gen, rel );
return GradedModule( module, HomalgModuleElement( [ degree ], degree_group ), S );
end );
##
InstallMethod( PresentationWithDegrees,
"constructor for homalg graded modules",
[ IsGeneratorsOfFinitelyGeneratedModuleRep,
IsRelationsOfFinitelyPresentedModuleRep,
IsHomalgElement,
IsHomalgGradedRingRep ],
function( gen, rel, degree, S )
local module;
module := Presentation( gen, rel );
return GradedModule( module, degree, S );
end );
##
InstallMethod( PresentationWithDegrees,
"constructor for homalg graded modules",
[ IsGeneratorsOfFinitelyGeneratedModuleRep,
IsRelationsOfFinitelyPresentedModuleRep,
IsHomalgGradedRingRep ],
function( gen, rel, S )
local module;
module := Presentation( gen, rel );
return GradedModule( module, S );
end );
##
InstallOtherMethod( Zero,
"for homalg modules",
[ IsGradedModuleRep and IsHomalgRightObjectOrMorphismOfRightObjects ], 10001, ## FIXME: is it O.K. to use such a high ranking
function( M )
return ZeroRightModule( HomalgRing( M ) );
end );
##
InstallOtherMethod( Zero,
"for homalg modules",
[ IsGradedModuleRep and IsHomalgLeftObjectOrMorphismOfLeftObjects ], 10001, ## FIXME: is it O.K. to use such a high ranking
function( M )
return ZeroLeftModule( HomalgRing( M ) );
end );
##
InstallMethod( \*,
"constructor for homalg free graded modules",
[ IsInt, IsHomalgGradedRingRep ],
function( rank, S )
if rank = 0 then
return ZeroLeftModule( S );
elif rank = 1 then
return AsLeftObject( S );
elif rank > 1 then
return FreeLeftModuleWithDegrees( rank, S );
fi;
Error( "virtual modules are not supported (yet)\n" );
end );
##
InstallMethod( \*,
"constructor for homalg free graded modules",
[ IsHomalgGradedRingRep, IsInt ],
function( S, rank )
if rank = 0 then
return ZeroRightModule( S );
elif rank = 1 then
return AsRightObject( S );
elif rank > 1 then
return FreeRightModuleWithDegrees( rank, S );
fi;
Error( "virtual modules are not supported (yet)\n" );
end );
##
InstallMethod( AsLeftObject,
"for homalg graded rings",
[ IsHomalgGradedRingRep ],
function( S )
local left;
if IsBound(S!.AsGradedLeftObject) then
return S!.AsGradedLeftObject;
fi;
left := GradedModule( 1 * UnderlyingNonGradedRing( S ), S );
left!.distinguished := true;
left!.not_twisted := true;
S!.AsGradedLeftObject := left;
return left;
end );
##
InstallMethod( AsRightObject,
"for homalg rings",
[ IsHomalgGradedRingRep ],
function( S )
local right;
if IsBound(S!.AsRightObject) then
return S!.AsRightObject;
fi;
right := GradedModule( UnderlyingNonGradedRing( S ) * 1, S );
right!.distinguished := true;
right!.not_twisted := true;
S!.AsRightObject := right;
return right;
end );
##
InstallMethod( POW,
"constructor for homalg graded free modules of rank 1",
[ IsGradedModuleRep, IsInt ],
function( M, twist ) ## M must be either 1 * R or R * 1
local S, G, w1, t, On;
S := HomalgRing( M );
G := DegreeGroup( S );
t := HomalgModuleElement( ListWithIdenticalEntries( NrGenerators( G ), twist ), G );
if IsIdenticalObj( M, 1 * S ) then
if not IsBound( S!.left_twists ) then
S!.left_twists := rec( );
fi;
if not IsBound( S!.left_twists.(String( t )) ) then
On := GradedModule( 1 * UnderlyingNonGradedRing( S ), -t, S );
On!.distinguished := true;
if twist = 0 then
On!.not_twisted := true;
fi;
S!.left_twists.(String( t )) := On;
fi;
return S!.left_twists.(String( t ));
elif IsIdenticalObj( M, S * 1 ) then
if not IsBound( S!.right_twists ) then
S!.right_twists := rec( );
fi;
if not IsBound( S!.right_twists.(String( t )) ) then
On := GradedModule( UnderlyingNonGradedRing( S ) * 1, -t, S );
On!.distinguished := true;
if twist = 0 then
On!.not_twisted := true;
fi;
S!.right_twists.(String( t )) := On;
fi;
return S!.right_twists.(String( t ));
fi;
TryNextMethod( );
end );
##
InstallMethod( POW,
"constructor for homalg graded free modules",
[ IsGradedModuleRep, IsList ],
function( M, twist )
local S, G, twist_set, weights, On;
S := HomalgRing( M );
G := DegreeGroup( S );
twist_set := Set( Flat( twist ) );
weights := GeneratingElements( G );
if Length( twist ) <> NrGenerators( G ) then
Error( "something went terribly wrong\n" );
fi;
twist := HomalgModuleElement( twist, G );
if IsIdenticalObj( M, 1 * S ) then
if not IsBound( S!.left_twists ) then
S!.left_twists := rec( );
fi;
if not IsBound( S!.left_twists.(String( twist )) ) then
On := FreeLeftModuleWithDegrees( S, -twist );
On!.distinguished := true;
if twist_set = [ 0 ] then
On!.not_twisted := true;
fi;
S!.left_twists.(String( twist )) := On;
fi;
return S!.left_twists.(String( twist ));
elif IsIdenticalObj( M, S * 1 ) then
if not IsBound( S!.right_twists ) then
S!.right_twists := rec( );
fi;
if not IsBound( S!.right_twists.(String( twist )) ) then
On := FreeRightModuleWithDegrees( S, -twist );
On!.distinguished := true;
if twist_set = [ 0 ] then
On!.not_twisted := true;
fi;
S!.right_twists.(String( twist )) := On;
fi;
return S!.right_twists.(String( twist ));
fi;
TryNextMethod( );
end );
InstallMethod( POW,
"constructor for homalg graded free modules",
[ IsGradedModuleRep, IsHomalgElement ],
function( M, twist )
local S, G, w1, t, On;
S := HomalgRing( M );
t := twist;
if IsIdenticalObj( M, 1 * S ) then
if not IsBound( S!.left_twists ) then
S!.left_twists := rec( );
fi;
if not IsBound( S!.left_twists.(String( t )) ) then
On := GradedModule( 1 * UnderlyingNonGradedRing( S ), -t, S );
On!.distinguished := true;
if twist = 0 then
On!.not_twisted := true;
fi;
S!.left_twists.(String( t )) := On;
fi;
return S!.left_twists.(String( t ));
elif IsIdenticalObj( M, S * 1 ) then
if not IsBound( S!.right_twists ) then
S!.right_twists := rec( );
fi;
if not IsBound( S!.right_twists.(String( t )) ) then
On := GradedModule( UnderlyingNonGradedRing( S ) * 1, -t, S );
On!.distinguished := true;
if twist = 0 then
On!.not_twisted := true;
fi;
S!.right_twists.(String( t )) := On;
fi;
return S!.right_twists.(String( t ));
fi;
TryNextMethod( );
end );
##
InstallMethod( POW,
"constructor for homalg graded free modules of rank 1",
[ IsHomalgGradedRingRep, IsInt ],
function( S, twist )
return ( 1 * S )^twist;
end );
##
InstallMethod( POW,
"constructor for homalg graded free modules",
[ IsHomalgGradedRingRep, IsList ],
function( S, twist )
return ( 1 * S )^twist;
end );
##
InstallMethod( POW,
"constructor for homalg graded free modules",
[ IsHomalgGradedRingRep, IsHomalgElement ],
function( S, twist )
return ( 1 * S )^twist;
end );
##
InstallMethod( Pullback,
"for a ring map and a graded module",
[ IsHomalgRingMap, IsGradedModuleRep ],
function( phi, M )
local rel, degrees, weights;
rel := MatrixOfRelations( M );
rel := Pullback( phi, rel );
degrees := DegreesOfGenerators( M );
weights := Set( List( ImagesOfRingMap( phi ), Degree ) );
if Length( weights ) <> 1 then
Error( "different weights are not supported yet\n" );
fi;
weights := HomalgElementToInteger( weights[1] );
degrees := List( degrees, i -> HomalgElementToInteger( i ) * weights );
if IsHomalgLeftObjectOrMorphismOfLeftObjects( M ) then
return LeftPresentationWithDegrees( rel, degrees );
else
return RightPresentationWithDegrees( rel, degrees );
fi;
end );
####################################
#
# View, Print, and Display methods:
#
####################################
##
InstallMethod( ViewObj,
"for categories of graded modules",
[ IsCategoryOfGradedModules ],
function( C )
local parity;
if IsCategoryOfFinitelyPresentedGradedLeftModulesRep( C ) then
parity := "left";
else
parity := "right";
fi;
Print( "<The Abelian category of f.p. graded ", parity, " modules over the ring " );
ViewObj( C!.ring );
Print( ">" );
end );
##
InstallMethod( ViewObj,
"for graded homalg modules",
[ IsGradedModuleOrGradedSubmoduleRep ],
function( o )
if IsBound( o!.distinguished ) then
Print( "<The graded" );
else
Print( "<A graded" );
fi;
Print( ViewString( UnderlyingModule( o ) ) );
Print( ">" );
end );
##
InstallMethod( Display,
"for graded homalg modules",
[ IsGradedModuleOrGradedSubmoduleRep ],
function( o )
local deg;
deg := DegreesOfGenerators( o );
if Length( deg ) > 1 then
Display( UnderlyingModule( o ) );
Print( "\n(graded, degrees of generators: ");
ViewObj( deg );
Print( ")\n" );
elif Length( deg ) = 1 then
Display( UnderlyingModule( o ) );
Print( "\n(graded, degree of generator: ");
ViewObj( deg[ 1 ] );
Print( ")\n" );
else
Display( UnderlyingModule( o ) );
Print( "\n(graded)\n" );
fi;
end );