Anforderungen  |   Konzepte  |   Entwurf  |   Entwicklung  |   Qualitätssicherung  |   Lebenszyklus  |   Steuerung
 
 
 
 


Quelle  HomalgChainMorphism.gi   Sprache: unbekannt

 
# SPDX-License-Identifier: GPL-2.0-or-later
# homalg: A homological algebra meta-package for computable Abelian categories
#
# Implementations
#

##  Implementations for homalg chain morphisms.

####################################
#
# representations:
#
####################################

##  <#GAPDoc Label="IsChainMorphismOfFinitelyPresentedObjectsRep">
##  <ManSection>
##    <Filt Type="Representation" Arg="c" Name="IsChainMorphismOfFinitelyPresentedObjectsRep"/>
##    <Returns><C>true</C> or <C>false</C></Returns>
##    <Description>
##      The &GAP; representation of chain morphisms of finitely presented &homalg; objects. <P/>
##      (It is a representation of the &GAP; category <Ref Filt="IsHomalgChainMorphism"/>,
##       which is a subrepresentation of the &GAP; representation <C>IsMorphismOfFinitelyGeneratedObjectsRep</C>.)
##    </Description>
##  </ManSection>
##  <#/GAPDoc>
##
DeclareRepresentation( "IsChainMorphismOfFinitelyPresentedObjectsRep",
        IsHomalgChainMorphism and IsMorphismOfFinitelyGeneratedObjectsRep,
        [  ] );

##  <#GAPDoc Label="IsCochainMorphismOfFinitelyPresentedObjectsRep">
##  <ManSection>
##    <Filt Type="Representation" Arg="c" Name="IsCochainMorphismOfFinitelyPresentedObjectsRep"/>
##    <Returns><C>true</C> or <C>false</C></Returns>
##    <Description>
##      The &GAP; representation of cochain morphisms of finitely presented &homalg; objects. <P/>
##      (It is a representation of the &GAP; category <Ref Filt="IsHomalgChainMorphism"/>,
##       which is a subrepresentation of the &GAP; representation <C>IsMorphismOfFinitelyGeneratedObjectsRep</C>.)
##    </Description>
##  </ManSection>
##  <#/GAPDoc>
##
DeclareRepresentation( "IsCochainMorphismOfFinitelyPresentedObjectsRep",
        IsHomalgChainMorphism and IsMorphismOfFinitelyGeneratedObjectsRep,
        [  ] );

####################################
#
# families and types:
#
####################################

# a new family:
BindGlobal( "TheFamilyOfHomalgChainMorphisms",
        NewFamily( "TheFamilyOfHomalgChainMorphisms" ) );

# eight new types:
BindGlobal( "TheTypeHomalgChainMorphismOfLeftObjects",
        NewType( TheFamilyOfHomalgChainMorphisms,
                IsChainMorphismOfFinitelyPresentedObjectsRep and IsHomalgLeftObjectOrMorphismOfLeftObjects ) );

BindGlobal( "TheTypeHomalgChainMorphismOfRightObjects",
        NewType( TheFamilyOfHomalgChainMorphisms,
                IsChainMorphismOfFinitelyPresentedObjectsRep and IsHomalgRightObjectOrMorphismOfRightObjects ) );

BindGlobal( "TheTypeHomalgCochainMorphismOfLeftObjects",
        NewType( TheFamilyOfHomalgChainMorphisms,
                IsCochainMorphismOfFinitelyPresentedObjectsRep and IsHomalgLeftObjectOrMorphismOfLeftObjects ) );

BindGlobal( "TheTypeHomalgCochainMorphismOfRightObjects",
        NewType( TheFamilyOfHomalgChainMorphisms,
                IsCochainMorphismOfFinitelyPresentedObjectsRep and IsHomalgRightObjectOrMorphismOfRightObjects ) );

BindGlobal( "TheTypeHomalgChainEndomorphismOfLeftObjects",
        NewType( TheFamilyOfHomalgChainMorphisms,
                IsChainMorphismOfFinitelyPresentedObjectsRep and IsHomalgChainEndomorphism and IsHomalgLeftObjectOrMorphismOfLeftObjects ) );

BindGlobal( "TheTypeHomalgChainEndomorphismOfRightObjects",
        NewType( TheFamilyOfHomalgChainMorphisms,
                IsChainMorphismOfFinitelyPresentedObjectsRep and IsHomalgChainEndomorphism and IsHomalgRightObjectOrMorphismOfRightObjects ) );

BindGlobal( "TheTypeHomalgCochainEndomorphismOfLeftObjects",
        NewType( TheFamilyOfHomalgChainMorphisms,
                IsCochainMorphismOfFinitelyPresentedObjectsRep and IsHomalgChainEndomorphism and IsHomalgLeftObjectOrMorphismOfLeftObjects ) );

BindGlobal( "TheTypeHomalgCochainEndomorphismOfRightObjects",
        NewType( TheFamilyOfHomalgChainMorphisms,
                IsCochainMorphismOfFinitelyPresentedObjectsRep and IsHomalgChainEndomorphism and IsHomalgRightObjectOrMorphismOfRightObjects ) );

####################################
#
# global variables:
#
####################################

HOMALG.PropertiesOfChainMorphisms :=
  [ IsZero,
    IsMorphism,
    IsGeneralizedMorphismWithFullDomain,
    IsGradedMorphism,
    IsSplitMonomorphism,
    IsMonomorphism,
    IsGeneralizedMonomorphism,
    IsSplitEpimorphism,
    IsEpimorphism,
    IsGeneralizedEpimorphism,
    IsIsomorphism,
    IsGeneralizedIsomorphism,
    IsQuasiIsomorphism,
    IsImageSquare,
    IsKernelSquare,
    IsLambekPairOfSquares ];

## do not delete the component to retain the caching!
HOMALG.AttributesOfChainMorphismsDoNotDelete :=
  [ CokernelEpi,
    ImageObjectEmb,
    ImageObjectEpi,
    KernelEmb,
    ];

####################################
#
# methods for operations:
#
####################################

##
InstallMethod( StructureObject,
        "for homalg chain morphisms",
        [ IsHomalgChainMorphism ],
        
  function( cm )
    
    return StructureObject( Source( cm ) );
    
end );

