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

##  Implementations for homalg spectral sequences.

##  <#GAPDoc Label="SpectralSequences:intro">
##    Spectral sequences are regarded as the computational sledgehammer in homological algebra. Quoting the last lines
##    of Rotman's book <Cite Key="rot"/>: <P/>
##    <Quoted>The reader should now be convinced that virtually every purely homological result may be proved with
##      spectral sequences. Even though <Q>elementary</Q> proofs may exist for many of these results, spectral sequences
##      offer a systematic approach in place of sporadic success.</Quoted>
##  <#/GAPDoc>

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

##  <#GAPDoc Label="IsSpectralSequenceOfFinitelyPresentedObjectsRep">
##  <ManSection>
##    <Filt Type="Representation" Arg="E" Name="IsSpectralSequenceOfFinitelyPresentedObjectsRep"/>
##    <Returns><C>true</C> or <C>false</C></Returns>
##    <Description>
##      The &GAP; representation of homological spectral sequences of finitley generated &homalg; objects. <P/>
##      (It is a representation of the &GAP; category <Ref Filt="IsHomalgSpectralSequence"/>,
##       which is a subrepresentation of the &GAP; representation <C>IsFinitelyPresentedObjectRep</C>.)
##    </Description>
##  </ManSection>
##  <#/GAPDoc>
##
DeclareRepresentation( "IsSpectralSequenceOfFinitelyPresentedObjectsRep",
        IsHomalgSpectralSequence and IsFinitelyPresentedObjectRep,
        [  ] );

##  <#GAPDoc Label="IsSpectralCosequenceOfFinitelyPresentedObjectsRep">
##  <ManSection>
##    <Filt Type="Representation" Arg="E" Name="IsSpectralCosequenceOfFinitelyPresentedObjectsRep"/>
##    <Returns><C>true</C> or <C>false</C></Returns>
##    <Description>
##      The &GAP; representation of cohomological spectral sequences of finitley generated &homalg; objects. <P/>
##      (It is a representation of the &GAP; category <Ref Filt="IsHomalgSpectralSequence"/>,
##       which is a subrepresentation of the &GAP; representation <C>IsFinitelyPresentedObjectRep</C>.)
##    </Description>
##  </ManSection>
##  <#/GAPDoc>
##
DeclareRepresentation( "IsSpectralCosequenceOfFinitelyPresentedObjectsRep",
        IsHomalgSpectralSequence and IsFinitelyPresentedObjectRep,
        [  ] );

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

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

# four new types:
BindGlobal( "TheTypeHomalgSpectralSequenceAssociatedToABicomplexOfLeftObjects",
        NewType( TheFamilyOfHomalgSpectralSequencees,
                IsSpectralSequenceOfFinitelyPresentedObjectsRep and
                IsHomalgSpectralSequenceAssociatedToABicomplex and
                IsHomalgSpectralSequenceAssociatedToAnExactCouple and
                IsHomalgLeftObjectOrMorphismOfLeftObjects ) );

BindGlobal( "TheTypeHomalgSpectralSequenceAssociatedToABicomplexOfRightObjects",
        NewType( TheFamilyOfHomalgSpectralSequencees,
                IsSpectralSequenceOfFinitelyPresentedObjectsRep and
                IsHomalgSpectralSequenceAssociatedToABicomplex and
                IsHomalgSpectralSequenceAssociatedToAnExactCouple and
                IsHomalgRightObjectOrMorphismOfRightObjects ) );

BindGlobal( "TheTypeHomalgSpectralCosequenceAssociatedToABicomplexOfLeftObjects",
        NewType( TheFamilyOfHomalgSpectralSequencees,
                IsSpectralCosequenceOfFinitelyPresentedObjectsRep and
                IsHomalgSpectralSequenceAssociatedToABicomplex and
                IsHomalgSpectralSequenceAssociatedToAnExactCouple and
                IsHomalgLeftObjectOrMorphismOfLeftObjects ) );

