GAP 4.8.9 installation with standard packages -- copy to your CoCalc project to get it
#############################################################################
##
## OtherFunctors.gi Graded Modules package
##
## Copyright 2007-2010, Mohamed Barakat, University of Kaiserslautern
## Markus Lange-Hegermann, RWTH Aachen
##
## Implementation stuff for some other graded functors.
##
#############################################################################
####################################
#
# install global functions/variables:
#
####################################
##
## DirectSum
##
InstallGlobalFunction( _Functor_DirectSum_OnGradedModules, ### defines: DirectSum
function( M, N )
local S, degMN, sum, iotaM, iotaN, piM, piN, natural, phi;
CheckIfTheyLieInTheSameCategory( M, N );
S := HomalgRing( M );
degMN := Concatenation( DegreesOfGenerators( M ), DegreesOfGenerators( N ) );
#degMN := List( degMN, HomalgElementToInteger );
sum := DirectSum( UnderlyingModule( M ), UnderlyingModule( N ) );
# take the non-graded natural transformations
iotaM := MonoOfLeftSummand( sum );
iotaN:= MonoOfRightSummand( sum );
piM := EpiOnLeftFactor( sum );
piN := EpiOnRightFactor( sum );
# create the graded sum with the help of its natural generalized embedding
natural := NaturalGeneralizedEmbedding( sum );
natural := GradedMap( natural, "create", degMN, S );
Assert( 4, IsGeneralizedMorphismWithFullDomain( natural ) );
SetIsGeneralizedMorphismWithFullDomain( natural, true );
sum := Source( natural );
sum!.NaturalGeneralizedEmbedding := natural;
# grade the natural transformations
iotaM := GradedMap( iotaM, M, sum, S );
iotaN := GradedMap( iotaN, N, sum, S );
piM := GradedMap( piM, sum, M, S );
piN := GradedMap( piN, sum, N, S );
Assert( 4, IsMorphism( iotaM ) );
SetIsMorphism( iotaM, true );
Assert( 4, IsMorphism( iotaN ) );
SetIsMorphism( iotaN, true );
Assert( 4, IsMorphism( piM ) );
SetIsMorphism( piM, true );
Assert( 4, IsMorphism( piN ) );
SetIsMorphism( piN, true );
if HasIsModuleOfGlobalSectionsTruncatedAtCertainDegree( M ) and IsInt( IsModuleOfGlobalSectionsTruncatedAtCertainDegree( M ) ) and
HasIsModuleOfGlobalSectionsTruncatedAtCertainDegree( N ) and IsInt( IsModuleOfGlobalSectionsTruncatedAtCertainDegree( N ) ) and
IsModuleOfGlobalSectionsTruncatedAtCertainDegree( N ) = IsModuleOfGlobalSectionsTruncatedAtCertainDegree( M ) then
SetIsModuleOfGlobalSectionsTruncatedAtCertainDegree( sum, IsModuleOfGlobalSectionsTruncatedAtCertainDegree( M ) );
fi;
return SetPropertiesOfDirectSum( [ M, N ], sum, iotaM, iotaN, piM, piN );
end );
InstallValue( Functor_DirectSum_for_graded_modules,
CreateHomalgFunctor(
[ "name", "DirectSum" ],
[ "category", HOMALG_GRADED_MODULES.category ],
[ "operation", "DirectSumOp" ],
[ "natural_transformation1", "EpiOnLeftFactor" ],
[ "natural_transformation2", "EpiOnRightFactor" ],
[ "natural_transformation3", "MonoOfLeftSummand" ],
[ "natural_transformation4", "MonoOfRightSummand" ],
[ "number_of_arguments", 2 ],
[ "1", [ [ "covariant" ], HOMALG_GRADED_MODULES.FunctorOn ] ],
[ "2", [ [ "covariant" ], HOMALG_GRADED_MODULES.FunctorOn ] ],
[ "OnObjects", _Functor_DirectSum_OnGradedModules ],
[ "OnMorphismsHull", _Functor_DirectSum_OnMaps ]
)
);
Functor_DirectSum_for_graded_modules!.ContainerForWeakPointersOnComputedBasicObjects := true;
Functor_DirectSum_for_graded_modules!.ContainerForWeakPointersOnComputedBasicMorphisms := true;
InstallFunctor( Functor_DirectSum_for_graded_modules );
##
## LinearPart
##
## (cf. Eisenbud, Floystad, Schreyer: Sheaf Cohomology and Free Resolutions over Exterior Algebras)
InstallGlobalFunction( _Functor_LinearPart_OnGradedModules, ### defines: LinearPart (object part)
function( M )
return M;
end );
##
InstallGlobalFunction( _Functor_LinearPart_OnGradedMaps, ### defines: LinearPart (morphism part)
function( F_source, F_target, arg_before_pos, phi, arg_behind_pos )
local deg_s, deg_t, S, zero, mat, deg, i, j, result;
if HasIsZero( phi ) and IsZero( phi ) then
return phi;
fi;
deg_s := Set( DegreesOfGenerators( F_source ) );
deg_t := Set( DegreesOfGenerators( F_source ) );
if Length( deg_s ) = 1 and Length( deg_t ) = 1 and deg_s[1] = deg_t[1] - 1 then
return phi;
fi;
S := HomalgRing( phi );
zero := Zero( S );
mat := ShallowCopy( MatrixOfMap( phi ) );
SetIsMutableMatrix( mat, true );
deg := DegreesOfEntries( mat );
if not ( deg <> [] and IsHomogeneousList( deg ) and IsHomogeneousList( deg[1] ) and IsInt( deg[1][1] ) ) then
Error( "Multigraduations are not yet supported" );
fi;
for i in [ 1 .. Length( deg ) ] do
for j in [ 1 .. Length( deg[1] ) ] do
if deg[i][j] <> -1 then
SetMatElm( mat, i, j, zero );
fi;
od;
od;
MakeImmutable( mat );
result := GradedMap( mat, F_source, F_target );
if HasIsMorphism( phi ) and IsMorphism( phi ) then
Assert( 4, IsMorphism( result ) );
SetIsMorphism( result, true );
fi;
return result;
end );
InstallValue( Functor_LinearPart_ForGradedModules,
CreateHomalgFunctor(
[ "name", "LinearPart" ],
[ "category", HOMALG_GRADED_MODULES.category ],
[ "operation", "LinearPart" ],
[ "number_of_arguments", 1 ],
[ "1", [ [ "covariant", "left adjoint", "distinguished" ], HOMALG_GRADED_MODULES.FunctorOn ] ],
[ "OnObjects", _Functor_LinearPart_OnGradedModules ],
[ "OnMorphisms", _Functor_LinearPart_OnGradedMaps ]
)
);
Functor_LinearPart_ForGradedModules!.ContainerForWeakPointersOnComputedBasicObjects := true;
Functor_LinearPart_ForGradedModules!.ContainerForWeakPointersOnComputedBasicMorphisms := true;
InstallFunctor( Functor_LinearPart_ForGradedModules );
##
## ProjectionToDirectSummandOfGradedFreeModuleGeneratedByACertainDegree
##
InstallGlobalFunction( _Functor_ProjectionToDirectSummandOfGradedFreeModuleGeneratedByACertainDegree_OnGradedModules,
function( d, M )
local S, deg, l, mat, pi;
S := HomalgRing( M );
if NrRelations( M ) <> 0 then
Error( "This functor only accepts graded free modules" );
fi;
deg := List( DegreesOfGenerators( M ), HomalgElementToInteger );
l := Filtered( [ 1 .. Length( deg ) ], a -> deg[a] = d );
if IsHomalgLeftObjectOrMorphismOfLeftObjects( M ) then
mat := CertainRows( HomalgIdentityMatrix( NrGenerators( M ), S ), l );
else
mat := CertainColumns( HomalgIdentityMatrix( NrGenerators( M ), S ), l );
fi;
pi := GradedMap( mat, ListWithIdenticalEntries( Length( l ), d ), M );
Assert( 4, IsMorphism( pi ) );
SetIsMorphism( pi, true );
if l = [ 1 .. Length( deg ) ] then
Assert( 3, IsEpimorphism( pi ) );
SetIsEpimorphism( pi, true );
fi;
Assert( 3, IsMonomorphism( pi ) );
SetIsMonomorphism( pi, true );
return pi;
end );
InstallValue( Functor_ProjectionToDirectSummandOfGradedFreeModuleGeneratedByACertainDegree_ForGradedModules,
CreateHomalgFunctor(
[ "name", "ProjectionToDirectSummandOfGradedFreeModuleGeneratedByACertainDegree" ],
[ "category", HOMALG_GRADED_MODULES.category ],
[ "operation", "ProjectionToDirectSummandOfGradedFreeModuleGeneratedByACertainDegree" ],
[ "number_of_arguments", 1 ],
[ "0", [ IsInt ] ],
[ "1", [ [ "covariant", "left adjoint", "distinguished" ], HOMALG_GRADED_MODULES.FunctorOn ] ],
[ "OnObjects", _Functor_ProjectionToDirectSummandOfGradedFreeModuleGeneratedByACertainDegree_OnGradedModules ]
)
);
Functor_ProjectionToDirectSummandOfGradedFreeModuleGeneratedByACertainDegree_ForGradedModules!.ContainerForWeakPointersOnComputedBasicObjects := true;
Functor_ProjectionToDirectSummandOfGradedFreeModuleGeneratedByACertainDegree_ForGradedModules!.ContainerForWeakPointersOnComputedBasicMorphisms := true;
InstallFunctor( Functor_ProjectionToDirectSummandOfGradedFreeModuleGeneratedByACertainDegree_ForGradedModules );
InstallMethod( ProjectionToDirectSummandOfGradedFreeModuleGeneratedByACertainDegree,
"for homalg elements",
[ IsHomalgElement, IsHomalgGradedModule ],
function( d, M )
return ProjectionToDirectSummandOfGradedFreeModuleGeneratedByACertainDegree( HomalgElementToInteger( d ), M );
end );
## DirectSummandOfGradedFreeModuleGeneratedByACertainDegree
InstallMethod( DirectSummandOfGradedFreeModuleGeneratedByACertainDegree,
"for linear complexes over the exterior algebra",
[ IsInt, IsGradedModuleRep ],
function( m, M )
local pi, N;
pi := ProjectionToDirectSummandOfGradedFreeModuleGeneratedByACertainDegree( m, M );
N := Source( pi );
return N;
end );
InstallMethod( DirectSummandOfGradedFreeModuleGeneratedByACertainDegree,
"for linear complexes over the exterior algebra",
[ IsInt, IsInt, IsMapOfGradedModulesRep ],
function( m, n, phi )
local pi1, pi2, pi2_minus_1;
pi1 := ProjectionToDirectSummandOfGradedFreeModuleGeneratedByACertainDegree( m, Source( phi ) );
pi2 := ProjectionToDirectSummandOfGradedFreeModuleGeneratedByACertainDegree( n, Range( phi ) );
# PostInverse of a SubidentityMatrix is a GAP-computation
pi2_minus_1 := PostInverse( pi2 );
return PreCompose( PreCompose( pi1, phi ), pi2_minus_1 );
end );
InstallMethod( DirectSummandOfGradedFreeModuleGeneratedByACertainDegree,
"for homalg elements",
[ IsHomalgElement, IsHomalgGradedModule ],
function( d, M )
return DirectSummandOfGradedFreeModuleGeneratedByACertainDegree( HomalgElementToInteger( d ), M );
end );
InstallMethod( DirectSummandOfGradedFreeModuleGeneratedByACertainDegree,
"for homalg elements",
[ IsHomalgElement, IsHomalgElement, IsHomalgGradedMap ],
function( d1, d2, M )
return DirectSummandOfGradedFreeModuleGeneratedByACertainDegree( HomalgElementToInteger( d1 ), HomalgElementToInteger( d2 ), M );
end );
##
## GeneralizedLinearStrand
##
InstallGlobalFunction( _Functor_GeneralizedLinearStrand_OnFreeCocomplexes,
function( f, T )
local i, alpha, alpha2, T2;
for i in MorphismDegreesOfComplex( T ) do
alpha := CertainMorphism( T, i );
alpha2 := DirectSummandOfGradedFreeModuleGeneratedByACertainDegree( f( i ), f( i + 1 ), alpha );
if not IsBound( T2 ) then
T2 := HomalgCocomplex( alpha2, i );
else
Add( T2, alpha2 );
fi;
od;
Assert( 3, IsComplex( T2 ) );
SetIsComplex( T2, true );
return T2;
end );
InstallGlobalFunction( _Functor_GeneralizedLinearStrand_OnCochainMaps,
function( F_source, F_target, arg_before_pos, phi, arg_behind_pos )
local f, i, alpha, f_i, alpha2, psi;
f := arg_before_pos[1];
for i in DegreesOfChainMorphism( phi ) do
alpha := CertainMorphism( phi, i );
f_i := f( i );
alpha2 := DirectSummandOfGradedFreeModuleGeneratedByACertainDegree( f_i, f_i, alpha );
if not IsBound( psi ) then
psi := HomalgChainMorphism( alpha2, F_source, F_target, i );
else
Add( psi, alpha2 );
fi;
od;
return psi;
end );
InstallValue( Functor_GeneralizedLinearStrand_ForGradedModules,
CreateHomalgFunctor(
[ "name", "GeneralizedLinearStrand" ],
[ "category", HOMALG_GRADED_MODULES.category ],
[ "operation", "GeneralizedLinearStrand" ],
[ "number_of_arguments", 1 ],
[ "0", [ IsFunction ] ],
[ "1", [ [ "covariant", "left adjoint", "distinguished" ], [ IsHomalgComplex, IsHomalgChainMorphism ] ] ],
[ "OnObjects", _Functor_GeneralizedLinearStrand_OnFreeCocomplexes ],
[ "OnMorphisms", _Functor_GeneralizedLinearStrand_OnCochainMaps ]
)
);
Functor_GeneralizedLinearStrand_ForGradedModules!.ContainerForWeakPointersOnComputedBasicObjects := true;
Functor_GeneralizedLinearStrand_ForGradedModules!.ContainerForWeakPointersOnComputedBasicMorphisms := true;
InstallFunctorOnObjects( Functor_GeneralizedLinearStrand_ForGradedModules );
InstallFunctorOnMorphisms( Functor_GeneralizedLinearStrand_ForGradedModules );
##
## LinearStrand
##
# returns the subcomplex of a free complex,
# where cohomological degree + shift = internal degree
InstallGlobalFunction( _Functor_LinearStrand_OnFreeCocomplexes,
function( shift, T )
return GeneralizedLinearStrand( function( i ) return i + shift; end, T );
end );
InstallGlobalFunction( _Functor_LinearStrand_OnCochainMaps,
function( F_source, F_target, arg_before_pos, phi, arg_behind_pos )
return _Functor_GeneralizedLinearStrand_OnCochainMaps( F_source, F_target, [ function( i ) return i + arg_before_pos[1]; end ], phi, arg_behind_pos );
end );
InstallValue( Functor_LinearStrand_ForGradedModules,
CreateHomalgFunctor(
[ "name", "LinearStrand" ],
[ "category", HOMALG_GRADED_MODULES.category ],
[ "operation", "LinearStrand" ],
[ "number_of_arguments", 1 ],
[ "0", [ IsInt ] ],
[ "1", [ [ "covariant", "left adjoint", "distinguished" ], [ IsHomalgComplex, IsHomalgChainMorphism ] ] ],
[ "OnObjects", _Functor_LinearStrand_OnFreeCocomplexes ],
[ "OnMorphisms", _Functor_LinearStrand_OnCochainMaps ]
)
);
Functor_LinearStrand_ForGradedModules!.ContainerForWeakPointersOnComputedBasicObjects := true;
Functor_LinearStrand_ForGradedModules!.ContainerForWeakPointersOnComputedBasicMorphisms := true;
# InstallFunctor( Functor_LinearStrand_ForGradedModules );
InstallFunctorOnObjects( Functor_LinearStrand_ForGradedModules );
InstallFunctorOnMorphisms( Functor_LinearStrand_ForGradedModules );
InstallMethod( LinearStrand,
"for homalg elements",
[ IsHomalgElement, IsHomalgMorphism ],
function( d, M )
return LinearStrand( HomalgElementToInteger( d ), M );
end );
##
## ConstantStrand
##
InstallGlobalFunction( _Functor_ConstantStrand_OnFreeCocomplexes,
function( d, T )
return GeneralizedLinearStrand( function( i ) return d; end, T );
end );
InstallGlobalFunction( _Functor_ConstantStrand_OnCochainMaps,
function( F_source, F_target, arg_before_pos, phi, arg_behind_pos )
return _Functor_GeneralizedLinearStrand_OnCochainMaps( F_source, F_target, [ function( i ) return arg_before_pos[1]; end ], phi, arg_behind_pos );
end );
InstallValue( Functor_ConstantStrand_ForGradedModules,
CreateHomalgFunctor(
[ "name", "ConstantStrand" ],
[ "category", HOMALG_GRADED_MODULES.category ],
[ "operation", "ConstantStrand" ],
[ "number_of_arguments", 1 ],
[ "0", [ IsInt ] ],
[ "1", [ [ "covariant", "left adjoint", "distinguished" ], [ IsHomalgComplex, IsHomalgChainMorphism ] ] ],
[ "OnObjects", _Functor_ConstantStrand_OnFreeCocomplexes ],
[ "OnMorphisms", _Functor_ConstantStrand_OnCochainMaps ]
)
);
Functor_ConstantStrand_ForGradedModules!.ContainerForWeakPointersOnComputedBasicObjects := true;
Functor_ConstantStrand_ForGradedModules!.ContainerForWeakPointersOnComputedBasicMorphisms := true;
# InstallFunctor( Functor_ConstantStrand_ForGradedModules );
InstallFunctorOnObjects( Functor_ConstantStrand_ForGradedModules );
InstallFunctorOnMorphisms( Functor_ConstantStrand_ForGradedModules );
InstallMethod( ConstantStrand,
"for homalg elements",
[ IsHomalgElement, IsHomalgMorphism ],
function( d, M )
return ConstantStrand( HomalgElementToInteger( d ), M );
end );
##
## LinearFreeComplexOverExteriorAlgebraToModule
##
# This functor creates a module from a linear complex over the exterior algebra
# (and a module map from a degree 0 cochain map).
# first we introduce two helper functions
##
# Takes a linear map phi over a graded ring with indeterminates x_i
# write phi = sum_i x_i*phi_i
# returns (for left objects) the matrix
# <phi_0,
# phi_1
#
# phi_n>
# and a map with matrix
# <x_0*I,
# x_1*I
#
# x_n*I>
# where I is the identity matrix of size Source( phi ), i.e. both matrices have the same number of rows
# later we will use these two maps to produce a pushout.
InstallMethod( SplitLinearMapAccordingToIndeterminates,
"for linear complexes over the exterior algebra",
[ IsMapOfGradedModulesRep ],
function( phi )
local E, n, S, K, l_var, left, map_E, map_S, t, F, var_s_morphism, k, alpha, alpha2, matrix_of_extension, c, extension_matrix,l_test;
E := HomalgRing( phi );
n := Length( Indeterminates( E ) );
S := KoszulDualRing( E );
K := CoefficientsRing( E );
Assert( 5, IsIdenticalObj( K, CoefficientsRing( S ) ) );
l_var := Length( Indeterminates( S ) );
left := IsHomalgLeftObjectOrMorphismOfLeftObjects( phi );
if left then
map_E := MaximalIdealAsLeftMorphism( E );
map_S := MaximalIdealAsLeftMorphism( S );
else
map_E := MaximalIdealAsRightMorphism( E );
map_S := MaximalIdealAsRightMorphism( S );
fi;
t := NrGenerators( Range( phi ) );
if left then
if DegreesOfGenerators( Range( phi ) ) <> [ ] then
F := FreeLeftModuleWithDegrees( NrGenerators( Source( phi ) ), S, DegreesOfGenerators( Range( phi ) )[1] - 1 - n );
else
F := FreeLeftModuleWithDegrees( NrGenerators( Source( phi ) ), S, 0 );
fi;
var_s_morphism := - TensorProduct( map_S, F );
else
if DegreesOfGenerators( Range( phi ) ) <> [ ] then
F := FreeRightModuleWithDegrees( NrGenerators( Source( phi ) ), S, DegreesOfGenerators( Range( phi ) )[1] - 1 - n );
else
F := FreeRightModuleWithDegrees( NrGenerators( Source( phi ) ), S, 0 );
fi;
var_s_morphism := - TensorProduct( map_S, F );
fi;
alpha := TensorProduct( map_E, Range( phi ) );
alpha2 := GradedMap( HomalgIdentityMatrix( NrGenerators( Range( phi ) ), HomalgRing( phi ) ), Range( alpha ), Range( phi ) );
alpha := PreCompose( alpha, alpha2 );
matrix_of_extension := phi / alpha;
matrix_of_extension := K * MatrixOfMap( matrix_of_extension );
if left then
extension_matrix := HomalgZeroMatrix( 0, NrGenerators( Range( phi ) ), K );
for k in [ 1 .. l_var ] do
c := CertainColumns( matrix_of_extension, [ (k-1) * t + 1 .. k * t ] );
extension_matrix := UnionOfRows( extension_matrix, c );
od;
else
extension_matrix := HomalgZeroMatrix( NrGenerators( Range( phi ) ), 0, K );
for k in [ 1 .. l_var ] do
c := CertainRows( matrix_of_extension, [ (k-1) * t + 1 .. k * t ] );
extension_matrix := UnionOfColumns( extension_matrix, c );
od;
fi;
return [ extension_matrix, var_s_morphism ];
end );
##
# Takes a linear map phi over a graded ring with indeterminates x_i
# write phi = sum_i x_i*phi_i
# creates (for left objects) the maps var_s_morphism and extension_map with matrices
# <x_0*I,
# x_1*I
#
# x_n*I>
# and
# <phi_0,
# phi_1
#
# phi_n>
# where I is the identity matrix of size Source( phi ),
# i.e. both matrices have the same number of rows and (accordingly) both maps the same source.
# The target of var_s_morphism is newly created
# and of extension_map is taken to be the source of the second argument psi.
# Then a base change is performed on source and target of extension_map, to have this
# map (with a matrix with entries over the ground field) in a simple shape for later use.
# In this process, a complement alpha of the image of extension_map is created (also for later use)
# we return [ var_s_morphism, extension_map, alpha ]
InstallMethod( ExtensionMapsFromExteriorComplex,
"for linear complexes over the exterior algebra",
[ IsMapOfGradedModulesRep, IsMapOfGradedModulesRep ],
function( phi, psi )
local N, E, S, K, extension_matrix, var_s_morphism, M, extension_map, alpha,l_test;
N := Source( psi );
E := HomalgRing( phi );
S := KoszulDualRing( E );
extension_matrix := SplitLinearMapAccordingToIndeterminates( phi );
var_s_morphism := extension_matrix[2];
M := Source( var_s_morphism );
extension_matrix := extension_matrix[1];
# compute over the free module instead of N, because it is faster
extension_map := GradedMap( S * extension_matrix, M, N, S );
if HasIsMorphism( phi ) and IsMorphism( phi ) then
Assert( 4, IsMorphism( extension_map ) );
SetIsMorphism( extension_map, true );
fi;
# This command changes the presentation of Source and Range of extension_map.
# In particular, N is changes, which was used before
# the change is due to the wish of a much faster ByASmallerPresentation
NormalizeGradedMorphism( extension_map );
alpha := extension_map!.complement_of_image;
return [ var_s_morphism, extension_map, alpha ];
end );
##
# This method creates a module from a single linear map over the exterior algebra.
# The idea behind this is, that the submodule of cohomology module generated by a certain degree
# above the regularity can be constructed from this single map phi.
# Let e_i be the generators of the exterior algebra and x_i the generators of the symmetric algebra.
# Write phi=sum e_i*phi_i, then the phi_i are matrices over the ground field.
# (Left modules) Let extension_map be the map with stacked matrix
# <phi_0,
# phi_1
#
# phi_n>
# and var_s_morphism the map with stacked matrix
# <x_0*I,
# x_1*I
#
# x_n*I>
# where I is the identity matrix of size Source( phi ).
# (both maps have the same source)
# Then cokernel( kernel( extension_map ) * var_s_morphism ) the the wanted module.
InstallMethod( ModuleFromExtensionMap,
"for linear complexes over the exterior algebra",
[ IsMapOfGradedModulesRep ],
function( phi )
local E, S, K, extension_matrix, var_s_morphism, M, ar, N, extension_map, result;
E := HomalgRing( phi );
S := KoszulDualRing( E );
if IsZero( phi ) then
if IsHomalgLeftObjectOrMorphismOfLeftObjects( phi ) then
return 0*S;
else
return S*0;
fi;
fi;
extension_matrix := SplitLinearMapAccordingToIndeterminates( phi );
var_s_morphism := extension_matrix[2];
M := Source( var_s_morphism );
extension_matrix := extension_matrix[1];
ar := [ NrGenerators( Range( phi ) ), S, DegreesOfGenerators( M )[1] ];
if IsHomalgLeftObjectOrMorphismOfLeftObjects( M ) then
N := CallFuncList( FreeLeftModuleWithDegrees, ar );
else
N := CallFuncList( FreeRightModuleWithDegrees, ar );
fi;
extension_map := GradedMap( S * extension_matrix, M, N, S );
if HasIsMorphism( phi ) and IsMorphism( phi ) then
Assert( 4, IsMorphism( extension_map ) );
SetIsMorphism( extension_map, true );
fi;
result := Cokernel( PreCompose( KernelEmb( extension_map ), var_s_morphism ) );
return result;
end );
InstallMethod( CompareArgumentsForLinearFreeComplexOverExteriorAlgebraToModuleOnObjects,
"for argument lists of the functor LinearFreeComplexOverExteriorAlgebraToModule on objects",
[ IsList, IsList ],
function( l_old, l_new )
local lower_bound1, lower_bound2;
lower_bound1 := Minimum( ObjectDegreesOfComplex( l_old[2] ) );
lower_bound2 := Minimum( ObjectDegreesOfComplex( l_new[2] ) );
return lower_bound1 = lower_bound2
and l_old[1] <= l_new[1]
and IsIdenticalObj(
CertainMorphism( l_old[2], lower_bound1 ),
CertainMorphism( l_new[2], lower_bound1 )
);
end );
InstallGlobalFunction( _Functor_LinearFreeComplexOverExteriorAlgebraToModule_OnGradedModules,
function( reg_sheaf, lin_tate )
local i, deg, A, n, S, k, result, EmbeddingsOfHigherDegrees, RecursiveEmbeddingsOfHigherDegrees, lower_bound, jj, j, tate_morphism, psi,
extension_map, var_s_morphism, T, T2, l, T2b, V1, V2, V1_iso_V2, isos, source_emb, map, certain_deg, t1, t2, phi, chain_phi, pos, Rresult, iso;
if not reg_sheaf < HomalgElementToInteger( HighestDegree( lin_tate ) ) then
Error( "the given regularity is larger than the number of morphisms in the complex" );
fi;
if not IsCocomplexOfFinitelyPresentedObjectsRep( lin_tate ) then
Error( "expected a _co_complex over the exterior algebra" );
fi;
for i in ObjectDegreesOfComplex( lin_tate ) do
deg := List( DegreesOfGenerators( CertainObject( lin_tate, i ) ), HomalgElementToInteger );
if not Length( Set( deg ) ) <= 1 then
Error( "for every cohomological degree in the cocomplex expected the degrees of generators of the object to be equal to each other" );
fi;
# if not ( deg = [] or deg[1] = i ) then
# Error( "expected the degrees of generators in the cocomplex to be equal to the cohomological degree" );
# fi;
od;
A := HomalgRing( lin_tate );
n:= Length( Indeterminates( A ) );
S := KoszulDualRing( A );
k := CoefficientsRing( A );
result := ModuleFromExtensionMap( CertainMorphism( lin_tate, reg_sheaf ) );
# each new step constructs a new StdM as pushout of
# extension_map*LeftPushoutMorphism and var_s_morphism.
# These maps are created from a modified Tate resolution.
#
# StdM = new (+) old Range( var_s_morphism )
# /\ /\
# | |
# | |
# | LeftPushoutMorphism | var_s_morphism
# | |
# | extension_map |
# new <-------------------------------- Source( var_s_morphism ) = Source( extension_map )
result := Pushout( TheZeroMorphism( Zero( result ), result ), TheZeroMorphism( Zero( result ), Zero( result ) ) );
EmbeddingsOfHigherDegrees := rec( (String( reg_sheaf )) := TheIdentityMorphism( result ) );
RecursiveEmbeddingsOfHigherDegrees := rec( );
lower_bound := Minimum( ObjectDegreesOfComplex( lin_tate ) );
for jj in [ lower_bound + 1 .. reg_sheaf ] do
j := reg_sheaf + lower_bound - jj;
# create the extension map from the tate-resolution
# e.g. ( e_0, e_1, 3*e_0+2*e_1 ) leads to / 1, 0, 3 \
# \ 0, 1, 2 /
# but the gaussian algorithm is applied to the latter matrix (both to rows an columns) for easier simplification
tate_morphism := CertainMorphism( lin_tate, j );
psi := LeftPushoutMorphism( result );
extension_map := ExtensionMapsFromExteriorComplex( tate_morphism, psi );
var_s_morphism := extension_map[1];
T := extension_map[3];
extension_map := extension_map[2];
# this line computes the global sections module
result := Pushout( var_s_morphism, PreCompose( extension_map, psi ) );
# This direct sum will be used in different contextes of the summands.
# We need to ensure that we speak about the same object in each of these cases.
# Thus, we force homalg to return this object regardless of the context of the summands.
Range( NaturalGeneralizedEmbedding( result ) )!.IgnoreContextOfArgumentsOfFunctor := true;
UnderlyingModule( Range( NaturalGeneralizedEmbedding( result ) ) )!.IgnoreContextOfArgumentsOfFunctor := true;
# the "old" ModuleOfGlobalSections (the one generated in larger degree) embeds into the new one
Assert( 3, IsMonomorphism( RightPushoutMorphism( result ) ) );
SetIsMonomorphism( RightPushoutMorphism( result ), true );
# the following block simplifies the ModuleOfGlobalSections much faster than ByASmallerPresentation could.
# We know in advance, which generators we need to generate result. These are
# 1) the new generators, i.e. Image( var_s_morphism ),
# 2) a basis of Cokernel( extension_map ) (which is free), i.e. Image( T ),
# 3) and the older generators, which have not been made superfluous, i.e. CertainGenerators( result, k ).
# We build the CoproductMorphism T2 of these three morphisms and its image is a smaller presentation of result
T := PreCompose( PreCompose( T, psi ), RightPushoutMorphism( result ) );
T2 := CoproductMorphism( LeftPushoutMorphism( result ), T );
l := PositionProperty( DegreesOfGenerators( result ), function( a ) return a > j+1; end );
if l <> fail then
l := [ l .. NrGenerators( result ) ];
T2b := GradedMap( CertainGenerators( result, l ), "free", result );
Assert( 4, IsMorphism( T2b ) );
SetIsMorphism( T2b, true );
T2 := CoproductMorphism( T2, T2b );
fi;
Assert( 3, IsMorphism( T2 ) );
SetIsMorphism( T2, true );
Assert( 3, IsEpimorphism( T2 ) );
SetIsEpimorphism( T2, true );
PushPresentationByIsomorphism( NaturalGeneralizedEmbedding( ImageObject( T2 ) ) );
# try to keep the information about higher modules
EmbeddingsOfHigherDegrees!.(String(j)) := TheIdentityMorphism( result );
for l in [ j + 1 .. reg_sheaf ] do
EmbeddingsOfHigherDegrees!.(String(l)) := PreCompose( EmbeddingsOfHigherDegrees!.(String(l)), RightPushoutMorphism( result ) );
od;
RecursiveEmbeddingsOfHigherDegrees!.(String(j+1)) := RightPushoutMorphism( result );
od;
# end core procedure
# Now set some properties of the module collected during the computation.
# Most of these are needed in the morphism part of this functor.
for l in [ lower_bound .. reg_sheaf ] do
if fail = GetFunctorObjCachedValue( Functor_TruncatedSubmodule_ForGradedModules, [ l, result ] ) then
SetFunctorObjCachedValue( Functor_TruncatedSubmodule_ForGradedModules, [ l, result ], FullSubobject( Source( EmbeddingsOfHigherDegrees!.(String(l)) ) ) );
SetNaturalTransformation( Functor_TruncatedSubmodule_ForGradedModules, [ l, result ], "TruncatedSubmoduleEmbed", EmbeddingsOfHigherDegrees!.(String(l)) );
fi;
od;
for l in [ lower_bound .. reg_sheaf - 1 ] do
if fail = GetFunctorObjCachedValue( Functor_TruncatedSubmoduleRecursiveEmbed_ForGradedModules, [ l, result ] ) then
SetFunctorObjCachedValue( Functor_TruncatedSubmoduleRecursiveEmbed_ForGradedModules, [ l, result ], RecursiveEmbeddingsOfHigherDegrees!.(String(l+1)) );
fi;
od;
isos := rec( );
for l in [ lower_bound .. reg_sheaf ] do
V1 := HomogeneousPartOverCoefficientsRing( l, CertainObject( lin_tate, l ) );
# modules of global sections truncated at different degrees do not share their V2 on purpose.
V1_iso_V2 := GradedMap( HomalgIdentityMatrix( NrGenerators( V1 ), k ), "free", V1 );
Assert( 4, IsMorphism( V1_iso_V2 ) );
SetIsMorphism( V1_iso_V2, true );
Assert( 4, IsIsomorphism( V1_iso_V2 ) );
SetIsIsomorphism( V1_iso_V2, true );
UpdateObjectsByMorphism( V1_iso_V2 );
isos.(l) := V1_iso_V2;
V2 := Source( V1_iso_V2 );
SetMapFromHomogenousPartOverSymmetricAlgebraToHomogeneousPartOverExteriorAlgebra( V2, V1_iso_V2 );
SetMapFromHomogenousPartOverExteriorAlgebraToHomogeneousPartOverSymmetricAlgebra( V1, V1_iso_V2 );
source_emb := Source( EmbeddingsOfHigherDegrees!.(String(l)) );
deg := List( DegreesOfGenerators( source_emb ), HomalgElementToInteger );
certain_deg := Filtered( [ 1 .. Length( deg ) ], a -> deg[a] = l );
if IsHomalgLeftObjectOrMorphismOfLeftObjects( result ) then
map := GradedMap( CertainRows( HomalgIdentityMatrix( NrGenerators( source_emb ), S ), certain_deg ), S * V2, source_emb );
else
map := GradedMap( CertainColumns( HomalgIdentityMatrix( NrGenerators( source_emb ), S ), certain_deg ), S * V2, source_emb );
fi;
Assert( 4, IsMorphism( map ) );
SetIsMorphism( map, true );
map := PreCompose( map, EmbeddingsOfHigherDegrees!.(String(l)) );
if fail = GetFunctorObjCachedValue( Functor_HomogeneousPartOverCoefficientsRing_ForGradedModules, [ l, result ] ) then
SetFunctorObjCachedValue( Functor_HomogeneousPartOverCoefficientsRing_ForGradedModules, [ l, result ], V2 );
fi;
SetNaturalTransformation(
Functor_HomogeneousPartOverCoefficientsRing_ForGradedModules,
[ l, result ],
"EmbeddingOfSubmoduleGeneratedByHomogeneousPart",
map
);
if l = lower_bound then
SetEmbeddingOfSubmoduleGeneratedByHomogeneousPart( V2, map );
fi;
od;
# set the koszul-right-adjoint matrices!
pos := PositionOfTheDefaultPresentation( result );
if not IsBound( result!.RepresentationMatricesOfKoszulId ) then
result!.RepresentationMatricesOfKoszulId := rec( );
fi;
if not IsBound( result!.RepresentationMatricesOfKoszulId!.(pos) ) then
result!.RepresentationMatricesOfKoszulId!.(pos) := rec( );
fi;
for l in MorphismDegreesOfComplex( lin_tate ) do
result!.RepresentationMatricesOfKoszulId!.(pos)!.(l) := MatrixOfMap( CertainMorphism( lin_tate, l ) );
od;
# this is now rather cheap, mostly the objects have to be created
Rresult := KoszulRightAdjoint( result, lower_bound, reg_sheaf );
for l in [ lower_bound .. reg_sheaf ] do
t1 := CertainObject( lin_tate, l );
t2 := CertainObject( Rresult, l ); # = omega_A * V2;
V1_iso_V2 := isos.(l);
V1 := Source( V1_iso_V2 );
iso := A^(-n) * ( A * V1_iso_V2^(-1) );
phi := GradedMap( HomalgIdentityMatrix( NrGenerators( t1 ), A ), t1, Source( iso ) );
Assert( 4, IsMorphism( phi ) );
SetIsMorphism( phi, true );
Assert( 4, IsIsomorphism( phi ) );
SetIsIsomorphism( phi, true );
UpdateObjectsByMorphism( phi );
phi := PreCompose( phi, iso );
phi := (-1)^l * phi;
if not IsBound( chain_phi ) then
chain_phi := HomalgChainMorphism( phi, lin_tate, Rresult, l );
else
Add( chain_phi, phi );
fi;
od;
SetNaturalMapFromExteriorComplexToRightAdjoint( lin_tate, chain_phi );
return result;
end );
InstallMethod( ConstructMorphismFromLayers,
"for argument lists of the functor LinearFreeComplexOverExteriorAlgebraToModule on objects",
[ IsGradedModuleRep, IsGradedModuleRep, IsHomalgChainMorphism ],
function( F_source, F_target, psi )
local reg, phi, lower_bound, jj, j, emb_new_source, emb_new_target, emb_old_source, emb_old_target, epi_source, epi_target, phi_new;
reg := HomalgElementToInteger( HighestDegree( psi ) );
phi := HighestDegreeMorphism( psi );
lower_bound := HomalgElementToInteger( LowestDegree( psi ) );
if reg = lower_bound then
phi := CompleteKernelSquare(
SubmoduleGeneratedByHomogeneousPart( lower_bound, F_source )!.map_having_subobject_as_its_image,
phi,
SubmoduleGeneratedByHomogeneousPart( lower_bound, F_target )!.map_having_subobject_as_its_image );
fi;
for jj in [ lower_bound + 1 .. reg ] do
j := reg + lower_bound - jj;
if j = reg - 1 then
emb_old_source := SubmoduleGeneratedByHomogeneousPartEmbed( j + 1, F_source ) / TruncatedSubmoduleEmbed( j, F_source );
emb_old_target := SubmoduleGeneratedByHomogeneousPartEmbed( j + 1, F_target ) / TruncatedSubmoduleEmbed( j, F_target );
else
emb_old_source := TruncatedSubmoduleRecursiveEmbed( j, F_source );
emb_old_target := TruncatedSubmoduleRecursiveEmbed( j, F_target );
fi;
emb_new_source := SubmoduleGeneratedByHomogeneousPartEmbed( j, F_source ) / TruncatedSubmoduleEmbed( j, F_source );
emb_new_target := SubmoduleGeneratedByHomogeneousPartEmbed( j, F_target ) / TruncatedSubmoduleEmbed( j, F_target );
epi_source := CoproductMorphism( emb_new_source, -emb_old_source );
epi_target := CoproductMorphism( emb_new_target, -emb_old_target );
Assert( 3, IsMorphism( epi_source ) );
SetIsMorphism( epi_source, true );
Assert( 3, IsEpimorphism( epi_source ) );
SetIsEpimorphism( epi_source, true );
Assert( 3, IsMorphism( epi_target ) );
SetIsMorphism( epi_target, true );
Assert( 3, IsEpimorphism( epi_target ) );
SetIsEpimorphism( epi_target, true );
phi_new := CertainMorphism( psi, j );
# We should have
# IsZero( PreCompose( PreCompose( KernelEmb( emb_new_source ), phi_new ), emb_new_target ) )
# to call CompleteKernelSquare. But since emb_new_source maps from a free module and not from
# SubmoduleGeneratedByHomogeneousPart( j, F_source ) the kernel is too big.
# We could compute the relations in Source( emb_new_source ). This would imply a costly syzygy
# computation, which i would like to circumwent. So CompleteKernelSquare does not yield a
# well defined result, but the final result is well defined
Assert( 5, IsZero( PreCompose( PreCompose( KernelEmb( emb_new_source ), phi_new ), emb_new_target ) ) );
phi := DiagonalMorphism( phi_new, phi );
Assert( 5, IsZero( PreCompose( PreCompose( KernelEmb( epi_source ), phi), epi_target ) ) );
phi := CompleteKernelSquare( epi_source, phi, epi_target );
od;
return phi;
end );
InstallMethod( HomogeneousPartOfCohomologicalDegreeOverCoefficientsRing,
"for homalg cocomplexes over graded rings",
[ IsHomalgComplex, IsInt, IsInt ],
function( C, min, max )
local HC, j;
HC := HomalgCocomplex( HomogeneousPartOverCoefficientsRing( min, CertainObject( C, min ) ), min );
for j in [ min + 1 .. max ] do
Add( HC, HomogeneousPartOverCoefficientsRing( j, CertainObject( C, j ) ) );
od;
return HC;
end );
InstallMethod( HomogeneousPartOfCohomologicalDegreeOverCoefficientsRing,
"for homalg cocomplexes over graded rings",
[ IsHomalgChainMorphism, IsInt, IsInt ],
function( C, min, max )
local HC, j, A, B;
A := HomogeneousPartOfCohomologicalDegreeOverCoefficientsRing( Source( C ), min, max );
B := HomogeneousPartOfCohomologicalDegreeOverCoefficientsRing( Range( C ), min, max );
HC := HomalgChainMorphism( HomogeneousPartOverCoefficientsRing( min, CertainMorphism( C, min ) ), A, B, min );
for j in [ min + 1 .. max ] do
Add( HC, HomogeneousPartOverCoefficientsRing( j, CertainMorphism( C, j ) ) );
od;
return HC;
end );
InstallMethod( CompleteKernelSquareByDualization,
"for homalg cocomplexes over graded rings",
[ IsMapOfGradedModulesRep, IsMapOfGradedModulesRep, IsMapOfGradedModulesRep ],
function( alpha2, phi, beta2 )
local A, alpha, id1, id2;
A := HomalgRing( phi );
if not ( HasIsFree( UnderlyingModule( Range( alpha2 ) ) ) and IsFree( UnderlyingModule( Range( alpha2 ) ) ) ) or
not ( HasIsFree( UnderlyingModule( Range( beta2 ) ) ) and IsFree( UnderlyingModule( Range( beta2 ) ) ) ) or
not ( HasIsFree( UnderlyingModule( Source( phi ) ) ) and IsFree( UnderlyingModule( Range( phi ) ) ) ) or
not ( HasIsFree( UnderlyingModule( Range( phi ) ) ) and IsFree( UnderlyingModule( Range( phi ) ) ) ) then
Error( "expect all graded modules to be graded free" );
fi;
alpha := CompleteImageSquare(
GradedHom( beta2, A ),
GradedHom( phi, A ),
GradedHom( alpha2, A )
);
alpha := GradedHom( alpha, A );
Assert( 3, IsMorphism( alpha ) );
SetIsMorphism( alpha, true );
id1 := NatTrIdToHomHom_R( Range( alpha2 ) );
Assert( 3, IsIsomorphism( id1 ) );
SetIsIsomorphism( id1, true );
UpdateObjectsByMorphism( id1 );
id2 := NatTrIdToHomHom_R( Range( beta2 ) );
Assert( 3, IsIsomorphism( id2 ) );
SetIsIsomorphism( id2, true );
UpdateObjectsByMorphism( id2 );
return PreCompose( PreCompose( id1, alpha ), id2^(-1) );
end );
InstallMethod( SetNaturalMapFromExteriorComplexToRightAdjointForModulesOfGlobalSections,
"for homalg cocomplexes over graded rings",
[ IsHomalgComplex, IsGradedModuleRep ],
function( lin_tate, M )
local truncation_bound, reg, RM, object, alpha, beta, jj, j;
truncation_bound := LowestDegree( lin_tate );
reg := Maximum( HighestDegree( lin_tate ), CastelnuovoMumfordRegularity( M ) );
RM := KoszulRightAdjoint( M, truncation_bound, reg );
object := CertainObject( lin_tate, reg );
alpha := TheIdentityMorphism( object );
beta := HomalgChainMorphism( alpha, lin_tate, RM, reg );
for jj in [ truncation_bound + 1 .. reg ] do
j := reg + truncation_bound - jj;
alpha := CompleteImageSquare( CertainMorphism( lin_tate, j ), alpha, CertainMorphism( RM, j ) );
Add( alpha, beta );
od;
SetNaturalMapFromExteriorComplexToRightAdjoint( lin_tate, beta );
end );
# Constructs a morphism between two modules F_source and F_target from the cochain map lin_tate
# We begin by constructing the map from F_source_{>=reg}=SubmoduleGeneratedByHomogeneousPart(reg,F_source)
# to F_target_{>=reg}=SubmoduleGeneratedByHomogeneousPart(reg,F_target).
# This map can be directly read of from the morphism in lin_tate at degree reg.
# Now we inductively construct maps from the submodules generated by a certain degree of F_source and F_target.
# Since F_{>=j} = F_{>=j+1} \oplus <F_j> we have the map starting from the direct sum and finally
# also from the factor of this direct sum.
InstallGlobalFunction( _Functor_LinearFreeComplexOverExteriorAlgebraToModule_OnGradedMaps,
function( F_source, F_target, arg_before_pos, lin_tate, arg_behind_pos )
local reg_sheaf, lower_bound, A, S, j, object, jj, RF_source, RF_target,
lin_tate_source, lin_tate_target, nat_source, nat_target, alpha,
id1, id2, Hnat_source, Hnat_target, phi, H_source, H_target, phi_source, phi_target, psi;
reg_sheaf := arg_before_pos[1];
lower_bound := LowestDegree( lin_tate );
A := HomalgRing( lin_tate );
S := HomalgRing( F_source );
RF_source := KoszulRightAdjoint( F_source, lower_bound, reg_sheaf );
RF_target := KoszulRightAdjoint( F_target, lower_bound, reg_sheaf );
lin_tate_source := Source( lin_tate );
lin_tate_target := Range( lin_tate );
if not HasNaturalMapFromExteriorComplexToRightAdjoint( lin_tate_source ) then
SetNaturalMapFromExteriorComplexToRightAdjointForModulesOfGlobalSections( lin_tate_source, F_source );
fi;
if not HasNaturalMapFromExteriorComplexToRightAdjoint( lin_tate_target ) then
SetNaturalMapFromExteriorComplexToRightAdjointForModulesOfGlobalSections( lin_tate_target, F_target );
fi;
nat_source := NaturalMapFromExteriorComplexToRightAdjoint( lin_tate_source );
nat_target := NaturalMapFromExteriorComplexToRightAdjoint( lin_tate_target );
Hnat_source := HomogeneousPartOfCohomologicalDegreeOverCoefficientsRing( nat_source, lower_bound, reg_sheaf );
Hnat_target := HomogeneousPartOfCohomologicalDegreeOverCoefficientsRing( nat_target, lower_bound, reg_sheaf );
for jj in [ lower_bound .. reg_sheaf ] do
j := reg_sheaf + lower_bound - jj;
phi := CertainMorphism( lin_tate, j );
phi_source := MapFromHomogeneousPartofModuleToHomogeneousPartOfKoszulRightAdjoint( j, F_source );
phi_source := PreCompose( phi_source, CertainMorphism( Hnat_source, j )^(-1) );
phi_target := MapFromHomogeneousPartofModuleToHomogeneousPartOfKoszulRightAdjoint( j, F_target );
phi_target := PreCompose( phi_target, CertainMorphism( Hnat_target, j )^(-1) );
phi := HomogeneousPartOverCoefficientsRing( j, phi );
H_source := HomogeneousPartOverCoefficientsRing( j, F_source );
H_target := HomogeneousPartOverCoefficientsRing( j, F_target );
phi := CompleteImageSquare( phi_source, phi, phi_target );
phi := S * phi;
if j = reg_sheaf then
psi := HomalgChainMorphism( phi, HomalgCocomplex( Source( phi ), reg_sheaf ), HomalgCocomplex( Range( phi ), reg_sheaf ), reg_sheaf );
else
Add( Source( phi ), Source( psi ) );
Add( Range( phi ), Range( psi ) );
Add( phi, psi );
fi;
od;
return ConstructMorphismFromLayers( F_source, F_target, psi );
end );
InstallValue( Functor_LinearFreeComplexOverExteriorAlgebraToModule_ForGradedModules,
CreateHomalgFunctor(
[ "name", "LinearFreeComplexOverExteriorAlgebraToModule" ],
[ "category", HOMALG_GRADED_MODULES.category ],
[ "operation", "LinearFreeComplexOverExteriorAlgebraToModule" ],
[ "number_of_arguments", 1 ],
[ "0", [ IsInt ] ],
[ "1", [ [ "covariant", "left adjoint", "distinguished" ], [ IsHomalgComplex, IsHomalgChainMorphism ] ] ],
[ "OnObjects", _Functor_LinearFreeComplexOverExteriorAlgebraToModule_OnGradedModules ],
[ "OnMorphisms", _Functor_LinearFreeComplexOverExteriorAlgebraToModule_OnGradedMaps ],
[ "CompareArgumentsForFunctorObj", CompareArgumentsForLinearFreeComplexOverExteriorAlgebraToModuleOnObjects ],
[ "MorphismConstructor", HOMALG_GRADED_MODULES.category.MorphismConstructor ]
)
);
Functor_LinearFreeComplexOverExteriorAlgebraToModule_ForGradedModules!.ContainerForWeakPointersOnComputedBasicObjects := true;
Functor_LinearFreeComplexOverExteriorAlgebraToModule_ForGradedModules!.ContainerForWeakPointersOnComputedBasicMorphisms := true;
InstallFunctor( Functor_LinearFreeComplexOverExteriorAlgebraToModule_ForGradedModules );
##
## ModuleOfGlobalSectionsTruncatedAtCertainDegree
##
## (cf. Eisenbud, Floystad, Schreyer: Sheaf Cohomology and Free Resolutions over Exterior Algebras)
InstallGlobalFunction( _Functor_ModuleOfGlobalSectionsTruncatedAtCertainDegree_OnGradedModules,
function( truncation_bound, M )
local V2, map, UM, SOUM, C, reg, tate, B, reg_sheaf, t1, t2, psi, RM, id_old, phi, lin_tate, fit, HM, ii, i, hom_part;
if HasIsModuleOfGlobalSectionsTruncatedAtCertainDegree( M ) and HomalgElementToInteger( IsModuleOfGlobalSectionsTruncatedAtCertainDegree( M ) ) = truncation_bound then
HM := M;
if truncation_bound = 0 then
V2 := HomogeneousPartOverCoefficientsRing( 0, HM );
map := EmbeddingOfSubmoduleGeneratedByHomogeneousPart( 0, HM );
SetEmbeddingOfSubmoduleGeneratedByHomogeneousPart( V2, map );
fi;
return HM;
fi;
if not IsBound( M!.NaturalMapToModuleOfGlobalSectionsTruncatedAtCertainDegree ) then
M!.NaturalMapToModuleOfGlobalSectionsTruncatedAtCertainDegree := rec( );
elif IsBound( M!.NaturalMapToModuleOfGlobalSectionsTruncatedAtCertainDegree!.(truncation_bound) ) then
HM := Range( M!.NaturalMapToModuleOfGlobalSectionsTruncatedAtCertainDegree!.(truncation_bound) );
return HM;
fi;
# 0 -> M -> SOUM -> C -> 0
# SOUM is module of global sections
# C does not have a non-trivial artinian submodule
# then M is already a module of global sections
# proof:
# 0 -> M ----> SOUM --> C -> 0
# | | |
# iota | Id | | phi
# \/ \/ \/
# 0-> HM ----> SOUM -> HC
# Show, that iota is an isomorphism.
# C does not have a non-trivial artinian submodule, so phi is mono.
# The claim follows from the five-lemma.
if HasUnderlyingSubobject( M ) then
UM := UnderlyingSubobject( M );
SOUM := SuperObject( UM );
if IsBound( UM!.map_having_subobject_as_its_image ) and HasIsModuleOfGlobalSectionsTruncatedAtCertainDegree( SOUM ) and
IsInt( HomalgElementToInteger( IsModuleOfGlobalSectionsTruncatedAtCertainDegree( SOUM ) ) ) and HomalgElementToInteger( IsModuleOfGlobalSectionsTruncatedAtCertainDegree( SOUM ) ) = truncation_bound then
C := Cokernel( UM!.map_having_subobject_as_its_image );
if HasIsTorsionFree( C ) and IsTorsionFree( C ) or TrivialArtinianSubmodule( C ) then
SetIsModuleOfGlobalSectionsTruncatedAtCertainDegree( M, HomalgElementToInteger( IsModuleOfGlobalSectionsTruncatedAtCertainDegree( SOUM ) ) );
HM := M;
if truncation_bound = 0 then
V2 := HomogeneousPartOverCoefficientsRing( 0, HM );
map := EmbeddingOfSubmoduleGeneratedByHomogeneousPart( 0, HM );
SetEmbeddingOfSubmoduleGeneratedByHomogeneousPart( V2, map );
fi;
M!.NaturalMapToModuleOfGlobalSectionsTruncatedAtCertainDegree!.(truncation_bound) := TheIdentityMorphism( M );
return HM;
fi;
fi;
fi;
# For free modules or modules with a regularity low enough we get the result
# by just truncating the module
if HasIsFree( UnderlyingModule( M ) ) and IsFree( UnderlyingModule( M ) ) or
HomalgElementToInteger( CastelnuovoMumfordRegularity( M ) ) <= truncation_bound then
psi := TruncatedSubmoduleEmbed( truncation_bound, M );
HM := Source( psi );
if truncation_bound = 0 then
V2 := HomogeneousPartOverCoefficientsRing( 0, HM );
map := EmbeddingOfSubmoduleGeneratedByHomogeneousPart( 0, HM );
SetEmbeddingOfSubmoduleGeneratedByHomogeneousPart( V2, map );
fi;
M!.NaturalMapToModuleOfGlobalSectionsTruncatedAtCertainDegree!.(truncation_bound) := TheIdentityMorphism( HM );
else
reg := Maximum( truncation_bound, HomalgElementToInteger( CastelnuovoMumfordRegularity( M ) ) );
# in certain cases, when we know that the map to the
# truncated module of global sections is injective,
# we can check by looking at dimensions, whether it is surjective.
# Then, we are done.
if HasIsTorsionFree( M ) and IsTorsionFree( M ) or TrivialArtinianSubmodule( M ) then
lin_tate := LinearStrandOfTateResolution( M, truncation_bound, reg+1 );
fit := true;
for i in [ truncation_bound .. reg+1 ] do
if not NrGenerators( CertainObject( lin_tate, i ) ) = NrGenerators( HomogeneousPartOverCoefficientsRing( i, M ) ) then
fit := false;
break;
fi;
od;
fi;
if IsBound( fit ) and fit then
psi := TruncatedSubmoduleEmbed( truncation_bound, M );
HM := Source( psi );
if truncation_bound = 0 then
V2 := HomogeneousPartOverCoefficientsRing( 0, HM );
map := EmbeddingOfSubmoduleGeneratedByHomogeneousPart( 0, HM );
SetEmbeddingOfSubmoduleGeneratedByHomogeneousPart( V2, map );
fi;
M!.NaturalMapToModuleOfGlobalSectionsTruncatedAtCertainDegree!.(truncation_bound) := TheIdentityMorphism( HM );
# the generic (expensive!) case.
else
lin_tate := LinearStrandOfTateResolution( M, truncation_bound, reg+1 );
reg_sheaf := HomalgElementToInteger( lin_tate!.regularity );
HM := LinearFreeComplexOverExteriorAlgebraToModule( reg_sheaf, lin_tate );
Assert( 5, HomalgElementToInteger( CastelnuovoMumfordRegularity( HM ) ) = reg_sheaf );
SetCastelnuovoMumfordRegularity( HM, reg_sheaf );
fi;
fi;
SetIsModuleOfGlobalSectionsTruncatedAtCertainDegree( HM, truncation_bound );
SetTrivialArtinianSubmodule( HM, true );
if HasIsZero( HM ) then
SetIsArtinian( M, IsZero( HM ) );
fi;
if truncation_bound = 0 then
Assert( 0, HasEmbeddingOfSubmoduleGeneratedByHomogeneousPart( HomogeneousPartOverCoefficientsRing( 0, HM ) ) );
fi;
return HM;
end );
##
InstallGlobalFunction( _Functor_ModuleOfGlobalSectionsTruncatedAtCertainDegree_OnGradedMaps,
function( F_source, F_target, arg_before_pos, mor, arg_behind_pos )
local truncation_bound, source, target, nat_source, nat_target, reg, lin_tate, reg_sheaf, H_mor;
if IsIdenticalObj( Source( mor ), F_source ) and IsIdenticalObj( Range( mor ), F_target ) then
return mor;
fi;
if not Length( arg_before_pos ) = 1 and IsInt( HomalgElementToInteger( arg_before_pos[1] ) ) then
Error( "expected a bound for the truncation" );
else
truncation_bound := HomalgElementToInteger( arg_before_pos[1] );
fi;
source := Source( mor );
target := Range( mor );
if IsBound( source!.NaturalMapToModuleOfGlobalSectionsTruncatedAtCertainDegree )
and IsBound( source!.NaturalMapToModuleOfGlobalSectionsTruncatedAtCertainDegree!.(truncation_bound) ) then
nat_source := source!.NaturalMapToModuleOfGlobalSectionsTruncatedAtCertainDegree!.(truncation_bound);
else
nat_source := fail;
fi;
if IsBound( target!.NaturalMapToModuleOfGlobalSectionsTruncatedAtCertainDegree )
and IsBound( target!.NaturalMapToModuleOfGlobalSectionsTruncatedAtCertainDegree!.(truncation_bound) ) then
nat_target := target!.NaturalMapToModuleOfGlobalSectionsTruncatedAtCertainDegree!.(truncation_bound);
else
nat_target := fail;
fi;
if IsIdenticalObj( source, F_source ) and
nat_target <> fail then
return PreCompose(
mor / TruncatedSubmoduleEmbed( truncation_bound, target ),
nat_target );
fi;
if nat_source <> fail and
HasIsEpimorphism( nat_source ) and
IsEpimorphism( nat_source ) and
IsIdenticalObj( target, F_target ) then
H_mor := PreDivide(
nat_source,
PreCompose( TruncatedSubmoduleEmbed( truncation_bound, source ), mor ) );
return H_mor;
fi;
if nat_source <> fail and
HasIsEpimorphism( nat_source ) and
IsEpimorphism( nat_source ) and
nat_target <> fail then
H_mor := CompleteKernelSquare(
nat_source,
TruncatedSubmodule( truncation_bound, mor ),
nat_target );
return H_mor;
fi;
reg := Maximum( truncation_bound, HomalgElementToInteger( CastelnuovoMumfordRegularity( mor ) ) );
lin_tate := LinearStrandOfTateResolution( mor, truncation_bound, reg+1 );
reg_sheaf := Maximum( truncation_bound, HomalgElementToInteger( CastelnuovoMumfordRegularity( F_source ) ), HomalgElementToInteger( CastelnuovoMumfordRegularity( F_target ) ) );
# setting these functors is vital, since ModuleOfGlobalSections on object does not compute with
# LinearFreeComplexOverExteriorAlgebraToModule in every case, but we want to have identical objects
if fail = GetFunctorObjCachedValue( Functor_LinearFreeComplexOverExteriorAlgebraToModule_ForGradedModules, [ reg_sheaf, Source( lin_tate ) ] ) then
SetFunctorObjCachedValue( Functor_LinearFreeComplexOverExteriorAlgebraToModule_ForGradedModules, [ reg_sheaf, Source( lin_tate ) ], ModuleOfGlobalSectionsTruncatedAtCertainDegree( truncation_bound, Source( mor ) ) );
fi;
if fail = GetFunctorObjCachedValue( Functor_LinearFreeComplexOverExteriorAlgebraToModule_ForGradedModules, [ reg_sheaf, Range( lin_tate ) ] ) then
SetFunctorObjCachedValue( Functor_LinearFreeComplexOverExteriorAlgebraToModule_ForGradedModules, [ reg_sheaf, Range( lin_tate ) ], ModuleOfGlobalSectionsTruncatedAtCertainDegree( truncation_bound, Range( mor ) ) );
fi;
H_mor := LinearFreeComplexOverExteriorAlgebraToModule( reg_sheaf, lin_tate );
if HasIsMorphism( mor ) and IsMorphism( mor ) then
SetIsMorphism( H_mor, true );
fi;
if HasIsMonomorphism( mor ) and IsMonomorphism( mor ) then
SetIsMonomorphism( H_mor, true );
fi;
return H_mor;
end );
##
## We create a map by following the layers from
## T1) the homogeneous layers of M to
## T2) the homogenous parts of coefficients rings in R(M) to
## T3) the linear strand of the Tate resolution of M (we possibly need to do CompleteImageSquare here to get down from the regularity of the module to the regularity of the sheaf) to
## T4) the homogenous parts of coefficients rings in R(Gamma(M)) (we possibly need to do CompleteKernelSquare here to get back up from the regularity of the sheaf to the regularity of the module) to
## T5) the homogeneous layers of Gamma(M)
##
InstallMethod( NaturalMapToModuleOfGlobalSectionsTruncatedAtCertainDegree,
"for integers and homalg graded modules",
[ IsInt, IsGradedModuleRep ],
function( truncation_bound, M )
local S, A, regM, HM, regHM, T1, i, RM, T2, t1, linTM, T3, tau2, ii, t2, RHM, T4, T5, tau3, alpha, id1, id2, t3, t4, phi;
if not IsBound( M!.NaturalMapToModuleOfGlobalSectionsTruncatedAtCertainDegree ) then
M!.NaturalMapToModuleOfGlobalSectionsTruncatedAtCertainDegree := rec( );
elif IsBound( M!.NaturalMapToModuleOfGlobalSectionsTruncatedAtCertainDegree!.(truncation_bound) ) then
return M!.NaturalMapToModuleOfGlobalSectionsTruncatedAtCertainDegree!.(truncation_bound);
fi;
if HasIsModuleOfGlobalSectionsTruncatedAtCertainDegree( M ) and IsInt( IsModuleOfGlobalSectionsTruncatedAtCertainDegree( M ) ) then
return TheIdentityMorphism( M );
fi;
S := HomalgRing( M );
A := KoszulDualRing( S );
regM := Maximum( truncation_bound, CastelnuovoMumfordRegularity( M ) );
HM := ModuleOfGlobalSectionsTruncatedAtCertainDegree( truncation_bound, M ); #This might set NaturalMapToModuleOfGlobalSections as a side effect
# generating the module might generate the map naturally.
if IsBound( M!.NaturalMapToModuleOfGlobalSectionsTruncatedAtCertainDegree!.(truncation_bound) ) then
return M!.NaturalMapToModuleOfGlobalSectionsTruncatedAtCertainDegree!.(truncation_bound);
fi;
regHM := CastelnuovoMumfordRegularity( HM );
T1 := HomalgCocomplex( HomogeneousPartOverCoefficientsRing( truncation_bound, M ), truncation_bound );
for i in [ truncation_bound + 1 .. regM +1 ] do
Add( T1, HomogeneousPartOverCoefficientsRing( i, M ) );
od;
RM := KoszulRightAdjoint( M, truncation_bound, regM + 1 );
T2 := HomogeneousPartOfCohomologicalDegreeOverCoefficientsRing( RM, truncation_bound, regM + 1 );
t1 := HomalgChainMorphism( MapFromHomogeneousPartofModuleToHomogeneousPartOfKoszulRightAdjoint( truncation_bound, M ), T1, T2, truncation_bound );
for i in [ truncation_bound + 1 .. regM +1 ] do
Add( t1, MapFromHomogeneousPartofModuleToHomogeneousPartOfKoszulRightAdjoint( i, M ) );
od;
Assert( 3, IsMorphism( t1 ) );
SetIsMorphism( t1, true );
linTM := LinearStrandOfTateResolution( M, truncation_bound, regM + 1 );
T3 := HomogeneousPartOfCohomologicalDegreeOverCoefficientsRing( linTM, truncation_bound, regM + 1 );
tau2 := HomalgChainMorphism( TheIdentityMorphism( CertainObject( RM, regM + 1 ) ), RM, linTM, regM + 1 );
for ii in [ truncation_bound .. regM ] do
i := regM + truncation_bound - ii;
Add( CompleteImageSquare( CertainMorphism( RM, i ), LowestDegreeMorphism( tau2 ), CertainMorphism( linTM, i ) ), tau2 );
od;
t2 := HomogeneousPartOfCohomologicalDegreeOverCoefficientsRing( tau2, truncation_bound, regM + 1 );
Assert( 3, IsMorphism( t2 ) );
SetIsMorphism( t2, true );
RHM := KoszulRightAdjoint( HM, truncation_bound, regM + 1 );
T4 := HomogeneousPartOfCohomologicalDegreeOverCoefficientsRing( RHM, truncation_bound, regM + 1 );
if not HasNaturalMapFromExteriorComplexToRightAdjoint( linTM ) then
SetNaturalMapFromExteriorComplexToRightAdjointForModulesOfGlobalSections( linTM, M );
fi;
tau3 := NaturalMapFromExteriorComplexToRightAdjoint( linTM );
for i in [ Maximum( DegreesOfChainMorphism( tau3 ) ) + 1 .. regM + 1 ] do
alpha := CompleteKernelSquareByDualization( CertainMorphism( linTM, i - 1 ), HighestDegreeMorphism( tau3 ), CertainMorphism( RHM, i - 1 ) );
Assert( 3, IsIsomorphism( alpha ) );
SetIsIsomorphism( alpha, true );
UpdateObjectsByMorphism( alpha );
if not i in ObjectDegreesOfComplex( Range( tau3 ) ) then
Add( Range( tau3 ), CertainMorphism( RHM, i - 1 ) );
fi;
Add( tau3, alpha );
od;
t3 := HomogeneousPartOfCohomologicalDegreeOverCoefficientsRing( tau3, truncation_bound, regM + 1 );
Assert( 3, IsMorphism( t3 ) );
SetIsMorphism( t3, true );
T5 := HomalgCocomplex( HomogeneousPartOverCoefficientsRing( truncation_bound, HM ), truncation_bound );
for i in [ truncation_bound + 1 .. regM +1 ] do
Add( T5, HomogeneousPartOverCoefficientsRing( i, HM ) );
od;
t4 := HomalgChainMorphism( MapFromHomogeneousPartofModuleToHomogeneousPartOfKoszulRightAdjoint( truncation_bound, HM )^(-1), T4, T5, truncation_bound );
for i in [ truncation_bound + 1 .. regM +1 ] do
Add( t4, MapFromHomogeneousPartofModuleToHomogeneousPartOfKoszulRightAdjoint( i, HM )^(-1) );
od;
Assert( 3, IsMorphism( t4 ) );
SetIsMorphism( t4, true );
phi := PreCompose( PreCompose( t1, t2 ), PreCompose( t3, t4 ) );
phi := ConstructMorphismFromLayers( TruncatedModule( truncation_bound, M ), HM, S * phi );
M!.NaturalMapToModuleOfGlobalSectionsTruncatedAtCertainDegree!.(truncation_bound) := phi;
return phi;
end );
InstallValue( Functor_ModuleOfGlobalSectionsTruncatedAtCertainDegree_ForGradedModules,
CreateHomalgFunctor(
[ "name", "ModuleOfGlobalSectionsTruncatedAtCertainDegree" ],
[ "category", HOMALG_GRADED_MODULES.category ],
[ "operation", "ModuleOfGlobalSectionsTruncatedAtCertainDegree" ],
[ "number_of_arguments", 1 ],
[ "0", [ IsInt ] ],
[ "1", [ [ "covariant", "left adjoint", "distinguished" ], HOMALG_GRADED_MODULES.FunctorOn ] ],
[ "OnObjects", _Functor_ModuleOfGlobalSectionsTruncatedAtCertainDegree_OnGradedModules ],
[ "OnMorphisms", _Functor_ModuleOfGlobalSectionsTruncatedAtCertainDegree_OnGradedMaps ],
[ "MorphismConstructor", HOMALG_GRADED_MODULES.category.MorphismConstructor ]
)
);
Functor_ModuleOfGlobalSectionsTruncatedAtCertainDegree_ForGradedModules!.ContainerForWeakPointersOnComputedBasicObjects := true;
Functor_ModuleOfGlobalSectionsTruncatedAtCertainDegree_ForGradedModules!.ContainerForWeakPointersOnComputedBasicMorphisms := true;
InstallFunctor( Functor_ModuleOfGlobalSectionsTruncatedAtCertainDegree_ForGradedModules );
##
InstallMethod( ModuleOfGlobalSectionsTruncatedAtCertainDegree,
"for homalg elements",
[ IsHomalgElement, IsHomalgGradedMap ],
function( d, M )
return ModuleOfGlobalSectionsTruncatedAtCertainDegree( HomalgElementToInteger( d ), M );
end );
##
InstallMethod( ModuleOfGlobalSectionsTruncatedAtCertainDegree,
"for homalg elements",
[ IsHomalgElement, IsHomalgGradedModule ],
function( d, M )
return ModuleOfGlobalSectionsTruncatedAtCertainDegree( HomalgElementToInteger( d ), M );
end );
##
InstallMethod( NaturalMapToModuleOfGlobalSectionsTruncatedAtCertainDegree,
"for homalg elements",
[ IsHomalgElement, IsHomalgGradedModule ],
function( d, M )
return NaturalMapToModuleOfGlobalSectionsTruncatedAtCertainDegree( HomalgElementToInteger( d ), M );
end );
##
## ModuleOfGlobalSections
##
InstallGlobalFunction( _Functor_ModuleOfGlobalSections_OnGradedModules,
function( M )
return ModuleOfGlobalSectionsTruncatedAtCertainDegree( HOMALG_GRADED_MODULES!.LowerTruncationBound, M );
end );
InstallGlobalFunction( _Functor_ModuleOfGlobalSections_OnGradedMaps,
function( F_source, F_target, arg_before_pos, mor, arg_behind_pos )
return ModuleOfGlobalSectionsTruncatedAtCertainDegree( HOMALG_GRADED_MODULES!.LowerTruncationBound, mor );
end );
InstallValue( Functor_ModuleOfGlobalSections_ForGradedModules,
CreateHomalgFunctor(
[ "name", "ModuleOfGlobalSections" ],
[ "category", HOMALG_GRADED_MODULES.category ],
[ "operation", "ModuleOfGlobalSections" ],
[ "number_of_arguments", 1 ],
[ "1", [ [ "covariant", "left adjoint", "distinguished" ], HOMALG_GRADED_MODULES.FunctorOn ] ],
[ "OnObjects", _Functor_ModuleOfGlobalSections_OnGradedModules ],
[ "OnMorphisms", _Functor_ModuleOfGlobalSections_OnGradedMaps ],
[ "MorphismConstructor", HOMALG_GRADED_MODULES.category.MorphismConstructor ]
)
);
Functor_ModuleOfGlobalSections_ForGradedModules!.ContainerForWeakPointersOnComputedBasicObjects := true;
Functor_ModuleOfGlobalSections_ForGradedModules!.ContainerForWeakPointersOnComputedBasicMorphisms := true;
InstallFunctor( Functor_ModuleOfGlobalSections_ForGradedModules );
##
InstallMethod( NaturalMapToModuleOfGlobalSections,
"for homalg graded modules",
[ IsGradedModuleRep ],
function( M )
return NaturalMapToModuleOfGlobalSectionsTruncatedAtCertainDegree( HOMALG_GRADED_MODULES!.LowerTruncationBound, M );
end );
##
InstallMethod( ModuleOfGlobalSections,
"for homalg elements",
[ IsHomalgElement, IsHomalgGradedMap ],
function( d, M )
return ModuleOfGlobalSections( HomalgElementToInteger( d ), M );
end );
##
InstallMethod( ModuleOfGlobalSectionsTruncatedAtCertainDegree,
"for homalg elements",
[ IsHomalgElement, IsHomalgGradedModule ],
function( d, M )
return ModuleOfGlobalSections( HomalgElementToInteger( d ), M );
end );
##
## GuessModuleOfGlobalSectionsFromATateMap
##
##
InstallMethod( GuessModuleOfGlobalSectionsFromATateMap,
"for homalg modules",
[ IsMapOfGradedModulesRep ],
function( phi )
return GuessModuleOfGlobalSectionsFromATateMap( 1, phi );
end );
InstallGlobalFunction( _Functor_GuessModuleOfGlobalSectionsFromATateMap_OnGradedMaps, ### defines: GuessModuleOfGlobalSectionsFromATateMap (object part)
[ IsInt, IsMapOfGradedModulesRep ],
function( steps, phi )
local A, n, psi, deg, lin_tate, alpha, j, K, tate, i, tate2;
Info( InfoWarning, 1, "GuessModuleOfGlobalSectionsFromATateMap uses a heuristic for efficiency;\nplease check the correctness of the following result\n" );
A := HomalgRing( phi );
n := Length( Indeterminates( A ) );
# go up to the regularity
psi := GradedHom( phi, A );
deg := Minimum( List( DegreesOfGenerators( Source( psi ) ), HomalgElementToInteger ) );
lin_tate := HomalgCocomplex( psi, deg );
alpha := LowestDegreeMorphism( lin_tate );
for j in [ 1 .. Maximum( 1, steps ) ] do
repeat
K := Kernel( alpha );
ByASmallerPresentation( K );
Add( PreCompose( CoveringEpi( K ), KernelEmb( alpha ) ), lin_tate );
alpha := LowestDegreeMorphism( lin_tate );
deg := Minimum( List( DegreesOfGenerators( Source( alpha ) ), HomalgElementToInteger ) );
if deg <> Minimum( ObjectDegreesOfComplex( lin_tate ) ) then
lin_tate := HomalgCocomplex( alpha, deg );
fi;
until Minimum( List( DegreesOfGenerators( Source( alpha ) ), HomalgElementToInteger ) ) = Maximum( List( DegreesOfGenerators( Source( alpha ) ), HomalgElementToInteger ) )
and Minimum( List( DegreesOfGenerators( Range( alpha ) ), HomalgElementToInteger ) ) = Maximum( List( DegreesOfGenerators( Range( alpha ) ), HomalgElementToInteger ) )
and HomalgElementToInteger( DegreesOfGenerators( Range( alpha ) )[1] ) = HomalgElementToInteger( DegreesOfGenerators( Source( alpha ) )[1] ) + 1;
od;
lin_tate := LinearStrand( 0, lin_tate );
tate := GradedHom( lin_tate, A );
tate := A^(-n) * tate;
for i in MorphismDegreesOfComplex( tate ) do
if not IsBound( tate2 ) then
tate2 := HomalgCocomplex( CertainMorphism( tate, i ), -i );
else
Add( CertainMorphism( tate, i ), tate2 );
fi;
od;
# go down to HOMALG_GRADED_MODULES!.LowerTruncationBound
ResolveLinearly( Minimum( List( ObjectDegreesOfComplex( tate2 ), HomalgElementToInteger ) ) - HomalgElementToInteger( HOMALG_GRADED_MODULES!.LowerTruncationBound ), tate2 );
# reconstruct the module
return LinearFreeComplexOverExteriorAlgebraToModule( Maximum( List( ObjectDegreesOfComplex( tate2 ), HomalgElementToInteger ) ) - 1, tate2 );
end );
InstallValue( Functor_GuessModuleOfGlobalSectionsFromATateMap_ForGradedMaps,
CreateHomalgFunctor(
[ "name", "GuessModuleOfGlobalSectionsFromATateMap" ],
[ "category", HOMALG_GRADED_MODULES.category ],
[ "operation", "GuessModuleOfGlobalSectionsFromATateMap" ],
[ "number_of_arguments", 1 ],
[ "0", [ IsInt ] ],
[ "1", [ [ "covariant", "left adjoint", "distinguished" ], [ IsMapOfGradedModulesRep ] ] ],
[ "OnObjects", _Functor_GuessModuleOfGlobalSectionsFromATateMap_OnGradedMaps ],
[ "MorphismConstructor", HOMALG_MODULES.category.MorphismConstructor ]
)
);
Functor_GuessModuleOfGlobalSectionsFromATateMap_ForGradedMaps!.ContainerForWeakPointersOnComputedBasicObjects := true;
InstallFunctor( Functor_GuessModuleOfGlobalSectionsFromATateMap_ForGradedMaps );
##
InstallMethod( GuessModuleOfGlobalSectionsFromATateMap,
"for homalg elements",
[ IsHomalgElement, IsHomalgGradedMap ],
function( d, M )
return GuessModuleOfGlobalSectionsFromATateMap( HomalgElementToInteger( d ), M );
end );