##
InstallMethod( homalgResetFilters,
        "for homalg chain morphisms",
        [ IsHomalgChainMorphism ],
        
  function( cm )
    local property, attribute;
    
    for property in HOMALG.PropertiesOfChainMorphisms do
        ResetFilterObj( cm, property );
    od;
    
    for attribute in HOMALG.AttributesOfChainMorphismsDoNotDelete do
        if Tester( attribute )( cm ) then
            ## do not delete the component to retain the caching!
            ResetFilterObj( cm, attribute );
        fi;
    od;
    
end );

## provided to avoid branching in the code and always returns fail
InstallMethod( PositionOfTheDefaultPresentation,
        "for homalg morphisms",
        [ IsHomalgChainMorphism ],
        
  function( M )
    
    return fail;
    
end );

##
InstallMethod( SourceOfSpecialChainMorphism,
        "for homalg image square chain morphisms",
        [ IsHomalgChainMorphism and IsImageSquare ],
        
  function( sq )
    
    return LowestDegreeMorphism( Source( sq ) );
    
end );

##
InstallMethod( SourceOfSpecialChainMorphism,
        "for homalg kernel square chain morphisms",
        [ IsHomalgChainMorphism and IsKernelSquare ],
        
  function( sq )
    
    return HighestDegreeMorphism( Source( sq ) );
    
end );

##
InstallMethod( SourceOfSpecialChainMorphism,
        "for homalg Lambek pair of squares",
        [ IsHomalgChainMorphism and IsLambekPairOfSquares ],
        
  function( sq )
    
    return AsATwoSequence( Source( sq ) );
    
end );

##
InstallMethod( RangeOfSpecialChainMorphism,
        "for homalg image square chain morphisms",
        [ IsHomalgChainMorphism and IsImageSquare ],
        
  function( sq )
    
    return LowestDegreeMorphism( Range( sq ) );
    
end );

##
InstallMethod( RangeOfSpecialChainMorphism,
        "for homalg kernel square chain morphisms",
        [ IsHomalgChainMorphism and IsKernelSquare ],
        
  function( sq )
    
    return HighestDegreeMorphism( Range( sq ) );
    
end );

##
InstallMethod( RangeOfSpecialChainMorphism,
        "for homalg Lambek pair of squares",
        [ IsHomalgChainMorphism and IsLambekPairOfSquares ],
        
  function( sq )
    
    return AsATwoSequence( Range( sq ) );
    
end );

##
InstallMethod( CertainMorphismOfSpecialChainMorphism,
        "for homalg image square chain morphisms",
        [ IsHomalgChainMorphism and IsImageSquare ],
        
  function( sq )
    local d;
    
    d := DegreesOfChainMorphism( sq )[1];
    
    return CertainMorphism( sq, d );
    
end );

##
InstallMethod( CertainMorphismOfSpecialChainMorphism,
        "for homalg kernel square chain morphisms",
        [ IsHomalgChainMorphism and IsKernelSquare ],
        
  function( sq )
    local d;
    
    d := DegreesOfChainMorphism( sq )[1];
    
    return CertainMorphism( sq, d );
    
end );

##
InstallMethod( CertainMorphismOfSpecialChainMorphism,
        "for homalg Lambek pair of squares",
        [ IsHomalgChainMorphism and IsLambekPairOfSquares ],
        
  function( sq )
    local d;
    
    d := DegreesOfChainMorphism( sq )[1];
    
    return CertainMorphism( sq, d );
    
end );

##
InstallMethod( DegreesOfChainMorphism, ## this might differ from ObjectDegreesOfComplex( Source( cm ) ) when the chain morphism is not full
        "for homalg chain morphisms",
        [ IsHomalgChainMorphism ],
        
  function( cm )
    
    return cm!.degrees;
    
end );

##
InstallMethod( ObjectDegreesOfComplex, ## this is not a mistake
        "for homalg chain morphisms",
        [ IsHomalgChainMorphism ],
        
  function( cm )
    
    return ObjectDegreesOfComplex( Source( cm ) );
    
end );

##
InstallMethod( MorphismDegreesOfComplex, ## this is not a mistake
        "for homalg chain morphisms",
        [ IsHomalgChainMorphism ],
        
  function( cm )
    
    return MorphismDegreesOfComplex( Source( cm ) );
    
end );

##
InstallMethod( CertainMorphism,
        "for homalg chain morphisms",
        [ IsHomalgChainMorphism, IsInt ],
        
  function( cm, i )
    
    if IsBound( cm!.(String( i )) ) and IsHomalgMorphism( cm!.(String( i )) ) then
        return cm!.(String( i ));
    fi;
    
    return fail;
    
end );

##
InstallMethod( MorphismsOfChainMorphism,
        "for homalg chain morphisms",
        [ IsHomalgChainMorphism ],
        
  function( cm )
    local degrees;
    
    degrees := DegreesOfChainMorphism( cm );
    
    return List( degrees, i -> CertainMorphism( cm, i ) );
    
end );

##
InstallMethod( LowestDegree,
        "for homalg chain morphisms",
        [ IsHomalgChainMorphism ],
        
  function( cm )
    
    return DegreesOfChainMorphism( cm )[1];
    
end );

##
InstallMethod( HighestDegree,
        "for homalg chain morphisms",
        [ IsHomalgChainMorphism ],
        
  function( cm )
    local degrees;
    
    degrees := DegreesOfChainMorphism( cm );
    
    return degrees[Length( degrees )];
    
end );

##
InstallMethod( LowestDegreeMorphism,
        "for homalg chain morphisms",
        [ IsHomalgChainMorphism ],
        
  function( cm )
    
    return CertainMorphism( cm, LowestDegree( cm ) );
    
end );

##
InstallMethod( HighestDegreeMorphism,
        "for homalg chain morphisms",
        [ IsHomalgChainMorphism ],
        
  function( cm )
    
    return CertainMorphism( cm, HighestDegree( cm ) );
    
end );

##
InstallMethod( SupportOfChainMorphism,
        "for homalg chain morphisms",
        [ IsHomalgChainMorphism ],
        
  function( cm )
    local degrees, morphisms, l;
    
    degrees := DegreesOfChainMorphism( cm );
    morphisms := MorphismsOfChainMorphism( cm );
    
    l := Length( degrees );
    
    return degrees{ Filtered( [ 1 .. l ], i -> not IsZero( morphisms[i] ) ) };
    
end );

