# SPDX-License-Identifier: GPL-2.0-or-later # Modules: A homalg based package for the Abelian category of finitely presented modules over computable rings # # Implementations #
## Implementation stuff for a set of relations.
## <#GAPDoc Label="Relations:intro"> ## A finite presentation of a module is given by a finite set of generators and a finite set of relations ## among these generators. In &homalg; a set of relations of a left/right module is given by a matrix <A>rel</A>, ## the rows/columns of which are interpreted as relations among <M>n</M> generators, <M>n</M> being the number ## of columns/rows of the matrix <A>rel</A>. ## <P/> ## The data structure of a module in &homalg; is designed to contain not only one but several sets of relations ## (together with corresponding sets of generators (&see; Chapter <Ref Chap="Generators"/>)). ## The different sets of relations are linked with so-called transition matrices (&see; Chapter <Ref Chap="Modules"/>). ## <P/> ## The relations of a &homalg; module are evaluated in a lazy way. This avoids unnecessary computations. ## <#/GAPDoc>
## <#GAPDoc Label="IsRelationsOfFinitelyPresentedModuleRep"> ## <ManSection> ## <Filt Type="Representation" Arg="rel" Name="IsRelationsOfFinitelyPresentedModuleRep"/> ## <Returns><C>true</C> or <C>false</C></Returns> ## <Description> ## The &GAP; representation of a finite set of relations of a finitely presented &homalg; module. <P/> ## (It is a representation of the &GAP; category <Ref Filt="IsHomalgRelations"/>) ## </Description> ## </ManSection> ## <#/GAPDoc> ##
DeclareRepresentation( "IsRelationsOfFinitelyPresentedModuleRep",
IsHomalgRelations,
[ ] );
#################################### # # families and types: # ####################################
# a new family:
BindGlobal( "TheFamilyOfHomalgRelations",
NewFamily( "TheFamilyOfHomalgRelations" ) );
# two new types:
BindGlobal( "TheTypeHomalgRelationsOfLeftModule",
NewType( TheFamilyOfHomalgRelations,
IsRelationsOfFinitelyPresentedModuleRep and IsHomalgRelationsOfLeftModule ) );
BindGlobal( "TheTypeHomalgRelationsOfRightModule",
NewType( TheFamilyOfHomalgRelations,
IsRelationsOfFinitelyPresentedModuleRep and IsHomalgRelationsOfRightModule ) );
#################################### # # immediate methods for properties: # ####################################
## a non trivial set of relations for a single generator over a domain => IsTorsion
InstallImmediateMethod( IsTorsion,
IsHomalgRelations and HasEvaluatedMatrixOfRelations, 0,
function( rel )
local torsion, R;
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 ) );
## this is the true reason for this immediate method if HasParent( rel ) then
SetIsTorsion( Parent( rel ), torsion ); fi;
return torsion;
fi; fi;
TryNextMethod( );
end );
## strictly less relations than generators => not IsTorsion
InstallImmediateMethod( IsTorsion,
IsHomalgRelations and HasEvaluatedMatrixOfRelations, 0,
function( rel )
if HasNrGenerators( rel ) and HasNrRelations( rel ) and
NrGenerators( rel ) > NrRelations( rel ) then
## this is the true reason for this immediate method if HasParent( rel ) then
SetIsTorsion( Parent( rel ), false ); fi;
return false; fi;
TryNextMethod( );
end );
#################################### # # immediate methods for attributes: # ####################################
##
InstallImmediateMethod( NrRelationsForRelations,
IsHomalgRelationsOfRightModule and HasEvaluatedMatrixOfRelations, 0,
##
InstallMethod( HasNrGenerators, "for sets of relations of homalg modules",
[ IsHomalgRelationsOfRightModule ],
function( rel )
return HasNumberRows( MatrixOfRelations( rel ) );
end );
##
InstallMethod( HasNrGenerators, "for sets of relations of homalg modules",
[ IsHomalgRelationsOfRightModule and HasEvalMatrixOfRelations ],
function( rel )
local func_arg, ar;
func_arg := EvalMatrixOfRelations( rel );
if IsIdenticalObj( func_arg[1], SyzygiesGeneratorsOfColumns ) then
ar := func_arg[2]; if IsList( ar ) and Length( ar ) = 2then
return HasNumberColumns( ar[1] ); fi; elif IsIdenticalObj( func_arg[1], \^ ) then
ar := func_arg[2]; if IsList( ar ) and Length( ar ) = 2then
return HasNumberRows( ar[2] ); fi; fi;
TryNextMethod( );
end );
##
InstallMethod( HasNrGenerators, "for sets of relations of homalg modules",
[ IsHomalgRelationsOfLeftModule ],
##
InstallMethod( HasNrGenerators, "for sets of relations of homalg modules",
[ IsHomalgRelationsOfLeftModule and HasEvalMatrixOfRelations ],
function( rel )
local func_arg, ar;
func_arg := EvalMatrixOfRelations( rel );
if IsIdenticalObj( func_arg[1], SyzygiesGeneratorsOfRows ) then
ar := func_arg[2]; if IsList( ar ) and Length( ar ) = 2then
return HasNumberRows( ar[1] ); fi; elif IsIdenticalObj( func_arg[1], \^ ) then
ar := func_arg[2]; if IsList( ar ) and Length( ar ) = 2then
return HasNumberColumns( ar[2] ); fi; fi;
TryNextMethod( );
end );
##
InstallMethod( NrGeneratorsForRelations, ### defines: NrGenerators (NumberOfGenerators) "for sets of relations of homalg modules",
[ IsHomalgRelationsOfRightModule ],
function( rel )
return NumberRows( MatrixOfRelations( rel ) );
end );
##
InstallMethod( NrGeneratorsForRelations, "for sets of relations of homalg modules",
[ IsHomalgRelationsOfRightModule and HasEvalMatrixOfRelations ],
function( rel )
local func_arg, ar;
func_arg := EvalMatrixOfRelations( rel );
if IsIdenticalObj( func_arg[1], SyzygiesGeneratorsOfColumns ) then
ar := func_arg[2]; if IsList( ar ) and Length( ar ) = 2then
return NumberColumns( ar[1] ); fi; elif IsIdenticalObj( func_arg[1], \^ ) then
ar := func_arg[2]; if IsList( ar ) and Length( ar ) = 2then
return NumberRows( ar[2] ); fi; fi;
TryNextMethod( );
end );
##
InstallMethod( NrGeneratorsForRelations, ### defines: NrGenerators (NumberOfGenerators) "for sets of relations of homalg modules",
[ IsHomalgRelationsOfLeftModule ],
function( rel )
return NumberColumns( MatrixOfRelations( rel ) );
end );
##
InstallMethod( NrGeneratorsForRelations, "for sets of relations of homalg modules",
[ IsHomalgRelationsOfLeftModule and HasEvalMatrixOfRelations ],
function( rel )
local func_arg, ar;
func_arg := EvalMatrixOfRelations( rel );
if IsIdenticalObj( func_arg[1], SyzygiesGeneratorsOfRows ) then
ar := func_arg[2]; if IsList( ar ) and Length( ar ) = 2then
return NumberRows( ar[1] ); fi; elif IsIdenticalObj( func_arg[1], \^ ) then
ar := func_arg[2]; if IsList( ar ) and Length( ar ) = 2then
return NumberColumns( ar[2] ); fi; fi;
TryNextMethod( );
end );
##
InstallMethod( NrGenerators, "for sets of relations of homalg modules",
[ IsHomalgRelations ],
NrGeneratorsForRelations );
##
InstallMethod( HasNrRelations, "for sets of relations of homalg modules",
[ IsHomalgRelationsOfRightModule ],
function( rel )
if HasEvaluatedMatrixOfRelations( rel ) then
return HasNumberColumns( MatrixOfRelations( rel ) ); fi;
return false;
end );
##
InstallMethod( HasNrRelations, "for sets of relations of homalg modules",
[ IsHomalgRelationsOfLeftModule ],
function( rel )
if HasEvaluatedMatrixOfRelations( rel ) then
return HasNumberRows( MatrixOfRelations( rel ) ); fi;
return false;
end );
##
InstallMethod( NrRelationsForRelations, ### defines: NrRelations (NumberOfColumns) "for sets of relations of homalg modules",
[ IsHomalgRelationsOfRightModule ],
function( rel )
return NumberColumns( MatrixOfRelations( rel ) );
end );
##
InstallMethod( NrRelationsForRelations, ### defines: NrRelations (NumberOfRows) "for sets of relations of homalg modules",
[ IsHomalgRelationsOfLeftModule ],
function( rel )
return NumberRows( MatrixOfRelations( rel ) );
end );
##
InstallMethod( NrRelations, "for sets of relations of homalg modules",
[ IsHomalgRelations ],
NrRelationsForRelations );
##
InstallMethod( CertainRelations, ### defines: CertainRelations "for sets of relations of homalg modules",
[ IsHomalgRelationsOfRightModule, IsList ],
##
InstallMethod( BasisOfModule, "for sets of relations of homalg modules",
[ IsHomalgRelationsOfRightModule ],
function( rel )
local mat, bas, inj, M, rk;
if not IsBound( rel!.BasisOfModule ) then
mat := MatrixOfRelations( rel );
bas := BasisOfColumns( mat );
inj := HasIsRightRegular( bas ) and IsRightRegular( bas );
if bas = mat then
SetCanBeUsedToDecideZeroEffectively( rel, true );
rel!.EvaluatedMatrixOfRelations := bas; ## when computing over finite fields in Maple taking a basis normalizes the entries if inj then
SetIsInjectivePresentation( rel, true ); fi;
return rel; else
rel!.BasisOfModule := bas;
SetCanBeUsedToDecideZeroEffectively( rel, false ); fi; else
bas := rel!.BasisOfModule;
inj := HasIsRightRegular( bas ) and IsRightRegular( bas ); fi;
bas := HomalgRelationsForRightModule( bas );
if inj then
SetIsInjectivePresentation( bas, true ); fi;
SetCanBeUsedToDecideZeroEffectively( bas, true );
return bas; end );
##
InstallMethod( BasisOfModule, "for sets of relations of homalg modules",
[ IsHomalgRelationsOfLeftModule ],
function( rel )
local mat, bas, inj, M, rk;
if not IsBound( rel!.BasisOfModule ) then
mat := MatrixOfRelations( rel );
bas := BasisOfRows( mat );
inj := HasIsLeftRegular( bas ) and IsLeftRegular( bas );
if bas = mat then
SetCanBeUsedToDecideZeroEffectively( rel, true );
rel!.EvaluatedMatrixOfRelations := bas; ## when computing over finite fields in Maple taking a basis normalizes the entries if inj then
SetIsInjectivePresentation( rel, true ); fi;
return rel; else
rel!.BasisOfModule := bas;
SetCanBeUsedToDecideZeroEffectively( rel, false ); fi; else
bas := rel!.BasisOfModule;
inj := HasIsLeftRegular( bas ) and IsLeftRegular( bas ); fi;
bas := HomalgRelationsForLeftModule( bas );
if inj then
SetIsInjectivePresentation( bas, true ); fi;
SetCanBeUsedToDecideZeroEffectively( bas, true );
return bas; end );
##
InstallMethod( BasisOfModule, "for sets of relations of homalg modules",
[ IsHomalgRelations and CanBeUsedToDecideZeroEffectively ],
## this will be obsolete for the modules over CAP
entry := ToDoListEntry( [ [ rels, "IsTorsion" ] ],
[ [ "if the relations HasIsTorsion propagate this property to the module",
[ M, "IsTorsion", [ IsTorsion, rels ] ] ],
]
);
AddToToDoList( entry );
entry := ToDoListEntry( [ [ rels, "IsInjectivePresentation", true ] ],
[ [ "the rank of the presented module can be computed as NrGenerators - NrRelations",
[ M, "RankOfObject", [ r -> NrGenerators( r ) - NrRelations( r ), rels ] ] ], ## the Euler characteristic
]
);
AddToToDoList( entry );
entry := ToDoListEntry( [ [ rels, "NrRelationsForRelations" ] ],
[ [ "f.p. modules with no relations are free", function() if NrRelations( rels ) = 0then SetIsFree( M, true ); SetRankOfObject( M, NrGenerators( rels ) ); fi; end ],
[ "compute the rank of modules over integral domains presented by diagonal matrices", function()
local R, diag;
diag := MatrixOfRelations( rels );
R := HomalgRing( M ); if HasIsIntegralDomain( R ) and IsIntegralDomain( R ) and
HasIsDiagonalMatrix( diag ) and IsDiagonalMatrix( diag ) then
diag := DiagonalEntries( diag );
SetRankOfObject( M, NrGenerators( rels ) - Length( Filtered( diag, a -> not IsZero( a ) ) ) ); fi; end ],
]
);
AddToToDoList( entry );
end );
##
InstallGlobalFunction( _HomalgRelationsForLeftModule, function( arg )
local l, relations, mat, M;
l := Length( arg );
relations := rec( );
if IsHomalgMatrix( arg[1] ) then
mat := arg[1];
ResetFilterObj( mat, IsMutable ); elif IsFunction( arg[1] ) then
if not ( l > 1 and IsList( arg[2] ) ) then
Error( "if the first argument is a function then the second argument must be the list of arguments\n" ); fi;
##
InstallMethod( HomalgRelationsForLeftModule, "for two objects",
[ IsObject, IsObject ],
_HomalgRelationsForLeftModule );
##
InstallMethod( HomalgRelationsForLeftModule, "for an object",
[ IsObject ],
_HomalgRelationsForLeftModule );
##
InstallGlobalFunction( _HomalgRelationsForRightModule, function( arg )
local l, relations, mat, M;
l := Length( arg );
relations := rec( );
if IsHomalgMatrix( arg[1] ) then
mat := arg[1];
ResetFilterObj( mat, IsMutable ); elif IsFunction( arg[1] ) then
if not ( l > 1 and IsList( arg[2] ) ) then
Error( "if the first argument is a function then the second argument must be the list of arguments\n" ); fi;
if HasNrRelations( o ) then
m := NrRelations( o ); else
m := "unknown number"; fi;
n := NrGenerators( o );
if IsString( m ) then
Print( "<An unevaluated set of relations " ); elif m = 0then
Print( "<An empty set of relations " ); elif m = 1then
Print( "<A set containing a single relation " ); else
Print( "<A set of ", m, " relations " ); fi;
if n = 0then
Print( "for an empty set of generators " ); elif n = 1then
Print( "for a single generator " ); else
Print( "for ", n, " generators " ); fi;
Print( "of a homalg " );
if IsHomalgRelationsOfLeftModule( o ) then
Print( "left " ); else
Print( "right " ); fi;
if m = 0then
Print( "an empty set of relations " ); if n = 0then
Print( "on an empty set of generators\n" ); elif n = 1then
Print( "on a single generator\n" ); else
Print( "on ", n, " generators\n" ); fi; else if n > 0then
Display( MatrixOfRelations( o ) );
Print( "\n" ); fi;
if m = 1then
Print( "a single relation " ); else
Print( m, " relations " ); fi;
if n = 0then
Print( "for an empty set of generators\n" ); else if n = 1then
Print( "for a single generator " ); else
Print( "for ", n, " generators " ); fi;
Print( "given by " );
if m = 1then
Print( "(" ); fi;
Print( "the " );
if IsHomalgRelationsOfLeftModule( o ) then
Print( "row" ); else
Print( "column" ); fi;
if m = 1then
Print( " of)" ); else
Print( "s of" ); fi;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.