1#############################################################################
2##
3##  Complexes.gi                homalg package               Mohamed Barakat
4##
5##  Copyright 2007-2008 Lehrstuhl B für Mathematik, RWTH Aachen
6##
7##  Implementations of homalg procedures for complexes.
8##
9#############################################################################
10
11####################################
12#
13# methods for operations:
14#
15####################################
16
17##
18InstallMethod( DefectOfExactness,
19        "for a homalg complexes",
20        [ IsComplexOfFinitelyPresentedObjectsRep, IsInt ],
21
22  function( C, i )
23    local degrees, mor, def;
24
25    degrees := ObjectDegreesOfComplex( C );
26
27    ## never use the following:
28    #elif HasIsGradedObject( C ) and IsGradedObject( C ) then
29    #    return CertainObject( C, i );
30
31    if PositionSet( degrees, i ) = fail then
32        Error( "the second argument ", i, " is outside the degree range of the complex\n" );
33    elif i = degrees[1] then
34        mor := CertainMorphism( C, i + 1 );
35        def := Cokernel( mor );
36    elif i = degrees[Length( degrees )] then
37        mor := CertainMorphism( C, i );
38        def := Kernel( mor );
39    else
40        mor := CertainTwoMorphismsAsSubcomplex( C, i );
41        mor := AsATwoSequence( mor );
42        def := DefectOfExactness( mor );
43    fi;
44
45    return def;
46
47end );
48
49##
50InstallMethod( DefectOfExactness,
51        "for a homalg complexes",
52        [ IsCocomplexOfFinitelyPresentedObjectsRep, IsInt ],
53
54  function( C, i )
55    local degrees, mor, def;
56
57    degrees := ObjectDegreesOfComplex( C );
58
59    ## never use the following:
60    #elif HasIsGradedObject( C ) and IsGradedObject( C ) then
61    #    return CertainObject( C, i );
62
63    if PositionSet( degrees, i ) = fail then
64        Error( "the second argument ", i, " is outside the degree range of the complex\n" );
65    elif i = degrees[1] then
66        mor := CertainMorphism( C, i );
67        def := Kernel( mor );
68    elif i = degrees[Length( degrees )] then
69        mor := CertainMorphism( C, i - 1 );
70        def := Cokernel( mor );
71    else
72        mor := CertainTwoMorphismsAsSubcomplex( C, i );
73        mor := AsATwoSequence( mor );
74        def := DefectOfExactness( mor );
75    fi;
76
77    return def;
78
79end );
80
81##
82InstallMethod( Homology,
83        "for a homalg complexes",
84        [ IsHomalgComplex, IsInt ],
85
86  function( C, i )
87
88    if IsCocomplexOfFinitelyPresentedObjectsRep( C ) then
89        Error( "this is a cocomplex: use \033[1mCohomology\033[0m instead\n" );
90    fi;
91
92    return DefectOfExactness( C, i );
93
94end );
95
96##
97InstallMethod( Cohomology,
98        "for a homalg complexes",
99        [ IsHomalgComplex, IsInt ],
100
101  function( C, i )
102
103    if IsComplexOfFinitelyPresentedObjectsRep( C ) then
104        Error( "this is a complex: use \033[1mHomology\033[0m instead\n" );
105    fi;
106
107    return DefectOfExactness( C, i );
108
109end );
110
111##
112InstallMethod( DefectOfExactness,
113        "for a homalg complexes",
114        [ IsComplexOfFinitelyPresentedObjectsRep ],
115
116  function( C )
117    local display, display_string, SimplifyObject, left, degrees, l,
118          morphisms, T, H, i, S;
119
120    if HasIsATwoSequence( C ) and IsATwoSequence( C ) then
121        TryNextMethod( );
122    fi;
123
124    if IsBound( C!.DisplayHomology ) and C!.DisplayHomology = true then
125        display := true;
126    else
127        display := false;
128    fi;
129
130    if IsBound( C!.StringBeforeDisplay ) and IsStringRep( C!.StringBeforeDisplay ) then
131        display_string := C!.StringBeforeDisplay;
132    else
133        display_string := "";
134    fi;
135
136    if IsBound( C!.HomologyOnLessGenerators ) then
137        if C!.HomologyOnLessGenerators = true then
138            SimplifyObject := ValueGlobal( "OnLessGenerators" );
139        elif IsFunction( C!.HomologyOnLessGenerators ) then
140            SimplifyObject := C!.HomologyOnLessGenerators;
141        else
142            SimplifyObject := a -> a;
143        fi;
144    else
145        SimplifyObject := a -> a;
146    fi;
147
148    ## never use the following:
149    #if IsGradedObject( C ) then
150    #    H := C;
151
152    if IsBound(C!.HomologyGradedObject) then
153        H := C!.HomologyGradedObject;
154    fi;
155
156    if IsBound( H ) then
157        SimplifyObject( H );
158
159        if display then
160            for i in ObjectsOfComplex( H ) do
161                Print( display_string );
162                Display( i );
163            od;
164        fi;
165
166        return H;
167    fi;
168
169    if not IsComplex( C ) then
170        Error( "the input is not a complex" );
171    fi;
172
173    left := IsHomalgLeftObjectOrMorphismOfLeftObjects( C );
174
175    degrees := MorphismDegreesOfComplex( C );
176
177    l := Length(degrees);
178
179    morphisms := MorphismsOfComplex( C );
180
181    if not IsBound( C!.SkipLowestDegreeHomology ) then
182        T := Cokernel( morphisms[1] );
183        H := HomalgComplex( T, degrees[1] - 1 );
184    else
185        if left then
186            T := DefectOfExactness( morphisms[2], morphisms[1] );
187        else
188            T := DefectOfExactness( morphisms[1], morphisms[2] );
189        fi;
190        H := HomalgComplex( T, degrees[1] );
191        morphisms := morphisms{[ 2 .. l ]};
192        l := l - 1;
193    fi;
194
195    SimplifyObject( T );
196
197    if display then
198        Print( display_string );
199        Display( T );
200    fi;
201
202    for i in [ 1 .. l - 1 ] do
203        if left then
204            S := DefectOfExactness( morphisms[i + 1], morphisms[i] );
205        else
206            S := DefectOfExactness( morphisms[i], morphisms[i + 1] );
207        fi;
208        Add( H, TheZeroMorphism( S, T ) );
209        T := S;
210
211        SimplifyObject( T );
212
213        if display then
214            Print( display_string );
215            Display( T );
216        fi;
217    od;
218
219    if not ( IsBound( C!.SkipHighestDegreeHomology ) and C!.SkipHighestDegreeHomology = true ) then
220        S := Kernel( morphisms[l] );
221        Add( H, TheZeroMorphism( S, T ) );
222
223        SimplifyObject( S );
224
225        if display then
226            Print( display_string );
227            Display( S );
228        fi;
229    fi;
230
231    SetIsGradedObject( H, true );
232
233    C!.HomologyGradedObject := H;
234
235    return H;
236
237end );
238
239##
240InstallMethod( DefectOfExactness,
241        "for a homalg complexes",
242        [ IsCocomplexOfFinitelyPresentedObjectsRep ],
243
244  function( C )
245    local display, display_string, SimplifyObject, left, degrees, l,
246          morphisms, S, H, i, T;
247
248    if IsBound( C!.DisplayCohomology ) and C!.DisplayCohomology = true then
249        display := true;
250    else
251        display := false;
252    fi;
253
254    if IsBound( C!.CohomologyOnLessGenerators ) then
255        if C!.CohomologyOnLessGenerators = true then
256            SimplifyObject := ValueGlobal( "OnLessGenerators" );
257        elif IsFunction( C!.CohomologyOnLessGenerators ) then
258            SimplifyObject := C!.CohomologyOnLessGenerators;
259        else
260            SimplifyObject := a -> a;
261        fi;
262    else
263        SimplifyObject := a -> a;
264    fi;
265
266    if IsBound( C!.StringBeforeDisplay ) and IsStringRep( C!.StringBeforeDisplay ) then
267        display_string := C!.StringBeforeDisplay;
268    else
269        display_string := "";
270    fi;
271
272    ## never use the following:
273    #if IsGradedObject( C ) then
274    #    H := C;
275
276    if IsBound(C!.CohomologyGradedObject) then
277        H := C!.CohomologyGradedObject;
278    fi;
279
280    if IsBound( H ) then
281        SimplifyObject( H );
282
283        if display then
284            for i in ObjectsOfComplex( H ) do
285                Print( display_string );
286                Display( i );
287            od;
288        fi;
289
290        return H;
291    fi;
292
293    if not IsComplex( C ) then
294        Error( "the input is not a cocomplex" );
295    fi;
296
297    left := IsHomalgLeftObjectOrMorphismOfLeftObjects( C );
298
299    degrees := MorphismDegreesOfComplex( C );
300
301    l := Length(degrees);
302
303    morphisms := MorphismsOfComplex( C );
304
305    if not IsBound( C!.SkipLowestDegreeCohomology ) then
306        S := Kernel( morphisms[1] );
307        H := HomalgCocomplex( S, degrees[1] );
308    else
309        if left then
310            S := DefectOfExactness( morphisms[1], morphisms[2] );
311        else
312            S := DefectOfExactness( morphisms[2], morphisms[1] );
313        fi;
314        H := HomalgCocomplex( S, degrees[1] + 1 );
315        morphisms := morphisms{[ 2 .. l ]};
316        l := l - 1;
317    fi;
318
319    SimplifyObject( S );
320
321    if display then
322        Print( display_string );
323        Display( S );
324    fi;
325
326    for i in [ 1 .. l - 1 ] do
327        if left then
328            T := DefectOfExactness( morphisms[i], morphisms[i + 1] );
329        else
330            T := DefectOfExactness( morphisms[i + 1], morphisms[i] );
331        fi;
332        Add( H, TheZeroMorphism( S, T ) );
333        S := T;
334
335        SimplifyObject( S );
336
337        if display then
338            Print( display_string );
339            Display( S );
340        fi;
341    od;
342
343    if not ( IsBound( C!.SkipHighestDegreeCohomology ) and C!.SkipHighestDegreeCohomology = true ) then
344        T := Cokernel( morphisms[l] );
345        Add( H, TheZeroMorphism( S, T ) );
346
347        SimplifyObject( T );
348
349        if display then
350            Print( display_string );
351            Display( T );
352        fi;
353    fi;
354
355    SetIsGradedObject( H, true );
356
357    C!.CohomologyGradedObject := H;
358
359    return H;
360
361end );
362
363##
364InstallMethod( Homology,			### defines: Homology (HomologyModules)
365        "for a homalg complexes",
366        [ IsHomalgComplex ],
367
368  function( C )
369
370    if IsCocomplexOfFinitelyPresentedObjectsRep( C ) then
371        Error( "this is a cocomplex: use \033[1mCohomology\033[0m instead\n" );
372    fi;
373
374    return DefectOfExactness( C );
375
376end );
377
378##
379InstallMethod( Cohomology,			### defines: Cohomology (CohomologyModules)
380        "for a homalg complexes",
381        [ IsHomalgComplex ],
382
383  function( C )
384
385    if IsComplexOfFinitelyPresentedObjectsRep( C ) then
386        Error( "this is a complex: use \033[1mHomology\033[0m instead\n" );
387    fi;
388
389    return DefectOfExactness( C );
390
391end );
392
393InstallMethod( HorseShoeResolution,
394        "for homalg complexes",
395        [ IsList, IsHomalgChainMorphism, IsHomalgChainMorphism, IsHomalgMorphism ],
396
397  function( l, d_phi, d_psi, dEj2 )
398  local dEj, dN, dE, dM, psi, phi, j, dMj, dNj, mu, SyzygiesObjectEmb_j_M, SyzygiesObjectEmb_j_N, epsilonM, epsilonN, epsilon_j, Pj;
399
400    dEj := dEj2;
401
402    dN := Source( d_phi );
403    dE := Range( d_phi );
404    dM := Range( d_psi );
405
406    if IsComplexOfFinitelyPresentedObjectsRep( dN ) then
407        psi := CertainMorphism( d_psi, l[1] - 1 );
408        phi := CertainMorphism( d_phi, l[1] - 1 );
409    else
410        psi := CertainMorphism( d_psi, l[1] + 1 );
411        phi := CertainMorphism( d_phi, l[1] + 1 );
412    fi;
413
414    if not IsIdenticalObj( dE, Source( d_psi ) ) then
415        Error( "expected a two composable chain morphisms" );
416    fi;
417
418    for j in l do
419
420        mu := KernelEmb( dEj );
421
422        dMj := CertainMorphism( dM, j );
423        dNj := CertainMorphism( dN, j );
424
425        SyzygiesObjectEmb_j_M := ImageObjectEmb( dMj );
426        SyzygiesObjectEmb_j_N := ImageObjectEmb( dNj );
427
428        psi := CompleteImageSquare( mu, psi, SyzygiesObjectEmb_j_M );
429        phi := CompleteImageSquare( SyzygiesObjectEmb_j_N, phi, mu );
430
431        # The HorseShoeResolution produces short exact sequences in each degree
432        Assert( 4, IsMorphism( phi ) );
433        SetIsMorphism( phi, true );
434        Assert( 4, IsMonomorphism( phi ) );
435        SetIsMonomorphism( phi, true );
436
437        Assert( 4, IsMorphism( psi ) );
438        SetIsMorphism( psi, true );
439        Assert( 4, IsEpimorphism( psi ) );
440        SetIsEpimorphism( psi, true );
441
442        SetKernelEmb( psi, phi );
443        SetCokernelEpi( phi, psi );
444
445        # if certain objects are known to be zero, the remaining morphism is an isomorphism
446        if HasIsZero( Source( phi ) ) then
447            Assert( 4, IsMorphism( psi ) );
448            SetIsMorphism( psi, true );
449            Assert( 4, IsMonomorphism( psi ) = IsZero( Source( phi ) ) );
450            SetIsMonomorphism( psi, IsZero( Source( phi ) ) );
451        fi;
452        if HasIsZero( Range( psi ) ) then
453            Assert( 4, IsMorphism( phi ) );
454            SetIsMorphism( phi, true );
455            Assert( 4, IsEpimorphism( phi ) = IsZero( Range( psi ) ) );
456            SetIsEpimorphism( phi, IsZero( Range( psi ) ) );
457        fi;
458
459        epsilonM := ImageObjectEpi( dMj );
460        epsilonN := ImageObjectEpi( dNj );
461
462        epsilonM := epsilonM / psi; ## projective lift or something similar
463        epsilonN := PreCompose( epsilonN, phi );
464
465        epsilon_j := CoproductMorphism( epsilonN, epsilonM );
466
467        Pj := Source( epsilon_j );
468
469        dEj := PreCompose( epsilon_j, mu );
470
471        psi := EpiOnRightFactor( Pj );
472        phi := MonoOfLeftSummand( Pj );
473
474        if IsComplexOfFinitelyPresentedObjectsRep( dN ) then
475            Add( dE, dEj );
476            Add( d_psi, psi );
477            Add( d_phi, phi );
478        else
479            Add( dEj, dE );
480            Add( psi, d_psi );
481            Add( phi, d_phi );
482        fi;
483
484    od;
485
486    ## check assertions
487    Assert( 4, IsMorphism( d_psi ) );
488    Assert( 4, IsMorphism( d_phi ) );
489
490end );
491
492## 0 <-- M <-(psi)- E <-(phi)- N <-- 0
493## or
494## 0 --> N -(phi)-> E -(psi)-> M --> 0
495InstallMethod( Resolution,	### defines: Resolution (generalizes ResolveShortExactSeq)
496        "for homalg complexes",
497        [ IsInt, IsHomalgComplex and IsShortExactSequence ],
498
499  function( _q, C )
500    local q, degrees, psi, phi, M, E, N, dM, dN, j,
501          index_pair_psi, index_pair_phi, epsilonN, epsilonM, epsilon,
502          dj, SetEpi, Pj, dE, d_psi, d_phi, horse_shoe, mu, epsilon_j;
503
504    q := _q;
505
506    if q = 0 then q := 1; fi;
507
508    degrees := ObjectDegreesOfComplex( C );
509
510    if IsComplexOfFinitelyPresentedObjectsRep( C ) then
511        psi := CertainMorphism( C, degrees[2] );
512        phi := CertainMorphism( C, degrees[3] );
513    else
514        phi := CertainMorphism( C, degrees[1] );
515        psi := CertainMorphism( C, degrees[2] );
516    fi;
517
518    M := Range( psi );
519    E := Source( psi );
520    N := Source( phi );
521
522    # For a category not having enough projectives, we need to resolve M
523    # with a resolution adapted to the morphism psi, such that the PostDivide
524    # used below works.
525    # For example for the category of coherent sheaves on projective space
526    # we compute a locally free resolution of M, where the zeroth object of
527    # the resolution is build the way such that "epsilonM/psi" works.
528    dM := ResolutionWithRespectToMorphism( q, M, psi );
529    dN := Resolution( q, N );
530
531    if q < 0 then
532        q := Maximum( List( [ M, N ], LengthOfResolution ) );
533        dM := ResolutionWithRespectToMorphism( q, M, psi );
534        dN := Resolution( q, N );
535    fi;
536
537    LockObjectOnCertainPresentation( N );
538    LockObjectOnCertainPresentation( E );
539    LockObjectOnCertainPresentation( M );
540
541    index_pair_psi := PairOfPositionsOfTheDefaultPresentations( psi );
542    index_pair_phi := PairOfPositionsOfTheDefaultPresentations( phi );
543
544    if IsBound( C!.resolutions ) and
545       IsBound( C!.resolutions.(String( [ index_pair_psi, index_pair_phi ] )) ) then
546
547        horse_shoe := C!.resolutions.(String( [ index_pair_psi, index_pair_phi ] ));
548
549        if IsComplexOfFinitelyPresentedObjectsRep( C ) then
550            d_psi := CertainMorphism( horse_shoe, degrees[2] );
551            d_phi := CertainMorphism( horse_shoe, degrees[3] );
552        else
553            d_psi := CertainMorphism( horse_shoe, degrees[1] );
554            d_phi := CertainMorphism( horse_shoe, degrees[2] );
555        fi;
556
557        j := HighestDegree( d_psi );
558
559        if j <> HighestDegree( d_phi ) then
560            Error( "the highest degrees of the two chain morphisms in the horse shoe do not coincide\n" );
561        fi;
562
563        psi := CertainMorphism( d_psi, j );
564        phi := CertainMorphism( d_phi, j );
565
566        dE := Source( d_psi );
567
568        dj := CertainMorphism( dE, j );
569
570        SetEpi := false;
571
572    else
573
574        j := 0;
575
576        epsilonM := CokernelEpi( LowestDegreeMorphism( dM ) );
577        epsilonN := CokernelEpi( LowestDegreeMorphism( dN ) );
578
579        epsilonM := epsilonM / psi; ## projective lift or something similar
580        epsilonN := PreCompose( epsilonN, phi );
581
582        dj := CoproductMorphism( epsilonN, epsilonM );
583
584        Assert( 4, IsMorphism( dj ) );
585        SetIsMorphism( dj, true );
586        Assert( 4, IsEpimorphism( dj ) );
587        SetIsEpimorphism( dj, true );
588
589        Pj := Source( dj );
590
591        dE := HomalgComplex( Pj );
592
593        psi := EpiOnRightFactor( Pj );
594        phi := MonoOfLeftSummand( Pj );
595
596        d_psi := HomalgChainMorphism( psi, dE, dM );
597        d_phi := HomalgChainMorphism( phi, dN, dE );
598
599        if IsComplexOfFinitelyPresentedObjectsRep( C ) then
600            horse_shoe := HomalgComplex( d_psi, degrees[2] );
601            Add( horse_shoe, d_phi );
602        else
603            horse_shoe := HomalgCocomplex( d_phi, degrees[1] );
604            Add( horse_shoe, d_psi );
605        fi;
606
607        C!.resolutions := rec( );
608        C!.resolutions.(String( [ index_pair_psi, index_pair_phi ] )) := horse_shoe;
609
610        SetEpi := true;
611
612    fi;
613
614    # up to now, only the horse shoe has been created
615    # now we fill the interior
616    # (if there is anything to fill)
617    if j + 1 <= q then
618        HorseShoeResolution( [ j + 1 .. q ] , d_phi, d_psi, dj );
619    fi;
620
621    if SetEpi and MorphismDegreesOfComplex( dE ) <> [] then
622        SetCokernelEpi( LowestDegreeMorphism( dE ), dj );
623    fi;
624
625    Assert( 5, IsMorphism( d_psi ) );
626    SetIsMorphism( d_psi, true );
627    SetIsEpimorphism( d_psi, true );
628
629    Assert( 5, IsMorphism( d_phi ) );
630    SetIsMorphism( d_phi, true );
631    SetIsMonomorphism( d_phi, true );
632
633    SetIsRightAcyclic( dE, true );
634    SetIsShortExactSequence( horse_shoe, true );
635
636    UnlockObject( N );
637    UnlockObject( E );
638    UnlockObject( M );
639
640    return horse_shoe;
641
642end );
643
644##
645InstallMethod( Resolution,
646        "for homalg complexes",
647        [ IsHomalgComplex ],
648
649  function( C )
650
651    return Resolution( -1, C );
652
653end );
654
655##
656InstallMethod( CompleteComplexByResolution,
657        "for homalg complexes",
658        [ IsInt, IsComplexOfFinitelyPresentedObjectsRep ],
659
660  function( q, C )
661    local zero, cpx, seq, mor, emb, ker, P, epi, i;
662
663    if q = infinity then
664        ## FIXME: should become obsolete
665        q := -1;
666    elif q = 0 then
667        return C;
668    fi;
669
670    if HasIsZero( C ) then
671        zero := IsZero( C );
672    fi;
673
674    if HasIsComplex( C ) then
675        cpx := IsComplex( C );
676    fi;
677
678    if HasIsSequence( C ) then
679        seq := IsSequence( C );
680    fi;
681
682    mor := HighestDegreeMorphism( C );
683
684    emb := KernelEmb( mor );
685
686    ker := Source( emb );
687
688    epi := CoveringEpi( ker );
689
690    Add( C, PreCompose( epi, emb ) );
691
692    if q > 1 then
693
694        P := Resolution( q - 1, ker );
695
696        for i in [ 1 .. HighestDegree( P ) ] do
697            Add( C, CertainMorphism( P, i ) );
698        od;
699
700    fi;
701
702    if IsBound( zero ) then
703        SetIsZero( C, zero );
704    fi;
705
706    if IsBound( cpx ) then
707        SetIsComplex( C, cpx );
708    fi;
709
710    if IsBound( seq ) then
711        SetIsSequence( C, seq );
712    fi;
713
714    return C;
715
716end );
717
718##
719InstallMethod( CompleteComplexByResolution,
720        "for homalg complexes",
721        [ IsInt, IsCocomplexOfFinitelyPresentedObjectsRep ],
722
723  function( q, C )
724    local zero, cpx, seq, mor, emb, ker, P, epi, i;
725
726    if q = infinity then
727        ## FIXME: should become obsolete
728        q := -1;
729    elif q = 0 then
730        return C;
731    fi;
732
733    if HasIsZero( C ) then
734        zero := IsZero( C );
735    fi;
736
737    if HasIsComplex( C ) then
738        cpx := IsComplex( C );
739    fi;
740
741    if HasIsSequence( C ) then
742        seq := IsSequence( C );
743    fi;
744
745    mor := LowestDegreeMorphism( C );
746
747    emb := KernelEmb( mor );
748
749    ker := Source( emb );
750
751    epi := CoveringEpi( ker );
752
753    Add( PreCompose( epi, emb ), C );
754
755    if q > 1 then
756
757        P := Resolution( q - 1, ker );
758
759        for i in [ 1 .. HighestDegree( P ) ] do
760            Add( CertainMorphism( P, i ), C );
761        od;
762
763    fi;
764
765    if IsBound( zero ) then
766        SetIsZero( C, zero );
767    fi;
768
769    if IsBound( cpx ) then
770        SetIsComplex( C, cpx );
771    fi;
772
773    if IsBound( seq ) then
774        SetIsSequence( C, seq );
775    fi;
776
777    return C;
778
779end );
780
781##
782InstallMethod( CompleteComplexByResolution,
783        "for homalg complexes",
784        [ IsHomalgComplex ],
785
786  function( C )
787
788    return CompleteComplexByResolution( infinity, C );
789
790end );
791
792#=======================================================================
793# Connecting homomorphism
794#
795#                         0
796#                         |
797#                         |
798#                         |
799#                         v
800#  0 <--- Hs[n-1] <--- Zs[n-1] <--(bs[n])-- Cs[n]/Bs[n] <--- Hs[n] <--- 0
801#            |            |                      |             |
802#            |         (i[n-1])                (i[n])          |
803#            |            |                      |             |
804#            v            v                      v             v
805#  0 <--- H[n-1]  <--- Z[n-1]  <--(b[n])---  C[n]/B[n]  <--- H[n]  <--- 0
806#            |            |                      |             |
807#            |         (j[n-1])                (j[n])          |
808#            |            |                      |             |
809#            v            v                      v             v
810#  0 <--- Hq[n-1] <--- Zq[n-1] <--(bq[n])-- Cq[n]/Bq[n] <--- Hq[n] <--- 0
811#                                                |
812#                                                |
813#                                                |
814#                                                v
815#                                                0
816#
817#_______________________________________________________________________
818InstallMethod( ConnectingHomomorphism,
819        "for homalg complexes",
820        [ IsStaticFinitelyPresentedObjectRep,
821          IsStaticMorphismOfFinitelyGeneratedObjectsRep,
822          IsStaticMorphismOfFinitelyGeneratedObjectsRep,
823          IsStaticMorphismOfFinitelyGeneratedObjectsRep,
824          IsStaticFinitelyPresentedObjectRep ],
825
826  function( Hqn, jn, bn, in_1, Hsn_1 )
827    local iota_Hqn, iota_Hsn_1, snake;
828
829    iota_Hqn := NaturalGeneralizedEmbedding( Hqn );
830    iota_Hsn_1 := NaturalGeneralizedEmbedding( Hsn_1 );
831
832    snake := iota_Hqn;
833    snake := snake / jn;
834    snake := PreCompose( snake, bn );	## the connecting homomorphism is what b[n] induces between certain subfactors of C[n] and C[n-1]
835    snake := snake / in_1;		## lift
836    snake := snake / iota_Hsn_1;	## lift
837
838    ## check assertion
839    Assert( 3, IsMorphism( snake ) );
840
841    SetIsMorphism( snake, true );
842
843    return snake;
844
845end );
846
847##
848InstallMethod( ConnectingHomomorphism,
849        "for short exact sequences of complexes",
850        [ IsComplexOfFinitelyPresentedObjectsRep and IsShortExactSequence, IsInt ],
851
852  function( E, n )
853    local j, i, Cq, C, Cs, Hqn, jn, bn, in_1, Hsn_1;
854
855    j := LowestDegreeMorphism( E );
856    i := HighestDegreeMorphism( E );
857
858    Cq := Range( j );
859    C := Source( j );
860    Cs := Source( i );
861
862    Hqn := DefectOfExactness( Cq, n );
863    jn := CertainMorphism( j, n );
864    bn := CertainMorphism( C, n );
865    in_1 := CertainMorphism( i, n - 1 );
866    Hsn_1 := DefectOfExactness( Cs, n - 1 );
867
868    return ConnectingHomomorphism( Hqn, jn, bn, in_1, Hsn_1 );
869
870end );
871
872##
873InstallMethod( ConnectingHomomorphism,
874        "for short exact sequences of complexes",
875        [ IsCocomplexOfFinitelyPresentedObjectsRep and IsShortExactSequence, IsInt ],
876
877  function( E, n )
878    local i, j, Cs, C, Cq, Hqn, jn, bn, inp1, Hsnp1;
879
880    i := LowestDegreeMorphism( E );
881    j := HighestDegreeMorphism( E );
882
883    Cs := Source( i );
884    C := Range( i );
885    Cq := Range( j );
886
887    Hqn := DefectOfExactness( Cq, n );
888    jn := CertainMorphism( j, n );
889    bn := CertainMorphism( C, n );
890    inp1 := CertainMorphism( i, n + 1 );
891    Hsnp1 := DefectOfExactness( Cs, n + 1 );
892
893    return ConnectingHomomorphism( Hqn, jn, bn, inp1, Hsnp1 );
894
895end );
896
897##
898InstallMethod( ConnectingHomomorphism,
899        "for short exact sequences of complexes",
900        [ IsComplexOfFinitelyPresentedObjectsRep and IsShortExactSequence ],
901
902  function( E )
903    local degrees, l, S, T, con, n;
904
905    degrees := DegreesOfChainMorphism( LowestDegreeMorphism( E ) );
906
907    l := Length( degrees );
908
909    if l < 2 then
910        Error( "complex too small\n" );
911    fi;
912
913    S := DefectOfExactness( LowestDegreeObject( E ) );
914    T := DefectOfExactness( HighestDegreeObject( E ) );
915
916    n := degrees[2];
917
918    con := HomalgChainMorphism( ConnectingHomomorphism( E, n ), S, T, [ n, -1 ] );
919
920    for n in degrees{[ 3 .. l ]} do
921        Add( con, ConnectingHomomorphism( E, n ) );
922    od;
923
924    SetIsGradedMorphism( con, true );
925
926    return con;
927
928end );
929
930##
931InstallMethod( ConnectingHomomorphism,
932        "for short exact sequences of complexes",
933        [ IsCocomplexOfFinitelyPresentedObjectsRep and IsShortExactSequence ],
934
935  function( E )
936    local degrees, l, S, T, con, n;
937
938    degrees := DegreesOfChainMorphism( HighestDegreeMorphism( E ) );
939
940    l := Length( degrees );
941
942    if l < 2 then
943        Error( "cocomplex too small\n" );
944    fi;
945
946    S := DefectOfExactness( HighestDegreeObject( E ) );
947    T := DefectOfExactness( LowestDegreeObject( E ) );
948
949    n := degrees[1];
950
951    con := HomalgChainMorphism( ConnectingHomomorphism( E, n ), S, T, [ n, 1 ] );
952
953    for n in degrees{[ 2 .. l - 1 ]} do
954        Add( con, ConnectingHomomorphism( E, n ) );
955    od;
956
957    SetIsGradedMorphism( con, true );
958
959    return con;
960
961end );
962
963##
964InstallMethod( ExactTriangle,
965        "for short exact sequences of complexes",
966        [ IsComplexOfFinitelyPresentedObjectsRep and IsShortExactSequence ],
967
968  function( E )
969    local deg, j, i, con, triangle;
970
971    deg := LowestDegree( E ) + 1;
972
973    j := DefectOfExactness( LowestDegreeMorphism( E ) );
974    i := DefectOfExactness( HighestDegreeMorphism( E ) );
975    con := ConnectingHomomorphism( E );
976
977    triangle := HomalgComplex( j, deg );
978    Add( triangle, i );
979    Add( triangle, con );
980
981    SetIsExactTriangle( triangle, true );
982
983    return triangle;
984
985end );
986
987##
988InstallMethod( ExactTriangle,
989        "for short exact sequences of complexes",
990        [ IsCocomplexOfFinitelyPresentedObjectsRep and IsShortExactSequence ],
991
992  function( E )
993    local deg, j, i, con, triangle;
994
995    deg := LowestDegree( E );
996
997    i := DefectOfExactness( LowestDegreeMorphism( E ) );
998    j := DefectOfExactness( HighestDegreeMorphism( E ) );
999    con := ConnectingHomomorphism( E );
1000
1001    triangle := HomalgCocomplex( i, deg );
1002    Add( triangle, j );
1003    Add( triangle, con );
1004
1005    SetIsExactTriangle( triangle, true );
1006
1007    return triangle;
1008
1009end );
1010
1011## [HS. Proof of Lemma. VIII.9.4]
1012InstallMethod( DefectOfExactnessSequence,
1013        "for homalg two-morphisms complexes",
1014        [ IsHomalgComplex and IsATwoSequence ],
1015
1016  function( cpx_post_pre )
1017    local pre, post, F_Z, F_B, Z_B, H, F_H, H_Z, C;
1018
1019    pre := HighestDegreeMorphism( cpx_post_pre );
1020    post := LowestDegreeMorphism( cpx_post_pre );
1021
1022    ## read: F <- Z
1023    F_Z := KernelEmb( post );
1024
1025    ## read: F <- B
1026    F_B := ImageObjectEmb( pre );
1027
1028    ## read: Z <- B
1029    Z_B := F_B / F_Z;	## lift
1030
1031    H := DefectOfExactness( cpx_post_pre );
1032
1033    ## read: F <- H
1034    F_H := NaturalGeneralizedEmbedding( H );
1035
1036    ## read: H <- Z
1037    H_Z := F_Z / F_H;	## generalized lift
1038
1039    C := HomalgComplex( H_Z );
1040
1041    Add( C, Z_B );
1042
1043    SetIsShortExactSequence( C, true );
1044
1045    ## read: H <- Z <- B, (H := Z/B)
1046    return C;
1047
1048end );
1049
1050## for convenience
1051InstallMethod( DefectOfExactnessSequence,
1052        "for composable homalg morphisms",
1053        [ IsStaticMorphismOfFinitelyGeneratedObjectsRep,
1054          IsStaticMorphismOfFinitelyGeneratedObjectsRep ],
1055
1056  function( phi, psi )
1057
1058    return DefectOfExactnessSequence( AsATwoSequence( phi, psi ) );
1059
1060end );
1061
1062## [HS. Proof of Lemma. VIII.9.4]
1063InstallMethod( DefectOfExactnessCosequence,
1064        "for homalg two-morphisms complexes",
1065        [ IsHomalgComplex and IsATwoSequence ],
1066
1067  function( cpx_post_pre )
1068    local pre, post, Z_F, B_F, B_Z, H, H_F, Z_H, C;
1069
1070    pre := HighestDegreeMorphism( cpx_post_pre );
1071    post := LowestDegreeMorphism( cpx_post_pre );
1072
1073    ## read: Z -> F
1074    Z_F := KernelEmb( post );
1075
1076    ## read: B -> F
1077    B_F := ImageObjectEmb( pre );
1078
1079    ## read: B -> Z
1080    B_Z := B_F / Z_F;	## lift
1081
1082    H := DefectOfExactness( cpx_post_pre );
1083
1084    ## read: H -> F
1085    H_F := NaturalGeneralizedEmbedding( H );
1086
1087    ## read: Z -> H
1088    Z_H := Z_F / H_F;	## generalized lift
1089
1090    C := HomalgCocomplex( B_Z );
1091
1092    Add( C, Z_H );
1093
1094    SetIsShortExactSequence( C, true );
1095
1096    ## read: B -> Z -> H, (H := Z/B)
1097    return C;
1098
1099end );
1100
1101## for convenience
1102InstallMethod( DefectOfExactnessCosequence,
1103        "for homalg composable maps",
1104        [ IsStaticMorphismOfFinitelyGeneratedObjectsRep,
1105          IsStaticMorphismOfFinitelyGeneratedObjectsRep ],
1106
1107  function( phi, psi )
1108
1109    return DefectOfExactnessCosequence( AsATwoSequence( phi, psi ) );
1110
1111end );
1112
1113## the Cartan-Eilenberg resolution [HS. Lemma VIII.9.4]
1114InstallMethod( Resolution,	### defines: Resolution
1115        "for homalg complexes",
1116        [ IsInt, IsComplexOfFinitelyPresentedObjectsRep ],
1117
1118  function( _q, C )
1119    local q, degrees, l, def, d, mor, index_pairs, QFB, FB, CE, natural_epis,
1120          HZB, Z, ZB, PZ, relZ, BFZ, BF, i, FZ;
1121
1122    if not IsComplex( C ) then
1123        Error( "the second argument is not a complex\n" );
1124    fi;
1125
1126    # Do the HorseShoeResolution in that case
1127    if HasIsShortExactSequence( C ) and IsShortExactSequence( C ) then
1128        TryNextMethod( );
1129    fi;
1130
1131    q := _q;
1132
1133    degrees := ObjectDegreesOfComplex( C );
1134
1135    l := Length( degrees ) - 1;
1136
1137    def := ObjectsOfComplex( DefectOfExactness( C ) );
1138
1139    if l = 0 then
1140        return HomalgComplex( Resolution( q, def[1] ), degrees[1] );
1141    fi;
1142
1143    d := List( def, M -> Resolution( q, M ) );
1144
1145    if q < 0 then
1146        q := Maximum( List( def, LengthOfResolution ) );
1147        d := List( def, M -> Resolution( q, M ) );
1148    fi;
1149
1150    mor := MorphismsOfComplex( C );
1151
1152    index_pairs := List( mor, PairOfPositionsOfTheDefaultPresentations );
1153
1154    ## F/B = Q <- F <- B (horse shoe)
1155    QFB := Resolution( q, CokernelSequence( mor[1] ) );
1156
1157    ## F <- B
1158    FB := HighestDegreeMorphism( QFB );
1159
1160    ## F
1161    CE := HomalgComplex( Range( FB ), degrees[1] );
1162
1163    ## enrich CE with the natrual epis
1164    natural_epis := rec( );
1165
1166    CE!.NaturalEpis := natural_epis;
1167
1168    natural_epis.(String( [ 0, 0 ] )) := CokernelEpi( LowestDegreeMorphism( Range( FB ) ) );
1169
1170    if l > 1 then
1171        if IsHomalgLeftObjectOrMorphismOfLeftObjects( C ) then
1172            ## Z/B =: H <- Z <- B
1173            HZB := DefectOfExactnessSequence( mor[2], mor[1] );
1174
1175            ## Z <- B
1176            ZB := HighestDegreeMorphism( HZB );
1177
1178            Z := Range( ZB );
1179
1180            ## horse shoe
1181            HZB := Resolution( q, HZB );
1182
1183            ## Z <- B
1184            ZB := HighestDegreeMorphism( HZB );
1185
1186            ## the horse shoe resolution of Z
1187            PZ := Range( ZB );
1188
1189            ## make this horse shoe resolution of Z the standard one
1190            SetCurrentResolution( Z, PZ );
1191
1192            ## B <- F <- Z (horse shoe)
1193            BFZ := Resolution( q, KernelSequence( mor[1] ) );
1194
1195            ## B <- F
1196            BF := LowestDegreeMorphism( BFZ );
1197
1198            ## enrich CE with the natrual epi
1199            natural_epis.(String( [ 1, 0 ] )) := CokernelEpi( LowestDegreeMorphism( Source( BF ) ) );
1200
1201            ## F[i] <- F[i+1]
1202            Add( CE, BF * FB );
1203
1204            ## F <- Z
1205            FZ := HighestDegreeMorphism( BFZ );
1206        else
1207            ## Z/B =: H <- Z <- B
1208            HZB := DefectOfExactnessSequence( mor[1], mor[2] );
1209
1210            ## Z <- B
1211            ZB := HighestDegreeMorphism( HZB );
1212
1213            Z := Range( ZB );
1214
1215            ## horse shoe
1216            HZB := Resolution( q, HZB );
1217
1218            ## Z <- B
1219            ZB := HighestDegreeMorphism( HZB );
1220
1221            ## the horse shoe resolution of Z
1222            PZ := Range( ZB );
1223
1224            ## make this horse shoe resolution of Z the standard one
1225            SetCurrentResolution( Z, PZ );
1226
1227            ## B <- F <- Z (horse shoe)
1228            BFZ := Resolution( q, KernelSequence( mor[1] ) );
1229
1230            ## B <- F
1231            BF := LowestDegreeMorphism( BFZ );
1232
1233            ## enrich CE with the natrual epi
1234            natural_epis.(String( [ 1, 0 ] )) := CokernelEpi( LowestDegreeMorphism( Source( BF ) ) );
1235
1236            ## F[i] <- F[i+1]
1237            Add( CE, FB * BF );
1238
1239            ## F <- Z
1240            FZ := HighestDegreeMorphism( BFZ );
1241        fi;
1242    fi;
1243
1244    if IsHomalgLeftObjectOrMorphismOfLeftObjects( C ) then
1245        for i in [ 3 .. l ] do
1246            ## Z/B =: H <- Z <- B
1247            HZB := DefectOfExactnessSequence( mor[i], mor[i-1] );
1248
1249            Z := Range( HighestDegreeMorphism( HZB ) );
1250
1251            ## horse shoe
1252            HZB := Resolution( q, HZB );
1253
1254            ## the horse shoe resolution of Z
1255            PZ := Range( HighestDegreeMorphism( HZB ) );
1256
1257            ## make this horse shoe resolution of Z the standard one
1258            SetCurrentResolution( Z, PZ );
1259
1260            ## B <- F <- Z (horse shoe)
1261            BFZ := Resolution( q, KernelSequence( mor[i-1] ) );
1262
1263            ## B <- F
1264            BF := LowestDegreeMorphism( BFZ );
1265
1266            ## enrich CE with the natrual epi
1267            natural_epis.(String( [ i - 1, 0 ] )) := CokernelEpi( LowestDegreeMorphism( Source( BF ) ) );
1268
1269            ## F[i] <- F[i+1]
1270            Add( CE, BF * ZB * FZ );
1271
1272            ## Z <- B
1273            ZB := HighestDegreeMorphism( HZB );
1274
1275            ## F <- Z
1276            FZ := HighestDegreeMorphism( BFZ );
1277        od;
1278    else
1279        for i in [ 3 .. l ] do
1280            ## Z/B =: H <- Z <- B
1281            HZB := DefectOfExactnessSequence( mor[i-1], mor[i] );
1282
1283            Z := Range( HighestDegreeMorphism( HZB ) );
1284
1285            ## horse shoe
1286            HZB := Resolution( q, HZB );
1287
1288            ## the horse shoe resolution of Z
1289            PZ := Range( HighestDegreeMorphism( HZB ) );
1290
1291            ## make this horse shoe resolution of Z the standard one
1292            SetCurrentResolution( Z, PZ );
1293
1294            ## B <- F <- Z (horse shoe)
1295            BFZ := Resolution( q, KernelSequence( mor[i-1] ) );
1296
1297            ## B <- F
1298            BF := LowestDegreeMorphism( BFZ );
1299
1300            ## enrich CE with the natrual epi
1301            natural_epis.(String( [ i - 1, 0 ] )) := CokernelEpi( LowestDegreeMorphism( Source( BF ) ) );
1302
1303            ## F[i] <- F[i+1]
1304            Add( CE, FZ * ZB * BF );
1305
1306            ## Z <- B
1307            ZB := HighestDegreeMorphism( HZB );
1308
1309            ## F <- Z
1310            FZ := HighestDegreeMorphism( BFZ );
1311        od;
1312    fi;
1313
1314    ## B <- F <- Z
1315    BFZ := Resolution( q, KernelSequence( mor[l] ) );
1316
1317    BF := LowestDegreeMorphism( BFZ );
1318
1319    ## enrich CE with the natrual epi
1320    natural_epis.(String( [ l, 0 ] )) := CokernelEpi( LowestDegreeMorphism( Source( BF ) ) );
1321
1322    if l > 1 then
1323        if IsHomalgLeftObjectOrMorphismOfLeftObjects( C ) then
1324            Add( CE, BF * ZB * FZ );
1325        else
1326            Add( CE, FZ * ZB * BF );
1327        fi;
1328    else
1329        if IsHomalgLeftObjectOrMorphismOfLeftObjects( C ) then
1330            Add( CE, BF * FB );
1331        else
1332            Add( CE, FB * BF );
1333        fi;
1334    fi;
1335
1336    if HasIsExactSequence( C ) and IsExactSequence( C ) then
1337        SetIsExactSequence( CE, true );
1338    elif HasIsRightAcyclic( C ) and IsRightAcyclic( C ) then
1339        SetIsRightAcyclic( CE, true );
1340    elif HasIsLeftAcyclic( C ) and IsLeftAcyclic( C ) then
1341        SetIsLeftAcyclic( CE, true );
1342    elif HasIsAcyclic( C ) and IsAcyclic( C ) then
1343        SetIsAcyclic( CE, true );
1344    else
1345        SetIsComplex( CE, true );
1346    fi;
1347
1348    ## the Cartan-Eilenberg resolution:
1349    return CE;
1350
1351end );
1352
1353## the Cartan-Eilenberg resolution [HS. Lemma VIII.9.4]
1354InstallMethod( Resolution,	### defines: Resolution
1355        "for homalg complexes",
1356        [ IsInt, IsCocomplexOfFinitelyPresentedObjectsRep ],
1357
1358  function( _q, C )
1359    local q, degrees, l, def, d, mor, index_pairs, ZFB, FB, CE, natural_epis,
1360          i, BZH, Z, PZ, relZ, BZ, ZF, BFQ, BF;
1361
1362    if not IsComplex( C ) then
1363        Error( "the second argument is not a cocomplex\n" );
1364    fi;
1365
1366    # Do the HorseShoeResolution in that case
1367    if HasIsShortExactSequence( C ) and IsShortExactSequence( C ) then
1368        TryNextMethod( );
1369    fi;
1370
1371    q := _q;
1372
1373    degrees := ObjectDegreesOfComplex( C );
1374
1375    l := Length( degrees ) - 1;
1376
1377    def := ObjectsOfComplex( DefectOfExactness( C ) );
1378
1379    if l = 0 then
1380        return HomalgCocomplex( Resolution( q, def[1] ), degrees[1] );
1381    fi;
1382
1383    d := List( def, M -> Resolution( q, M ) );
1384
1385    if q < 0 then
1386        q := Maximum( List( def, LengthOfResolution ) );
1387        d := List( def, M -> Resolution( q, M ) );
1388    fi;
1389
1390    mor := MorphismsOfComplex( C );
1391
1392    index_pairs := List( mor, PairOfPositionsOfTheDefaultPresentations );
1393
1394    ## Z -> F -> B (horse shoe)
1395    ZFB := Resolution( q, KernelCosequence( mor[1] ) );
1396
1397    ## F -> B
1398    FB := HighestDegreeMorphism( ZFB );
1399
1400    ## F
1401    CE := HomalgCocomplex( Source( FB ), degrees[1] );
1402
1403    ## enrich CE with the natrual epis
1404    natural_epis := rec( );
1405
1406    CE!.NaturalEpis := natural_epis;
1407
1408    natural_epis.(String( [ 0, 0 ] )) := CokernelEpi( LowestDegreeMorphism( Source( FB ) ) );
1409
1410    for i in [ 2 .. l ] do
1411
1412        if IsHomalgLeftObjectOrMorphismOfLeftObjects( C ) then
1413            ## B -> Z -> H := Z/B
1414            BZH := DefectOfExactnessCosequence( mor[i-1], mor[i] );
1415        else
1416            ## B -> Z -> H := Z/B
1417            BZH := DefectOfExactnessCosequence( mor[i], mor[i-1] );
1418        fi;
1419
1420        ## B -> Z
1421        BZ := LowestDegreeMorphism( BZH );
1422
1423        Z := Range( BZ );
1424
1425        ## horse shoe
1426        BZH := Resolution( q, BZH );
1427
1428        ## B -> Z
1429        BZ := LowestDegreeMorphism( BZH );
1430
1431        ## the horse shoe resolution of Z
1432        PZ := Range( BZ );
1433
1434        ## make this horse shoe resolution of Z the standard one
1435        SetCurrentResolution( Z, PZ );
1436
1437        ## Z -> F -> B (horse shoe)
1438        ZFB := Resolution( q, KernelCosequence( mor[i] ) );
1439
1440        ## Z -> F
1441        ZF := LowestDegreeMorphism( ZFB );
1442
1443        ## enrich CE with the natrual epi
1444        natural_epis.(String( [ i - 1, 0 ] )) := CokernelEpi( LowestDegreeMorphism( Range( ZF ) ) );
1445
1446        ## F[i-1] -> F[i]
1447        Add( CE, PreCompose( PreCompose( FB, BZ ), ZF ) );
1448
1449        ## F -> B
1450        FB := HighestDegreeMorphism( ZFB );
1451    od;
1452
1453    ## B -> F -> Q = F/B
1454    BFQ := Resolution( q, CokernelCosequence( mor[l] ) );
1455
1456    BF := LowestDegreeMorphism( BFQ );
1457
1458    ## enrich CE with the natrual epi
1459    natural_epis.(String( [ l, 0 ] )) := CokernelEpi( LowestDegreeMorphism( Range( BF ) ) );
1460
1461    if IsHomalgLeftObjectOrMorphismOfLeftObjects( C ) then
1462        Add( CE, FB * BF );
1463    else
1464        Add( CE, BF * FB );
1465    fi;
1466
1467    if HasIsExactSequence( C ) and IsExactSequence( C ) then
1468        SetIsExactSequence( CE, true );
1469    elif HasIsRightAcyclic( C ) and IsRightAcyclic( C ) then
1470        SetIsRightAcyclic( CE, true );
1471    elif HasIsLeftAcyclic( C ) and IsLeftAcyclic( C ) then
1472        SetIsLeftAcyclic( CE, true );
1473    elif HasIsAcyclic( C ) and IsAcyclic( C ) then
1474        SetIsAcyclic( CE, true );
1475    else
1476        SetIsComplex( CE, true );
1477    fi;
1478
1479    ## the Cartan-Eilenberg resolution:
1480    return CE;
1481
1482end );
1483
1484