##
InstallMethod( Add,
        "for homalg chain morphisms",
        [ IsHomalgChainMorphism, IsMorphismOfFinitelyGeneratedObjectsRep ],
        
  function( cm, phi )
    local d, degrees, l;
    
    if HasIsChainMorphismForPullback( cm ) and IsChainMorphismForPullback( cm ) then
        Error( "this chain morphism is write-protected since IsChainMorphismForPullback = true\n" );
    elif HasIsChainMorphismForPushout( cm ) and IsChainMorphismForPushout( cm ) then
        Error( "this chain morphism is write-protected since IsChainMorphismForPushout = true\n" );
    elif HasIsKernelSquare( cm ) and IsKernelSquare( cm ) then
        Error( "this chain morphism is write-protected since IsKernelSquare = true\n" );
    elif HasIsImageSquare( cm ) and IsImageSquare( cm ) then
        Error( "this chain morphism is write-protected since IsImageSquare = true\n" );
    elif HasIsLambekPairOfSquares( cm ) and IsLambekPairOfSquares( cm ) then
        Error( "this chain morphism is write-protected since IsLambekPairOfSquares = true\n" );
    fi;
    
    d := DegreeOfMorphism( cm );
    
    degrees := DegreesOfChainMorphism( cm );
    
    l := Length( degrees );
    
    l := degrees[l] + 1;
    
    if not l in ObjectDegreesOfComplex( cm ) then
        Error( "there is no object in the source complex with index ", l, "\n" );
    fi;
    
    if IsHomalgStaticObject( Source( phi ) ) then
        if not IsIdenticalObj( CertainObject( Source( cm ), l ), Source( phi ) ) then
            Error( "the ", l, ". object of the source complex in the chain morphism and the source of the new morphism are not identical\n" );
        elif not IsIdenticalObj( CertainObject( Range( cm ), l + d ), Range( phi ) ) then
            Error( "the ", l, ". object of the target complex in the chain morphism and the target of the new morphism are not identical\n" );
        fi;
    else
        if CertainObject( Source( cm ), l ) <> Source( phi ) then
            Error( "the ", l, ". object of the source complex in the chain morphism and the source of the new morphism are not equal\n" );
        elif CertainObject( Range( cm ), l + d ) <> Range( phi ) then
            Error( "the ", l, ". object of the target complex in the chain morphism and the target of the new morphism are not equal\n" );
        fi;
    fi;
    
    Add( degrees, l );
    
    cm!.(String( l )) := phi;
    
    ConvertToRangeRep( cm!.degrees );
    
    homalgResetFilters( cm );
    
    return cm;
    
end );

##
InstallMethod( Add,
        "for homalg chain morphisms",
        [ IsMorphismOfFinitelyGeneratedObjectsRep, IsHomalgChainMorphism ],
        
  function( phi, cm )
    local d, degrees, l;
    
    if HasIsChainMorphismForPullback( cm ) and IsChainMorphismForPullback( cm ) then
        Error( "this chain morphism is write-protected since IsChainMorphismForPullback = true\n" );
    elif HasIsChainMorphismForPushout( cm ) and IsChainMorphismForPushout( cm ) then
        Error( "this chain morphism is write-protected since IsChainMorphismForPushout = true\n" );
    elif HasIsKernelSquare( cm ) and IsKernelSquare( cm ) then
        Error( "this chain morphism is write-protected since IsKernelSquare = true\n" );
    elif HasIsImageSquare( cm ) and IsImageSquare( cm ) then
        Error( "this chain morphism is write-protected since IsImageSquare = true\n" );
    elif HasIsLambekPairOfSquares( cm ) and IsLambekPairOfSquares( cm ) then
        Error( "this chain morphism is write-protected since IsLambekPairOfSquares = true\n" );
    fi;
    
    d := DegreeOfMorphism( cm );
    
    degrees := DegreesOfChainMorphism( cm );
    
    l := degrees[1] - 1;
    
    if not l in ObjectDegreesOfComplex( cm ) then
        Error( "there is no object in the source complex with index ", l, "\n" );
    fi;
    
    if IsHomalgStaticObject( Source( phi ) ) then
        if not IsIdenticalObj( CertainObject( Source( cm ), l ), Source( phi ) ) then
            Error( "the ", l, ". object of the source complex in the chain morphism and the source of the new morphism are not identical\n" );
        elif not IsIdenticalObj( CertainObject( Range( cm ), l + d ), Range( phi ) ) then
            Error( "the ", l, ". object of the target complex in the chain morphism and the target of the new morphism are not identical\n" );
        fi;
    else
        if CertainObject( Source( cm ), l ) <> Source( phi ) then
            Error( "the ", l, ". object of the source complex in the chain morphism and the source of the new morphism are not equal\n" );
        elif CertainObject( Range( cm ), l + d ) <> Range( phi ) then
            Error( "the ", l, ". object of the target complex in the chain morphism and the target of the new morphism are not equal\n" );
        fi;
    fi;
    
    cm!.degrees := Concatenation( [ l ], degrees );
    
    cm!.(String( l )) := phi;
    
    ConvertToRangeRep( cm!.degrees );
    
    homalgResetFilters( cm );
    
    return cm;
    
end );

##
InstallMethod( AreComparableMorphisms,
        "for homalg chain morphisms",
        [ IsHomalgChainMorphism, IsHomalgChainMorphism ],
        
  function( phi1, phi2 )
    
    return Source( phi1 ) = Source( phi2 ) and
           Range( phi1 ) = Range( phi2 ) and
           DegreeOfMorphism( phi1 ) = DegreeOfMorphism( phi2 );;
    
end );

##
InstallMethod( \=,
        "for two comparable homalg chain morphisms",
        [ IsHomalgChainMorphism, IsHomalgChainMorphism ],
        
  function( phi1, phi2 )
    local morphisms1, morphisms2;
    
    if not AreComparableMorphisms( phi1, phi2 ) then
        return false;
    fi;
    
    morphisms1 := MorphismsOfChainMorphism( phi1 );
    morphisms2 := MorphismsOfChainMorphism( phi2 );
    
    return ForAll( [ 1 .. Length( morphisms1 ) ], i -> morphisms1[i] = morphisms2[i] );
    
end );