BindGlobal( "TheTypeHomalgSpectralCosequenceAssociatedToABicomplexOfRightObjects",
        NewType( TheFamilyOfHomalgSpectralSequencees,
                IsSpectralCosequenceOfFinitelyPresentedObjectsRep and
                IsHomalgSpectralSequenceAssociatedToABicomplex and
                IsHomalgSpectralSequenceAssociatedToAnExactCouple and
                IsHomalgRightObjectOrMorphismOfRightObjects ) );

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

##
InstallMethod( StructureObject,
        "for homalg spectral sequences",
        [ IsHomalgSpectralSequence ],
        
  function( E )
    
    return StructureObject( LowestLevelSheetInSpectralSequence( E ) );
    
end );

##
InstallMethod( homalgResetFilters,
        "for homalg spectral sequences",
        [ IsHomalgSpectralSequence ],
        
  function( E )
    local property;
    
    if not IsBound( HOMALG.PropertiesOfSpectralSequencees ) then
        HOMALG.PropertiesOfSpectralSequencees :=
          [ IsZero ];
    fi;
    
    for property in HOMALG.PropertiesOfSpectralSequencees do
        ResetFilterObj( E, property );
    od;
    
end );

## provided to avoid branching in the code and always returns fail
InstallMethod( PositionOfTheDefaultPresentation,
        "for homalg spectral sequences",
        [ IsHomalgSpectralSequence ],
        
  function( E )
    
    return fail;
    
end );

##
InstallMethod( LevelsOfSpectralSequence,
        "for homalg spectral sequences",
        [ IsHomalgSpectralSequence ],
        
  function( E )
    
    return E!.levels;
    
end );

##
InstallMethod( CertainSheet,
        "for homalg spectral sequences",
        [ IsHomalgSpectralSequence, IsInt ],
        
  function( E, r )
    
    if IsBound(E!.(String( r ))) then
        return E!.(String( r ));
    fi;
    
    return fail;
    
end );

##
InstallMethod( LowestLevelInSpectralSequence,
        "for homalg spectral sequences",
        [ IsHomalgSpectralSequence ],
        
  function( E )
    
    return LevelsOfSpectralSequence( E )[1];
    
end );

##
InstallMethod( HighestLevelInSpectralSequence,
        "for homalg spectral sequences",
        [ IsHomalgSpectralSequence ],
        
  function( E )
    local levels;
    
    levels := LevelsOfSpectralSequence( E );
    
    return levels[Length( levels )];
    
end );

##
InstallMethod( SheetsOfSpectralSequence,
        "for homalg spectral sequences",
        [ IsHomalgSpectralSequence ],
        
  function( E )
    
    return List( LevelsOfSpectralSequence( E ), r -> CertainSheet( E, r ) );
    
end );

##
InstallMethod( LowestLevelSheetInSpectralSequence,
        "for homalg spectral sequences",
        [ IsHomalgSpectralSequence ],
        
  function( E )
    
    return CertainSheet( E, LowestLevelInSpectralSequence( E ) );
    
end );

##
InstallMethod( HighestLevelSheetInSpectralSequence,
        "for homalg spectral sequences",
        [ IsHomalgSpectralSequence ],
        
  function( E )
    
    return CertainSheet( E, HighestLevelInSpectralSequence( E ) );
    
end );

##
InstallMethod( ObjectDegreesOfSpectralSequence,
        "for homalg spectral sequences",
        [ IsHomalgSpectralSequence ],
        
  function( E )
    
    return E!.bidegrees;
    
end );

##
InstallMethod( CertainObject,
        "for homalg spectral sequences",
        [ IsHomalgSpectralSequence, IsList, IsInt ],
        
  function( E, pq, r )
    local Er;
    
    Er := CertainSheet( E, r );
    
    if Er = fail then
        return fail;
    fi;
    
    return CertainObject( Er, pq );
    
end );

##
InstallMethod( CertainObject,
        "for homalg spectral sequences",
        [ IsHomalgSpectralSequence, IsList ],
        
  function( E, pq )
    
    return CertainObject( E, pq, HighestLevelInSpectralSequence( E ) );
    
end );

