|
# SPDX-License-Identifier: GPL-2.0-or-later
# homalg: A homological algebra meta-package for computable Abelian categories
#
# Implementations
#
## Implementation stuff for homalg complexes.
####################################
#
# representations:
#
####################################
## <#GAPDoc Label="IsComplexOfFinitelyPresentedObjectsRep">
## <ManSection>
## <Filt Type="Representation" Arg="C" Name="IsComplexOfFinitelyPresentedObjectsRep"/>
## <Returns><C>true</C> or <C>false</C></Returns>
## <Description>
## The &GAP; representation of complexes of finitley presented &homalg; objects. <P/>
## (It is a representation of the &GAP; category <Ref Filt="IsHomalgComplex"/>,
## which is a subrepresentation of the &GAP; representation <C>IsFinitelyPresentedObjectRep</C>.)
## </Description>
## </ManSection>
## <#/GAPDoc>
##
DeclareRepresentation( "IsComplexOfFinitelyPresentedObjectsRep",
IsHomalgComplex and IsFinitelyPresentedObjectRep,
[ ] );
## <#GAPDoc Label="IsCocomplexOfFinitelyPresentedObjectsRep">
## <ManSection>
## <Filt Type="Representation" Arg="C" Name="IsCocomplexOfFinitelyPresentedObjectsRep"/>
## <Returns><C>true</C> or <C>false</C></Returns>
## <Description>
## The &GAP; representation of cocomplexes of finitley presented &homalg; objects. <P/>
## (It is a representation of the &GAP; category <Ref Filt="IsHomalgComplex"/>,
## which is a subrepresentation of the &GAP; representation <C>IsFinitelyPresentedObjectRep</C>.)
## </Description>
## </ManSection>
## <#/GAPDoc>
##
DeclareRepresentation( "IsCocomplexOfFinitelyPresentedObjectsRep",
IsHomalgComplex and IsFinitelyPresentedObjectRep,
[ ] );
####################################
#
# families and types:
#
####################################
# a new family:
BindGlobal( "TheFamilyOfHomalgComplexes",
NewFamily( "TheFamilyOfHomalgComplexes" ) );
# four new types:
BindGlobal( "TheTypeHomalgComplexOfLeftObjects",
NewType( TheFamilyOfHomalgComplexes,
IsComplexOfFinitelyPresentedObjectsRep and IsHomalgLeftObjectOrMorphismOfLeftObjects ) );
BindGlobal( "TheTypeHomalgComplexOfRightObjects",
NewType( TheFamilyOfHomalgComplexes,
IsComplexOfFinitelyPresentedObjectsRep and IsHomalgRightObjectOrMorphismOfRightObjects ) );
BindGlobal( "TheTypeHomalgCocomplexOfLeftObjects",
NewType( TheFamilyOfHomalgComplexes,
IsCocomplexOfFinitelyPresentedObjectsRep and IsHomalgLeftObjectOrMorphismOfLeftObjects ) );
BindGlobal( "TheTypeHomalgCocomplexOfRightObjects",
NewType( TheFamilyOfHomalgComplexes,
IsCocomplexOfFinitelyPresentedObjectsRep and IsHomalgRightObjectOrMorphismOfRightObjects ) );
####################################
#
# global variables:
#
####################################
HOMALG.PropertiesOfComplexes :=
[ IsZero,
IsSequence,
IsComplex,
IsAcyclic,
IsRightAcyclic,
IsLeftAcyclic,
IsGradedObject,
IsExactSequence,
IsShortExactSequence,
IsTriangle,
IsExactTriangle,
IsSplitShortExactSequence ];
####################################
#
# methods for operations:
#
####################################
##
InstallMethod( homalgResetFilters,
"for homalg complexes",
[ IsHomalgComplex ],
function( C )
local property;
for property in HOMALG.PropertiesOfComplexes do
ResetFilterObj( C, property );
od;
if HasBettiTable( C ) then
ResetFilterObj( C, BettiTable );
Unbind( C!.BettiTable );
fi;
if HasFiltrationByShortExactSequence( C ) then
ResetFilterObj( C, FiltrationByShortExactSequence );
Unbind( C!.FiltrationByShortExactSequence );
fi;
if IsBound( C!.HomologyGradedObject ) then
Unbind( C!.HomologyGradedObject );
fi;
if IsBound( C!.CohomologyGradedObject ) then
Unbind( C!.CohomologyGradedObject );
fi;
if IsBound( C!.resolutions ) then
Unbind( C!.resolutions );
fi;
end );
##
InstallMethod( StructureObject,
"for homalg complexes",
[ IsHomalgComplex ],
function( C )
return StructureObject( LowestDegreeObject( C ) );
end );
##
InstallMethod( HomalgCategory,
"for homalg morphisms",
[ IsHomalgComplex ],
function( phi )
return HomalgCategory( LowestDegreeObject( phi ) );
end );
## provided to avoid branching in the code and always returns fail
InstallMethod( PositionOfTheDefaultPresentation,
"for homalg complexes",
[ IsHomalgComplex ],
function( C )
return fail;
end );
##
InstallMethod( ObjectDegreesOfComplex,
"for homalg complexes",
[ IsHomalgComplex ],
function( C )
return C!.degrees;
end );
##
InstallMethod( MorphismDegreesOfComplex,
"for homalg complexes",
[ IsHomalgComplex ],
function( C )
local degrees, l;
degrees := ObjectDegreesOfComplex( C );
l := Length( degrees );
if l = 1 then
return [ ];
elif IsComplexOfFinitelyPresentedObjectsRep( C ) then
return degrees{[ 2 .. l ]};
else
return degrees{[ 1 .. l - 1 ]};
fi;
end );
##
InstallMethod( CertainMorphism,
"for homalg complexes",
[ IsHomalgComplex, IsInt ],
function( C, i )
local m;
if IsBound( C!.(String( i )) ) and IsHomalgMorphism( C!.(String( i )) ) then
return C!.(String( i ));
fi;
if IsBound( C!.MorphismConstructor ) then
m := C!.MorphismConstructor( i );
C!.(String( i )) := m;
return m;
fi;
return fail;
end );
##
InstallMethod( CertainObject,
"for homalg complexes",
[ IsHomalgComplex, IsInt ],
function( C, i )
local degrees, l, o;
if IsBound( C!.(String( i )) ) then
if IsHomalgObject( C!.(String( i )) ) then
return C!.(String( i ));
else
return Source( C!.(String( i )) );
fi;
fi;
degrees := ObjectDegreesOfComplex( C );
l := Length( degrees );
if IsComplexOfFinitelyPresentedObjectsRep( C ) and degrees[1] = i then
return Range( CertainMorphism( C, i + 1 ) );
elif IsCocomplexOfFinitelyPresentedObjectsRep( C ) and degrees[l] = i then
return Range( CertainMorphism( C, i - 1 ) );
fi;
if IsBound( C!.ObjectConstructor ) then
o := C!.ObjectConstructor( i );
C!.(String( i )) := o;
return o;
fi;
return fail;
end );
##
InstallMethod( MorphismsOfComplex,
"for homalg complexes",
[ IsHomalgComplex ],
function( C )
local degrees;
degrees := MorphismDegreesOfComplex( C );
if Length( degrees ) = 0 then
return [ ];
fi;
return List( degrees, i -> CertainMorphism( C, i ) );
end );
##
InstallMethod( ObjectsOfComplex,
"for homalg complexes",
[ IsHomalgComplex ],
function( C )
local morphisms, l, objects;
morphisms := MorphismsOfComplex( C );
l := Length( morphisms );
if l = 0 then
return [ CertainObject( C, ObjectDegreesOfComplex( C )[1] ) ];
elif IsComplexOfFinitelyPresentedObjectsRep( C ) then
objects := List( morphisms, Range );
Add( objects, Source( morphisms[l] ) );
else
objects := List( morphisms, Source );
Add( objects, Range( morphisms[l] ) );
fi;
return objects;
end );
##
InstallMethod( LowestDegree,
"for homalg complexes",
[ IsHomalgComplex ],
function( C )
return ObjectDegreesOfComplex( C )[1];
end );
##
InstallMethod( HighestDegree,
"for homalg complexes",
[ IsHomalgComplex ],
function( C )
local degrees;
degrees := ObjectDegreesOfComplex( C );
return degrees[Length( degrees )];
end );
##
InstallMethod( LowestDegreeObject,
"for homalg complexes",
[ IsHomalgComplex ],
function( C )
return CertainObject( C, LowestDegree( C ) );
end );
##
InstallMethod( HighestDegreeObject,
"for homalg complexes",
[ IsHomalgComplex ],
function( C )
local degrees;
degrees := ObjectDegreesOfComplex( C );
return CertainObject( C, HighestDegree( C ) );
end );
##
InstallMethod( LowestDegreeMorphism,
"for homalg complexes",
[ IsHomalgComplex ],
function( C )
local degrees;
degrees := MorphismDegreesOfComplex( C );
return CertainMorphism( C, degrees[1] );
end );
##
InstallMethod( HighestDegreeMorphism,
"for homalg complexes",
[ IsHomalgComplex ],
function( C )
local degrees;
degrees := MorphismDegreesOfComplex( C );
return CertainMorphism( C, degrees[Length( degrees )] );
end );
##
InstallMethod( SupportOfComplex,
"for homalg complexes",
[ IsHomalgComplex ],
function( C )
local degrees, l, objects;
degrees := ObjectDegreesOfComplex( C );
l := Length( degrees );
objects := ObjectsOfComplex( C );
return degrees{ Filtered( [ 1 .. l ], i -> not IsZero( objects[i] ) ) };
end );
## <#GAPDoc Label="Add:complex">
## <ManSection>
## <Oper Arg="C, phi" Name="Add" Label="to complexes given a morphism"/>
## <Oper Arg="C, mat" Name="Add" Label="to complexes given a matrix"/>
## <Returns>a &homalg; complex</Returns>
## <Description>
## In the first syntax the morphism <A>phi</A> is added to the (co)chain complex <A>C</A>
## (&see; <Ref Sect="Complexes:Constructors"/>) as the new <E>highest</E> degree
## morphism and the altered argument <A>C</A> is returned. In case <A>C</A> is a chain complex, the highest degree
## object in <A>C</A> and the target of <A>phi</A> must be <E>identical</E>. In case <A>C</A> is a <E>co</E>chain
## complex, the highest degree object in <A>C</A> and the source of <A>phi</A> must be <E>identical</E>. <P/>
## In the second syntax the matrix <A>mat</A> is interpreted as the matrix of the new <E>highest</E> degree morphism
## <M>psi</M>, created according to the following rules:
## In case <A>C</A> is a chain complex, the highest degree left (resp. right) object <M>C_d</M> in <A>C</A>
## is declared as the target of <M>psi</M>, while its source is taken to be a free left (resp. right) object of rank
## equal to <C>NumberRows</C>(<A>mat</A>) (resp. <C>NumberColumns</C>(<A>mat</A>)). For this <C>NumberColumns</C>(<A>mat</A>)
## (resp. <C>NumberRows</C>(<A>mat</A>)) must coincide with the <C>NrGenerators</C>(<M>C_d</M>).
## In case <A>C</A> is a <E>co</E>chain complex, the highest degree left (resp. right) object <M>C^d</M> in <A>C</A>
## is declared as the source of <M>psi</M>, while its target is taken to be a free left (resp. right) object of rank
## equal to <C>NumberColumns</C>(<A>mat</A>) (resp. <C>NumberRows</C>(<A>mat</A>)). For this <C>NumberRows</C>(<A>mat</A>)
## (resp. <C>Columns</C>(<A>mat</A>)) must coincide with the <C>NrGenerators</C>(<M>C^d</M>).
## <Example><![CDATA[
## gap> zz := HomalgRingOfIntegers( );
## Z
## gap> mat := HomalgMatrix( "[ 0, 1, 0, 0 ]", 2, 2, zz );
## <A 2 x 2 matrix over an internal ring>
## gap> phi := HomalgMap( mat );
## <A homomorphism of left modules>
## gap> C := HomalgComplex( phi );
## <A non-zero acyclic complex containing a single morphism of left modules at de\
## grees [ 0 .. 1 ]>
## gap> Add( C, mat );
## gap> C;
## <A sequence containing 2 morphisms of left modules at degrees [ 0 .. 2 ]>
## gap> Display( C );
## -------------------------
## at homology degree: 2
## Z^(1 x 2)
## -------------------------
## [ [ 0, 1 ],
## [ 0, 0 ] ]
##
## the map is currently represented by the above 2 x 2 matrix
## ------------v------------
## at homology degree: 1
## Z^(1 x 2)
## -------------------------
## [ [ 0, 1 ],
## [ 0, 0 ] ]
##
## the map is currently represented by the above 2 x 2 matrix
## ------------v------------
## at homology degree: 0
## Z^(1 x 2)
## -------------------------
## gap> IsComplex( C );
## true
## gap> IsAcyclic( C );
## true
## gap> IsExactSequence( C );
## false
## gap> C;
## <A non-zero acyclic complex containing 2 morphisms of left modules at degrees
## [ 0 .. 2 ]>
## ]]></Example>
## </Description>
## </ManSection>
## <#/GAPDoc>
##
InstallMethod( Add,
"for homalg complexes",
[ IsComplexOfFinitelyPresentedObjectsRep, IsMorphismOfFinitelyGeneratedObjectsRep ],
function( C, phi )
local degrees, l, psi;
if HasIsATwoSequence( C ) and IsATwoSequence( C ) then
Error( "this complex is write-protected since IsATwoSequence = true\n" );
fi;
degrees := ObjectDegreesOfComplex( C );
l := Length( degrees );
if l = 1 then
l := degrees[l];
if IsHomalgChainMorphism( phi ) then
if CertainObject( C, l ) <> Range( phi ) then
Error( "the unique object in the complex and the target of the new chain morphism are not equal\n" );
fi;
else
if not IsIdenticalObj( CertainObject( C, l ), Range( phi ) ) then
Error( "the unique object in the complex and the target of the new morphism are not identical\n" );
fi;
fi;
Unbind( C!.(String( l )) );
Add( degrees, l + 1 );
C!.(String( l + 1 )) := phi;
else
l := degrees[l];
if IsHomalgChainMorphism( phi ) then
if Source( CertainMorphism( C, l ) ) <> Range( phi ) then
Error( "the source of the ", l, ". chain morphism in the complex (i.e. the highest one) and the target of the new one are not equal\n" );
fi;
else
if not IsIdenticalObj( Source( CertainMorphism( C, l ) ), Range( phi ) ) then
Error( "the source of the ", l, ". morphism in the complex (i.e. the highest one) and the target of the new one are not identical\n" );
fi;
fi;
Add( degrees, l + 1 );
C!.(String( l + 1 )) := phi;
fi;
ConvertToRangeRep( degrees );
if HasIsGradedObject( C ) and IsGradedObject( C ) and
HasIsMorphism( phi ) and IsMorphism( phi ) then
homalgResetFilters( C );
SetIsComplex( C, true );
elif HasIsSequence( C ) and IsSequence( C ) and
HasIsMorphism( phi ) and IsMorphism( phi ) then
homalgResetFilters( C );
SetIsSequence( C, true );
else
homalgResetFilters( C );
fi;
if Length( degrees ) = 3 then
psi := LowestDegreeMorphism( C );
if HasIsEpimorphism( psi ) and IsEpimorphism( psi ) and
( ( HasKernelEmb( psi ) and IsIdenticalObj( KernelEmb( psi ), phi ) ) or
( HasCokernelEpi( phi ) and IsIdenticalObj( CokernelEpi( phi ), psi ) ) ) then
SetIsShortExactSequence( C, true );
fi;
fi;
return C;
end );
##
InstallMethod( Add,
"for homalg cocomplexes",
[ IsMorphismOfFinitelyGeneratedObjectsRep, IsComplexOfFinitelyPresentedObjectsRep ],
function( phi, C )
local degrees, l, psi;
degrees := ObjectDegreesOfComplex( C );
l := Length( degrees );
if l = 1 then
l := degrees[1];
if IsHomalgChainMorphism( phi ) then
if CertainObject( C, l ) <> Source( phi ) then
Error( "the unique object in the complex and the source of the new chain morphism are not equal\n" );
fi;
else
if not IsIdenticalObj( CertainObject( C, l ), Source( phi ) ) then
Error( "the unique object in the complex and the source of the new morphism are not identical\n" );
fi;
fi;
else
l := degrees[1];
if IsHomalgChainMorphism( phi ) then
if Range( CertainMorphism( C, l + 1 ) ) <> Source( phi ) then
Error( "the target of the ", l + 1, ". chain morphism in the complex (i.e. the highest one) and the source of the new one are not equal\n" );
fi;
else
if not IsIdenticalObj( Range( CertainMorphism( C, l + 1 ) ), Source( phi ) ) then
Error( "the target of the ", l + 1, ". morphism in the complex (i.e. the highest one) and the source of the new one are not identical\n" );
fi;
fi;
fi;
C!.degrees := Concatenation( [ l - 1 ], degrees );
C!.(String( l )) := phi;
degrees := C!.degrees;
ConvertToRangeRep( degrees );
if HasIsGradedObject( C ) and IsGradedObject( C ) and
HasIsMorphism( phi ) and IsMorphism( phi ) then
homalgResetFilters( C );
SetIsComplex( C, true );
elif HasIsSequence( C ) and IsSequence( C ) and
HasIsMorphism( phi ) and IsMorphism( phi ) then
homalgResetFilters( C );
SetIsSequence( C, true );
else
homalgResetFilters( C );
fi;
if Length( degrees ) = 3 then
psi := LowestDegreeMorphism( C );
if HasIsEpimorphism( psi ) and IsEpimorphism( psi ) and
( ( HasKernelEmb( psi ) and IsIdenticalObj( KernelEmb( psi ), phi ) ) or
( HasCokernelEpi( phi ) and IsIdenticalObj( CokernelEpi( phi ), psi ) ) ) then
SetIsShortExactSequence( C, true );
fi;
fi;
return C;
end );
##
InstallMethod( Add,
"for homalg cocomplexes",
[ IsCocomplexOfFinitelyPresentedObjectsRep, IsMorphismOfFinitelyGeneratedObjectsRep ],
function( C, phi )
local degrees, l, psi;
degrees := ObjectDegreesOfComplex( C );
l := Length( degrees );
if l = 1 then
if IsHomalgChainMorphism( phi ) then
if CertainObject( C, degrees[1] ) <> Source( phi ) then
Error( "the unique object in the cocomplex and the source of the new chain morphism are not equal\n" );
fi;
else
if not IsIdenticalObj( CertainObject( C, degrees[1] ), Source( phi ) ) then
Error( "the unique object in the cocomplex and the source of the new morphism are not identical\n" );
fi;
fi;
Add( degrees, degrees[1] + 1 );
C!.(String( degrees[1] )) := phi;
else
l := degrees[l - 1];
if IsHomalgChainMorphism( phi ) then
if Range( CertainMorphism( C, l ) ) <> Source( phi ) then
Error( "the target of the ", l, ". chain morphism in the cocomplex (i.e. the highest one) and the source of the new one are not equal\n" );
fi;
else
if not IsIdenticalObj( Range( CertainMorphism( C, l ) ), Source( phi ) ) then
Error( "the target of the ", l, ". morphism in the cocomplex (i.e. the highest one) and the source of the new one are not identical\n" );
fi;
fi;
Add( degrees, l + 2 );
C!.(String( l + 1 )) := phi;
fi;
ConvertToRangeRep( degrees );
if HasIsGradedObject( C ) and IsGradedObject( C ) and
HasIsMorphism( phi ) and IsMorphism( phi ) then
homalgResetFilters( C );
SetIsComplex( C, true );
elif HasIsSequence( C ) and IsSequence( C ) and
HasIsMorphism( phi ) and IsMorphism( phi ) then
homalgResetFilters( C );
SetIsSequence( C, true );
else
homalgResetFilters( C );
fi;
if Length( degrees ) = 3 then
psi := LowestDegreeMorphism( C );
if HasIsMonomorphism( psi ) and IsMonomorphism( psi ) and
( ( HasCokernelEpi( psi ) and IsIdenticalObj( CokernelEpi( psi ), phi ) ) or
( HasKernelEmb( phi ) and IsIdenticalObj( KernelEmb( phi ), psi ) ) ) then
SetIsShortExactSequence( C, true );
fi;
fi;
return C;
end );
##
InstallMethod( Add,
"for homalg cocomplexes",
[ IsMorphismOfFinitelyGeneratedObjectsRep, IsCocomplexOfFinitelyPresentedObjectsRep ],
function( phi, C )
local degrees, l, psi;
degrees := ObjectDegreesOfComplex( C );
l := Length( degrees );
if l = 1 then
l := degrees[1];
if IsHomalgChainMorphism( phi ) then
if CertainObject( C, l ) <> Range( phi ) then
Error( "the unique object in the cocomplex and the range of the new chain morphism are not equal\n" );
fi;
else
if not IsIdenticalObj( CertainObject( C, l ), Range( phi ) ) then
Error( "the unique object in the cocomplex and the range of the new morphism are not identical\n" );
fi;
fi;
C!.degrees := Concatenation( [ l - 1 ], degrees );
C!.(String( l - 1 )) := phi;
else
l := degrees[1];
if IsHomalgChainMorphism( phi ) then
if Source( CertainMorphism( C, l ) ) <> Range( phi ) then
Error( "the source of the ", l, ". chain morphism in the cocomplex (i.e. the lowest one) and the target of the new one are not equal\n" );
fi;
else
if not IsIdenticalObj( Source( CertainMorphism( C, l ) ), Range( phi ) ) then
Error( "the source of the ", l, ". morphism in the cocomplex (i.e. the lowest one) and the target of the new one are not identical\n" );
fi;
fi;
C!.degrees := Concatenation( [ l - 1 ], degrees );
C!.(String( l - 1 )) := phi;
fi;
degrees := C!.degrees;
ConvertToRangeRep( degrees );
if HasIsSequence( C ) and IsSequence( C ) and
HasIsMorphism( phi ) and IsMorphism( phi ) then
homalgResetFilters( C );
SetIsSequence( C, true );
else
homalgResetFilters( C );
fi;
## FIXME: insert a SetIsShortExactSequence statement, analogous to the above Add method
return C;
end );
##
InstallMethod( Add,
"for homalg complexes",
[ IsComplexOfFinitelyPresentedObjectsRep, IsStaticFinitelyPresentedObjectRep ],
function( C, M )
local T, grd, cpx, seq;
T := HighestDegreeObject( C );
if HasIsGradedObject( C ) then
grd := IsGradedObject( C );
elif HasIsComplex( C ) then
cpx := IsComplex( C );
elif HasIsSequence( C ) then
seq := IsSequence ( C );
fi;
Add( C, TheZeroMorphism( M, T ) );
if IsBound( grd ) then
SetIsGradedObject( C, grd );
elif IsBound( cpx ) then
SetIsComplex( C, cpx );
elif IsBound( seq ) then
SetIsSequence( C, seq );
fi;
end );
##
InstallMethod( Add,
"for homalg complexes",
[ IsCocomplexOfFinitelyPresentedObjectsRep, IsStaticFinitelyPresentedObjectRep ],
function( C, M )
local S, grd, cpx, seq;
S := HighestDegreeObject( C );
if HasIsGradedObject( C ) then
grd := IsGradedObject( C );
elif HasIsComplex( C ) then
cpx := IsComplex( C );
elif HasIsSequence( C ) then
seq := IsSequence ( C );
fi;
Add( C, TheZeroMorphism( S, M ) );
if IsBound( grd ) then
SetIsGradedObject( C, grd );
elif IsBound( cpx ) then
SetIsComplex( C, cpx );
elif IsBound( seq ) then
SetIsSequence( C, seq );
fi;
end );
##
InstallMethod( Add,
"for homalg complexes",
[ IsStaticFinitelyPresentedObjectRep, IsComplexOfFinitelyPresentedObjectsRep ],
function( M, C )
local T, grd, cpx, seq;
T := LowestDegreeObject( C );
if HasIsGradedObject( C ) then
grd := IsGradedObject( C );
elif HasIsComplex( C ) then
cpx := IsComplex( C );
elif HasIsSequence( C ) then
seq := IsSequence ( C );
fi;
Add( TheZeroMorphism( T, M ), C );
if IsBound( grd ) then
SetIsGradedObject( C, grd );
elif IsBound( cpx ) then
SetIsComplex( C, cpx );
elif IsBound( seq ) then
SetIsSequence( C, seq );
fi;
end );
##
InstallMethod( Add,
"for homalg complexes",
[ IsStaticFinitelyPresentedObjectRep, IsCocomplexOfFinitelyPresentedObjectsRep ],
function( M, C )
local S, grd, cpx, seq;
S := LowestDegreeObject( C );
if HasIsGradedObject( C ) then
grd := IsGradedObject( C );
elif HasIsComplex( C ) then
cpx := IsComplex( C );
elif HasIsSequence( C ) then
seq := IsSequence ( C );
fi;
Add( TheZeroMorphism( M, S ), C );
if IsBound( grd ) then
SetIsGradedObject( C, grd );
elif IsBound( cpx ) then
SetIsComplex( C, cpx );
elif IsBound( seq ) then
SetIsSequence( C, seq );
fi;
end );
##
InstallMethod( Shift,
"for homalg complexes",
[ IsHomalgComplex, IsInt ],
function( C, s )
local d, Cd, Cs;
d := LowestDegree( C );
Cd := LowestDegreeObject( C );
if IsComplexOfFinitelyPresentedObjectsRep( C ) then
Cs := HomalgComplex( Cd, d - s );
else
Cs := HomalgCocomplex( Cd, d - s );
fi;
Perform ( MorphismsOfComplex( C ), function( m ) Add( Cs, m ); end );
if HasIsGradedObject( C ) and IsGradedObject( C ) then
SetIsGradedObject( Cs, true );
elif HasIsComplex( C ) and IsComplex( C ) then
SetIsComplex( Cs, true );
elif HasIsSequence( C ) and IsSequence( C ) then
SetIsSequence( Cs, true );
fi;
return Cs;
end );
##
InstallMethod( Reflect,
"for homalg complexes",
[ IsHomalgComplex, IsInt ],
function( C, s )
local d, Cd, Cs;
d := HighestDegree( C );
Cd := HighestDegreeObject( C );
if IsComplexOfFinitelyPresentedObjectsRep( C ) then
Cs := HomalgCocomplex( Cd, - d - s );
else
Cs := HomalgComplex( Cd, - d - s );
fi;
Perform ( Reversed( MorphismsOfComplex( C ) ), function( m ) Add( Cs, m ); end );
if HasIsGradedObject( C ) and IsGradedObject( C ) then
SetIsGradedObject( Cs, true );
elif HasIsComplex( C ) and IsComplex( C ) then
SetIsComplex( Cs, true );
elif HasIsSequence( C ) and IsSequence( C ) then
SetIsSequence( Cs, true );
fi;
return Cs;
end );
##
InstallMethod( Reflect,
"for homalg complexes",
[ IsHomalgComplex ],
function( C )
return Reflect( C, 0 );
end );
##
InstallMethod( \+,
"for two homalg complexes",
[ IsHomalgComplex and IsGradedObject, IsHomalgComplex and IsGradedObject ],
function( C1, C2 )
local cpx, d1, d2, d, Cd, Cs, i;
if IsComplexOfFinitelyPresentedObjectsRep( C1 ) and IsComplexOfFinitelyPresentedObjectsRep( C2 ) then
cpx := true;
elif IsCocomplexOfFinitelyPresentedObjectsRep( C1 ) and IsCocomplexOfFinitelyPresentedObjectsRep( C2 ) then
cpx := false;
else
Error( "first and second argument must either be both complexes or both cocomplexes\n" );
fi;
d1 := LowestDegree( C1 );
d2 := LowestDegree( C2 );
d := Minimum( d1, d2 );
if d1 < d2 then
Cd := LowestDegreeObject( C1 );
elif d2 < d1 then
Cd := LowestDegreeObject( C2 );
else
Cd := LowestDegreeObject( C1 ) + LowestDegreeObject( C2 );
fi;
if cpx then
Cs := HomalgComplex( Cd, d );
else
Cs := HomalgCocomplex( Cd, d );
fi;
d1 := ObjectDegreesOfComplex( C1 );
d2 := ObjectDegreesOfComplex( C2 );
for i in [ d + 1 .. Maximum( List( [ C1, C2 ], HighestDegree ) ) ] do
if not i in d2 then
Cd := CertainObject( C1, i );
elif not i in d1 then
Cd := CertainObject( C2, i );
else
Cd := CertainObject( C1, i ) + CertainObject( C2, i );
fi;
Add( Cs, Cd );
od;
SetIsGradedObject( Cs, true );
return Cs;
end );
##
InstallMethod( Subcomplex,
"for homalg complexes",
[ IsComplexOfFinitelyPresentedObjectsRep, IsInt, IsInt ],
function( C, i, j )
local m, A, k;
m := CertainMorphism( C, i + 1 );
if m = fail then
Error( "The complex does not have the demanded degree" );
fi;
A := HomalgComplex( m, i + 1 );
for k in [ i + 2 .. j ] do
m := CertainMorphism( C, k );
if m = fail then
Error( "The complex does not have the demanded degree" );
fi;
Add( A, m );
od;
if HasIsZero( C ) and IsZero( C ) then
SetIsZero( A, true );
elif HasIsGradedObject( C ) and IsGradedObject( C ) then
SetIsGradedObject( A, true );
elif HasIsComplex( C ) and IsComplex( C ) then
SetIsComplex( A, true );
fi;
return A;
end );
##
InstallMethod( Subcomplex,
"for homalg complexes",
[ IsCocomplexOfFinitelyPresentedObjectsRep, IsInt, IsInt ],
function( C, i, j )
local m, A, k;
m := CertainMorphism( C, i );
if m = fail then
Error( "The cocomplex does not have the demanded degree" );
fi;
A := HomalgCocomplex( m, i );
for k in [ i+1 .. j-1 ] do
m := CertainMorphism( C, k );
if m = fail then
Error( "The cocomplex does not have the demanded degree" );
fi;
Add( A, m );
od;
if HasIsZero( C ) and IsZero( C ) then
SetIsZero( A, true );
elif HasIsGradedObject( C ) and IsGradedObject( C ) then
SetIsGradedObject( A, true );
elif HasIsComplex( C ) and IsComplex( C ) then
SetIsComplex( A, true );
fi;
return A;
end );
##
InstallMethod( CertainMorphismAsSubcomplex,
"for homalg complexes",
[ IsComplexOfFinitelyPresentedObjectsRep, IsInt ],
function( C, i )
local m, A;
m := CertainMorphism( C, i );
if m = fail then
m := CertainMorphism( C, i + 1 );
if m = fail then
return fail;
fi;
m := CokernelEpi( m );
fi;
A := HomalgComplex( m, i );
if HasIsZero( C ) and IsZero( C ) then
SetIsZero( A, true );
elif HasIsGradedObject( C ) and IsGradedObject( C ) then
SetIsGradedObject( A, true );
elif HasIsComplex( C ) and IsComplex( C ) then
SetIsComplex( A, true );
elif HasIsSequence( C ) and IsSequence( C ) then
SetIsComplex( A, true ); ## this is not a mistake
fi;
return A;
end );
##
InstallMethod( CertainMorphismAsSubcomplex,
"for homalg complexes",
[ IsCocomplexOfFinitelyPresentedObjectsRep, IsInt ],
function( C, i )
local m, A;
m := CertainMorphism( C, i );
if m = fail then
return fail;
fi;
A := HomalgCocomplex( m, i );
if HasIsZero( C ) and IsZero( C ) then
SetIsZero( A, true );
elif HasIsGradedObject( C ) and IsGradedObject( C ) then
SetIsGradedObject( A, true );
elif HasIsComplex( C ) and IsComplex( C ) then
SetIsComplex( A, true );
elif HasIsSequence( C ) and IsSequence( C ) then
SetIsComplex( A, true ); ## this is not a mistake
fi;
return A;
end );
##
InstallMethod( CertainTwoMorphismsAsSubcomplex,
"for homalg complexes",
[ IsComplexOfFinitelyPresentedObjectsRep, IsInt ],
function( C, i )
local m, A;
m := CertainMorphism( C, i );
if m = fail then
return fail;
fi;
A := HomalgComplex( m, i );
m := CertainMorphism( C, i + 1 );
if m = fail then
return fail;
fi;
Add( A, m );
if HasIsZero( C ) and IsZero( C ) then
SetIsZero( A, true );
elif HasIsGradedObject( C ) and IsGradedObject( C ) then
SetIsGradedObject( A, true );
elif HasIsComplex( C ) and IsComplex( C ) then
SetIsComplex( A, true );
elif HasIsSequence( C ) and IsSequence( C ) then
SetIsSequence( A, true );
fi;
SetIsATwoSequence( A, true );
return A;
end );
##
InstallMethod( CertainTwoMorphismsAsSubcomplex,
"for homalg complexes",
[ IsCocomplexOfFinitelyPresentedObjectsRep, IsInt ],
function( C, i )
local m, A;
m := CertainMorphism( C, i - 1 );
if m = fail then
return fail;
fi;
A := HomalgCocomplex( m, i - 1 );
m := CertainMorphism( C, i );
if m = fail then
return fail;
fi;
Add( A, m );
if HasIsZero( C ) and IsZero( C ) then
SetIsZero( A, true );
elif HasIsGradedObject( C ) and IsGradedObject( C ) then
SetIsGradedObject( A, true );
elif HasIsComplex( C ) and IsComplex( C ) then
SetIsComplex( A, true );
elif HasIsSequence( C ) and IsSequence( C ) then
SetIsSequence( A, true );
fi;
SetIsATwoSequence( A, true );
return A;
end );
##
InstallMethod( LongSequence,
"for homalg complexes",
[ IsComplexOfFinitelyPresentedObjectsRep and IsTriangle ],
function( T )
local mor, deg, C, j;
mor := MorphismsOfComplex( T );
deg := DegreesOfChainMorphism( mor[1] );
C := HomalgComplex( CertainMorphism( mor[1], deg[1] ) );
Add( C, CertainMorphism( mor[2], deg[1] ) );
for j in deg{[ 2 .. Length( deg ) ]} do
Add( C, CertainMorphism( mor[3], j ) );
Add( C, CertainMorphism( mor[1], j ) );
Add( C, CertainMorphism( mor[2], j ) );
od;
return C;
end );
##
InstallMethod( LongSequence,
"for homalg complexes",
[ IsCocomplexOfFinitelyPresentedObjectsRep and IsTriangle ],
function( T )
local mor, deg, C, j;
mor := MorphismsOfComplex( T );
deg := DegreesOfChainMorphism( mor[1] );
C := HomalgCocomplex( CertainMorphism( mor[1], deg[1] ) );
Add( C, CertainMorphism( mor[2], deg[1] ) );
for j in deg{[ 2 .. Length( deg ) ]} do
Add( C, CertainMorphism( mor[3], j - 1 ) );
Add( C, CertainMorphism( mor[1], j ) );
Add( C, CertainMorphism( mor[2], j ) );
od;
return C;
end );
##
InstallMethod( PreCompose,
"for homalg complexes",
[ IsComplexOfFinitelyPresentedObjectsRep,
IsComplexOfFinitelyPresentedObjectsRep ],
function( C1, C2 )
local mor2, mor1, deg, C, l, m;
mor2 := MorphismsOfComplex( C2 );
if mor2 = [ ] then
return C1;
fi;
mor1 := MorphismsOfComplex( C1 );
if mor1 = [ ] then
return C2;
fi;
deg := LowestDegree( C2 ) + 1;
C := HomalgComplex( mor2[1], deg );
l := Length( mor2 );
for m in mor2{[ 2 .. l - 1 ]} do
Add( C, m );
od;
Add( C, PreCompose( mor1[1], mor2[l] ) );
for m in mor1{[ 2 .. Length( mor1 ) ]} do
Add( C, m );
od;
return C;
end );
##
InstallMethod( PreCompose,
"for homalg complexes",
[ IsCocomplexOfFinitelyPresentedObjectsRep,
IsCocomplexOfFinitelyPresentedObjectsRep ],
function( C1, C2 )
local mor1, mor2, deg, C, l, m;
mor1 := MorphismsOfComplex( C1 );
if mor1 = [ ] then
return C2;
fi;
mor2 := MorphismsOfComplex( C2 );
if mor2 = [ ] then
return C1;
fi;
deg := LowestDegree( C1 );
C := HomalgCocomplex( mor1[1], deg );
l := Length( mor1 );
for m in mor1{[ 2 .. l - 1 ]} do
Add( C, m );
od;
Add( C, PreCompose( mor1[l], mor2[1] ) );
for m in mor2{[ 2 .. Length( mor2 ) ]} do
Add( C, m );
od;
return C;
end );
##
InstallMethod( DecideZero,
"for homalg complexes",
[ IsHomalgComplex ],
function( C )
List( ObjectsOfComplex( C ), DecideZero );
if Length( ObjectDegreesOfComplex( C ) ) > 1 then
List( MorphismsOfComplex( C ), DecideZero );
fi;
IsZero( C );
return C;
end );
## <#GAPDoc Label="ByASmallerPresentation:complex">
## <ManSection>
## <Meth Arg="C" Name="ByASmallerPresentation" Label="for complexes"/>
## <Returns>a &homalg; complex</Returns>
## <Description>
## It invokes <C>ByASmallerPresentation</C> for &homalg; (static) objects.
## <Listing Type="Code"><![CDATA[
InstallMethod( ByASmallerPresentation,
"for homalg complexes",
[ IsHomalgComplex ],
function( C )
List( ObjectsOfComplex( C ), ByASmallerPresentation );
if Length( ObjectDegreesOfComplex( C ) ) > 1 then
List( MorphismsOfComplex( C ), DecideZero );
fi;
IsZero( C );
return C;
end );
## ]]></Listing>
## This method performs side effects on its argument <A>C</A> and returns it.
## <Example><![CDATA[
## gap> zz := HomalgRingOfIntegers( );
## Z
## gap> M := HomalgMatrix( "[ 2, 3, 4, 5, 6, 7 ]", 2, 3, zz );
## <A 2 x 3 matrix over an internal ring>
## gap> M := LeftPresentation( M );
## <A non-torsion left module presented by 2 relations for 3 generators>
## gap> N := HomalgMatrix( "[ 2, 3, 4, 5, 6, 7, 8, 9 ]", 2, 4, zz );
## <A 2 x 4 matrix over an internal ring>
## gap> N := LeftPresentation( N );
## <A non-torsion left module presented by 2 relations for 4 generators>
## gap> mat := HomalgMatrix( "[ \
## > 0, 3, 6, 9, \
## > 0, 2, 4, 6, \
## > 0, 3, 6, 9 \
## > ]", 3, 4, zz );
## <A 3 x 4 matrix over an internal ring>
## gap> phi := HomalgMap( mat, M, N );
## <A "homomorphism" of left modules>
## gap> IsMorphism( phi );
## true
## gap> phi;
## <A homomorphism of left modules>
## gap> C := HomalgComplex( phi );
## <A non-zero acyclic complex containing a single morphism of left modules at de\
## grees [ 0 .. 1 ]>
## gap> Display( C );
## -------------------------
## at homology degree: 1
## [ [ 2, 3, 4 ],
## [ 5, 6, 7 ] ]
##
## Cokernel of the map
##
## Z^(1x2) --> Z^(1x3),
##
## currently represented by the above matrix
## -------------------------
## [ [ 0, 3, 6, 9 ],
## [ 0, 2, 4, 6 ],
## [ 0, 3, 6, 9 ] ]
##
## the map is currently represented by the above 3 x 4 matrix
## ------------v------------
## at homology degree: 0
## [ [ 2, 3, 4, 5 ],
## [ 6, 7, 8, 9 ] ]
##
## Cokernel of the map
##
## Z^(1x2) --> Z^(1x4),
##
## currently represented by the above matrix
## -------------------------
## ]]></Example>
## And now:
## <Example><![CDATA[
## gap> ByASmallerPresentation( C );
## <A non-zero acyclic complex containing a single morphism of left modules at de\
## grees [ 0 .. 1 ]>
## gap> Display( C );
## -------------------------
## at homology degree: 1
## Z/< 3 > + Z^(1 x 1)
## -------------------------
## [ [ 0, 0, 0 ],
## [ 2, 0, 0 ] ]
##
## the map is currently represented by the above 2 x 3 matrix
## ------------v------------
## at homology degree: 0
## Z/< 4 > + Z^(1 x 2)
## -------------------------
## ]]></Example>
## </Description>
## </ManSection>
## <#/GAPDoc>
##
InstallMethod( SetCurrentResolution,
"for a homalg static object and a homalg complex",
[ IsHomalgStaticObject, IsHomalgComplex ],
function( M, P )
local d1, pos;
d1 := CertainMorphism( P, 1 );
if not ( HasCokernelEpi( d1 ) and
IsIdenticalObj( Range( CokernelEpi( d1 ) ), M ) ) then
Error( "the object is not (known to be) the cokernel of the first morphism of the complex\n" );
fi;
pos := PositionOfTheDefaultPresentation( M );
M!.Resolutions.(pos) := P;
end );
####################################
#
# constructor functions and methods:
#
####################################
## <#GAPDoc Label="HomalgComplex">
## <ManSection>
## <Func Arg="M[, d]" Name="HomalgComplex" Label="constructor for complexes given an object"/>
## <Func Arg="phi[, d]" Name="HomalgComplex" Label="constructor for complexes given a morphism"/>
## <Func Arg="C[, d]" Name="HomalgComplex" Label="constructor for complexes given a complex"/>
## <Func Arg="cm[, d]" Name="HomalgComplex" Label="constructor for complexes given a chain morphism"/>
## <Returns>a &homalg; complex</Returns>
## <Description>
## The first syntax creates a complex (i.e. chain complex) with the single &homalg; object <A>M</A>
## at (homological) degree <A>d</A>. <P/>
## The second syntax creates a complex with the single &homalg; morphism <A>phi</A>, its source placed at
## (homological) degree <A>d</A> (and its target at <A>d</A><M>-1</M>). <P/>
## The third syntax creates a complex (i.e. chain complex) with the single &homalg; (co)complex <A>C</A>
## at (homological) degree <A>d</A>. <P/>
## The fourth syntax creates a complex with the single &homalg; (co)chain morphism <A>cm</A>
## (&see; <Ref Func="HomalgChainMorphism" Label="constructor for chain morphisms given a morphism"/>), its source placed at
## (homological) degree <A>d</A> (and its target at <A>d</A><M>-1</M>). <P/>
## If <A>d</A> is not provided it defaults to zero in all cases. <Br/>
## To add a morphism (resp. (co)chain morphism) to a complex use <Ref Oper="Add" Label="to complexes given a morphism"/>.
## <Example><![CDATA[
## gap> zz := HomalgRingOfIntegers( );
## Z
## gap> M := HomalgMatrix( "[ 2, 3, 4, 5, 6, 7 ]", 2, 3, zz );
## <A 2 x 3 matrix over an internal ring>
## gap> M := LeftPresentation( M );
## <A non-torsion left module presented by 2 relations for 3 generators>
## gap> N := HomalgMatrix( "[ 2, 3, 4, 5, 6, 7, 8, 9 ]", 2, 4, zz );
## <A 2 x 4 matrix over an internal ring>
## gap> N := LeftPresentation( N );
## <A non-torsion left module presented by 2 relations for 4 generators>
## gap> mat := HomalgMatrix( "[ \
## > 0, 3, 6, 9, \
## > 0, 2, 4, 6, \
## > 0, 3, 6, 9 \
## > ]", 3, 4, zz );
## <A 3 x 4 matrix over an internal ring>
## gap> phi := HomalgMap( mat, M, N );
## <A "homomorphism" of left modules>
## gap> IsMorphism( phi );
## true
## gap> phi;
## <A homomorphism of left modules>
## ]]></Example>
## The first possibility:
## <Example><![CDATA[
## gap> C := HomalgComplex( N );
## <A non-zero graded homology object consisting of a single left module at degre\
## e 0>
## gap> Add( C, phi );
## gap> C;
## <A complex containing a single morphism of left modules at degrees [ 0 .. 1 ]>
## ]]></Example>
## The second possibility:
## <Example><![CDATA[
## gap> C := HomalgComplex( phi );
## <A non-zero acyclic complex containing a single morphism of left modules at de\
## grees [ 0 .. 1 ]>
## ]]></Example>
## </Description>
## </ManSection>
## <#/GAPDoc>
##
InstallGlobalFunction( HomalgComplex,
function( arg )
local nargs, C, complex, degrees, object, obj_or_mor, left, type;
nargs := Length( arg );
if nargs = 0 then
Error( "empty input\n" );
fi;
C := rec( );
if IsStringRep( arg[nargs] ) and ( arg[nargs] = "co" or arg[nargs] = "cocomplex" ) then
complex := false;
C.string := "cocomplex";
C.string_plural := "cocomplexes";
else
complex := true;
C.string := "complex";
C.string_plural := "complexes";
fi;
if nargs > 1 and ( IsInt( arg[2] )
or ( IsList( arg[2] ) and Length( arg[2] ) > 0 and ForAll( arg[2], IsInt ) ) ) then
degrees := [ arg[2] ];
elif complex and IsMorphismOfFinitelyGeneratedObjectsRep( arg[1] ) then
degrees := [ 1 ];
else
degrees := [ 0 ];
fi;
if IsStructureObjectOrFinitelyPresentedObjectRep( arg[1] ) then
object := true;
if IsStructureObject( arg[1] ) then
obj_or_mor := AsLeftObject( arg[1] );
else
obj_or_mor := arg[1];
fi;
C.degrees := degrees;
left := IsHomalgLeftObjectOrMorphismOfLeftObjects( obj_or_mor );
elif IsMorphismOfFinitelyGeneratedObjectsRep( arg[1] ) then
object := false;
obj_or_mor := arg[1];
if complex then
C.degrees := [ degrees[1] - 1, degrees[1] ];
else
C.degrees := [ degrees[1], degrees[1] + 1 ];
fi;
else
Error( "the first argument must be either a homalg object or a homalg morphism\n" );
fi;
left := IsHomalgLeftObjectOrMorphismOfLeftObjects( obj_or_mor );
C.( String( degrees[1] ) ) := obj_or_mor;
if complex then
if left then
type := TheTypeHomalgComplexOfLeftObjects;
else
type := TheTypeHomalgComplexOfRightObjects;
fi;
else
if left then
type := TheTypeHomalgCocomplexOfLeftObjects;
else
type := TheTypeHomalgCocomplexOfRightObjects;
fi;
fi;
ConvertToRangeRep( C.degrees );
## Objectify
Objectify( type, C );
if object then
SetIsRightAcyclic( C, true );
if HasIsZero( obj_or_mor ) then
SetIsLeftAcyclic( C, IsZero( obj_or_mor ) );
SetIsZero( C, IsZero( obj_or_mor ) );
fi;
SetIsGradedObject( C, true );
elif HasIsIsomorphism( obj_or_mor ) and IsIsomorphism( obj_or_mor ) then
SetIsExactSequence( C, true );
elif HasIsEpimorphism( obj_or_mor ) and IsEpimorphism( obj_or_mor ) then
if complex then
SetIsLeftAcyclic( C, true );
else
SetIsRightAcyclic( C, true );
fi;
elif HasIsMonomorphism( obj_or_mor ) and IsMonomorphism( obj_or_mor ) then
if complex then
SetIsRightAcyclic( C, true );
else
SetIsLeftAcyclic( C, true );
fi;
elif HasIsMorphism( obj_or_mor ) and IsMorphism( obj_or_mor ) then
SetIsAcyclic( C, true );
fi;
return C;
end );
## <#GAPDoc Label="HomalgCocomplex">
## <ManSection>
## <Func Arg="M[, d]" Name="HomalgCocomplex" Label="constructor for cocomplexes given a object"/>
## <Func Arg="phi[, d]" Name="HomalgCocomplex" Label="constructor for cocomplexes given a morphism"/>
## <Func Arg="C[, d]" Name="HomalgCocomplex" Label="constructor for cocomplexes given a complex"/>
## <Func Arg="cm[, d]" Name="HomalgCocomplex" Label="constructor for cocomplexes given a chain morphism"/>
## <Returns>a &homalg; complex</Returns>
## <Description>
## The first syntax creates a cocomplex (i.e. cochain complex) with the single &homalg; object <A>M</A> at
## (cohomological) degree <A>d</A>. <P/>
## The second syntax creates a cocomplex with the single &homalg; morphism <A>phi</A>, its source placed at (cohomological)
## degree <A>d</A> (and its target at <A>d</A><M>+1</M>). <P/>
## The third syntax creates a cocomplex (i.e. cochain complex) with the single &homalg; cocomplex <A>C</A> at
## (cohomological) degree <A>d</A>. <P/>
## The fourth syntax creates a cocomplex with the single &homalg; (co)chain morphism <A>cm</A>
## (&see; <Ref Func="HomalgChainMorphism" Label="constructor for chain morphisms given a morphism"/>), its source placed at
## (cohomological) degree <A>d</A> (and its target at <A>d</A><M>+1</M>). <P/>
## If <A>d</A> is not provided it defaults to zero in all cases. <Br/>
## To add a morphism (resp. (co)chain morphism) to a cocomplex use <Ref Oper="Add" Label="to complexes given a morphism"/>.
## <Example><![CDATA[
## gap> zz := HomalgRingOfIntegers( );
## Z
## gap> M := HomalgMatrix( "[ 2, 3, 4, 5, 6, 7 ]", 2, 3, zz );
## <A 2 x 3 matrix over an internal ring>
## gap> M := RightPresentation( Involution( M ) );
## <A non-torsion right module on 3 generators satisfying 2 relations>
## gap> N := HomalgMatrix( "[ 2, 3, 4, 5, 6, 7, 8, 9 ]", 2, 4, zz );
## <A 2 x 4 matrix over an internal ring>
## gap> N := RightPresentation( Involution( N ) );
## <A non-torsion right module on 4 generators satisfying 2 relations>
## gap> mat := HomalgMatrix( "[ \
## > 0, 3, 6, 9, \
## > 0, 2, 4, 6, \
## > 0, 3, 6, 9 \
## > ]", 3, 4, zz );
## <A 3 x 4 matrix over an internal ring>
## gap> phi := HomalgMap( Involution( mat ), M, N );
## <A "homomorphism" of right modules>
## gap> IsMorphism( phi );
## true
## gap> phi;
## <A homomorphism of right modules>
## ]]></Example>
## The first possibility:
## <Example><![CDATA[
## gap> C := HomalgCocomplex( M );
## <A non-zero graded cohomology object consisting of a single right module at de\
## gree 0>
## gap> Add( C, phi );
## gap> C;
## <A cocomplex containing a single morphism of right modules at degrees
## [ 0 .. 1 ]>
## ]]></Example>
## The second possibility:
## <Example><![CDATA[
## gap> C := HomalgCocomplex( phi );
## <A non-zero acyclic cocomplex containing a single morphism of right modules at\
## degrees [ 0 .. 1 ]>
## ]]></Example>
## </Description>
## </ManSection>
## <#/GAPDoc>
##
InstallGlobalFunction( HomalgCocomplex,
function( arg )
return CallFuncList( HomalgComplex, Concatenation( arg, [ "cocomplex" ] ) );
end );
####################################
#
# constructors
#
####################################
##
InstallMethod( \*,
"for a structure object and a complex",
[ IsStructureObject, IsHomalgComplex ],
function( R, C )
return BaseChange( R, C );
end );
##
InstallMethod( \*,
"for a complex and a structure object",
[ IsHomalgComplex, IsStructureObject ],
function( C, R )
return R * C;
end );
##
InstallMethod( ShallowCopy,
"for a complex",
[ IsHomalgComplex ],
function( C )
return Shift( C, 0 );
end );
####################################
#
# View, Print, and Display methods:
#
####################################
##
InstallMethod( ViewObj,
"for homalg complexes",
[ IsHomalgComplex ],
function( o )
local cpx, first_attribute, degrees, l, oi;
cpx := IsComplexOfFinitelyPresentedObjectsRep( o );
first_attribute := false;
Print( "<A" );
if HasIsZero( o ) then ## if this method applies and HasIsZero is set we already know that o is a non-zero homalg (co)complex
Print( " non-zero" );
first_attribute := true;
fi;
if HasIsExactTriangle( o ) and IsExactTriangle( o ) then
if not first_attribute then
Print( "n" );
fi;
if cpx then
Print( " exact triangle" );
else
Print( " exact cotriangle" );
fi;
elif HasIsSplitShortExactSequence( o ) and IsSplitShortExactSequence( o ) then
if cpx then
Print( " split short exact sequence" );
else
Print( " split short exact cosequence" );
fi;
elif HasIsShortExactSequence( o ) and IsShortExactSequence( o ) then
if cpx then
Print( " short exact sequence" );
else
Print( " short exact cosequence" );
fi;
elif HasIsExactSequence( o ) and IsExactSequence( o ) then
if not first_attribute then
Print( "n" );
fi;
if cpx then
Print( " exact sequence" );
else
Print( " exact cosequence" );
fi;
elif HasIsRightAcyclic( o ) and IsRightAcyclic( o ) then
if cpx then
Print( " right acyclic complex" );
else
Print( " right acyclic cocomplex" );
fi;
elif HasIsLeftAcyclic( o ) and IsLeftAcyclic( o ) then
if cpx then
Print( " left acyclic complex" );
else
Print( " left acyclic cocomplex" );
fi;
elif HasIsAcyclic( o ) and IsAcyclic( o ) then
if not first_attribute then
Print( "n" );
fi;
if cpx then
Print( " acyclic complex" );
else
Print( " acyclic cocomplex" );
fi;
elif HasIsComplex( o ) then
if IsComplex( o ) then
if cpx then
Print( " complex" );
else
Print( " cocomplex" );
fi;
else
if cpx then
Print( " non-complex" );
else
Print( " non-cocomplex" );
fi;
fi;
elif HasIsSequence( o ) then
if IsSequence( o ) then
if cpx then
Print( " sequence" );
else
Print( " cosequence" );
fi;
else
if cpx then
Print( " sequence of non-well-definded morphisms" );
else
Print( " cosequence of non-well-definded morphisms" );
fi;
fi;
else
if cpx then
Print( " \"complex\"" );
else
Print( " \"cocomplex\"" );
fi;
fi;
Print( " containing " );
degrees := ObjectDegreesOfComplex( o );
l := Length( degrees );
oi := CertainObject( o, degrees[1] );
if l = 1 then
Print( "a single " );
if IsHomalgLeftObjectOrMorphismOfLeftObjects( o ) then
Print( "left" );
else
Print( "right" );
fi;
if IsBound( oi!.string ) then
Print( " ", oi!.string );
else
Print( " object" );
fi;
Print( " at degree ", degrees[1], ">" );
else
if l = 2 then
Print( "a single morphism" );
else
Print( l - 1, " morphisms" );
fi;
Print( " of " );
if IsBound( oi!.adjective ) then
Print( oi!.adjective, " " );
fi;
if IsHomalgLeftObjectOrMorphismOfLeftObjects( o ) then
Print( "left " );
else
Print( "right " );
fi;
if IsBound( oi!.string_plural ) then
Print( oi!.string_plural );
elif IsBound( oi!.string ) then
Print( oi!.string, "s" );
else
Print( "objects" );
fi;
if HasIsExactTriangle( o ) and IsExactTriangle( o ) then
if cpx then
Print( " at degrees ", [ degrees[2], degrees[3], degrees[4], degrees[2] ], ">" );
else
Print( " at degrees ", [ degrees[1], degrees[2], degrees[3], degrees[1] ], ">" );
fi;
else
Print( " at degrees ", degrees, ">" );
fi;
fi;
end );
##
InstallMethod( ViewObj,
"for homalg complexes",
[ IsHomalgComplex and IsGradedObject ],
function( o )
local degrees, l, oi;
Print( "<A" );
if HasIsZero( o ) then ## if this method applies and HasIsZero is set we already know that o is a non-zero homology object
Print( " non-zero" );
fi;
Print( " graded " );
if IsCocomplexOfFinitelyPresentedObjectsRep( o ) then
Print( "co" );
fi;
Print( "homology object consisting of " );
degrees := ObjectDegreesOfComplex( o );
l := Length( degrees );
if l = 1 then
Print( "a single " );
else
Print( l, " " );
fi;
oi := CertainObject( o, degrees[1] );
if IsBound( oi!.adjective ) then
Print( oi!.adjective, " " );
fi;
if IsHomalgLeftObjectOrMorphismOfLeftObjects( o ) then
Print( "left " );
else
Print( "right " );
fi;
if IsBound( oi!.string ) then
if l = 1 then
Print( oi!.string );
else
if IsBound( oi!.string_plural ) then
Print( oi!.string_plural );
else
Print( oi!.string, "s" );
fi;
fi;
else
Print( "object" );
if l > 1 then
Print( "s" );
fi;
fi;
Print( " at degree" );
if l = 1 then
Print( " ", degrees[1] );
else
Print( "s ", degrees );
fi;
Print( ">" );
end );
##
InstallMethod( ViewObj,
"for homalg complexes",
[ IsComplexOfFinitelyPresentedObjectsRep and IsZero ],
function( o )
local degrees, l;
degrees := ObjectDegreesOfComplex( o );
l := Length( degrees );
Print( "<A zero " );
if IsHomalgLeftObjectOrMorphismOfLeftObjects( o ) then
Print( "left" );
else
Print( "right" );
fi;
Print( " complex with degree" );
if l > 1 then
Print( "s" );
fi;
Print( " ", degrees, ">" );
end );
##
InstallMethod( ViewObj,
"for homalg complexes",
[ IsCocomplexOfFinitelyPresentedObjectsRep and IsZero ],
function( o )
local degrees, l;
degrees := ObjectDegreesOfComplex( o );
l := Length( degrees );
Print( "<A zero " );
if IsHomalgLeftObjectOrMorphismOfLeftObjects( o ) then
Print( "left" );
else
Print( "right" );
fi;
Print( " cocomplex with degree" );
if l > 1 then
Print( "s" );
fi;
Print( " ", degrees, ">" );
end );
##
InstallMethod( Display,
"for homalg complexes",
[ IsComplexOfFinitelyPresentedObjectsRep ],
function( o )
local degrees, l, i;
degrees := ObjectDegreesOfComplex( o );
l := Length( degrees );
Print( "-------------------------\n" );
Print( "at homology degree: ", degrees[l], "\n" );
Display( CertainObject( o, degrees[l] ) );
for i in Reversed( degrees{[ 1 .. l - 1 ]} ) do
Print( "-------------------------\n" );
Display( CertainMorphism( o, i + 1 ) );
Print( "------------v------------\n" );
Print( "at homology degree: ", i, "\n" );
Display( CertainObject( o, i ) );
od;
Print( "-------------------------\n" );
end );
##
InstallMethod( Display,
"for homalg complexes",
[ IsCocomplexOfFinitelyPresentedObjectsRep ],
function( o )
local degrees, i;
degrees := ObjectDegreesOfComplex( o );
Print( "-------------------------\n" );
for i in Reversed( degrees{[ 2 .. Length( degrees ) ]} ) do
Print( "at cohomology degree: ", i, "\n" );
Display( CertainObject( o, i ) );
Print( "------------^------------\n" );
Display( CertainMorphism( o, i - 1 ) );
Print( "-------------------------\n" );
od;
Print( "at cohomology degree: ", degrees[1], "\n" );
Display( CertainObject( o, degrees[1] ) );
Print( "-------------------------\n" );
end );
##
InstallMethod( Display,
"for homalg complexes",
[ IsComplexOfFinitelyPresentedObjectsRep and IsGradedObject ],
function( o )
local i;
for i in Reversed( ObjectDegreesOfComplex( o ) ) do
Print( "-------------------------\n" );
Print( "at homology degree: ", i, "\n" );
Display( CertainObject( o, i ) );
od;
Print( "-------------------------\n" );
end );
##
InstallMethod( Display,
"for homalg complexes",
[ IsCocomplexOfFinitelyPresentedObjectsRep and IsGradedObject ],
function( o )
local i;
for i in Reversed( ObjectDegreesOfComplex( o ) ) do
Print( "---------------------------\n" );
Print( "at cohomology degree: ", i, "\n" );
Display( CertainObject( o, i ) );
od;
Print( "---------------------------\n" );
end );
##
InstallMethod( Display,
"for homalg complexes",
[ IsComplexOfFinitelyPresentedObjectsRep and IsZero ],
function( o )
Print( "0\n" );
end );
##
InstallMethod( Display,
"for homalg complexes",
[ IsCocomplexOfFinitelyPresentedObjectsRep and IsZero ],
function( o )
Print( "0\n" );
end );
[ Dauer der Verarbeitung: 0.31 Sekunden
(vorverarbeitet)
]
|