##
InstallMethod( ZeroMutable,
        "for homalg chain morphisms",
        [ IsHomalgChainMorphism ],
        
  function( phi )
    local degree, S, T, degrees, morphisms, zeta, i;
    
    degree := DegreeOfMorphism( phi );
    
    S := Source( phi );
    T := Range( phi );
    
    degrees := ObjectDegreesOfComplex( S );
    
    morphisms := MorphismsOfChainMorphism( phi );
    
    zeta := HomalgChainMorphism( 0 * morphisms[1], S, T, [ degrees[1], degree ] );
    
    for i in [ 2 .. Length( morphisms ) ] do
        Add( zeta, 0 * morphisms[i] );
    od;
    
    return zeta;
    
end );

##
InstallMethod( \*,
        "of two homalg chain morphisms",
        [ IsRingElement, IsHomalgChainMorphism ], 1001, ## it could otherwise run into the method ``PROD: negative integer * additive element with inverse'', value: 24
        
  function( a, phi )
    local degree, S, T, degrees, morphisms, psi, i;
    
    degree := DegreeOfMorphism( phi );
    
    S := Source( phi );
    T := Range( phi );
    
    degrees := ObjectDegreesOfComplex( S );
    
    morphisms := MorphismsOfChainMorphism( phi );
    
    psi := HomalgChainMorphism( a * morphisms[1], S, T, [ degrees[1], degree ] );
    
    for i in [ 2 .. Length( morphisms ) ] do
        Add( psi, a * morphisms[i] );
    od;
    
    if IsUnit( StructureObject( phi ), a ) then
        if HasIsIsomorphism( phi ) and IsIsomorphism( phi ) then
            SetIsIsomorphism( psi, true );
        else
            if HasIsSplitMonomorphism( phi ) and IsSplitMonomorphism( phi ) then
                SetIsSplitMonomorphism( psi, true );
            elif HasIsMonomorphism( phi ) and IsMonomorphism( phi ) then
                SetIsMonomorphism( psi, true );
            fi;
            
            if HasIsSplitEpimorphism( phi ) and IsSplitEpimorphism( phi ) then
                SetIsSplitEpimorphism( psi, true );
            elif HasIsEpimorphism( phi ) and IsEpimorphism( phi ) then
                SetIsEpimorphism( psi, true );
            elif HasIsMorphism( phi ) and IsMorphism( phi ) then
                SetIsMorphism( psi, true );
            fi;
        fi;
    elif HasIsMorphism( phi ) and IsMorphism( phi ) then
        SetIsMorphism( psi, true );
    fi;
    
    return psi;
    
end );

##
InstallMethod( \+,
        "of two homalg chain morphisms",
        [ IsHomalgChainMorphism, IsHomalgChainMorphism ],
        
  function( phi1, phi2 )
    local degree, S, T, degrees, morphisms1, morphisms2, psi, i;
    
    if not AreComparableMorphisms( phi1, phi2 ) then
        return Error( "the two chain morphisms are not comparable" );
    fi;
    
    degree := DegreeOfMorphism( phi1 );
    
    S := Source( phi1 );
    T := Range( phi1 );
    
    degrees := ObjectDegreesOfComplex( S );
    
    morphisms1 := MorphismsOfChainMorphism( phi1 );
    morphisms2 := MorphismsOfChainMorphism( phi2 );
    
    psi := HomalgChainMorphism( morphisms1[1] + morphisms2[1], S, T, [ degrees[1], degree ] );
    
    for i in [ 2 .. Length( morphisms1 ) ] do
        Add( psi, morphisms1[i] + morphisms2[i] );
    od;
    
    if HasIsMorphism( phi1 ) and IsMorphism( phi1 ) and
       HasIsMorphism( phi2 ) and IsMorphism( phi2 ) then
        SetIsMorphism( psi, true );
    fi;
    
    return psi;
    
end );

## a synonym of `-<elm>':
InstallMethod( AdditiveInverseMutable,
        "of homalg chain morphisms",
        [ IsHomalgChainMorphism ],
        
  function( phi )
    
    return (-1) * phi;
    
end );

## a synonym of `-<elm>':
InstallMethod( AdditiveInverseMutable,
        "of homalg chain morphisms",
        [ IsHomalgChainMorphism and IsZero ],
        
  function( phi )
    
    return phi;
    
end );

##
InstallMethod( \-,
        "of two homalg chain morphisms",
        [ IsHomalgChainMorphism, IsHomalgChainMorphism ],
        
  function( phi1, phi2 )
    local degree, S, T, degrees, morphisms1, morphisms2, psi, i;
    
    if not AreComparableMorphisms( phi1, phi2 ) then
        return Error( "the two chain morphisms are not comparable" );
    fi;
    
    degree := DegreeOfMorphism( phi1 );
    
    S := Source( phi1 );
    T := Range( phi1 );
    
    degrees := ObjectDegreesOfComplex( S );
    
    morphisms1 := MorphismsOfChainMorphism( phi1 );
    morphisms2 := MorphismsOfChainMorphism( phi2 );
    
    psi := HomalgChainMorphism( morphisms1[1] - morphisms2[1], S, T, [ degrees[1], degree ] );
    
    for i in [ 2 .. Length( morphisms1 ) ] do
        Add( psi, morphisms1[i] - morphisms2[i] );
    od;
    
    if HasIsMorphism( phi1 ) and IsMorphism( phi1 ) and
       HasIsMorphism( phi2 ) and IsMorphism( phi2 ) then
        SetIsMorphism( psi, true );
    fi;
    
    return psi;
    
end );

##
InstallMethod( PreCompose,
        "for two composable homalg chain morphisms",
        [ IsHomalgChainMorphism, IsHomalgChainMorphism ],
        
  function( pre, post )
    local degree_pre, degree_post, S, T, degrees, morphisms_pre, morphisms_post, psi, i;
    
    if IsHomalgLeftObjectOrMorphismOfLeftObjects( pre ) then
        if not AreComposableMorphisms( pre, post ) then
            Error( "the two chain morphisms are not composable, since the target of the left one and the source of right one are not equal\n" );
        fi;
    else
        if not AreComposableMorphisms( post, pre ) then
            Error( "the two chain morphisms are not composable, since the target of the left one and the source of right one are not equal\n" );
        fi;
    fi;
    
    degree_pre := DegreeOfMorphism( pre );
    degree_post := DegreeOfMorphism( post );
    
    S := Source( pre );
    T := Range( post );
    
    degrees := ObjectDegreesOfComplex( S );
    
    morphisms_pre := MorphismsOfChainMorphism( pre );
    morphisms_post := MorphismsOfChainMorphism( post );
    
    psi := HomalgChainMorphism( PreCompose( morphisms_pre[1], morphisms_post[1] ), S, T, [ degrees[1], degree_pre + degree_post ] );
    
    for i in [ 2 .. Length( morphisms_pre ) ] do
        Add( psi, PreCompose( morphisms_pre[i], morphisms_post[i] ) );
    od;
    
    SetPropertiesOfComposedMorphism( pre, post, psi );
    
    return psi;
    
end );