##
InstallMethod( ObjectsOfSpectralSequence,
        "for homalg spectral sequences",
        [ IsHomalgSpectralSequence, IsInt ],
        
  function( E, r )
    local Er;
    
    Er := CertainSheet( E, r );
    
    if Er = fail then
        return fail;
    fi;
    
    return ObjectsOfBigradedObject( Er );
    
end );

##
InstallMethod( ObjectsOfSpectralSequence,
        "for homalg spectral sequences",
        [ IsHomalgSpectralSequence ],
        
  function( E )
    
    return ObjectsOfSpectralSequence( E, HighestLevelInSpectralSequence( E ) );
    
end );

##
InstallMethod( LowestBidegreeInSpectralSequence,
        "for homalg spectral sequences",
        [ IsHomalgSpectralSequence ],
        
  function( E )
    local bidegrees;
    
    bidegrees := ObjectDegreesOfSpectralSequence( E );
    
    return [ bidegrees[1][1], bidegrees[2][1] ];
    
end );

##
InstallMethod( HighestBidegreeInSpectralSequence,
        "for homalg spectral sequences",
        [ IsHomalgSpectralSequence ],
        
  function( E )
    local bidegrees;
    
    bidegrees := ObjectDegreesOfSpectralSequence( E );
    
    return [ bidegrees[1][Length( bidegrees[1] )], bidegrees[2][Length( bidegrees[2] )] ];
    
end );

##
InstallMethod( LowestTotalDegreeInSpectralSequence,
        "for homalg spectral sequences",
        [ IsHomalgSpectralSequence ],
        
  function( B )
    local pq_lowest;
    
    pq_lowest := LowestBidegreeInSpectralSequence( B );
    
    return pq_lowest[1] + pq_lowest[2];
    
end );

##
InstallMethod( HighestTotalDegreeInSpectralSequence,
        "for homalg spectral sequences",
        [ IsHomalgSpectralSequence ],
        
  function( B )
    local pq_highest;
    
    pq_highest := HighestBidegreeInSpectralSequence( B );
    
    return pq_highest[1] + pq_highest[2];
    
end );

##
InstallMethod( TotalDegreesOfSpectralSequence,
        "for homalg spectral sequences",
        [ IsHomalgSpectralSequence ],
        
  function( B )
    
    return [ LowestTotalDegreeInSpectralSequence( B ) .. HighestTotalDegreeInSpectralSequence( B ) ];
    
end );

##
InstallMethod( BidegreesOfSpectralSequence,
        "for homalg spectral sequences",
        [ IsHomalgSpectralSequence, IsInt ],
        
  function( E, n )
    local bidegrees, lq, max, n_lowest, n_highest, bidegrees_n, p, q;
    
    bidegrees := ObjectDegreesOfSpectralSequence( E );
    
    lq := Length( bidegrees[2] );
    max := Minimum( Length( bidegrees[1] ),  lq ) - 1;
    
    n_lowest := LowestTotalDegreeInSpectralSequence( E );
    n_highest := HighestTotalDegreeInSpectralSequence( E );
    
    bidegrees_n := [ ];
    
    if n < n_lowest or n > n_highest then
        return bidegrees_n;
    fi;
    
    if n - n_lowest < lq then
        for p in bidegrees[1][1] + [ 0 .. Minimum( n - n_lowest, max ) ] do
            Add( bidegrees_n, [ p, n - p ] );
        od;
    else
        for q in bidegrees[2][lq] - [ 0 .. Minimum( n_highest - n, max ) ] do
            Add( bidegrees_n, [ n - q, q ] );
        od;
    fi;
    
    return bidegrees_n;
    
end );

##
InstallMethod( LowestBidegreeObjectInSpectralSequence,
        "for homalg spectral sequences",
        [ IsHomalgSpectralSequence, IsInt ],
        
  function( E, r )
    local Er, pq;
    
    Er := CertainSheet( E, r );
    
    if Er = fail then
        return fail;
    fi;
    
    pq := LowestBidegreeInSpectralSequence( E );
    
    return CertainObject( Er, pq );
    
end );

