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############################################################################# ## ## LIMOD.gi LIMOD subpackage Mohamed Barakat ## ## LIMOD = Logical Implications for homalg MODules ## ## Copyright 2007-2008 Lehrstuhl B für Mathematik, RWTH Aachen ## ## Implementation stuff for the LIMOD subpackage. ## ############################################################################# #################################### # # global variables: # #################################### # a central place for configuration variables: InstallValue( LIMOD, rec( color := "\033[4;30;46m", ## used in a InstallLogicalImplicationsForHomalgSubobjects call below intrinsic_properties_specific_shared_with_subobjects_and_ideals := [ "IsFree", "IsStablyFree", "IsCyclic", "HasConstantRank", ], ## used in a InstallLogicalImplicationsForHomalgSubobjects call below intrinsic_properties_specific_shared_with_factors_modulo_ideals := [ "IsPrimeModule", "IsHolonomic", "IsReduced", ], 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 HomalgSubmodule.gi intrinsic_properties_shared_with_subobjects_and_ideals := Concatenation( LIOBJ.intrinsic_properties_shared_with_subobjects_and_ideals, ~.intrinsic_properties_specific_shared_with_subobjects_and_ideals ), ## intrinsic_properties_shared_with_factors_modulo_ideals := Concatenation( LIOBJ.intrinsic_properties_shared_with_factors_modulo_ideals, ~.intrinsic_properties_specific_shared_with_factors_modulo_ideals ), ## needed for MatchPropertiesAndAttributes in HomalgSubmodule.gi intrinsic_properties_shared_with_subobjects_which_are_not_ideals := Concatenation( LIOBJ.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( LIOBJ.intrinsic_properties, ~.intrinsic_properties_specific ), ## used in a InstallLogicalImplicationsForHomalgSubobjects call below intrinsic_attributes_specific_shared_with_subobjects_and_ideals := [ ], ## 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 "ElementaryDivisors", "FittingIdeal", "NonFlatLocus", "LargestMinimalNumberOfLocalGenerators", ], 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 HomalgSubmodule.gi intrinsic_attributes_shared_with_subobjects_and_ideals := Concatenation( LIOBJ.intrinsic_attributes_shared_with_subobjects_and_ideals, ~.intrinsic_attributes_specific_shared_with_subobjects_and_ideals ), ## intrinsic_attributes_shared_with_factors_modulo_ideals := Concatenation( LIOBJ.intrinsic_attributes_shared_with_factors_modulo_ideals, ~.intrinsic_attributes_specific_shared_with_factors_modulo_ideals ), ## needed for MatchPropertiesAndAttributes in HomalgSubmodule.gi intrinsic_attributes_shared_with_subobjects_which_are_not_ideals := Concatenation( LIOBJ.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( LIOBJ.intrinsic_attributes, ~.intrinsic_attributes_specific ), ) ); ## ## take care that we distinguish between objects and subobjects: ## some properties of a subobject might be those of the factor ## and not of the underlying object ## InstallValue( LogicalImplicationsForHomalgModules, [ ## IsTorsionFree: [ IsZero, "implies", IsFree ], [ IsFree, "implies", IsStablyFree ], [ IsStablyFree, "implies", IsProjective ], ## Serre's 1955 remark: ## for a module with a finite free resolution (FFR) ## "projective" and "stably free" are equivalent [ IsProjective, "and", FiniteFreeResolutionExists, "imply", IsStablyFree ], ## IsTorsion: [ IsZero, "and", IsFinitelyPresentedModuleRep, "imply", IsHolonomic ], [ IsZero, "and", IsFinitelyPresentedSubmoduleRep, "and", NotConstructedAsAnIdeal, "imply", IsHolonomic ], ## [ IsHolonomic, ## "implies", IsTorsion ], false for fields ## [ IsHolonomic, ## "implies", IsArtinian ], there is no clear definition of holonomic ## see homalg/LIOBJ.gi for more implications ] ); ## InstallValue( LogicalImplicationsForHomalgModulesOverSpecialRings, [ ## logical implications for modules over special rings ## Kaplansky's theorem [Lam06, Theorem II.2.2] [ [ IsTorsionFree ], HomalgRing, [ [ IsLeftHereditary ], [ IsRightHereditary ], [ IsHereditary ] ], "imply", IsProjective, 0 ], ## Serre's 1955 remark [ [ IsProjective ], HomalgRing, [ [ IsLeftFiniteFreePresentationRing ], [ IsRightFiniteFreePresentationRing ], [ IsFiniteFreePresentationRing ], ], "imply", IsStablyFree, 0 ], ## by definition [Lam06, Definition I.4.6] [ [ IsStablyFree ], HomalgRing, [ [ IsLeftHermite ], [ IsRightHermite ], [ IsHermite ] ], "imply", IsFree, 0 ], ## projective modules over local domains are free [ [ IsProjective ], HomalgRing, [ [ IsLocal, IsIntegralDomain ] ], "imply", IsFree, 1001 ], ] ); #################################### # # logical implications methods: # #################################### InstallLogicalImplicationsForHomalgSubobjects( List( LIMOD.intrinsic_properties_specific_shared_with_subobjects_which_are_not_ideals, ValueGlobal ), IsFinitelyPresentedSubmoduleRep and NotConstructedAsAnIdeal, HasEmbeddingInSuperObject, UnderlyingObject ); InstallLogicalImplicationsForHomalgSubobjects( List( LIMOD.intrinsic_properties_specific_shared_with_subobjects_and_ideals, ValueGlobal ), IsFinitelyPresentedSubmoduleRep and ConstructedAsAnIdeal, HasEmbeddingInSuperObject, UnderlyingObject ); InstallLogicalImplicationsForHomalgSubobjects( List( LIMOD.intrinsic_properties_specific_shared_with_factors_modulo_ideals, ValueGlobal ), IsFinitelyPresentedSubmoduleRep and ConstructedAsAnIdeal, HasFactorObject, FactorObject ); InstallLogicalImplicationsForHomalgSubobjects( List( LIMOD.intrinsic_attributes_specific_shared_with_subobjects_which_are_not_ideals, ValueGlobal ), IsFinitelyPresentedSubmoduleRep and NotConstructedAsAnIdeal, HasEmbeddingInSuperObject, UnderlyingObject ); InstallLogicalImplicationsForHomalgSubobjects( List( LIMOD.intrinsic_attributes_specific_shared_with_subobjects_and_ideals, ValueGlobal ), IsFinitelyPresentedSubmoduleRep and ConstructedAsAnIdeal, HasEmbeddingInSuperObject, UnderlyingObject ); InstallLogicalImplicationsForHomalgSubobjects( List( LIMOD.intrinsic_attributes_specific_shared_with_factors_modulo_ideals, ValueGlobal ), IsFinitelyPresentedSubmoduleRep and ConstructedAsAnIdeal, HasFactorObject, FactorObject ); #################################### # # immediate methods for properties: # #################################### ## InstallImmediateMethod( IsZero, IsFinitelyPresentedModuleRep and HasAffineDimension, 0, function( M ) return AffineDimension( M ) <= HOMALG_MODULES.DimensionOfZeroModules; end ); ## InstallImmediateMethod( IsTorsion, IsElementOfAnObjectGivenByAMorphismRep, 0, function( m ) local M; M := SuperObject( m ); if HasIsTorsionFree( M ) and IsTorsionFree( M ) then ## in a torsion-free module only zero is torsion if HasIsZero( m ) and not IsZero( m ) then return false; fi; elif HasIsTorsion( M ) and IsTorsion( M ) then ## every element in a torsion module is torsion return true; fi; TryNextMethod( ); end ); ## InstallImmediateMethod( IsTorsion, IsElementOfAnObjectGivenByAMorphismRep and HasAnnihilator, 0, function( m ) local Ann, M, R; Ann := Annihilator( m ); if HasIsZero( Ann ) then M := SuperObject( m ); ## we assume that the ring R ≠ 0 if IsZero( Ann ) then ## 0 ≠ R = R / Ann( m ) ≅ R m ≤ M SetIsTorsion( M, false ); return false; elif not HasIsZero( m ) then TryNextMethod( ); elif IsZero( m ) then return true; fi; ## we now know that m ≠ 0 and Ann( m ) ≠ 0 R := HomalgRing( m ); ## Z/2 is torsion-free over Z/6 with annihilator <3> if HasIsIntegralDomain( R ) and IsIntegralDomain( R ) then SetIsTorsionFree( M, false ); return true; fi; fi; TryNextMethod( ); end ); ## InstallImmediateMethod( IsTorsion, IsElementOfAnObjectGivenByAMorphismRep and IsZero, 0, function( m ) return true; end ); ## InstallImmediateMethod( IsArtinian, IsFinitelyPresentedModuleRep and HasGrade, 0, function( M ) local R, global_dimension; R := HomalgRing( M ); if IsHomalgLeftObjectOrMorphismOfLeftObjects( M ) then global_dimension := LeftGlobalDimension; else global_dimension := RightGlobalDimension; fi; if Tester( global_dimension )( R ) and ( ( HasIsFreePolynomialRing( R ) and IsFreePolynomialRing( R ) ) or ( HasIsWeylRing( R ) and IsWeylRing( R ) ) or ( HasIsLocalizedWeylRing( R ) and IsLocalizedWeylRing( R ) ) ) then return Grade( M ) = global_dimension( R ); fi; TryNextMethod( ); end ); ## a presentation must be on a single generator InstallImmediateMethod( IsCyclic, IsFinitelyPresentedModuleRep, 0, function( M ) local l, p, rel; l := ListOfPositionsOfKnownSetsOfRelations( M ); for p in l do; rel := RelationsOfModule( M, p ); if IsHomalgRelations( rel ) then if HasNrGenerators( rel ) and NrGenerators( rel ) = 1 then return true; fi; fi; od; TryNextMethod( ); end ); ## [Coutinho, A Primer of Algebraic D-modules, Thm. 10.25, p. 90] InstallImmediateMethod( IsCyclic, IsFinitelyPresentedModuleRep and IsArtinian, 0, function( M ) local R; R := HomalgRing( M ); if not ( HasIsSimpleRing( R ) and IsSimpleRing( R ) ) then TryNextMethod( ); fi; if IsHomalgLeftObjectOrMorphismOfLeftObjects( M ) then if HasIsLeftNoetherian( R ) and IsLeftNoetherian( R ) and HasIsLeftArtinian( R ) and not IsLeftArtinian( R ) then return true; fi; else if HasIsRightNoetherian( R ) and IsRightNoetherian( R ) and HasIsRightArtinian( R ) and not IsRightArtinian( R ) then return true; fi; fi; TryNextMethod( ); end ); ## strictly less relations than generators => not IsTorsion InstallImmediateMethod( IsTorsion, IsFinitelyPresentedModuleRep, 0, function( M ) local l, p, rel; l := ListOfPositionsOfKnownSetsOfRelations( M ); for p in l do; rel := RelationsOfModule( M, p ); if IsHomalgRelations( rel ) then if HasNrGenerators( rel ) and HasNrRelations( rel ) and NrGenerators( rel ) > NrRelations( rel ) then return false; fi; fi; od; TryNextMethod( ); end ); ## a non trivial set of relations for a single generator over a domain => IsTorsion InstallImmediateMethod( IsTorsion, IsFinitelyPresentedModuleRep and IsCyclic, 0, function( M ) local l, p, rel, R, torsion; l := ListOfPositionsOfKnownSetsOfRelations( M ); for p in l do; rel := RelationsOfModule( M, p ); if IsHomalgRelations( rel ) and HasEvaluatedMatrixOfRelations( rel ) then if HasNrGenerators( rel ) and NrGenerators( rel ) = 1 and HasIsZero( MatrixOfRelations( rel ) ) then R := HomalgRing( rel ); if HasIsIntegralDomain( R ) and IsIntegralDomain( R ) then torsion := not IsZero( MatrixOfRelations( rel ) ); SetIsTorsion( rel, torsion ); return torsion; fi; fi; fi; od; TryNextMethod( ); end ); ## InstallImmediateMethod( IsTorsion, IsFinitelyPresentedModuleOrSubmoduleRep and HasRankOfObject, 0, function( M ) local R; R := HomalgRing( M ); ## Z/2 is torsion-free over Z/6 with annihilator <3> if HasIsIntegralDomain( R ) and IsIntegralDomain( R ) then return RankOfObject( M ) = 0; fi; TryNextMethod( ); end ); ## InstallImmediateMethod( IsTorsionFree, IsFinitelyPresentedModuleRep and HasIsProjective, 0, function( M ) local R, global_dimension; R := HomalgRing( M ); if IsHomalgLeftObjectOrMorphismOfLeftObjects( M ) then global_dimension := LeftGlobalDimension; else global_dimension := RightGlobalDimension; fi; if Tester( global_dimension )( R ) and global_dimension( R ) <= 1 and not IsProjective( M ) then return false; fi; ## the true case is taken care of elsewhere TryNextMethod( ); end ); ## InstallImmediateMethod( IsReflexive, IsFinitelyPresentedModuleRep and HasIsProjective, 0, function( M ) local R, global_dimension; R := HomalgRing( M ); if IsHomalgLeftObjectOrMorphismOfLeftObjects( M ) then global_dimension := LeftGlobalDimension; else global_dimension := RightGlobalDimension; fi; if Tester( global_dimension )( R ) and global_dimension( R ) <= 2 and not IsProjective( M ) then return false; fi; ## the true case is taken care of elsewhere TryNextMethod( ); end ); ## InstallImmediateMethod( IsProjective, IsFinitelyPresentedModuleRep and IsTorsionFree, 0, function( M ) local R, global_dimension; R := HomalgRing( M ); if IsHomalgLeftObjectOrMorphismOfLeftObjects( M ) then global_dimension := LeftGlobalDimension; else global_dimension := RightGlobalDimension; fi; if Tester( global_dimension )( R ) and global_dimension( R ) <= 1 then return true; fi; ## the false case is taken care of elsewhere TryNextMethod( ); end ); ## InstallImmediateMethod( IsProjective, IsFinitelyPresentedModuleRep and IsReflexive, 0, function( M ) local R, global_dimension; R := HomalgRing( M ); if IsHomalgLeftObjectOrMorphismOfLeftObjects( M ) then global_dimension := LeftGlobalDimension; else global_dimension := RightGlobalDimension; fi; if Tester( global_dimension )( R ) and global_dimension( R ) <= 2 then return true; fi; TryNextMethod( ); end ); ## InstallImmediateMethod( IsFree, IsFinitelyPresentedModuleRep, 0, function( M ) ## NrRelations is not an attribute and HasNrRelations might return fail! if HasNrRelations( M ) = true and NrRelations( M ) = 0 then return true; fi; TryNextMethod( ); end ); ## InstallImmediateMethod( IsFree, IsFinitelyPresentedModuleRep, 0, function( M ) local R; R := HomalgRing( M ); ## modules over divison rings are free if HasIsDivisionRingForHomalg( R ) and IsDivisionRingForHomalg( R ) then return true; fi; TryNextMethod( ); end ); ## InstallImmediateMethod( IsFree, IsFinitelyPresentedModuleRep and IsTorsionFree and HasRankOfObject, 0, function( M ) local R; ## HasNrGenerators is allowed to return fail if HasNrGenerators( M ) = true and RankOfObject( M ) = NrGenerators( M ) then return true; fi; TryNextMethod( ); end ); ## InstallImmediateMethod( IsFree, IsFinitelyPresentedModuleRep and IsStablyFree and HasRankOfObject, 0, function( M ) local R; R := HomalgRing( M ); if HasIsCommutative( R ) and IsCommutative( R ) and RankOfObject( M ) = 1 then ## [Lam06, Theorem I.4.11], this is in principle the Cauchy-Binet formula return true; elif HasGeneralLinearRank( R ) and GeneralLinearRank( R ) <= RankOfObject( M ) then ## [McCRob, Theorem 11.1.14] return true; elif HasElementaryRank( R ) and ElementaryRank( R ) <= RankOfObject( M ) then ## [McCRob, Theorem 11.1.14 and Proposition 11.3.11] return true; elif HasStableRank( R ) and StableRank( R ) <= RankOfObject( M ) then ## [McCRob, Theorem 11.1.14 and Proposition 11.3.11] return true; fi; TryNextMethod( ); end ); ## InstallImmediateMethod( IsPure, IsFinitelyPresentedModuleRep and IsTorsion, 0, function( M ) local R, global_dimension; R := HomalgRing( M ); if IsHomalgLeftObjectOrMorphismOfLeftObjects( M ) then global_dimension := LeftGlobalDimension; else global_dimension := RightGlobalDimension; fi; if Tester( global_dimension )( R ) and global_dimension( R ) <= 1 then return true; fi; TryNextMethod( ); end ); ## InstallImmediateMethod( IsPure, IsFinitelyPresentedModuleRep and HasGrade, 0, function( M ) local R, global_dimension; R := HomalgRing( M ); if IsHomalgLeftObjectOrMorphismOfLeftObjects( M ) then global_dimension := LeftGlobalDimension; else global_dimension := RightGlobalDimension; fi; if Tester( global_dimension )( R ) and global_dimension( R ) = Grade( M ) then return true; fi; TryNextMethod( ); end ); #################################### # # immediate methods for attributes: # #################################### ## InstallImmediateMethod( RankOfObject, IsFinitelyPresentedModuleRep, 0, function( M ) local m; ## NrRelations is not an attribute and HasNrRelations might return fail! if HasNrGenerators( M ) and HasNrRelations( M ) = true then m := MatrixOfRelations( M ); if IsHomalgLeftObjectOrMorphismOfLeftObjects( M ) then if HasIsLeftRegular( m ) and IsLeftRegular( m ) then return NrColumns( m ) - NrRows( m ); fi; else if HasIsRightRegular( m ) and IsRightRegular( m ) then return NrRows( m ) - NrColumns( m ); fi; fi; fi; TryNextMethod( ); end ); ## InstallImmediateMethod( RankOfObject, IsFinitelyPresentedModuleRep and IsFree, 0, function( M ) ## NrRelations is not an attribute and HasNrRelations might return fail! if HasNrRelations( M ) = true and NrRelations( M ) = 0 then return NrGenerators( M ); fi; TryNextMethod( ); end ); ## InstallImmediateMethod( Grade, IsFinitelyPresentedModuleRep and IsTorsion and HasIsZero, 0, function( M ) local R, global_dimension; R := HomalgRing( M ); if IsHomalgLeftObjectOrMorphismOfLeftObjects( M ) then global_dimension := LeftGlobalDimension; else global_dimension := RightGlobalDimension; fi; if not IsZero( M ) and Tester( global_dimension )( R ) and global_dimension( R ) = 1 then return 1; fi; TryNextMethod( ); end ); #################################### # # methods for properties: # #################################### ## A module element over a commutative ring is torsion, ## if it is annihilated by a regular element of the ring. InstallMethod( IsTorsion, "LIOBJ: for homalg object elements", [ IsElementOfAnObjectGivenByAMorphismRep ], function( m ) local M, Ann, R, gens; if IsZero( m ) then return true; fi; ## M ≠ 0 since m ≠ 0 M := SuperObject( m ); if HasIsTorsionFree( M ) and IsTorsionFree( M ) then ## in a torsion-free module only zero is torsion ## and we already know that m ≠ 0 return false; elif HasIsTorsion( M ) and IsTorsion( M ) then ## every element in a torsion module is torsion return true; fi; Ann := Annihilator( m ); if IsZero( Ann ) then ## we assume that the ring R ≠ 0, so ## 0 ≠ R = R / Ann( m ) ≅ R m ≤ M SetIsTorsion( M, false ); return false; fi; ## we now know that m ≠ 0 and Ann( m ) ≠ 0 R := HomalgRing( m ); ## Z/2 is torsion-free over Z/6 with annihilator <3> if HasIsIntegralDomain( R ) and IsIntegralDomain( R ) then SetIsTorsionFree( M, false ); return true; fi; ## I am not sure about the appropriate definition in the ## noncommutative setting if not ( HasIsCommutative( R ) and IsCommutative( R ) ) then TryNextMethod( ); fi; ## now that the annihilator is nontrivial ## check if any of its generators is regular (i.e., a nonzerodivisor) gens := GeneratingElements( Ann ); if ForAny( gens, a -> IsZero( Annihilator( a ) ) ) then return true; fi; TryNextMethod( ); end ); ## InstallMethod( IsZero, "LIMOD: for homalg submodules", [ IsFinitelyPresentedSubmoduleRep ], function( M ) local is_zero; is_zero := IsZero( DecideZero( MatrixOfSubobjectGenerators( M ), SuperObject( M ) ) ); if HasEmbeddingInSuperObject( M ) then SetIsZero( UnderlyingObject( M ), is_zero ); fi; return is_zero; end ); ## InstallMethod( IsZero, "LIMOD: for homalg modules", [ IsFinitelyPresentedModuleRep ], function( M ) return NrGenerators( GetRidOfZeroGenerators( M ) ) = 0; end ); ## InstallMethod( IsZero, "LIMOD: for homalg modules", [ IsFinitelyPresentedModuleRep and HasUnderlyingSubobject ], function( M ) local N; N := UnderlyingSubobject( M ); if HasNrRelations( M ) and NrGenerators( M ) <= NrGenerators( SuperObject( N ) ) then TryNextMethod( ); fi; ## avoids computing syzygies return IsZero( N ); end ); ## InstallMethod( IsZero, "LIMOD: for homalg modules", [ IsFinitelyPresentedModuleRep ], 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( R ); if not ( IsBound( RP!.AffineDimension ) or IsBound( RP!.CoefficientsOfUnreducedNumeratorOfHilbertPoincareSeries ) or IsBound( RP!.CoefficientsOfNumeratorOfHilbertPoincareSeries ) ) then TryNextMethod( ); fi; return AffineDimension( M ) <= HOMALG_MODULES.DimensionOfZeroModules; end ); ## InstallMethod( IsArtinian, "LIMOD: for homalg modules", [ IsFinitelyPresentedModuleRep ], function( M ) local R; R := HomalgRing( M ); if HasGlobalDimension( R ) and ## FIXME: declare an appropriate property for such rings ( ( HasIsIntegersForHomalg( R ) and IsIntegersForHomalg( R ) ) or ( HasIsFreePolynomialRing( R ) and IsFreePolynomialRing( R ) ) or ( HasIsWeylRing( R ) and IsWeylRing( R ) ) or ( HasIsLocalizedWeylRing( R ) and IsLocalizedWeylRing( R ) ) ) then return Grade( M ) >= GlobalDimension( R ); fi; TryNextMethod( ); end ); ## InstallMethod( IsCyclic, "LIMOD: for homalg modules", [ IsFinitelyPresentedModuleRep ], function( M ) ByASmallerPresentation( M ); if HasIsCyclic( M ) then return IsCyclic( M ); fi; TryNextMethod( ); end ); ## RedispatchOnCondition( IsCyclic, true, [ IsFinitelyPresentedModuleRep ], [ IsArtinian ], 0 ); ## InstallMethod( IsHolonomic, "LIMOD: for homalg modules", [ IsFinitelyPresentedModuleRep ], function( M ) local R; R := HomalgRing( M ); if HasGlobalDimension( R ) and ## FIXME: declare an appropriate property for such rings ( ( HasIsIntegersForHomalg( R ) and IsIntegersForHomalg( R ) ) or ( HasIsFreePolynomialRing( R ) and IsFreePolynomialRing( R ) ) or ( HasIsWeylRing( R ) and IsWeylRing( R ) ) or ( HasIsLocalizedWeylRing( R ) and IsLocalizedWeylRing( R ) ) ) then return IsArtinian( M ); fi; TryNextMethod( ); end ); ## InstallMethod( IsReflexive, "LIMOD: for homalg modules", [ IsFinitelyPresentedModuleRep ], function( M ) local R, global_dimension; R := HomalgRing( M ); if IsHomalgLeftObjectOrMorphismOfLeftObjects( M ) then global_dimension := LeftGlobalDimension; else global_dimension := RightGlobalDimension; fi; if Tester( global_dimension )( R ) and global_dimension( R ) <= 1 then return IsTorsionFree( M ); fi; TryNextMethod( ); end ); ## InstallMethod( IsProjective, "LIMOD: for homalg modules", [ IsFinitelyPresentedModuleRep ], function( M ) local R, proj; R := HomalgRing( M ); if FiniteFreeResolution( M ) = fail then TryNextMethod( ); fi; proj := ProjectiveDimension( M ) = 0; if proj then M!.UpperBoundForProjectiveDimension := 0; fi; return proj; end ); ## InstallGlobalFunction( IsProjectiveByCheckingIfExt1WithValuesInFirstSyzygiesModuleIsZero, function( M ) local R, K, proj; R := HomalgRing( M ); if not ( HasIsCommutative( R ) and IsCommutative( R ) ) then return fail; fi; K := SyzygiesObject( M ); proj := IsZero( Ext( 1, M, K ) ); if proj then M!.UpperBoundForProjectiveDimension := 0; fi; SetIsProjective( M, proj ); return proj; end ); ## InstallMethod( IsProjective, "LIMOD: for homalg modules", [ IsFinitelyPresentedModuleRep ], function( M ) local b; b := IsProjectiveByCheckingForASplit( M ); if b = fail then TryNextMethod( ); fi; return b; end ); ## InstallMethod( IsProjective, "LIMOD: for homalg modules", [ IsFinitelyPresentedModuleRep ], function( M ) local R, proj; R := HomalgRing( M ); if not ( HasIsFiniteFreePresentationRing( R ) and IsFiniteFreePresentationRing( R ) ) then TryNextMethod( ); fi; if FiniteFreeResolution( M ) = fail then TryNextMethod( ); fi; proj := ProjectiveDimension( M ) = 0; if proj then M!.UpperBoundForProjectiveDimension := 0; fi; return proj; end ); ## InstallMethod( IsProjective, "LIMOD: for homalg modules", [ IsFinitelyPresentedModuleRep ], function( M ) local R, global_dimension; R := HomalgRing( M ); if IsHomalgLeftObjectOrMorphismOfLeftObjects( M ) then global_dimension := LeftGlobalDimension; else global_dimension := RightGlobalDimension; fi; if Tester( global_dimension )( R ) and global_dimension( R ) < infinity then return DegreeOfTorsionFreeness( M ) = infinity; fi; TryNextMethod( ); end ); ## InstallMethod( IsProjective, "LIMOD: for homalg modules", [ IsFinitelyPresentedModuleRep ], function( M ) local R, global_dimension; R := HomalgRing( M ); if IsHomalgLeftObjectOrMorphismOfLeftObjects( M ) then global_dimension := LeftGlobalDimension; else global_dimension := RightGlobalDimension; fi; if Tester( global_dimension )( R ) and global_dimension( R ) <= 2 then return IsReflexive( M ); fi; TryNextMethod( ); end ); ## InstallGlobalFunction( IsProjectiveOfConstantRankByCheckingFittingsCondition, function( M ) local R, b; R := HomalgRing( M ); if not ( HasIsCommutative( R ) and IsCommutative( R ) ) then return fail; fi; b := ( FittingIdeal( M ) = R ); SetIsProjectiveOfConstantRank( M, b ); return b; end ); ## InstallMethod( IsProjectiveOfConstantRank, "LIMOD: for homalg modules", [ IsFinitelyPresentedModuleRep ], function( M ) local b; b := IsProjectiveOfConstantRankByCheckingFittingsCondition( M ); if b = fail then TryNextMethod( ); fi; return b; end ); ## InstallMethod( IsStablyFree, "LIMOD: for homalg modules", [ IsFinitelyPresentedModuleRep ], function( M ) if not IsProjective( M ) then return false; fi; if FiniteFreeResolution( M ) = fail then TryNextMethod( ); fi; ## Serre's 1955 remark: ## for a module with a finite free resolution (FFR) ## "projective" and "stably free" are equivalent return IsProjective( M ); end ); ## InstallMethod( IsFree, "LIMOD: for homalg modules", [ IsFinitelyPresentedModuleRep ], function( M ) local R, par, img, free; R := HomalgRing( M ); if not HasRankOfObject( M ) then ## automatically sets the rank if it succeeds ## to compute a complete free resolution: Resolution( M ); fi; if HasRankOfObject( M ) and RankOfObject( M ) = 1 then ## this returns a minimal parametrization of M ## (minimal = cokernel is torsion); ## I learned this from Alban Quadrat par := MinimalParametrization( M ); if IsMonomorphism( par ) then img := MatrixOfMap( par ); ## Plesken: a good notion of basis (involutive/groebner/...) ## should respect principal ideals and hence, ## due to the uniqueness of the basis, ## can be used to decide if an ideal is principal or not if IsHomalgLeftObjectOrMorphismOfLeftObjects( M ) then img := BasisOfRows( img ); free := NrRows( img ) <= 1; else img := BasisOfColumns( img ); free := NrColumns( img ) <= 1; fi; if free then return true; elif HasBasisAlgorithmRespectsPrincipalIdeals( R ) and BasisAlgorithmRespectsPrincipalIdeals( R ) then return false; fi; else return false; fi; fi; TryNextMethod( ); end ); ## InstallMethod( IsFree, "LIMOD: for homalg modules", [ IsFinitelyPresentedModuleRep ], function( M ) local R; R := HomalgRing( M ); if not IsStablyFree( M ) then return false; fi; if not HasRankOfObject( M ) then ## this should set the rank if it doesn't fail if FiniteFreeResolution( M ) = fail then TryNextMethod( ); fi; fi; ## by now RankOfObject will exist and this ## should trigger immediate methods to check IsFree if HasIsFree( M ) then return IsFree( M ); fi; if IsStablyFree( M ) then ## FIXME: sometimes the immediate methods are not triggered and do not set IsFree if HasIsCommutative( R ) and IsCommutative( R ) and RankOfObject( M ) = 1 then ## [Lam06, Theorem I.4.11], this is in principle the Cauchy-Binet formula return true; elif HasGeneralLinearRank( R ) and GeneralLinearRank( R ) <= RankOfObject( M ) then ## [McCRob, Theorem 11.1.14] return true; elif HasElementaryRank( R ) and ElementaryRank( R ) <= RankOfObject( M ) then ## [McCRob, Theorem 11.1.14 and Proposition 11.3.11] return true; elif HasStableRank( R ) and StableRank( R ) <= RankOfObject( M ) then ## [McCRob, Theorem 11.1.14 and Proposition 11.3.11] return true; fi; fi; TryNextMethod( ); end ); ## InstallMethod( IsReduced, "LIMOD: for homalg modules", [ IsHomalgModule ], function( M ) local I; I := Annihilator( M ); return IsSubset( I, RadicalSubobject( I ) ); end ); ## fallback method InstallMethod( IsPrimeModule, "for homalg modules", [ IsHomalgModule ], function( M ) local dec; dec := PrimaryDecomposition( M ); return Length( dec ) = 1 and IsSubset( dec[1][1], dec[1][2] ); end ); ## InstallMethod( IsPrimeModule, "for homalg modules", [ IsFinitelyPresentedModuleRep ], function( M ) local R, RP, tr, subobject, mat; R := HomalgRing( M ); RP := homalgTable( R ); if not IsBound( RP!.IsPrime ) then TryNextMethod( ); fi; if IsHomalgLeftObjectOrMorphismOfLeftObjects( M ) then tr := IdFunc; else tr := Involution; fi; mat := MatrixOfRelations( M ); return IsPrimeModule( tr( mat ) ); end ); ## IsPrime is unfortunately hijacked as an operation InstallMethod( IsPrime, "for homalg modules", [ IsHomalgModule ], IsPrimeModule ); #################################### # # methods for attributes: # #################################### ## InstallMethod( Annihilator, "for homalg module elements", [ IsElementOfAModuleGivenByAMorphismRep ], function( e ) local mat, rel; mat := MatrixOfMap( UnderlyingMorphism( e ) ); rel := RelationsOfModule( SuperObject( e ) ); return Annihilator( mat, rel ); end ); ## InstallMethod( Annihilator, "for homalg modules", [ IsFinitelyPresentedModuleRep ], function( M ) local R, gens, Ann, i; if IsZero( M ) then return FullSubobject( One( M ) ); elif HasIsTorsion( M ) and not IsTorsion( M ) then R := HomalgRing( M ); ## Z/2 is torsion-free over Z/6 with annihilator <3> if HasIsIntegralDomain( R ) and IsIntegralDomain( R ) then return ZeroSubobject( One( M ) ); fi; fi; gens := GeneratingElements( M ); ## since M is nontrivial gens is nonempty Ann := Annihilator( gens[1] ); for i in [ 2 .. Length( gens ) ] do if IsZero( Ann ) then ## return the standard zero ideal return ZeroSubobject( One( M ) ); fi; Ann := Intersect2( Ann, Annihilator( gens[i] ) ); od; if IsZero( Ann ) then ## return the standard zero ideal return ZeroSubobject( One( M ) ); fi; return Ann; end ); ## InstallMethod( TorsionSubobject, "LIMOD: for homalg modules", [ IsHomalgModule ], function( M ) local par, emb, tor; if HasIsTorsion( M ) and IsTorsion( M ) then return FullSubobject( M ); fi; ## compute any parametrization since computing ## a "minimal" parametrization requires the ## rank which if unknown would probably trigger Resolution par := AnyParametrization( M ); tor := KernelSubobject( par ); SetIsTorsion( tor, true ); return tor; end ); ## InstallMethod( TheMorphismToZero, "LIMOD: for homalg modules", [ IsFinitelyPresentedModuleRep ], function( M ) return HomalgZeroMap( M, 0*M ); ## never set its Kernel to M, since a possibly existing NaturalGeneralizedEmbedding in M will be overwritten! end ); ## InstallMethod( TheIdentityMorphism, "LIMOD: for homalg modules", [ IsHomalgModule ], function( M ) return HomalgIdentityMap( M ); end ); ## InstallMethod( FullSubobject, "LIMOD: for homalg modules", [ IsFinitelyPresentedModuleRep ], function( M ) local subobject; if HasIsFree( M ) and IsFree( M ) then subobject := ImageSubobject( TheIdentityMorphism( M ) ); else subobject := Subobject( HomalgIdentityMatrix( NrGenerators( M ), HomalgRing( M ) ), M ); fi; MatchPropertiesAndAttributesOfSubobjectAndUnderlyingObject( subobject, M ); SetEmbeddingInSuperObject( subobject, TheIdentityMorphism( M ) ); return subobject; end ); ## InstallMethod( ZeroSubobject, "LIMOD: for homalg modules", [ IsFinitelyPresentedModuleRep ], function( M ) local n, R, zero; n := NrGenerators( M ); R := HomalgRing( M ); if IsHomalgLeftObjectOrMorphismOfLeftObjects( M ) then zero := HomalgZeroMatrix( 0, n, R ); else zero := HomalgZeroMatrix( n, 0, R ); fi; return Subobject( zero, M ); end ); ## InstallMethod( RankOfObject, "LIMOD: for homalg modules", [ IsFinitelyPresentedModuleRep ], function( M ) local R; R := HomalgRing( M ); if not ( HasIsCommutative( R ) and IsCommutative( R ) ) then ## cannot use the Fitting ideal criterion below TryNextMethod( ); elif HasGlobalDimension( R ) and GlobalDimension( R ) < infinity then ## try computing the rank via a free resolution ## which is hopefully cheaper TryNextMethod( ); fi; return NumberOfFirstNonZeroFittingIdeal( M ); end ); ## InstallMethod( RankOfObject, "LIMOD: for homalg modules", [ IsFinitelyPresentedModuleRep ], function( M ) local l, p, m; l := ListOfPositionsOfKnownSetsOfRelations( M ); for p in l do m := MatrixOfRelations( M, p ); if IsHomalgMatrix( m ) then if IsHomalgLeftObjectOrMorphismOfLeftObjects( M ) then if IsLeftRegular( m ) then return NrColumns( m ) - NrRows( m ); fi; else if IsRightRegular( m ) then return NrRows( m ) - NrColumns( m ); fi; fi; fi; od; TryNextMethod( ); end ); ## InstallMethod( RankOfObject, "LIMOD: for homalg modules", [ IsFinitelyPresentedModuleRep ], function( M ) local R, K, RP, d, dim; R := HomalgRing( M ); if not ( HasIsCommutative( R ) and IsCommutative( R ) and HasCoefficientsRing( R ) and HasKrullDimension( R ) ) then TryNextMethod( ); fi; K := CoefficientsRing( R ); if not ( HasIsFieldForHomalg( K ) and IsFieldForHomalg( K ) ) then TryNextMethod( ); fi; RP := homalgTable( R ); if not ( IsBound( RP!.CoefficientsOfUnreducedNumeratorOfHilbertPoincareSeries ) or IsBound( RP!.CoefficientsOfNumeratorOfHilbertPoincareSeries ) ) then TryNextMethod( ); fi; d := KrullDimension( R ); dim := AffineDimension( M ); if dim > d then Error( "the dimension of the module is greater than the Krull dimension of the ring\n" ); fi; if dim < d then return 0; fi; return AffineDegree( M ); end ); ## InstallMethod( DegreeOfTorsionFreeness, "LIMOD: for homalg modules", [ IsFinitelyPresentedModuleRep ], function( M ) local DM, k, R, gdim, bound; DM := AuslanderDual( M ); if IsTorsionFree( M ) then k := 2; else return 0; fi; if IsReflexive( M ) then k := 3; fi; ## do not return 1 in case the ring has global dimension 0 R := HomalgRing( M ); if IsHomalgLeftObjectOrMorphismOfLeftObjects( M ) then if not HasLeftGlobalDimension( R ) then TryNextMethod( ); fi; gdim := LeftGlobalDimension( R ); else if not HasRightGlobalDimension( R ) then TryNextMethod( ); fi; gdim := RightGlobalDimension( R ); fi; if gdim = infinity then bound := BoundForResolution( M ); else bound := gdim; fi; while k <= bound do if not IsZero( Ext( k, DM ) ) then return k - 1; fi; k := k + 1; od; if gdim < infinity then return infinity; fi; TryNextMethod( ); end ); ## InstallMethod( ProjectiveDimension, "LIMOD: for homalg modules", [ IsFinitelyPresentedModuleRep ], function( M ) local d, ld, pd, s; ## in future Resolution( M ) might compute a free resolution only up to ## an a priori known upper bound of the projective dimension (+1), which ## would mean that such an "incomplete" resolution is not acyclic in general ## and ShortenResolution will not apply. Therefore: d := FiniteFreeResolution( M ); if d = fail then TryNextMethod( ); fi; ld := Length( MorphismDegreesOfComplex( d ) ); d := ShortenResolution( d ); pd := Length( MorphismDegreesOfComplex( d ) ); if pd < ld then ResetFilterObj( M, AFiniteFreeResolution ); SetAFiniteFreeResolution( M, d ); fi; ## Serre's 1955 remark: ## for a module with a finite free resolution (FFR) ## "projective" and "stably free" are equivalent ## (so now we check stably freeness) if pd = 1 then s := PostInverse( LowestDegreeMorphism( d ) ); if not IsBool( s ) then pd := 0; fi; fi; return pd; end ); ## InstallMethod( CoefficientsOfUnreducedNumeratorOfHilbertPoincareSeries, "for a homalg module", [ IsFinitelyPresentedModuleRep ], function( M ) local mat; mat := MatrixOfRelations( M ); if IsHomalgRightObjectOrMorphismOfRightObjects( M ) then mat := Involution( mat ); fi; mat := BasisOfRows( mat ); return CoefficientsOfUnreducedNumeratorOfHilbertPoincareSeries( mat ); end ); ## InstallMethod( CoefficientsOfNumeratorOfHilbertPoincareSeries, "for a homalg module", [ IsFinitelyPresentedModuleRep ], function( M ) local mat; mat := MatrixOfRelations( M ); if IsHomalgRightObjectOrMorphismOfRightObjects( M ) then mat := Involution( mat ); fi; mat := BasisOfRows( mat ); return CoefficientsOfNumeratorOfHilbertPoincareSeries( mat ); end ); ## InstallMethod( UnreducedNumeratorOfHilbertPoincareSeries, "for a homalg module", [ IsFinitelyPresentedModuleRep ], function( M ) local mat; mat := MatrixOfRelations( M ); if IsHomalgRightObjectOrMorphismOfRightObjects( M ) then mat := Involution( mat ); fi; mat := BasisOfRows( mat ); return UnreducedNumeratorOfHilbertPoincareSeries( mat ); end ); ## InstallMethod( NumeratorOfHilbertPoincareSeries, "for a homalg module", [ IsFinitelyPresentedModuleRep ], function( M ) local mat; mat := MatrixOfRelations( M ); if IsHomalgRightObjectOrMorphismOfRightObjects( M ) then mat := Involution( mat ); fi; mat := BasisOfRows( mat ); return NumeratorOfHilbertPoincareSeries( mat ); end ); ## InstallMethod( HilbertPoincareSeries, "for a homalg module", [ IsHomalgModule ], function( M ) return HilbertPoincareSeries( M, VariableForHilbertPoincareSeries( ) ); end ); ## InstallMethod( HilbertPolynomial, "for a homalg module", [ IsHomalgModule ], function( M ) return HilbertPolynomial( M, VariableForHilbertPolynomial( ) ); end ); ## InstallMethod( DataOfHilbertFunction, "for a homalg module", [ IsHomalgModule and IsFinitelyPresentedObjectRep ], function( M ) local HP; HP := HilbertPoincareSeries( M ); return DataOfHilbertFunction( HP ); end ); ## InstallMethod( HilbertFunction, "for a homalg module", [ IsHomalgModule and IsFinitelyPresentedObjectRep ], function( M ) local HP; HP := HilbertPoincareSeries( M ); return HilbertFunction( HP ); end ); ## InstallMethod( IndexOfRegularity, "for a homalg module", [ IsHomalgModule and IsFinitelyPresentedObjectRep ], function( M ) local range; if IsZero( M ) then Error( "GAP does not support -infinity yet\n" ); fi; range := DataOfHilbertFunction( M )[1][2]; return range[Length( range )] + 1; end ); ## InstallMethod( ElementOfGrothendieckGroup, "for a homalg module", [ IsHomalgModule and IsFinitelyPresentedObjectRep ], function( M ) local chi, dim; chi := HilbertPolynomial( M ); dim := Length( Indeterminates( HomalgRing( M ) ) ) - 1; return CreateElementOfGrothendieckGroupOfProjectiveSpace( chi, dim ); end ); ## InstallMethod( ChernPolynomial, "for a homalg module", [ IsHomalgModule and IsFinitelyPresentedObjectRep ], function( M ) local P; P := ElementOfGrothendieckGroup( M ); return ChernPolynomial( P ); end ); ## InstallMethod( ChernCharacter, "for a homalg module", [ IsHomalgModule and IsFinitelyPresentedObjectRep ], function( M ) local c; c := ChernPolynomial( M ); return ChernCharacter( c ); end ); ## InstallMethod( PrimaryDecomposition, "for homalg modules", [ IsFinitelyPresentedModuleRep ], function( M ) local tr, subobject, mat; if IsHomalgLeftObjectOrMorphismOfLeftObjects( M ) then tr := IdFunc; subobject := LeftSubmodule; else tr := Involution; subobject := RightSubmodule; fi; ## FIXME: PrimaryDecompostion of submodules is delegated to the factor object, ## this is a bad. Until we fix it we have to take care of the unit ideal if IsZero( M ) then mat := HomalgIdentityMatrix( 1, HomalgRing( M ) ); return [ ListWithIdenticalEntries( 2, subobject( mat ) ) ]; fi; mat := MatrixOfRelations( M ); return List( PrimaryDecompositionOp( tr( mat ) ), function( pp ) local primary, prime; primary := subobject( tr( pp[1] ) ); prime := subobject( tr( pp[2] ) ); return [ primary, prime ]; end ); end ); ## fallback method InstallMethod( RadicalDecomposition, "for homalg modules", [ IsHomalgModule and IsFinitelyPresentedObjectRep ], function( M ) return List( PrimaryDecomposition( M ), a -> a[2] ); end ); ## InstallMethod( RadicalDecomposition, "for homalg modules", [ IsFinitelyPresentedModuleRep ], function( M ) local R, RP, tr, subobject, mat; R := HomalgRing( M ); RP := homalgTable( R ); if not IsBound( RP!.RadicalDecomposition ) then TryNextMethod( ); fi; if IsHomalgLeftObjectOrMorphismOfLeftObjects( M ) then tr := IdFunc; subobject := LeftSubmodule; else tr := Involution; subobject := RightSubmodule; fi; mat := MatrixOfRelations( M ); return List( RadicalDecompositionOp( tr( mat ) ), pp -> subobject( tr( pp ) ) ); end ); ## fallback method InstallMethod( RadicalSubobject, "for homalg modules", [ IsHomalgModule and IsFinitelyPresentedObjectRep ], function( J ) return Intersect( RadicalDecomposition( J ) ); end ); ## InstallMethod( ResidueClassRing, "for homalg ideals", [ IsFinitelyPresentedSubmoduleRep and ConstructedAsAnIdeal ], function( J ) local A, ring_rel, R; A := HomalgRing( J ); Assert( 3, not J = A ); ring_rel := MatrixOfGenerators( J ); if IsHomalgLeftObjectOrMorphismOfLeftObjects( J ) then ring_rel := HomalgRingRelationsAsGeneratorsOfLeftIdeal( ring_rel ); else ring_rel := HomalgRingRelationsAsGeneratorsOfRightIdeal( ring_rel ); fi; R := A / ring_rel; if HasContainsAField( A ) and ContainsAField( A ) then SetContainsAField( R, true ); if HasCoefficientsRing( A ) then SetCoefficientsRing( R, CoefficientsRing( A ) ); fi; fi; SetDefiningIdeal( R, J ); return R; end ); ## InstallMethod( FittingIdeal, "for homalg modules", [ IsFinitelyPresentedModuleRep ], function( M ) local r, Fitt, R; r := RankOfObject( M ); Fitt := FittingIdeal( r, M ); R := HomalgRing( M ); SetIsZero( Fitt, IsZero( R ) ); if Fitt = R then ## if Fitt < R, then M might still be projective ## but with non-constant rank SetIsProjective( M, true ); SetHasConstantRank( M, true ); elif HasIsProjective( M ) and IsProjective( M ) then SetHasConstantRank( M, false ); elif HasHasConstantRank( M ) and HasConstantRank( M ) then SetIsProjective( M, false ); fi; return Fitt; end ); ## InstallMethod( NonFlatLocus, "for homalg modules", [ IsFinitelyPresentedModuleRep ], function( M ) local R, i, Fitt; R := HomalgRing( M ); if not ( HasIsCommutative( R ) and IsCommutative( R ) ) then TryNextMethod( ); fi; return FactorObject( FittingIdeal( M ) ); end ); ## InstallMethod( LargestMinimalNumberOfLocalGenerators, "for homalg modules", [ IsHomalgModule and IsStaticFinitelyPresentedObjectRep ], function( M ) local R, i, Fitt_i; if IsZero( M ) then return 0; fi; R := HomalgRing( M ); if not ( HasIsCommutative( R ) and IsCommutative( R ) ) then TryNextMethod( ); fi; for i in Reversed( [ 0 .. NrGenerators( M ) - 1 ] ) do Fitt_i := FittingIdeal( i, M ); if not Fitt_i = R then return i + 1; fi; od; ## should never be reached Error( "something went wrong\n" ); end ); ## InstallMethod( SymmetricAlgebra, "for a homalg matrix", [ IsHomalgMatrix, IsList ], function( M, gvar ) local n, Sym, 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; Sym := HomalgRing( M ) * gvar; gvar := RelativeIndeterminatesOfPolynomialRing( Sym ); gvar := HomalgMatrix( gvar, Length( gvar ), 1, Sym ); rel := LeftSubmodule( ( Sym * M ) * gvar ); Sym := Sym / rel; SetDefiningIdeal( Sym, rel ); return Sym; end ); ## InstallMethod( SymmetricAlgebra, "for homalg modules", [ IsHomalgModule and IsStaticFinitelyPresentedObjectRep, IsList ], function( M, gvar ) local rel; rel := MatrixOfRelations( M ); if IsHomalgRightObjectOrMorphismOfRightObjects( M ) then rel := Involution( rel ); fi; return SymmetricAlgebra( rel, gvar ); end ); ## InstallMethod( SymmetricAlgebra, "for homalg submodules", [ IsHomalgModule and IsStaticFinitelyPresentedSubobjectRep, IsList ], function( M, gvar ) return SymmetricAlgebra( UnderlyingObject( M ), gvar ); end ); ## InstallMethod( SymmetricAlgebra, "for homalg modules", [ IsHomalgModule and IsStaticFinitelyPresentedObjectRep, IsString ], function( M, str ) local n; n := NrGenerators( M ); str := ParseListOfIndeterminates( SplitString( str, "," ) ); if Length( str ) = 1 and not n = 1 then str := str[1]; str := List( [ 1 .. n ], i -> Concatenation( str, String( i ) ) ); fi; return SymmetricAlgebra( M, str ); end ); ## InstallMethod( SymmetricAlgebra, "for homalg submodules", [ IsHomalgModule and IsStaticFinitelyPresentedSubobjectRep, IsString ], function( M, str ) return SymmetricAlgebra( UnderlyingObject( M ), str ); end ); ## InstallMethod( SymmetricAlgebraFromSyzygiesObject, "for homalg submodules", [ IsHomalgModule and IsStaticFinitelyPresentedSubobjectRep, IsList ], function( M, gvar ) M := MatrixOfSubobjectGenerators( M ); return SymmetricAlgebra( M, gvar ); end ); ## InstallMethod( SymmetricAlgebraFromSyzygiesObject, "for homalg submodules", [ IsHomalgModule and IsStaticFinitelyPresentedSubobjectRep, IsString ], function( M, str ) local n; n := NrGenerators( M ); str := ParseListOfIndeterminates( SplitString( str, "," ) ); if Length( str ) = 1 and not n = 1 then str := str[1]; str := List( [ 1 .. n ], i -> Concatenation( str, String( i ) ) ); fi; return SymmetricAlgebraFromSyzygiesObject( M, str ); end ); ## InstallMethod( ExteriorAlgebra, "for a homalg matrix", [ IsHomalgMatrix, IsList ], function( M, gvar ) local n, 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; A := ExteriorRing( HomalgRing( M ) * List( gvar, v -> Concatenation( "XX", v ) ), gvar ); gvar := IndeterminateAntiCommutingVariablesOfExteriorRing( A ); gvar := HomalgMatrix( gvar, Length( gvar ), 1, A ); rel := LeftSubmodule( ( A * M ) * gvar ); A := A / rel; SetDefiningIdeal( A, rel ); return A; end ); ## InstallMethod( ExteriorAlgebra, "for homalg modules", [ IsHomalgModule and IsStaticFinitelyPresentedObjectRep, IsList ], function( M, gvar ) local rel; rel := MatrixOfRelations( M ); if IsHomalgRightObjectOrMorphismOfRightObjects( M ) then rel := Involution( rel ); fi; return ExteriorAlgebra( rel, gvar ); end ); ## InstallMethod( ExteriorAlgebra, "for homalg submodules", [ IsHomalgModule and IsStaticFinitelyPresentedSubobjectRep, IsList ], function( M, gvar ) return ExteriorAlgebra( UnderlyingObject( M ), gvar ); end ); ## InstallMethod( ExteriorAlgebra, "for homalg modules", [ IsHomalgModule and IsStaticFinitelyPresentedObjectRep, IsString ], function( M, str ) local n; n := NrGenerators( M ); str := ParseListOfIndeterminates( SplitString( str, "," ) ); if Length( str ) = 1 and not n = 1 then str := str[1]; str := List( [ 1 .. n ], i -> Concatenation( str, String( i ) ) ); fi; return ExteriorAlgebra( M, str ); end ); ## InstallMethod( ExteriorAlgebra, "for homalg submodules", [ IsHomalgModule and IsStaticFinitelyPresentedSubobjectRep, IsString ], function( M, str ) return ExteriorAlgebra( UnderlyingObject( M ), str ); end ); ## InstallMethod( ExteriorAlgebraFromSyzygiesObject, "for homalg submodules", [ IsHomalgModule and IsStaticFinitelyPresentedSubobjectRep, IsList ], function( M, gvar ) M := MatrixOfSubobjectGenerators( M ); return ExteriorAlgebra( M, gvar ); end ); ## InstallMethod( ExteriorAlgebraFromSyzygiesObject, "for homalg submodules", [ IsHomalgModule and IsStaticFinitelyPresentedSubobjectRep, IsString ], function( M, str ) local n; n := NrGenerators( M ); str := ParseListOfIndeterminates( SplitString( str, "," ) ); if Length( str ) = 1 and not n = 1 then str := str[1]; str := List( [ 1 .. n ], i -> Concatenation( str, String( i ) ) ); fi; return ExteriorAlgebraFromSyzygiesObject( M, str ); end ); #################################### # # logical implications methods: # #################################### InstallLogicalImplicationsForHomalgObjects( LogicalImplicationsForHomalgModules, IsHomalgModule ); InstallLogicalImplicationsForHomalgObjects( LogicalImplicationsForHomalgModulesOverSpecialRings, IsHomalgModule, IsHomalgRing );