##
InstallMethod( DecideZero,
        "for homalg chain morphisms",
        [ IsHomalgChainMorphism ],
        
  function( phi )
    
    DecideZero( Source( phi ) );
    DecideZero( Range( phi ) );
    
    List( MorphismsOfChainMorphism( phi ), DecideZero );
    
    return phi;
    
end );

##  <#GAPDoc Label="ByASmallerPresentation:chainmorphism">
##  <ManSection>
##    <Meth Arg="cm" Name="ByASmallerPresentation" Label="for chain morphisms"/>
##    <Returns>a &homalg; complex</Returns>
##    <Description>
##    See <Ref Meth="ByASmallerPresentation" Label="for complexes"/> on complexes.
##      <Listing Type="Code"><![CDATA[
InstallMethod( ByASmallerPresentation,
        "for homalg chain morphisms",
        [ IsHomalgChainMorphism ],
        
  function( cm )
    
    ByASmallerPresentation( Source( cm ) );
    ByASmallerPresentation( Range( cm ) );
    
    List( MorphismsOfChainMorphism( cm ), DecideZero );
    
    return cm;
    
end );
##  ]]></Listing>
##      This method performs side effects on its argument <A>cm</A> and returns it.
##    </Description>
##  </ManSection>
##  <#/GAPDoc>

##
InstallMethod( CertainMorphismAsKernelSquare,
        "for homalg chain morphisms",
        [ IsHomalgChainMorphism, IsInt ],
        
  function( cm, i )
    local degree, phi, S, T, sub;
    
    degree := DegreeOfMorphism( cm );
    
    phi := CertainMorphism( cm, i );
    
    S := CertainMorphismAsSubcomplex( Source( cm ), i );
    T := CertainMorphismAsSubcomplex( Range( cm ), i + degree );
    
    if phi = fail or S = fail or T = fail then
        return fail;
    fi;
    
    sub := HomalgChainMorphism( phi, S, T, [ i, degree ] );
    
    if HasIsMorphism( cm ) and IsMorphism( cm ) then
        SetIsMorphism( sub, true );
    fi;
    
    SetIsKernelSquare( sub, true );
    
    return sub;
    
end );

##
InstallMethod( CertainMorphismAsImageSquare,
        "for homalg chain morphisms",
        [ IsChainMorphismOfFinitelyPresentedObjectsRep, IsInt ],
        
  function( cm, i )
    local degree, phi, S, T, sub;
    
    degree := DegreeOfMorphism( cm );
    
    phi := CertainMorphism( cm, i );
    
    S := CertainMorphismAsSubcomplex( Source( cm ), i + 1 );
    T := CertainMorphismAsSubcomplex( Range( cm ), i + 1 + degree );
    
    if phi = fail or S = fail or T = fail then
        return fail;
    fi;
    
    sub := HomalgChainMorphism( phi, S, T, [ i, degree ] );
    
    if HasIsMorphism( cm ) and IsMorphism( cm ) then
        SetIsMorphism( sub, true );
    fi;
    
    SetIsImageSquare( sub, true );
    
    return sub;
    
end );

##
InstallMethod( CertainMorphismAsImageSquare,
        "for homalg chain morphisms",
        [ IsCochainMorphismOfFinitelyPresentedObjectsRep, IsInt ],
        
  function( cm, i )
    local degree, phi, S, T, sub;
    
    degree := DegreeOfMorphism( cm );
    
    phi := CertainMorphism( cm, i );
    
    S := CertainMorphismAsSubcomplex( Source( cm ), i - 1 );
    T := CertainMorphismAsSubcomplex( Range( cm ), i - 1 );
    
    if phi = fail or S = fail or T = fail then
        return fail;
    fi;
    
    sub := HomalgChainMorphism( phi, S, T, [ i, degree ] );
    
    if HasIsMorphism( cm ) and IsMorphism( cm ) then
        SetIsMorphism( sub, true );
    fi;
    
    SetIsImageSquare( sub, true );
    
    return sub;
    
end );

##
InstallMethod( CertainMorphismAsLambekPairOfSquares,
        "for homalg chain morphisms",
        [ IsHomalgChainMorphism, IsInt ],
        
  function( cm, i )
    local degree, phi, S, T, sub;
    
    degree := DegreeOfMorphism( cm );
    
    phi := CertainMorphism( cm, i );
    
    S := CertainTwoMorphismsAsSubcomplex( Source( cm ), i );
    T := CertainTwoMorphismsAsSubcomplex( Range( cm ), i + degree );
    
    if phi = fail or S = fail or T = fail then
        return fail;
    fi;
    
    sub := HomalgChainMorphism( phi, S, T, [ i, degree ] );
    
    if HasIsMorphism( cm ) and IsMorphism( cm ) then
        SetIsMorphism( sub, true );
    fi;
    
    SetIsLambekPairOfSquares( sub, true );
    
    return sub;
    
end );

##
InstallMethod( CompleteImageSquare,
        "for homalg chain morphisms",
        [ IsHomalgChainMorphism and IsImageSquare ],
        
  function( cm )
    local alpha, phi, beta;
    
    alpha := LowestDegreeMorphism( Source( cm ) );
    phi := LowestDegreeMorphism( cm );
    beta := LowestDegreeMorphism( Range( cm ) );
    
    return CompleteImageSquare( alpha, phi, beta );
    
end );