##
InstallMethod( LowestBidegreeObjectInSpectralSequence,
        "for homalg spectral sequences",
        [ IsHomalgSpectralSequence ],
        
  function( E )
    
    return LowestBidegreeObjectInSpectralSequence( E, HighestLevelInSpectralSequence( E ) );
    
end );

##
InstallMethod( HighestBidegreeObjectInSpectralSequence,
        "for homalg spectral sequences",
        [ IsHomalgSpectralSequence, IsInt ],
        
  function( E, r )
    local Er, pq;
    
    Er := CertainSheet( E, r );
    
    if Er = fail then
        return fail;
    fi;
    
    pq := HighestBidegreeInSpectralSequence( E );
    
    return CertainObject( Er, pq );
    
end );

##
InstallMethod( HighestBidegreeObjectInSpectralSequence,
        "for homalg spectral sequences",
        [ IsHomalgSpectralSequence ],
        
  function( E )
    
    return HighestBidegreeObjectInSpectralSequence( E, HighestLevelInSpectralSequence( E ) );
    
end );

##
InstallMethod( CertainMorphism,
        "for homalg spectral sequences",
        [ IsHomalgSpectralSequence, IsList, IsInt ],
        
  function( E, pq, r )
    local Er;
    
    Er := CertainSheet( E, r );
    
    if Er = fail then
        return fail;
    fi;
    
    return CertainMorphism( Er, pq );
    
end );

##
InstallMethod( CertainMorphism,
        "for homalg spectral sequences",
        [ IsHomalgSpectralSequence, IsList ],
        
  function( E, pq )
    
    return CertainMorphism( E, pq, HighestLevelInSpectralSequence( E ) );
    
end );

##
InstallMethod( UnderlyingBicomplex,
        "for homalg spectral sequences stemming from a bicomplex",
        [ IsHomalgSpectralSequenceAssociatedToABicomplex ],
        
  function( E )
    
    if IsBound(E!.bicomplex) then
        return E!.bicomplex;
    fi;
    
    Error( "it seems that the spectral sequence does not stem from a bicomplex\n" );
    
end );

##
InstallMethod( AssociatedFilteredComplex,
        "for homalg spectral sequences stemming from a bicomplex",
        [ IsHomalgSpectralSequenceAssociatedToABicomplex ],
        
  function( E )
    
    return TotalComplex( UnderlyingBicomplex( E ) );
    
end );

##
InstallMethod( AssociatedFirstSpectralSequence,
        "for homalg spectral sequences stemming from a bicomplex",
        [ IsHomalgSpectralSequenceAssociatedToABicomplex ],
        
  function( II_E )
    local BC, I_E;
    
    if not IsBound(II_E!.TransposedSpectralSequence) then
        BC := UnderlyingBicomplex( II_E );
        
        if not IsTransposedWRTTheAssociatedComplex( BC ) then
            return fail; ## this doesn't seem like the second spectral sequence
        fi;
        
        BC := TransposedBicomplex( BC );
        
        ## the first spectral sequence associated to BC,
        ## also called the first spectral sequence of the bicomplex BC;
        ## it becomes intrinsic at the second level (w.r.t. some original data)
        ## which is often its limit sheet
        I_E := HomalgSpectralSequence( BC );
        
        ## enforce computation till the second sheet, even if things stabilize earlier
        if HighestLevelInSpectralSequence( I_E ) < 2 then
            I_E := HomalgSpectralSequence( 2, BC ); ## FIXME: find a way to avoid recomputing things
        fi;
        
        ## finally enrich the second spectral sequence with the first
        II_E!.TransposedSpectralSequence := I_E;
        
    fi;
    
    return II_E!.TransposedSpectralSequence;
    
end );

##
InstallMethod( LevelOfStability,
        "for homalg spectral sequences",
        [ IsHomalgSpectralSequenceAssociatedToABicomplex, IsList, IsInt ],
        
  function( E, pq, a )
    local bidegrees, p, q, i, j, lq, r, Er;
    
    if CertainObject( E, pq ) = fail then
        return fail;
    fi;
    
    bidegrees := ObjectDegreesOfSpectralSequence( E );
    
    p := bidegrees[1];
    q := bidegrees[2];
    
    i := Position( p, pq[1] );
    j := Position( q, pq[2] );
    
    lq := Length( q );
    
    for r in LevelsOfSpectralSequence( E ) do
        Er := CertainSheet( E, r );
        if IsBound( Er!.stability_table ) and Er!.stability_table[lq-j+1][i] in [ '.', 's' ] then
            return Maximum( r, a );
        fi;
    od;
    
    return fail;
    
end );

