Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
| Download
GAP 4.8.9 installation with standard packages -- copy to your CoCalc project to get it
Project: cocalc-sagemath-dev-slelievre
Views: 418346############################################################################# ## ## LIGrMOD.gi LIGrMOD subpackage ## ## LIGrMOD = Logical Implications for Graded MODules ## ## Copyright 2010, Mohamed Barakat, University of Kaiserslautern ## Markus Lange-Hegermann, RWTH Aachen ## ## Implementations for the LIGrMOD subpackage. ## ############################################################################# #################################### # # global variables: # #################################### # a central place for configuration variables: InstallValue( LIGrMOD, rec( color := "\033[4;30;46m", ## used in a InstallLogicalImplicationsForHomalgSubobjects call below intrinsic_properties_specific_shared_with_subobjects_and_ideals := [ "IsCohenMacaulay", ], ## used in a InstallLogicalImplicationsForHomalgSubobjects call below intrinsic_properties_specific_shared_with_factors_modulo_ideals := [ ], intrinsic_properties_specific_not_shared_with_subobjects := [ ], ## used in a InstallLogicalImplicationsForHomalgSubobjects call below intrinsic_properties_specific_shared_with_subobjects_which_are_not_ideals := Concatenation( ~.intrinsic_properties_specific_shared_with_subobjects_and_ideals, ~.intrinsic_properties_specific_shared_with_factors_modulo_ideals ), ## needed to define intrinsic_properties below intrinsic_properties_specific := Concatenation( ~.intrinsic_properties_specific_not_shared_with_subobjects, ~.intrinsic_properties_specific_shared_with_subobjects_which_are_not_ideals ), ## needed for MatchPropertiesAndAttributes in GradedSubmodule.gi intrinsic_properties_shared_with_subobjects_and_ideals := Concatenation( LIMOD.intrinsic_properties_shared_with_subobjects_and_ideals, ~.intrinsic_properties_specific_shared_with_subobjects_and_ideals ), ## intrinsic_properties_shared_with_factors_modulo_ideals := Concatenation( LIMOD.intrinsic_properties_shared_with_factors_modulo_ideals, ~.intrinsic_properties_specific_shared_with_factors_modulo_ideals ), ## needed for MatchPropertiesAndAttributes in GradedSubmodule.gi intrinsic_properties_shared_with_subobjects_which_are_not_ideals := Concatenation( LIMOD.intrinsic_properties_shared_with_subobjects_which_are_not_ideals, ~.intrinsic_properties_specific_shared_with_subobjects_which_are_not_ideals ), ## needed for UpdateObjectsByMorphism intrinsic_properties := Concatenation( LIMOD.intrinsic_properties, ~.intrinsic_properties_specific ), ## used in a InstallLogicalImplicationsForHomalgSubobjects call below intrinsic_attributes_specific_shared_with_subobjects_and_ideals := [ "BettiTable", "LinearRegularityInterval", "LinearRegularity", "CastelnuovoMumfordRegularity", "CastelnuovoMumfordRegularityOfSheafification", ], ## used in a InstallLogicalImplicationsForHomalgSubobjects call below intrinsic_attributes_specific_shared_with_factors_modulo_ideals := [ "AffineDimension", "AffineDegree", "ProjectiveDegree", "PrimaryDecomposition", ## wrong, we need the preimages of this "RadicalDecomposition", ## wrong, we need the preimages of this "RadicalSubobject", ## wrong, we need the preimages of this "HilbertPolynomial", ], intrinsic_attributes_specific_not_shared_with_subobjects := [ ], ## used in a InstallLogicalImplicationsForHomalgSubobjects call below intrinsic_attributes_specific_shared_with_subobjects_which_are_not_ideals := Concatenation( ~.intrinsic_attributes_specific_shared_with_subobjects_and_ideals, ~.intrinsic_attributes_specific_shared_with_factors_modulo_ideals ), ## needed to define intrinsic_attributes below intrinsic_attributes_specific := Concatenation( ~.intrinsic_attributes_specific_not_shared_with_subobjects, ~.intrinsic_attributes_specific_shared_with_subobjects_which_are_not_ideals ), ## needed for MatchPropertiesAndAttributes in GradedSubmodule.gi intrinsic_attributes_shared_with_subobjects_and_ideals := Concatenation( LIMOD.intrinsic_attributes_shared_with_subobjects_and_ideals, ~.intrinsic_attributes_specific_shared_with_subobjects_and_ideals ), ## intrinsic_attributes_shared_with_factors_modulo_ideals := Concatenation( LIMOD.intrinsic_attributes_shared_with_factors_modulo_ideals, ~.intrinsic_attributes_specific_shared_with_factors_modulo_ideals ), ## needed for MatchPropertiesAndAttributes in GradedSubmodule.gi intrinsic_attributes_shared_with_subobjects_which_are_not_ideals := Concatenation( LIMOD.intrinsic_attributes_shared_with_subobjects_which_are_not_ideals, ~.intrinsic_attributes_specific_shared_with_subobjects_which_are_not_ideals ), ## needed for UpdateObjectsByMorphism intrinsic_attributes := Concatenation( LIMOD.intrinsic_attributes, ~.intrinsic_attributes_specific ), exchangeable_properties := [ "IsZero", "IsProjective", "IsProjectiveOfConstantRank", "IsReflexive", "IsTorsionFree", "IsTorsion", "IsArtinian", "IsPure", "IsFree", "IsStablyFree", "IsCyclic", "HasConstantRank", "IsHolonomic", ], exchangeable_attributes := [ "RankOfObject", "ProjectiveDimension", "DegreeOfTorsionFreeness", "CodegreeOfPurity", "Grade", ], ) ); #################################### # # logical implications methods: # #################################### InstallLogicalImplicationsForHomalgSubobjects( List( LIGrMOD.intrinsic_properties_specific_shared_with_subobjects_which_are_not_ideals, ValueGlobal ), IsGradedSubmoduleRep and NotConstructedAsAnIdeal, HasEmbeddingInSuperObject, UnderlyingObject ); InstallLogicalImplicationsForHomalgSubobjects( List( LIGrMOD.intrinsic_properties_specific_shared_with_subobjects_and_ideals, ValueGlobal ), IsGradedSubmoduleRep and ConstructedAsAnIdeal, HasEmbeddingInSuperObject, UnderlyingObject ); InstallLogicalImplicationsForHomalgSubobjects( List( LIGrMOD.intrinsic_properties_specific_shared_with_factors_modulo_ideals, ValueGlobal ), IsGradedSubmoduleRep and ConstructedAsAnIdeal, HasFactorObject, FactorObject ); InstallLogicalImplicationsForHomalgSubobjects( List( LIGrMOD.intrinsic_attributes_specific_shared_with_subobjects_which_are_not_ideals, ValueGlobal ), IsGradedSubmoduleRep and NotConstructedAsAnIdeal, HasEmbeddingInSuperObject, UnderlyingObject ); InstallLogicalImplicationsForHomalgSubobjects( List( LIGrMOD.intrinsic_attributes_specific_shared_with_subobjects_and_ideals, ValueGlobal ), IsGradedSubmoduleRep and ConstructedAsAnIdeal, HasEmbeddingInSuperObject, UnderlyingObject ); InstallLogicalImplicationsForHomalgSubobjects( List( LIGrMOD.intrinsic_attributes_specific_shared_with_factors_modulo_ideals, ValueGlobal ), IsGradedSubmoduleRep and ConstructedAsAnIdeal, HasFactorObject, FactorObject ); #################################### # # immediate methods for properties: # #################################### ## InstallImmediateMethod( IsZero, IsGradedModuleRep and HasAffineDimension, 0, function( M ) return AffineDimension( M ) <= HOMALG_MODULES.DimensionOfZeroModules; end ); ## InstallImmediateMethodToPullPropertiesOrAttributes( IsHomalgGradedModule, IsHomalgGradedModule, LIGrMOD.exchangeable_properties, Concatenation( LIGrMOD.intrinsic_properties, LIGrMOD.intrinsic_attributes ), UnderlyingModule ); ## InstallImmediateMethodToPushPropertiesOrAttributes( Twitter, IsHomalgGradedModule, LIGrMOD.exchangeable_properties, UnderlyingModule ); #################################### # # immediate methods for attributes: # #################################### ## InstallImmediateMethodToPullPropertiesOrAttributes( IsHomalgGradedModule, IsHomalgGradedModule, LIGrMOD.exchangeable_attributes, Concatenation( LIGrMOD.intrinsic_properties, LIGrMOD.intrinsic_attributes ), UnderlyingModule ); ## InstallImmediateMethodToPushPropertiesOrAttributes( Twitter, IsHomalgGradedModule, LIGrMOD.exchangeable_attributes, UnderlyingModule ); # ## # InstallImmediateMethod( IsModuleOfGlobalSectionsTruncatedAtCertainDegree, # IsHomalgGradedModule, 0, # # function( M ) # local UM; # # UM := UnderlyingModule( M ); # # if DegreesOfGenerators( M ) <> [] and HasIsFree( UM ) and IsFree( UM ) then # return Minimum( DegreesOfGenerators( M ) ); # fi; # # TryNextMethod( ); # # end ); # ## # InstallImmediateMethod( IsModuleOfGlobalSectionsTruncatedAtCertainDegree, # IsHomalgGradedModule and HasCastelnuovoMumfordRegularity, 0, # # function( M ) # local UM; # # if DegreesOfGenerators( M ) <> [] and CastelnuovoMumfordRegularity( M ) <= Minimum( DegreesOfGenerators( M ) ) then # return Minimum( DegreesOfGenerators( M ) ); # fi; # # TryNextMethod( ); # # end ); ## InstallImmediateMethod( IsModuleOfGlobalSectionsTruncatedAtCertainDegree, IsHomalgGradedModule and HasIsZero and IsZero, 0, function( M ) local UM; return true; end ); ## InstallImmediateMethod( LinearRegularity, IsGradedModuleRep and HasLinearRegularityInterval, 0, function( M ) local linreg; linreg := LinearRegularityInterval( M ); return linreg[Length( linreg )]; end ); #################################### # # methods for properties: # #################################### ## InstallMethod( IsZero, "LIGrMOD: for homalg graded modules", [ IsGradedModuleRep ], function( M ) local R, K, RP; R := HomalgRing( M ); if not ( HasIsCommutative( R ) and IsCommutative( R ) ) or not HasCoefficientsRing( R ) then TryNextMethod( ); fi; K := CoefficientsRing( R ); if not ( HasIsFieldForHomalg( K ) and IsFieldForHomalg( K ) ) then TryNextMethod( ); fi; RP := homalgTable( UnderlyingNonGradedRing( R ) ); if IsBound( RP!.AffineDimension ) or IsBound( RP!.CoefficientsOfUnreducedNumeratorOfHilbertPoincareSeries ) or IsBound( RP!.CoefficientsOfNumeratorOfHilbertPoincareSeries ) then ## hand over to UnderlyingModule; ## this avoids the unnecessary degree calls triggered by AffineDimension( M ) below TryNextMethod( ); fi; if not ( IsBound( RP!.CoefficientsOfUnreducedNumeratorOfWeightedHilbertPoincareSeries ) or IsBound( RP!.CoefficientsOfNumeratorOfWeightedHilbertPoincareSeries ) ) then TryNextMethod( ); fi; return AffineDimension( M ) <= HOMALG_MODULES.DimensionOfZeroModules; end ); ## # Fallback, works in general InstallMethod( IsArtinian, "LIGrMOD: for homalg graded modules", [ IsGradedModuleRep ], -10, function( M ) return IsEmptyMatrix( GeneratorsOfHomogeneousPart( HomalgElementToInteger( CastelnuovoMumfordRegularity( M ) ) + 1, M ) ); end ); ## # faster, needs a field as CoefficientsRing and a medthod AffineDimension InstallMethod( IsArtinian, "LIGrMOD: for homalg graded modules", [ IsGradedModuleRep ], function( M ) local S, R, K, RP; if IsZero( M ) then return true; fi; S := HomalgRing( M ); R := UnderlyingNonGradedRing( S ); K := CoefficientsRing( R ); if not ( HasIsFieldForHomalg( K ) and IsFieldForHomalg( K ) ) then TryNextMethod( ); fi; RP := homalgTable( R ); if not IsBound( RP!.AffineDimension ) then TryNextMethod( ); fi; return AffineDimension( M ) <= 0; end ); ## InstallMethod( IsCohenMacaulay, "LIGrMOD: for homalg graded modules", [ IsGradedModuleRep ], function( M ) local S, m; S := HomalgRing( M ); if IsHomalgLeftObjectOrMorphismOfLeftObjects( M ) then m := MaximalGradedLeftIdeal( S ); else m := MaximalGradedRightIdeal( S ); fi; return AffineDimension( M ) = Grade( m, M ); end ); #################################### # # methods for attributes: # #################################### ## InstallMethod( Annihilator, "for homalg graded modules", [ IsGradedModuleRep ], function( M ) return GradedModule( Annihilator( UnderlyingModule( M ) ), HomalgRing( M ) ); end ); ## InstallMethod( BettiTable, "LIGrMOD: for homalg graded modules", [ IsHomalgGradedModule ], function( M ) local C, degrees, min, C_degrees, l, ll, r, beta; ## M = coker( F_0 <-- F_1 ) C := Resolution( 1, M ); ## [ F_0, F_1 ]; C := ObjectsOfComplex( C ){[ 1 .. 2 ]}; ## the list of generators degrees of F_0 and F_1 degrees := List( C, DegreesOfGenerators ); degrees := List( degrees, i -> List( i, HomalgElementToInteger ) ); ## the homological degrees of the resolution complex C: F_0 <- F_1 C_degrees := [ 0 .. 1 ]; ## a counting list l := [ 1 .. Length( C_degrees ) ]; ## the non-empty list ll := Filtered( l, j -> degrees[j] <> [ ] ); ## the degree of the lowest row in the Betti diagram if ll <> [ ] then r := MaximumList( List( ll, j -> MaximumList( degrees[j] ) - ( j - 1 ) ) ); else r := 0; fi; ## the lowest generator degree of F_0 if degrees[1] <> [ ] then min := MinimumList( degrees[1] ); else min := r; fi; ## the row range of the Betti diagram r := [ min .. r ]; ## the Betti table beta := List( r, i -> List( l, j -> Length( Filtered( degrees[j], a -> a = i + ( j - 1 ) ) ) ) ); return HomalgBettiTable( beta, r, C_degrees, M ); end ); ## InstallMethod( CastelnuovoMumfordRegularity, "LIGrMOD: for homalg graded modules", [ IsGradedModuleRep ], function( M ) local S, B, nS, nB, max, B_S, B2, l; S := HomalgRing( M ); B := BaseRing( S ); nS := Length( Indeterminates( S ) ); nB := Length( Indeterminates( B ) ); ## FIXME: use IrrelevantIdeal( M ) if IsHomalgLeftObjectOrMorphismOfLeftObjects( M ) then max := CertainRows( MaximalIdealAsColumnMatrix( S ), [ nB+1 .. nS ] ); B_S := LeftPresentationWithDegrees( max ); else max := CertainColumns( MaximalIdealAsRowMatrix( S ), [ nB+1 .. nS ] ); B_S := RightPresentationWithDegrees( max ); fi; # Computations with the residue class rings are inefficient B2 := S / max; SetWeightsOfIndeterminates( B2, WeightsOfIndeterminates( B ) ); l := List( [ 0 .. nS ], i-> HomalgElementToInteger( CastelnuovoMumfordRegularity( B2 * Tor( i, B_S, M ) ) ) - i ); return Maximum( l ); end ); ## InstallMethod( CastelnuovoMumfordRegularity, "LIGrMOD: for homalg graded modules", [ IsGradedModuleRep ], function( M ) local S, minus_infinity, betti, degrees, B, nS, nB, max, B_S, B2, l; S := HomalgRing( M ); minus_infinity := HOMALG_TOOLS.minus_infinity; ## TODO: Every ring should have a base ring if HasBaseRing( S ) and not IsIdenticalObj( BaseRing( S ), CoefficientsRing( S ) ) then TryNextMethod( ); fi; if IsZero( M ) then return minus_infinity; ## do not use IsQuasiZero unless it does not fall back to CastelnuovoMumfordRegularity elif AffineDimension( M ) = 0 then return Degree( HilbertPoincareSeries( M ) ); fi; betti := BettiTable( Resolution( M ) ); degrees := RowDegreesOfBettiTable( betti ); return degrees[Length(degrees)]; end ); ## FIXME: knowledge propagation suggests the use of IsFree in the list of conditions InstallMethod( CastelnuovoMumfordRegularity, "LIGrMOD: for homalg graded free modules", [ IsGradedModuleRep ],10, function( M ) local UM, minus_infinity, deg; UM := UnderlyingModule( M ); minus_infinity := HOMALG_TOOLS.minus_infinity; if HasIsFree( UM ) and IsFree( UM ) then if HasIsZero( M ) and IsZero( M ) then # todo: -infinity return minus_infinity; fi; deg := DegreesOfGenerators( M ); if IsList( deg ) and ( IsInt( deg[1] ) or IsHomalgElement( deg[ 1 ] ) ) then return Maximum( deg ); fi; fi; TryNextMethod( ); end ); ## InstallMethod( CastelnuovoMumfordRegularityOfSheafification, "LIGrMOD: for homalg graded modules", [ IsGradedModuleRep ], function( M ) local min_deg, CMreg; ## we cannot expect this to be less or equal to the ## Castelnuovo-Mumford regularity of the sheafification min_deg := Minimum( DegreesOfGenerators( M ) ); CMreg := CastelnuovoMumfordRegularity( M ); TateResolution( M, min_deg, CMreg ); if HasCastelnuovoMumfordRegularityOfSheafification( M ) then return CastelnuovoMumfordRegularityOfSheafification( M ); fi; TryNextMethod( ); end ); ## InstallGlobalFunction( LinearRegularityIntervalViaMinimalResolution, function( M ) local S, minus_infinity, dim, betti, cols, degrees, col0, col1, mat, rows, d, d0, d1; S := HomalgRing( M ); ## TODO: Every ring should have a base ring if HasBaseRing( S ) and not IsIdenticalObj( BaseRing( S ), CoefficientsRing( S ) ) then TryNextMethod( ); fi; minus_infinity := HOMALG_TOOLS.minus_infinity; if IsZero( M ) then return [ minus_infinity ]; ## do not use IsQuasiZero unless it does not fall back to CastelnuovoMumfordRegularity elif AffineDimension( M ) = 0 then return [ Degree( HilbertPoincareSeries( M ) ) ]; fi; if HasRelativeIndeterminatesOfPolynomialRing( S ) then dim := Length( RelativeIndeterminatesOfPolynomialRing( S ) ); else dim := Length( IndeterminatesOfPolynomialRing( S ) ); fi; betti := BettiTable( Resolution( M ) ); cols := ColumnDegreesOfBettiTable( betti ); cols := Intersection2( cols, [ dim - 1, dim ] ); if IsEmpty( cols ) then return [ minus_infinity ]; fi; degrees := RowDegreesOfBettiTable( betti ); ## 0 stands for Ext^0 col0 := Intersection2( cols, [ dim ] ); col0 := col0 + 1; d0 := minus_infinity; if not IsEmpty( col0 ) then mat := List( betti!.matrix, b -> b{col0} ); rows := Filtered( [ 1 .. Length( mat ) ], a -> not IsZero( mat[a] ) ); if not IsEmpty( rows ) then d := degrees{rows}; d0 := d[Length( rows )]; fi; fi; ## 1 stand for Ext^1 col1 := Intersection2( cols, [ dim - 1 ] ); col1 := col1 + 1; d1 := minus_infinity; if not IsEmpty( col1 ) then mat := List( betti!.matrix, b -> b{col1} ); rows := Filtered( [ 1 .. Length( mat ) ], a -> not IsZero( mat[a] ) ); if not IsEmpty( rows ) then d := degrees{rows}; d1 := d[Length( rows )] - 1; fi; fi; return [ d0 .. Maximum( d0, d1 ) ]; end ); ## InstallGlobalFunction( LinearRegularityIntervalViaExt01OverBaseField, function( M ) local S, minus_infinity, m, k, d0, d1, linreg; S := HomalgRing( M ); ## TODO: Every ring should have a base ring if HasBaseRing( S ) and not IsIdenticalObj( BaseRing( S ), CoefficientsRing( S ) ) then TryNextMethod( ); fi; minus_infinity := HOMALG_TOOLS.minus_infinity; if IsZero( M ) then return [ minus_infinity ]; ## do not use IsQuasiZero unless it does not fall back to CastelnuovoMumfordRegularity elif AffineDimension( M ) = 0 then return [ Degree( HilbertPoincareSeries( M ) ) ]; fi; if IsHomalgLeftObjectOrMorphismOfLeftObjects( M ) then m := MaximalGradedLeftIdeal( S ); else m := MaximalGradedRightIdeal( S ); fi; k := FactorObject( m ); d0 := Degree( HilbertPoincareSeries( GradedHom( k, M ) ) ); d1 := Degree( HilbertPoincareSeries( GradedExt( 1, k, M ) ) ); ## FIXME if d0 = -infinity then d0 := minus_infinity; fi; if d1 = -infinity then d1 := minus_infinity; fi; linreg := [ d0 .. Maximum( d0, d1 ) ]; SetLinearRegularityInterval( M, linreg ); return linreg; end ); ## InstallMethod( LinearRegularityInterval, "LIGrMOD: for homalg graded modules", [ IsGradedModuleRep ], LinearRegularityIntervalViaMinimalResolution ); ## InstallMethod( LinearRegularity, "LIGrMOD: for homalg graded modules", [ IsGradedModuleRep ], function( M ) local linreg; linreg := LinearRegularityInterval( M ); return linreg[Length( linreg )]; end ); ## InstallMethod( Depth, "LIMOD: for two homalg modules", [ IsGradedModuleRep, IsGradedModuleRep ], function( M, N ) return Depth( UnderlyingModule( M ), UnderlyingModule( N ) ); end ); ## InstallMethod( ResidueClassRing, "for homalg ideals", [ IsGradedSubmoduleRep and ConstructedAsAnIdeal ], function( J ) local S, R, RR, result, A; S := HomalgRing( J ); R := UnderlyingNonGradedRing( S ); Assert( 3, not J = S ); RR := ResidueClassRing( UnderlyingModule( J ) ); ## do not do this, use the given J #J := GradedModule( DefiningIdeal( RR ), S ); result := GradedRing( RR ); if HasContainsAField( S ) and ContainsAField( S ) then SetContainsAField( result, true ); if HasCoefficientsRing( S ) then SetCoefficientsRing( result, CoefficientsRing( S ) ); fi; fi; SetDefiningIdeal( result, J ); if HasAmbientRing( S ) then A := AmbientRing( S ); elif HasAmbientRing( R ) then A := GradedRing( AmbientRing( R ) ); else A := S; fi; SetAmbientRing( result, A ); SetRingRelations( result, A * RingRelations( RR ) ); return result; end ); ## InstallMethod( FullSubobject, "for homalg graded modules", [ IsGradedModuleRep ], function( M ) local subobject; if HasIsFree( UnderlyingModule( M ) ) and IsFree( UnderlyingModule( M ) ) then subobject := ImageSubobject( TheIdentityMorphism( M ) ); else subobject := ImageSubobject( GradedMap( FullSubobject( UnderlyingModule( M ) )!.map_having_subobject_as_its_image, "create", M ) ); fi; SetEmbeddingInSuperObject( subobject, TheIdentityMorphism( M ) ); return subobject; end ); ## InstallMethod( ZeroSubobject, "for homalg graded modules", [ IsGradedModuleRep ], function( M ) local alpha; alpha := ZeroSubobject( UnderlyingModule( M ) )!.map_having_subobject_as_its_image; return UnderlyingSubobject( ImageObject( GradedMap( alpha, "create", M ) ) ); end ); ## InstallMethod( ZerothRegularity, "for homalg graded modules", [ IsGradedModuleRep ], function( M ) local B, r_min, r_max, c, last_column, reg, i, j; B := BettiTable( Resolution( M ) ); r_min := HomalgElementToInteger( RowDegreesOfBettiTable( B )[ 1 ] ); r_max := HomalgElementToInteger( RowDegreesOfBettiTable( B )[ Length( RowDegreesOfBettiTable( B ) ) ] ); c := Length( ColumnDegreesOfBettiTable( B ) ); last_column := List( MatrixOfDiagram( B ), function( a ) return a[c]; end ); reg := r_min; for i in [ r_min + 1 .. r_max ] do j := i - r_min + 1; if not IsZero( last_column[j] ) then reg := i; fi; od; return reg; end ); ## InstallMethod( TrivialArtinianSubmodule, "for homalg graded modules", [ IsGradedModuleRep ], function( M ) local S, k; S := HomalgRing( M ); if IsHomalgLeftObjectOrMorphismOfLeftObjects( M ) then k := ResidueClassRingAsGradedLeftModule( S ); else k := ResidueClassRingAsGradedRightModule( S ); fi; return IsZero( GradedHom( k, M ) ); end ); ## InstallMethod( CoefficientsOfUnreducedNumeratorOfHilbertPoincareSeries, "for a homalg graded module", [ IsGradedModuleRep ], function( M ) local R, weights, degrees; R := HomalgRing( M ); weights := WeightsOfIndeterminates( R ); weights := List( weights, HomalgElementToInteger ); degrees := DegreesOfGenerators( M ); degrees := List( degrees, HomalgElementToInteger ); return CoefficientsOfUnreducedNumeratorOfHilbertPoincareSeries( UnderlyingModule( M ), weights, degrees ); end ); ## InstallMethod( CoefficientsOfNumeratorOfHilbertPoincareSeries, "for a homalg graded module", [ IsGradedModuleRep ], CoefficientsOfNumeratorOfHilbertPoincareSeries_ViaBettiTableOfMinimalFreeResolution ); ## InstallMethod( CoefficientsOfNumeratorOfHilbertPoincareSeries, "for a homalg graded module", [ IsGradedModuleRep ], function( M ) local R, weights, degrees, coeffs; R := HomalgRing( M ); weights := List( WeightsOfIndeterminates( R ), HomalgElementToInteger ); degrees := List( DegreesOfGenerators( M ), HomalgElementToInteger ); coeffs := CoefficientsOfNumeratorOfHilbertPoincareSeries( UnderlyingModule( M ), weights, degrees ); if coeffs = fail then TryNextMethod( ); fi; return coeffs; end ); ## InstallMethod( UnreducedNumeratorOfHilbertPoincareSeries, "for a homalg graded module and a ring element", [ IsGradedModuleRep, IsRingElement ], function( M, lambda ) local R, weights, degrees; R := HomalgRing( M ); weights := WeightsOfIndeterminates( R ); weights := List( weights, HomalgElementToInteger ); degrees := DegreesOfGenerators( M ); degrees := List( degrees, HomalgElementToInteger ); return UnreducedNumeratorOfHilbertPoincareSeries( UnderlyingModule( M ), weights, degrees, lambda ); end ); ## InstallMethod( UnreducedNumeratorOfHilbertPoincareSeries, "for a homalg graded module", [ IsGradedModuleRep ], function( M ) return UnreducedNumeratorOfHilbertPoincareSeries( M, VariableForHilbertPoincareSeries( ) ); end ); ## InstallMethod( NumeratorOfHilbertPoincareSeries, "for a homalg graded module and a ring element", [ IsGradedModuleRep, IsRingElement ], function( M, lambda ) local R, weights, degrees; R := HomalgRing( M ); weights := List( WeightsOfIndeterminates( R ), HomalgElementToInteger ); degrees := List( DegreesOfGenerators( M ), HomalgElementToInteger ); return NumeratorOfHilbertPoincareSeries( UnderlyingModule( M ), weights, degrees, lambda ); end ); ## InstallMethod( NumeratorOfHilbertPoincareSeries, "for a homalg graded module", [ IsGradedModuleRep ], function( M ) return NumeratorOfHilbertPoincareSeries( M, VariableForHilbertPoincareSeries( ) ); end ); ## InstallMethod( HilbertPoincareSeries, "for a homalg graded module", [ IsGradedModuleRep, IsRingElement ], HilbertPoincareSeries_ViaBettiTableOfMinimalFreeResolution ); ## InstallMethod( HilbertPoincareSeries, "for a homalg graded module", [ IsGradedModuleRep, IsRingElement ], function( M, lambda ) local R, weights, degrees, series; R := HomalgRing( M ); weights := List( WeightsOfIndeterminates( R ), HomalgElementToInteger ); degrees := List( DegreesOfGenerators( M ), HomalgElementToInteger ); series := HilbertPoincareSeries( UnderlyingModule( M ), weights, degrees, lambda ); if series = fail then TryNextMethod( ); fi; return series; end ); ## InstallMethod( HilbertPoincareSeries, "for a homalg graded module", [ IsGradedModuleRep ], function( M ) return HilbertPoincareSeries( M, VariableForHilbertPoincareSeries( ) ); end ); ## InstallMethod( HilbertPoincareSeries, "for a Betti diagram, an integer, and a ring element", [ IsBettiTable, IsInt, IsRingElement ], function( betti, n, s ) local row_range, col_range, r, hilb; row_range := RowDegreesOfBettiTable( betti ); col_range := ColumnDegreesOfBettiTable( betti ); r := Length( row_range ); betti := MatrixOfDiagram( betti ); hilb := 1 / ( 1 - s )^n * Sum( col_range, i -> (-1)^i * Sum( [ 1 .. r ], k -> betti[k][i + 1] * s^(i + row_range[k]) ) ); return hilb; end ); ## InstallMethod( HilbertPoincareSeries, [ IsBettiTable, IsHomalgElement, IsRingElement ], function( betti, n, s ) return HilbertPoincareSeries( betti, HomalgElementToInteger( n ), s ); end ); ## InstallMethod( HilbertPoincareSeries, "for a Betti diagram and an integer", [ IsBettiTable, IsInt ], function( betti, n ) local s; s := VariableForHilbertPoincareSeries( ); return HilbertPoincareSeries( betti, n, s ); end ); ## InstallMethod( HilbertPoincareSeries, [ IsBettiTable, IsHomalgElement ], function( betti, n ) return HilbertPoincareSeries( betti, HomalgElementToInteger( n ) ); end ); ## InstallMethod( HilbertPolynomial, "for a homalg graded module", [ IsGradedModuleRep, IsRingElement ], HilbertPolynomial_ViaBettiTableOfMinimalFreeResolution ); ## InstallMethod( HilbertPolynomial, "for a homalg graded module", [ IsGradedModuleRep, IsRingElement ], function( M, lambda ) local R, weights, degrees, hilb; R := HomalgRing( M ); weights := List( WeightsOfIndeterminates( R ), HomalgElementToInteger ); degrees := List( DegreesOfGenerators( M ), HomalgElementToInteger ); hilb := HilbertPolynomial( UnderlyingModule( M ), weights, degrees, lambda ); if hilb = fail then TryNextMethod( ); fi; return hilb; end ); ## InstallMethod( HilbertPolynomial, "for a homalg graded module", [ IsGradedModuleRep ], function( M ) return HilbertPolynomial( M, VariableForHilbertPolynomial( ) ); end ); ## InstallMethod( HilbertPolynomial, "for a Betti diagram, an integer, and a ring element", [ IsBettiTable, IsInt, IsRingElement ], function( betti, n, s ) local series; series := HilbertPoincareSeries( betti, n, s ); return HilbertPolynomialOfHilbertPoincareSeries( series ); end ); ## InstallMethod( HilbertPolynomial, "for a Betti diagram and an integer", [ IsBettiTable, IsInt ], function( betti, n ) local t; t := VariableForHilbertPolynomial( ); return HilbertPolynomial( betti, n, t ); end ); ## InstallMethod( HilbertPolynomial, [ IsBettiTable, IsHomalgElement, IsRingElement ], function( betti, n, s ) return HilbertPolynomial( betti, HomalgElementToInteger( n ), s ); end ); ## InstallMethod( HilbertPolynomial, [ IsBettiTable, IsHomalgElement ], function( betti, n ) return HilbertPolynomial( betti, HomalgElementToInteger( n ) ); end ); ## for CASs which do not support Hilbert* for non-graded modules InstallMethod( AffineDimension, "for a homalg graded module", [ IsGradedModuleRep ], function( M ) local R, weights, degrees; R := HomalgRing( M ); weights := List( WeightsOfIndeterminates( R ), HomalgElementToInteger ); degrees := List( DegreesOfGenerators( M ), HomalgElementToInteger ); return AffineDimension( UnderlyingModule( M ), weights, degrees ); end ); ## InstallMethod( AffineDegree, "for a homalg graded module", [ IsGradedModuleRep ], function( M ) local R, weights, degrees; R := HomalgRing( M ); weights := List( WeightsOfIndeterminates( R ), HomalgElementToInteger ); degrees := List( DegreesOfGenerators( M ), HomalgElementToInteger ); return AffineDegree( UnderlyingModule( M ), weights, degrees ); end ); ## InstallMethod( ProjectiveDegree, "for a homalg graded module", [ IsGradedModuleRep ], function( M ) local R, weights, degrees; R := HomalgRing( M ); weights := List( WeightsOfIndeterminates( R ), HomalgElementToInteger ); degrees := List( DegreesOfGenerators( M ), HomalgElementToInteger ); return ProjectiveDegree( UnderlyingModule( M ), weights, degrees ); end ); ## InstallMethod( ConstantTermOfHilbertPolynomial, "for a homalg graded module", [ IsGradedModuleRep ], function( M ) local R, weights, degrees; R := HomalgRing( M ); weights := List( WeightsOfIndeterminates( R ), HomalgElementToInteger ); degrees := List( DegreesOfGenerators( M ), HomalgElementToInteger ); return ConstantTermOfHilbertPolynomial( UnderlyingModule( M ), weights, degrees ); end ); ## InstallGlobalFunction( HilbertPoincareSeries_ViaBettiTableOfMinimalFreeResolution, function( arg ) local M, s, betti, n; if Length( arg ) > 0 then M := arg[1]; else Error( "empty arguments\n" ); fi; if Length( arg ) > 1 and IsRingElement( arg[2] ) then s := arg[2]; else s := VariableForHilbertPoincareSeries( ); fi; if IsZero( M ) then return 0 * s; fi; betti := BettiTable( Resolution( M ) ); n := Length( IndeterminatesOfPolynomialRing( HomalgRing( M ) ) ); return HilbertPoincareSeries( betti, n, s ); end ); ## InstallGlobalFunction( CoefficientsOfNumeratorOfHilbertPoincareSeries_ViaBettiTableOfMinimalFreeResolution, function( M ) local series; series := HilbertPoincareSeries_ViaBettiTableOfMinimalFreeResolution( M ); return CoefficientsOfNumeratorOfHilbertPoincareSeries( series ); end ); ## InstallGlobalFunction( HilbertPolynomial_ViaBettiTableOfMinimalFreeResolution, function( arg ) local series; series := CallFuncList( HilbertPoincareSeries_ViaBettiTableOfMinimalFreeResolution, arg ); return HilbertPolynomialOfHilbertPoincareSeries( series ); end ); ## InstallMethod( PrimaryDecomposition, "for homalg graded modules", [ IsGradedModuleRep ], function( M ) return List( PrimaryDecomposition( UnderlyingModule( M ) ), function( pp ) local primary, prime; ##FIXME: fix the degrees primary := ImageSubobject( GradedMap( pp[1]!.map_having_subobject_as_its_image, "create", "create", HomalgRing( M ) ) ); prime := ImageSubobject( GradedMap( pp[2]!.map_having_subobject_as_its_image, "create", "create", HomalgRing( M ) ) ); return [ primary, prime ]; end ); end ); ## InstallMethod( RadicalDecomposition, "for homalg graded modules", [ IsGradedModuleRep ], function( M ) return List( RadicalDecomposition( UnderlyingModule( M ) ), function( pp ) ##FIXME: fix the degrees return ImageSubobject( GradedMap( pp!.map_having_subobject_as_its_image, "create", "create", HomalgRing( M ) ) ); end ); end ); ## InstallMethod( ModuleOfKaehlerDifferentials, "for homalg rings", [ IsHomalgRing and HasRingRelations ], function( R ) local A, var, I, jac; A := AmbientRing( R ); if not ( HasIsFreePolynomialRing( A ) and IsFreePolynomialRing( A ) ) then TryNextMethod( ); fi; var := Indeterminates( A ); var := HomalgMatrix( var, 1, Length( var ), A ); I := MatrixOfRelations( R ); jac := R * Diff( var, I ); return LeftPresentation( jac ); end ); ## InstallMethod( ModuleOfKaehlerDifferentials, "for homalg rings", [ IsHomalgGradedRingRep and HasRingRelations ], function( S ) local R, K; R := UnderlyingNonGradedRing( S ); K := ModuleOfKaehlerDifferentials( R ); return GradedModule( K, S ); end ); ## InstallMethod( SymmetricAlgebra, "for a homalg matrix", [ IsHomalgMatrixOverGradedRingRep, IsList ], function( M, gvar ) local n, R, Sym, weights, rel; n := NrColumns( M ); if not n = Length( gvar ) then Error( "the length of the list of variables is ", "not equal to the number of columns of the matrix\n" ); fi; R := HomalgRing( M ); Sym := R * gvar; weights := Concatenation( ListWithIdenticalEntries( Length( Indeterminates( R ) ), 0 ), ListWithIdenticalEntries( Length( gvar ), 1 ) ); SetWeightsOfIndeterminates( Sym, weights ); gvar := RelativeIndeterminatesOfPolynomialRing( Sym ); gvar := HomalgMatrix( gvar, Length( gvar ), 1, Sym ); rel := GradedLeftSubmodule( ( Sym * M ) * gvar ); Sym := Sym / rel; SetDefiningIdeal( Sym, rel ); return Sym; end ); ## InstallMethod( ExteriorAlgebra, "for a homalg matrix", [ IsHomalgMatrixOverGradedRingRep, IsList ], function( M, gvar ) local n, R, S, weights, A, rel; n := NrColumns( M ); if not n = Length( gvar ) then Error( "the length of the list of variables is ", "not equal to the number of columns of the matrix\n" ); fi; R := HomalgRing( M ); S := R * List( gvar, v -> Concatenation( "XX", v ) ); weights := Concatenation( ListWithIdenticalEntries( Length( Indeterminates( R ) ), 0 ), ListWithIdenticalEntries( Length( gvar ), -1 ) ); SetWeightsOfIndeterminates( S, weights ); A := KoszulDualRing( S, gvar ); gvar := IndeterminateAntiCommutingVariablesOfExteriorRing( A ); gvar := HomalgMatrix( gvar, Length( gvar ), 1, A ); rel := GradedLeftSubmodule( ( A * M ) * gvar ); A := A / rel; SetDefiningIdeal( A, rel ); return A; end ); ## InstallMethod( SymmetricPower, "for free modules", [ IsInt, IsGradedModuleRep and IsFree ], function( k, M ) local R, r, degrees, l, P, powers; if HasSymmetricPowers( M ) then powers := SymmetricPowers( M ); else powers := rec( ); fi; if IsBound( powers!.( k ) ) then return powers!.( k ); fi; R := HomalgRing( M ); r := Rank( M ); degrees := DegreesOfGenerators( M ); l := Length( degrees ); if k in [ 0 .. l ] then degrees := List( UnorderedTuples( [ 1 .. l ], k ), i -> Sum( degrees{i} ) ); else degrees := [ ]; fi; if IsHomalgLeftObjectOrMorphismOfLeftObjects( M ) then P := FreeLeftModuleWithDegrees( R, degrees ); else P := FreeRightModuleWithDegrees( R, degrees ); fi; SetIsSymmetricPower( P, true ); SetSymmetricPowerExponent( P, k ); SetSymmetricPowerBaseModule( P, M ); powers!.( k ) := P; SetSymmetricPowers( M, powers ); return P; end ); ## InstallMethod( SymmetricPower, "for graded modules", [ IsInt, IsGradedModuleRep ], function( k, M ) local phi, T; if k = 0 then return One( M ); elif k = 1 then return M; elif not k in [ 2 .. NrGenerators( M ) ] then return Zero( M ); fi; phi := PresentationMorphism( M ); T := SymmetricPower( k, Range( phi ) ); phi := SymmetricPowerOfPresentationMorphism( k, phi ); phi := GradedMap( phi, "free", T ); return Cokernel( phi ); end ); ## InstallMethod( ExteriorPower, "for free modules", [ IsInt, IsGradedModuleRep and IsFree ], function( k, M ) local R, r, degrees, l, P, powers; if HasExteriorPowers( M ) then powers := ExteriorPowers( M ); else powers := rec( ); fi; if IsBound( powers!.( k ) ) then return powers!.( k ); fi; R := HomalgRing( M ); r := Rank( M ); degrees := DegreesOfGenerators( M ); l := Length( degrees ); if k in [ 0 .. l ] then degrees := List( Combinations( [ 1 .. l ], k ), i -> Sum( degrees{i} ) ); else degrees := [ ]; fi; if IsHomalgLeftObjectOrMorphismOfLeftObjects( M ) then P := FreeLeftModuleWithDegrees( R, degrees ); else P := FreeRightModuleWithDegrees( R, degrees ); fi; SetIsExteriorPower( P, true ); SetExteriorPowerExponent( P, k ); SetExteriorPowerBaseModule( P, M ); powers!.( k ) := P; SetExteriorPowers( M, powers ); return P; end ); ## InstallMethod( ExteriorPower, "for a graded map", [ IsInt, IsMapOfGradedModulesRep ], function( k, phi ) local S, T, mat; S := Source( phi ); T := Range( phi ); mat := MatrixOfMap( phi ); S := ExteriorPower( k, S ); T := ExteriorPower( k, T ); mat := ExteriorPower( k, mat ); return GradedMap( mat, S, T ); end ); ## InstallMethod( ExteriorPower, "for graded modules", [ IsInt, IsGradedModuleRep ], function( k, M ) local phi, T; if k = 0 then return One( M ); elif k = 1 then return M; elif not k in [ 2 .. NrGenerators( M ) ] then return Zero( M ); fi; phi := PresentationMorphism( M ); T := ExteriorPower( k, Range( phi ) ); phi := ExteriorPowerOfPresentationMorphism( k, phi ); phi := GradedMap( phi, "free", T ); return Cokernel( phi ); end ); ## InstallMethod( GradedTorsionFreeFactor, "for graded modules", [ IsGradedModuleRep ], function( M ) local S, m, k, N, pi; S := HomalgRing( M ); if IsHomalgLeftObjectOrMorphismOfLeftObjects( M ) then m := MaximalGradedLeftIdeal( S ); else m := MaximalGradedRightIdeal( S ); fi; k := FactorObject( m ); N := GradedHom( k, M ); if IsZero( N ) then return M; fi; pi := CokernelEpi( EmbeddingInSuperObject( m ) ); while not IsZero( N ) do M := Cokernel( GradedHom( S, GradedHom( pi, M ) ) ); N := GradedHom( k, M ); od; return M; end ); ## InstallMethod( SaturateToDegreeZero, "for graded modules", [ IsGradedModuleRep ], function( M ) local S, m, iota, phi; S := HomalgRing( M ); if IsHomalgLeftObjectOrMorphismOfLeftObjects( M ) then m := MaximalGradedLeftIdeal( S ); else m := MaximalGradedRightIdeal( S ); fi; M := GradedTorsionFreeFactor( M ); iota := EmbeddingInSuperObject( m ); while LinearRegularity( M ) >= 0 do phi := GradedHom( S, GradedHom( iota, M ) ); M := Range( phi ); od; return M; end );