##
InstallMethod( PostDivide,
        "for two chain morphisms with the same target",
        [ IsHomalgChainMorphism, IsHomalgChainMorphism ],
        
  function( gamma, beta )
    local degree_gamma, degree_beta, S, T, degrees, morphisms_gamma, morphisms_beta,
          psi_i, b, psi, i;
    
    if not Range( gamma ) = Range( beta ) then
        Error( "the target objects of the two morphisms are not equal\n" );
    fi;
    
    degree_gamma := DegreeOfMorphism( gamma );
    degree_beta := DegreeOfMorphism( beta );
    
    S := Source( gamma );
    T := Source( beta );
    
    degrees := ObjectDegreesOfComplex( S );
    
    morphisms_gamma := MorphismsOfChainMorphism( gamma );
    morphisms_beta := MorphismsOfChainMorphism( beta );
    
    psi_i := PostDivide( morphisms_gamma[1], morphisms_beta[1] );
    
    b := HasIsMorphism( psi_i ) and IsMorphism( psi_i );
    
    psi := HomalgChainMorphism( psi_i, S, T, [ degrees[1], degree_gamma - degree_beta ] );
    
    for i in [ 2 .. Length( morphisms_gamma ) ] do
        psi_i := PostDivide( morphisms_gamma[i], morphisms_beta[i] );
        b := b and HasIsMorphism( psi_i ) and IsMorphism( psi_i );
        Add( psi, psi_i );
    od;
    
    Assert( 4, IsMorphism( psi ) );
    
    if b then
        SetIsMorphism( psi, true );
    fi;
    
    return psi;
    
end );

##
InstallMethod( PreDivide,
        "for two chain morphisms with the same source",
        [ IsHomalgChainMorphism, IsHomalgChainMorphism ],
        
  function( epsilon, eta )
    local degree_epsilon, degree_eta, S, T, degrees, morphisms_epsilon, morphisms_eta,
          psi_i, b, psi, i;
    
    if not Source( epsilon ) = Source( eta ) then
        Error( "the source objects of the two chain morphisms are not equal\n" );
    fi;
    
    degree_epsilon := DegreeOfMorphism( epsilon );
    degree_eta := DegreeOfMorphism( eta );
    
    S := Range( epsilon );
    T := Range( eta );
    
    degrees := ObjectDegreesOfComplex( S );
    
    morphisms_epsilon := MorphismsOfChainMorphism( epsilon );
    morphisms_eta := MorphismsOfChainMorphism( eta );
    
    psi_i := PreDivide( morphisms_epsilon[1], morphisms_eta[1] );
    
    b := HasIsMorphism( psi_i ) and IsMorphism( psi_i );
    
    psi := HomalgChainMorphism( psi_i, S, T, [ degrees[1], degree_epsilon - degree_eta ] );
    
    for i in [ 2 .. Length( morphisms_epsilon ) ] do
        psi_i := PreDivide( morphisms_epsilon[i], morphisms_eta[i] );
        b := b and HasIsMorphism( psi_i ) and IsMorphism( psi_i );
        Add( psi, psi_i );
    od;
    
    Assert( 4, IsMorphism( psi ) );
    
    if b then
        SetIsMorphism( psi, true );
    fi;
    
    return psi;
    
end );

##
InstallMethod( SubChainMorphism,
        "for homalg chain morphisms",
        [ IsHomalgChainMorphism, IsInt, IsInt ],
        
  function( d_phi, i, j )
    local dS, dT, phi, d_psi, k;
    
    dS := Subcomplex( Source( d_phi ), i, j );
    
    if IsHomalgEndomorphism( d_phi ) then
        dT := dS;
    else
        dT := Subcomplex( Range( d_phi ), i, j );
    fi;
    
    phi := CertainMorphism( d_phi, i );
    
    if phi = fail then
        Error( "The chain map does not have the demanded degree" );
    fi;
    
    d_psi := HomalgChainMorphism( phi, dS, dT, i );
    
    for k in [ i+1 .. j ] do
        
        phi := CertainMorphism( d_phi, k );
        
        if phi = fail then
            Error( "The chain map does not have the demanded degree" );
        fi;
        
        Add( d_psi, phi );
        
    od;
    
    if HasIsZero( d_phi ) and IsZero( d_phi ) then
        SetIsZero( d_psi, true );
    elif HasIsGradedMorphism( d_phi ) and IsGradedMorphism( d_phi ) then
        SetIsGradedMorphism( d_psi, true );
    fi;
    
    if HasIsOne( d_phi ) and IsOne( d_phi ) then
        SetIsOne( d_psi, true );
    fi;
    
    if HasIsMorphism( d_phi ) and IsMorphism( d_phi ) then
        SetIsMorphism( d_psi, true );
    fi;
    
    if HasIsGeneralizedMorphismWithFullDomain( d_phi ) and IsGeneralizedMorphismWithFullDomain( d_phi ) then
        SetIsGeneralizedMorphismWithFullDomain( d_psi, true );
    fi;
    
    if HasIsGeneralizedEpimorphism( d_phi ) and IsGeneralizedEpimorphism( d_phi ) then
        SetIsGeneralizedEpimorphism( d_psi, true );
    fi;
    
    if HasIsGeneralizedMonomorphism( d_phi ) and IsGeneralizedMonomorphism( d_phi ) then
        SetIsGeneralizedMonomorphism( d_psi, true );
    fi;
    
    if HasIsMonomorphism( d_phi ) and IsMonomorphism( d_phi ) then
        SetIsMonomorphism( d_psi, true );
    fi;
    
    if HasIsEpimorphism( d_phi ) and IsEpimorphism( d_phi ) then
        SetIsEpimorphism( d_psi, true );
    fi;
    
    if HasIsSplitMonomorphism( d_phi ) and IsSplitMonomorphism( d_phi ) then
        SetIsSplitMonomorphism( d_psi, true );
    fi;
    
    if HasIsSplitEpimorphism( d_phi ) and IsSplitEpimorphism( d_phi ) then
        SetIsSplitEpimorphism( d_psi, true );
    fi;
    
    return d_psi;
    
end );

####################################
#
# constructor functions and methods:
#
####################################