##
InstallMethod( LevelOfStability,
        "for homalg spectral sequences",
        [ IsHomalgSpectralSequenceAssociatedToABicomplex, IsList ],
        
  function( E, pq )
    
    return LevelOfStability( E, pq, LevelsOfSpectralSequence( E )[1] );
    
end );

##
InstallMethod( StaircaseOfStability,
        "for homalg spectral sequences",
        [ IsHomalgSpectralSequenceAssociatedToABicomplex, IsList, IsInt ],
        
  function( E, pq, a )
    local l, bidegrees, p, q, r, Er, st, c;
    
    l := LevelOfStability( E, pq, a ) - a;
    
    ## the trivial cases:
    if l = 0 then
        return [ 0 ];
    elif l = 1 then
        return [ 1 ];
    elif l = fail then
        return fail;
    fi;
    
    bidegrees := ObjectDegreesOfSpectralSequence( E );
    
    p := pq[1];
    q := pq[2];
    
    st := [ ];
    c := 1;
    
    for r in Filtered( LevelsOfSpectralSequence( E ), i -> i >= a + 1 and i <= a + l ) do
        Er := CertainSheet( E, r );
        if IsBound( Er!.embeddings ) then
            if IsIsomorphism( Er!.embeddings.(String( [ p, q ] )) ) then
                c := c + 1;
            else
                Add( st, c );
                c := 1;
            fi;
        else
            return fail;
        fi;
    od;
    
    if st = [ ] then
        return fail;
    else
        return st;
    fi;
    
end );

##
InstallMethod( StaircaseOfStability,
        "for homalg spectral sequences",
        [ IsHomalgSpectralSequenceAssociatedToABicomplex, IsList ],
        
  function( E, pq )
    
    return StaircaseOfStability( E, pq, LevelsOfSpectralSequence( E )[1] );
    
end );

##
InstallMethod( DecideZero,
        "for homalg spectral sequences",
        [ IsHomalgSpectralSequence ],
        
  function( E )
    
    return DecideZero( HighestLevelSheetInSpectralSequence( E ) );
    
end );

##  <#GAPDoc Label="ByASmallerPresentation:spectralsequence">
##  <ManSection>
##    <Meth Arg="E" Name="ByASmallerPresentation" Label="for spectral sequences"/>
##    <Returns>a &homalg; spectral sequence</Returns>
##    <Description>
##    See <Ref Meth="ByASmallerPresentation" Label="for bigraded objects"/> on bigraded object.
##      <Listing Type="Code"><![CDATA[
InstallMethod( ByASmallerPresentation,
        "for homalg spectral sequences",
        [ IsHomalgSpectralSequence ],
        
  function( E )
    
    ByASmallerPresentation( HighestLevelSheetInSpectralSequence( E ) );
    
    if IsBound( E!.TransposedSpectralSequence ) then
        ByASmallerPresentation( E!.TransposedSpectralSequence );
    fi;
    
    return E;
    
end );
##  ]]></Listing>
##      This method performs side effects on its argument <A>E</A> and returns it.
##    </Description>
##  </ManSection>
##  <#/GAPDoc>

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