##  <#GAPDoc Label="HomalgChainMorphism">
##  <ManSection>
##    <Func Arg="phi[, C][, D][, d]" Name="HomalgChainMorphism" Label="constructor for chain morphisms given a morphism"/>
##    <Returns>a &homalg; chain morphism</Returns>
##    <Description>
##      The constructor creates a (co)chain morphism given a source &homalg; (co)chain complex <A>C</A>,
##      a target &homalg; (co)chain complex <A>D</A>, and a &homalg; morphism <A>phi</A> at (co)homological degree <A>d</A>.
##      The returned (co)chain morphism will cautiously be indicated using parenthesis: <Q>chain morphism</Q>.
##      To verify if the result is indeed a (co)chain morphism use <Ref Prop="IsMorphism" Label="for chain morphisms"/>.
##      If source and target are identical objects, and only then, the (co)chain morphism is created as a (co)chain endomorphism.
##      <P/>
##      The following examples shows a chain morphism that induces the zero morphism on homology, but is itself <E>not</E> zero
##      in the derived category:
##      <Example><![CDATA[
##  gap> zz := HomalgRingOfIntegers( );
##  Z
##  gap> M := 1 * zz;
##  <The free left module of rank 1 on a free generator>
##  gap> Display( M );
##  Z^(1 x 1)
##  gap> N := HomalgMatrix( "[3]", 1, 1, zz );;
##  gap> N := LeftPresentation( N );
##  <A cyclic torsion left module presented by 1 relation for
##   a cyclic generator>
##  gap> Display( N );
##  Z/< 3 >
##  gap> a := HomalgMap( HomalgMatrix( "[2]", 1, 1, zz ), M, M );
##  <An endomorphism of a left module>
##  gap> c := HomalgMap( HomalgMatrix( "[2]", 1, 1, zz ), M, N );
##  <A homomorphism of left modules>
##  gap> b := HomalgMap( HomalgMatrix( "[1]", 1, 1, zz ), M, M );
##  <An endomorphism of a left module>
##  gap> d := HomalgMap( HomalgMatrix( "[1]", 1, 1, zz ), M, N );
##  <A homomorphism of left modules>
##  gap> C1 := HomalgComplex( a );
##  <A non-zero acyclic complex containing a single morphism of left modules at de\
##  grees [ 0 .. 1 ]>
##  gap> C2 := HomalgComplex( c );
##  <A non-zero acyclic complex containing a single morphism of left modules at de\
##  grees [ 0 .. 1 ]>
##  gap> cm := HomalgChainMorphism( d, C1, C2 );
##  <A "chain morphism" containing a single left morphism at degree 0>
##  gap> Add( cm, b );
##  gap> IsMorphism( cm );
##  true
##  gap> cm;
##  <A chain morphism containing 2 morphisms of left modules at degrees
##  [ 0 .. 1 ]>
##  gap> hcm := DefectOfExactness( cm );
##  <A chain morphism of graded objects containing
##  2 morphisms of left modules at degrees [ 0 .. 1 ]>
##  gap> IsZero( hcm );
##  true
##  gap> IsZero( Source( hcm ) );
##  false
##  gap> IsZero( Range( hcm ) );
##  false
##  ]]></Example>
##    </Description>
##  </ManSection>
##  <#/GAPDoc>
##
InstallGlobalFunction( HomalgChainMorphism,
  function( arg )
    local nargs, morphism, left, source, target, degrees, degree,
          S, category, chainmorphism, type, cm;
    
    nargs := Length( arg );
    
    if nargs < 2 then
        Error( "too few arguments\n" );
    fi;
    
    if IsMorphismOfFinitelyGeneratedObjectsRep( arg[1] ) then
        left := IsHomalgLeftObjectOrMorphismOfLeftObjects( arg[1] );
        morphism := arg[1];
    elif nargs = 1 then
        Error( "if a single argument is given it must be a homalg morphism\n" );
    fi;
    
    if nargs > 1 and IsHomalgComplex( arg[2] ) then
        if not IsBound( left ) then
            left := IsHomalgLeftObjectOrMorphismOfLeftObjects( arg[2] );
        fi;
        source := arg[2];
    fi;
    
    if nargs > 2 and IsHomalgComplex( arg[3] ) then
        if ( IsHomalgRightObjectOrMorphismOfRightObjects( arg[3] ) and left ) or
           ( IsHomalgLeftObjectOrMorphismOfLeftObjects( arg[3] ) and not left ) then
            Error( "the two complexes must either be both left or both right complexes\n" );
        fi;
        target := arg[3];
    else
        target := source;
    fi;
    
    if IsInt( arg[nargs] ) then
        degrees := [ arg[nargs] ];
        degree := 0;
    elif IsList( arg[nargs] ) and Length( arg[nargs] ) = 2 and ForAll( arg[nargs], IsInt ) then
        degrees := [ arg[nargs][1] ];
        degree := arg[nargs][2];
    else
        degrees := [ ObjectDegreesOfComplex( source )[1] ];
        degree := 0;
    fi;
    
    if not IsBound( morphism ) then
        ## FIXME: the only IsMatrixObj left in the code
        if IsMatrixObj( arg[1] ) then
            S := CertainObject( source, degrees[1] );
            category := HomalgCategory( S );
            if IsBound( category!.MorphismConstructor ) then
                morphism := category!.MorphismConstructor( arg[1], S, CertainObject( target, degrees[1] + degree ) );
            else
                Error( "didn't find the morphism constructor in the category of the source object\n" );
            fi;
        else
            Error( "the first argument must be a homalg matrix or a morphism\n" );
        fi;
    fi;
    
    if IsHomalgChainMorphism( morphism ) then
        if Source( morphism ) <> CertainObject( source, degrees[1] ) then
            Error( "the chain morphism and the source complex do not match\n" );
        elif Range( morphism ) <> CertainObject( target, degrees[1] ) then
            Error( "the chain morphism and the target complex do not match\n" );
        fi;
    else
        if not IsIdenticalObj( Source( morphism ), CertainObject( source, degrees[1] ) ) then
            Error( "the morphism and the source complex do not match\n" );
        elif not IsIdenticalObj( Range( morphism ), CertainObject( target, degrees[1] + degree ) ) then
            Error( "the morphism and the target complex do not match\n" );
        fi;
    fi;
    
    ConvertToRangeRep( degrees );
    
    cm := rec( degrees := degrees );
    
    cm.(String( degrees[1] )) := morphism;
    
    if IsComplexOfFinitelyPresentedObjectsRep( source ) and
       IsComplexOfFinitelyPresentedObjectsRep( target ) then
        chainmorphism := true;
    elif IsCocomplexOfFinitelyPresentedObjectsRep( source ) and
      IsCocomplexOfFinitelyPresentedObjectsRep( target ) then
        chainmorphism := false;
    else
        Error( "source and target must either be both complexes or both cocomplexes\n" );
    fi;
    
    if source = target then
        if chainmorphism then
            if left then
                type := TheTypeHomalgChainEndomorphismOfLeftObjects;
            else
                type := TheTypeHomalgChainEndomorphismOfRightObjects;
            fi;
        else
            if left then
                type := TheTypeHomalgCochainEndomorphismOfLeftObjects;
            else
                type := TheTypeHomalgCochainEndomorphismOfRightObjects;
            fi;
        fi;
    else
        if chainmorphism then
            if left then
                type := TheTypeHomalgChainMorphismOfLeftObjects;
            else
                type := TheTypeHomalgChainMorphismOfRightObjects;
            fi;
        else
            if left then
                type := TheTypeHomalgCochainMorphismOfLeftObjects;
            else
                type := TheTypeHomalgCochainMorphismOfRightObjects;
            fi;
        fi;
    fi;
    
    ## Objectify
    ObjectifyWithAttributes(
            cm, type,
            Source, source,
            Range, target,
            DegreeOfMorphism, degree
            );
    
    return cm;
    
end );


####################################
#
# constructors
#
####################################

##
InstallMethod( \*,
        "for a structure object and a chain morphism",
        [ IsStructureObject, IsHomalgChainMorphism ],
        
  function( R, phi )
    
    return BaseChange( R, phi );
    
end );

##
InstallMethod( \*,
        "for a chain morphism and a structure object",
        [ IsHomalgChainMorphism, IsStructureObject ],
        
  function( phi, R )
    
    return R * phi;
    
end );

####################################
#
# View, Print, and Display methods:
#
####################################

##
InstallMethod( ViewObj,
        "for homalg chain morphisms",
        [ IsHomalgChainMorphism ],
        
  function( o )
    local degrees, l, oi;
    
    Print( "<A" );
    
    if HasDegreeOfMorphism( o ) and DegreeOfMorphism( o ) <> 0 then
        Print( " degree ", DegreeOfMorphism( o ) );
    fi;
    
    if HasIsZero( o ) then
        if IsZero ( o ) then
            Print( " zero" );
        else
            Print( " non-zero" );
        fi;
    fi;
    
    if HasIsMorphism( o ) then
        if IsMorphism( o ) then
            if IsChainMorphismOfFinitelyPresentedObjectsRep( o ) then
                Print( " chain " );
            else
                Print( " cochain " );
            fi;
            if HasIsIsomorphism( o ) and IsIsomorphism( o ) then
                Print( "iso" );
            elif HasIsQuasiIsomorphism( o ) and IsQuasiIsomorphism( o ) then
                Print( "quasi-iso" );
            elif HasIsMonomorphism( o ) and IsMonomorphism( o ) then
                Print( "mono" );
            elif HasIsEpimorphism( o ) and IsEpimorphism( o ) then
                Print( "epi" );
            fi;
        else
            if IsChainMorphismOfFinitelyPresentedObjectsRep( o ) then
                Print( " non-chain " );
            else
                Print( " non-cochain " );
            fi;
        fi;
        Print( "morphism" );
    elif HasIsGeneralizedMorphismWithFullDomain( o ) then
        if IsGeneralizedMorphismWithFullDomain( o ) then
            if IsChainMorphismOfFinitelyPresentedObjectsRep( o ) then
                Print( " generalized chain " );
            else
                Print( " generalized cochain " );
            fi;
        else
            if IsChainMorphismOfFinitelyPresentedObjectsRep( o ) then
                Print( " non-chain " );
            else
                Print( " non-cochain " );
            fi;
        fi;
        Print( "morphism" );
    else
        if IsChainMorphismOfFinitelyPresentedObjectsRep( o ) then
            Print( " \"chain morphism\"" );
        else
            Print( " \"cochain morphism\"" );
                   fi;
    fi;
    
    if HasIsGradedMorphism( o ) and IsGradedMorphism( o ) then
        Print( " of graded objects" );
    fi;
    
    Print( " containing " );
    
    degrees := DegreesOfChainMorphism( o );
    
    l := Length( degrees );
    
    if l = 1 then
        
        Print( "a single " );
        
        if IsHomalgLeftObjectOrMorphismOfLeftObjects( o ) then
            Print( "left" );
        else
            Print( "right" );
        fi;
        
        Print( " morphism at degree ", degrees[1], ">" );
        
    else
        
        Print( l, " morphisms" );
        
        Print( " of " );
        
        if IsBound( o!.adjective ) then
            Print( o!.adjective, " " );
        fi;
        
        if IsHomalgLeftObjectOrMorphismOfLeftObjects( o ) then
            Print( "left " );
        else
            Print( "right " );
        fi;
        
        oi := Source( CertainMorphism( o, degrees[1] ) );
        
        if IsBound( oi!.string ) then
            if IsBound( oi!.string_plural ) then
                Print( oi!.string_plural );
            else
                Print( oi!.string, "s" );
            fi;
        else
            Print( "objects" );
        fi;
        
        Print( " at degrees ", degrees, ">" );
        
    fi;
    
end );

##
InstallMethod( Display,
        "for homalg chain morphisms",
        [ IsChainMorphismOfFinitelyPresentedObjectsRep ],
        
  function( o )
    local i;
    
    for i in Reversed( DegreesOfChainMorphism( o ) ) do
        Print( "-------------------------\n" );
        Print( "at homology degree: ", i, "\n" );
        Display( CertainMorphism( o, i ) );
    od;
    
    Print( "-------------------------\n" );
    
end );

##
InstallMethod( Display,
        "for homalg chain morphisms",
        [ IsCochainMorphismOfFinitelyPresentedObjectsRep ],
        
  function( o )
    local i;
    
    for i in Reversed( DegreesOfChainMorphism( o ) ) do
        Print( "---------------------------\n" );
        Print( "at cohomology degree: ", i, "\n" );
        Display( CertainMorphism( o, i ) );
    od;
    
    Print( "-------------------------\n" );
    
end );


[ Dauer der Verarbeitung: 0.21 Sekunden  (vorverarbeitet)  ]

                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Software

     Produkte
     Quellcodebibliothek

Aktivitäten

     Artikel über Sicherheit
     Anleitung zur Aktivierung von SSL

Muße

     Gedichte
     Musik
     Bilder

Jenseits des Üblichen ....

Besucherstatistik

Besucherstatistik

Monitoring

Montastic status badge