##  <#GAPDoc Label="HomalgSpectralSequence">
##  <ManSection>
##    <Oper Arg="r, B, a" Name="HomalgSpectralSequence" Label="constructor for spectral sequences given a bicomplex"/>
##    <Oper Arg="r, B" Name="HomalgSpectralSequence" Label="constructor for spectral sequences without a special sheet given a bicomplex"/>
##    <Oper Arg="B, a" Name="HomalgSpectralSequence" Label="constructor for spectral sequences without bound given a bicomplex"/>
##    <Oper Arg="B" Name="HomalgSpectralSequence" Label="constructor for spectral sequences without bound and without a special sheet given a bicomplex"/>
##    <Returns>a &homalg; spectral sequence</Returns>
##    <Description>
##    The first syntax is the main constructor. It creates the homological (resp. cohomological) spectral sequence
##    associated to the homological (resp. cohomological) bicomplex <A>B</A> starting at level <M>0</M> and ending
##    at level <A>r</A><M>\geq 0</M> (regardless if the spectral sequence stabilizes earlier). The generalized embeddings
##    into the objects of 0-th sheet are always computed for each higher sheet <M>Er</M> and stored as
##    a record under the component <M>Er</M>!.absolute_embeddings. If <A>a</A> is greater than <M>0</M> the generalized
##    embeddings into the objects of the <A>a</A>-th sheet also get computed for each higher sheet <M>Er</M> and stored
##    as a record under the component <M>Er</M>!.relative_embeddings. The level <A>a</A> at which the spectral sequence
##    becomes intrinsic is a natural candidate for <A>a</A>. The <A>a</A>-th sheet is called the <E>special</E> sheet.
##    <P/>
##    If <A>r</A><M>=-1</M> it computes all the sheets of the spectral sequence until the sequence stabilizes,
##    i.e. until all higher arrows become zero.
##    <P/>
##    If <A>a</A><M>=-1</M> no special sheet is specified.
##    <P/>
##    In the second syntax <A>a</A> is set to <M>-1</M>.
##    <P/>
##    In the third syntax <A>r</A> is set to <M>-1</M>.
##    <P/>
##    In the fourth syntax both <A>r</A> and <A>a</A> are set to <M>-1</M>.
##    <P/>
##    The following example demonstrates the computation of a <M>Tor-Ext</M> spectral sequence:
##      <Example><![CDATA[
##  gap> ZZ := HomalgRingOfIntegers( );
##  Z
##  gap> M := HomalgMatrix( "[ 2, 3, 4,   5, 6, 7 ]", 2, 3, ZZ );;
##  gap> M := LeftPresentation( M );
##  <A non-torsion left module presented by 2 relations for 3 generators>
##  gap> dM := Resolution( M );
##  <A non-zero right acyclic complex containing a single morphism of left modules\
##   at degrees [ 0 .. 1 ]>
##  gap> CC := Hom( dM, dM );
##  <A non-zero acyclic cocomplex containing a single morphism of right complexes \
##  at degrees [ 0 .. 1 ]>
##  gap> B := HomalgBicomplex( CC );
##  <A non-zero bicocomplex containing right modules at bidegrees [ 0 .. 1 ]x
##  [ -1 .. 0 ]>
##  ]]></Example>
##    Now we construct the spectral sequence associated to the bicomplex <M>B</M>, also called the <E>first</E>
##    spectral sequence:
##      <Example><![CDATA[
##  gap> I_E := HomalgSpectralSequence( 2, B );
##  <A stable cohomological spectral sequence with sheets at levels 
##  [ 0 .. 2 ] each consisting of right modules at bidegrees [ 0 .. 1 ]x
##  [ -1 .. 0 ]>
##  gap> Display( I_E );
##  a cohomological spectral sequence at bidegrees
##  [ [ 0 .. 1 ], [ -1 .. 0 ] ]
##  ---------
##  Level 0:
##  
##   * *
##   * *
##  ---------
##  Level 1:
##  
##   * *
##   . .
##  ---------
##  Level 2:
##  
##   s s
##   . .
##  ]]></Example>
##    Legend:
##    <List>
##      <Item>A star <A>*</A> stands for a nonzero object.</Item>
##      <Item>A dot <A>.</A> stands for a zero object.</Item>
##      <Item>The letter <A>s</A> stands for a nonzero object that became stable.</Item>
##    </List>
##    <P/>
##    The <E>second</E> spectral sequence of the bicomplex is, by definition, the spectral sequence associated to
##    the transposed bicomplex:
##      <Example><![CDATA[
##  gap> tB := TransposedBicomplex( B );
##  <A non-zero bicocomplex containing right modules at bidegrees [ -1 .. 0 ]x
##  [ 0 .. 1 ]>
##  gap> II_E := HomalgSpectralSequence( tB, 2 );
##  <A stable cohomological spectral sequence with sheets at levels 
##  [ 0 .. 2 ] each consisting of right modules at bidegrees [ -1 .. 0 ]x
##  [ 0 .. 1 ]>
##  gap> Display( II_E );
##  a cohomological spectral sequence at bidegrees
##  [ [ -1 .. 0 ], [ 0 .. 1 ] ]
##  ---------
##  Level 0:
##  
##   * *
##   * *
##  ---------
##  Level 1:
##  
##   * *
##   * *
##  ---------
##  Level 2:
##  
##   s s
##   . s
##  ]]></Example>
##    </Description>
##  </ManSection>
##  <#/GAPDoc>
##
InstallMethod( HomalgSpectralSequence,
        "for homalg bicomplexes",
        [ IsInt, IsHomalgBicomplex, IsInt ],
        
  function( r, B, a ) ## a could, for example, be the level where E_r becomes intrinsic
    local bidegrees, E, Ei, type, rr, i;
    
    bidegrees := ObjectDegreesOfBicomplex( B );
    
    E := rec( bidegrees := bidegrees,
              levels := [ 0 ],
              bicomplex := B );
    
    Ei := HomalgBigradedObject( B );
    
    E.0 := Ei;
    
    if IsHomalgLeftObjectOrMorphismOfLeftObjects( E.0 ) then
        if IsBicomplexOfFinitelyPresentedObjectsRep( B ) then
            type := TheTypeHomalgSpectralSequenceAssociatedToABicomplexOfLeftObjects;
        else
            type := TheTypeHomalgSpectralCosequenceAssociatedToABicomplexOfLeftObjects;
        fi;
    else
        if IsBicomplexOfFinitelyPresentedObjectsRep( B ) then
            type := TheTypeHomalgSpectralSequenceAssociatedToABicomplexOfRightObjects;
        else
            type := TheTypeHomalgSpectralCosequenceAssociatedToABicomplexOfRightObjects;
        fi;
    fi;
    
    rr := r;
    i := 0;
    
    while rr <> 0 do
        if r <  0 and
           ( ( IsZero( Ei ) and i > 0 ) or
             ( ( HasIsStableSheet( Ei ) or IsBound( Ei!.stable ) ) and IsStableSheet( Ei ) ) ) then
            break;
        fi;
        AsDifferentialObject( Ei );
        if i = a then
            ## generalized embeddings into this sheet are computed
            Ei!.SpecialSheet := true;
        fi;
        Ei := DefectOfExactness( Ei );
        i := i + 1;
        Add( E.levels, i );
        E.(String(i)) := Ei;
        rr := rr - 1;
    od;
    
    ConvertToRangeRep( E.levels );
    
    ## Objectify
    Objectify( type, E );
    
    return E;
    
end );


##
InstallMethod( HomalgSpectralSequence,
        "for homalg bicomplexes",
        [ IsInt, IsHomalgBicomplex ],
        
  function( r, B )
    
    return HomalgSpectralSequence( r, B, -1 );
    
end );

##
InstallMethod( HomalgSpectralSequence,
        "for homalg bicomplexes",
        [ IsHomalgBicomplex, IsInt ],
        
  function( B, a )
    local E;
    
    E := HomalgSpectralSequence( -1, B, a );
    
    SetSpectralSequence( B, E );
    
    return E;
    
end );

##
InstallMethod( HomalgSpectralSequence,
        "for homalg bicomplexes",
        [ IsHomalgBicomplex ],
        
  function( B )
    local E;
    
    E := HomalgSpectralSequence( -1, B, -1 );
    
    SetSpectralSequence( B, E );
    
    return E;
    
end );

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

##
InstallMethod( ViewObj,
        "for homalg spectral sequences",
        [ IsHomalgSpectralSequence ],
        
  function( o )
    local Er, levels, degrees, l, opq;
    
    Print( "<A" );
    
    if HasIsZero( o ) then ## if this method applies and HasIsZero is set we already know that o is a non-zero homalg spectral sequence
        Print( " non-zero" );
    fi;
    
    Er := HighestLevelSheetInSpectralSequence( o );
    
    if HasIsStableSheet( Er ) then
        if IsStableSheet( Er ) then
            Print( " stable" );
        else
            Print( " yet unstable" );
        fi;
    fi;
    
    if IsSpectralCosequenceOfFinitelyPresentedObjectsRep( o ) then
        Print( " co" );
    else
        Print( " " );
    fi;
    
    Print( "homological spectral sequence with " );
    
    levels := o!.levels;
    
    if Length( levels ) = 1 then
        Print( "a single sheet at level ", levels[1], " consisting of " );
    else
        Print( "sheets at levels ", levels, " each consisting of " );
    fi;
    
    degrees := ObjectDegreesOfSpectralSequence( o );
    
    l := Length( degrees[1] ) * Length( degrees[2] );
    
    opq := CertainObject( o, [ degrees[1][1], degrees[2][1] ] );
    
    if l = 1 then
        
        Print( "a single " );
        
        if IsHomalgLeftObjectOrMorphismOfLeftObjects( o ) then
            Print( "left" );
        else
            Print( "right" );
        fi;
        
        if IsHomalgStaticObject( opq ) then
            if IsBound( opq!.string ) then
                Print( " ", opq!.string );
            else
                Print( " object" );
            fi;
        else
            if IsComplexOfFinitelyPresentedObjectsRep( opq ) then
                Print( " complex" );
            else
                Print( " cocomplex" );
            fi;
        fi;
        
        Print( " per sheet at bidegree ", [ degrees[1][1], degrees[2][1] ], ">" );
        
    else
        
        if IsBound( opq!.adjective ) then
            Print( opq!.adjective, " " );
        fi;
        
        if IsHomalgLeftObjectOrMorphismOfLeftObjects( o ) then
            Print( "left " );
        else
            Print( "right " );
        fi;
        
        if IsHomalgStaticObject( opq ) then
            if IsBound( opq!.string_plural ) then
                Print( opq!.string_plural );
            else
                Print( "objects" );
            fi;
        else
            if IsComplexOfFinitelyPresentedObjectsRep( opq ) then
                Print( "complexes" );
            else
                Print( "cocomplexes" );
            fi;
        fi;
        
        Print( " at bidegrees ", degrees[1], "x", degrees[2], ">" );
        
    fi;
    
end );

##
InstallMethod( ViewObj,
        "for homalg spectral sequences",
        [ IsHomalgSpectralSequence and IsZero ],
        
  function( o )
    
    Print( "<A zero " );
    
    if IsHomalgLeftObjectOrMorphismOfLeftObjects( o ) then
        Print( "left" );
    else
        Print( "right" );
    fi;
    
    if IsSpectralCosequenceOfFinitelyPresentedObjectsRep( o ) then
        Print( " co" );
    else
        Print( " " );
    fi;
    
    Print( "homological spectral sequence>" );
    
end );

##
InstallMethod( Display,
        "for homalg spectral sequences",
        [ IsHomalgSpectralSequence ],
        
  function( o )
    local I_E, Ers, Er;
    
    if IsBound( o!.TransposedSpectralSequence ) then
        Print( "The associated transposed spectral sequence:\n\n" );
        Display( o!.TransposedSpectralSequence );
        Print( "\nNow the spectral sequence of the bicomplex:\n\n" );
    fi;
    
    Ers := SheetsOfSpectralSequence( o );
    
    Print( "a " );
    
    if IsSpectralCosequenceOfFinitelyPresentedObjectsRep( o ) then
        Print( "co" );
    fi;
    
    Print( "homological spectral sequence at bidegrees\n", ObjectDegreesOfSpectralSequence( o ), "\n---------\n" );
    
    Display( Ers[1] );
    
    for Er in Ers{[ 2 .. Length( Ers ) ]} do
        Print( "---------\n" );
        Display( Er );
    od;
    
end );

back to top