Goto Chapter: Top 1 2 3 4 5 6 7 8 9 10 11 12 13 Bib Ind
[Top of Book] [Contents] [Previous Chapter] [Next Chapter]

[MathJax on]

10 Chain complexes
10.1 Introduction
10.2 Infinite lists
10.2-1 IsInfiniteNumber
10.2-2 PositiveInfinity
10.2-3 NegativeInfinity
10.2-4 IsInfList
10.2-5 IsHalfInfList
10.2-6 \^
10.2-7 MakeHalfInfList
10.2-8 StartPosition
10.2-9 Direction
10.2-10 InfListType
10.2-11 RepeatingList
10.2-12 ElementFunction
10.2-13 IsStoringValues
10.2-14 NewValueCallback
10.2-15 IsRepeating
10.2-16 InitialValue
10.2-17 LowestKnownPosition
10.2-18 HighestKnownValue
10.2-19 Shift
10.2-20 Cut
10.2-21 HalfInfList
10.2-22 MakeInfListFromHalfInfLists
10.2-23 MakeInfList
10.2-24 FunctionInfList
10.2-25 ConstantInfList
10.2-26 FiniteInfList
10.2-27 MiddleStart
10.2-28 MiddleEnd
10.2-29 MiddlePart
10.2-30 PositivePart
10.2-31 NegativePart
10.2-32 HighestKnownPosition
10.2-33 LowestKnownPosition
10.2-34 UpperBound
10.2-35 LowerBound
10.2-36 FinitePartAsList
10.2-37 PositivePartFrom
10.2-38 NegativePartFrom
10.2-39 Shift
10.2-40 Splice
10.2-41 InfConcatenation
10.2-42 InfList
10.2-43 IntegersList
10.3 Representation of categories
10.3-1 IsCat
10.3-2 CatOfRightAlgebraModules
10.4 Making a complex
10.4-1 IsQPAComplex
10.4-2 IsZeroComplex
10.4-3 Complex
10.4-4 ZeroComplex
10.4-5 FiniteComplex
10.4-6 StalkComplex
10.4-7 ShortExactSequence
10.5 Information about a complex
10.5-1 CatOfComplex
10.5-2 ObjectOfComplex
10.5-3 DifferentialOfComplex
10.5-4 DifferentialsOfComplex
10.5-5 CyclesOfComplex
10.5-6 BoundariesOfComplex
10.5-7 HomologyOfComplex
10.5-8 IsFiniteComplex
10.5-9 UpperBound
10.5-10 LowerBound
10.5-11 LengthOfComplex
10.5-12 HighestKnownDegree
10.5-13 LowestKnownDegree
10.5-14 IsExactSequence
10.5-15 IsExactInDegree
10.5-16 IsShortExactSequence
10.5-17 ForEveryDegree
10.6 Transforming and combining complexes
10.6-1 Shift
10.6-2 ShiftUnsigned
10.6-3 YonedaProduct
10.6-4 BrutalTruncationBelow
10.6-5 BrutalTruncationAbove
10.6-6 BrutalTruncation
10.6-7 SyzygyTruncation
10.6-8 CosyzygyTruncation
10.6-9 SyzygyCosyzygyTruncation
10.7 Chain maps
10.7-1 IsChainMap
10.7-2 ChainMap
10.7-3 ZeroChainMap
10.7-4 FiniteChainMap
10.7-5 ComplexAndChainMaps
10.7-6 MorphismOfChainMap
10.7-7 MorphismsOfChainMap
10.7-8 ComparisonLifting
10.7-9 ComparisonLiftingToProjectiveResolution
10.7-10 MappingCone

### 10 Chain complexes

#### 10.1 Introduction

If mathcalA is an abelian category, then a chain complex of objects of mathcal A is a sequence

\cdots \longrightarrow C_{i+1} \stackrel{d_{i+1}}{\longrightarrow} C_i \stackrel{d_i}{\longrightarrow} C_{i-1} \stackrel{d_{i-1}}{\longrightarrow} \cdots

where C_i is an object of mathcal A for all i, and d_i is a morphism of mathcal A for all i such that the composition of two consecutive maps of the complex is zero. The maps are called the differentials of the complex. A complex is called bounded above (resp. below) if there is a bound b such that C_i = 0 for all i>b (resp. i<b). A complex is bounded if it is both bounded below and bounded above.

The challenge when representing chain complexes in software is to handle their infinite nature. If a complex is not bounded, or not known to be bounded, how can we represent it in an immutable way? Our solution is to use a category called `InfList` (for ``infinite list'') to store the differentials of the complex. The properties of the `IsInfList` category is described in 10.2. An `IsQPAComplex` object consists of one `IsInfList` for the differentials, and it also has an `IsCat` object as an attribute. The `IsCat` category is a representation of an abelian category, see 10.3.

To work with bounded complexes one does not need to know much about the `IsInfList` category. A bounded complex can be created by simply giving a list of the differentials and the degree of the first differential as input (see `FiniteComplex` (10.4-5)), and to create a stalk complex the stalk object and its degree suffice as input (see `StalkComplex` (10.4-6)). In both cases an `IsCat` object is also needed.

    gap> C := FiniteComplex(cat, 1, [g,f]);
    0 -> 2:(1,0) -> 1:(2,2) -> 0:(1,1) -> 0
    gap> Ms := StalkComplex(cat, M, 3);
    0 -> 3:(2,2) -> 0

#### 10.2 Infinite lists

In this section we give documentation for the `IsInfList` category. We start by giving a representation of ± ∞. Then we quickly describe the `IsInfList` category, before we turn to the underlying structure of the infinite lists -- the half infinite lists (`IsHalfInfList`). Most of the functionality of the infinite lists come from this category. Finally, we give the constructors for infinite lists, and some methods for manipulating such objects.

##### 10.2-1 IsInfiniteNumber

`‣ IsInfiniteNumber` | ( category )

A category for infinite numbers.

##### 10.2-2 PositiveInfinity

`‣ PositiveInfinity` | ( var )

A global variable representing the number ∞. It is greater than any integer, but it can not be compared to numbers which are not integers. It belongs to the `IsInfiniteNumber` category.

##### 10.2-3 NegativeInfinity

`‣ NegativeInfinity` | ( var )

A global variable representing the number -∞. It is smaller than any integer, but it can not be compared to numbers which are not integers. It belongs to the `IsInfiniteNumber` category.

##### 10.2-4 IsInfList

`‣ IsInfList` | ( category )

An infinite list is an immutable representation of a list with possibly infinite range of indeces. It consists of three parts: The ``middle part'' is finite and covers some range [a,b] of indices, the ``positive part'' covers the range [b+1,∞) of indices, and the ``negative part'' convers the range (-∞,a-1] of indices. Note that none of the three parts are mandatory: The middle part may be an empty list, and the positive part may be set to `fail` to achieve index range ending at b < ∞. Similary, if the index range has lower bound a < ∞, put the negative part to be `fail`.

Each of the two infinite parts are described in one of the following ways: (1) A finite list which is repeated indefinitely; (2) A function which takes an index in the list as argument and returns the corresponding list item; (3) A function which takes an item from the list as argument and returns the next item.

The two infinite parts are represented as ``half infinite lists'', see 10.2-5. An infinite list can be constructed in the following ways:

- From two half infinite lists and a middle part, `MakeInfListFromHalfInfLists` (10.2-22).

- Directly, by giving the same input as when constructing the above, `MakeInfList` (10.2-23).

- If all values of the infinite list are the image of the index under a function f, one can use `FunctionInfList` (10.2-24).

- If all values of the infinite list are the same, one can use `ConstantInfList` (10.2-25).

- If the infinite list has a finite range, one can use `FiniteInfList` (10.2-26).

In addition, new infinite lists can be constructed from others by shift, splice, concatenation, extracting parts or applying a function to the elements.

##### 10.2-5 IsHalfInfList

`‣ IsHalfInfList` | ( category )

A half infinite list is a representation of a list with indeces in the range [a,∞) or (-∞,b]. An infinite list is typically made from two half infinite lists, and half infinite lists can be extracted from an infinite list. Hence, the half infinite list stores much of the information about an infinite list. One main difference between an infinite list and a half infinite list is that the half infinite list does not have any finite part, as the ``middle'' part of an infinite list.

##### 10.2-6 \^

`‣ \^`( list, pos ) | ( operation )

Arguments: list -- either an infinite list or a half infinite list, pos -- a valid index for list.

Returns: The value at position pos of list.

##### 10.2-7 MakeHalfInfList

`‣ MakeHalfInfList`( start, direction, typeWithArgs, callback, repeatifyCallback ) | ( function )

Arguments: start -- an integer, direction -- either 1 or -1, typeWithArgs -- a list which may have different formats, callback -- a function, repeatifyCallback -- a function.

Returns: A newly created half infinite list with index range from start to ∞, or from -∞ to start.

If the range should be [mathttstart,∞) then the value of direction is 1. if the range should be (-∞,mathttstart], then the value of direction is -1.

The argument typeWithArgs can take one of the following forms:

- `[ "repeat", repeatList ]`

- `[ "next", nextFunction, initialValue ]`

- `[ "next/repeat", nextFunction, initialValue ]`

- `[ "pos", posFunction ]`

- `[ "pos", posFunction, storeValues ]`

`repeatList` is a list of values that should be repeated in the half infinite list. `nextFunction` returns the value at position i, given the value at the previous position as argument. Here `initialValue` is the value at position `start`. Similarly, `posFunction` returns the value at any position i, and it may or may not store the values between the previous computed indeces and the newly computed index. The default value of `storeValues` is `true` for `"next"` and `"pos"`, and `false` for `"repeat"`. The type `"next/repeat"` works exactly like the type `"next"`, except that when values in the list are computed, the list will try to discover if the values are repeating. If this happens, the function repeatifyCallback is called with two arguments: the non-repeating part at the beginning as a normal list (this might be empty) and a new HalfInfList of type `"repeat"` for the repeating part.

The argument `callback` is a function that is called whenever a new value of the list is computed. It takes three arguments: The current position, the direction and the type (that is, `typeWithArgs[1]`). If no callback function is needed, use `false`.

All the information given to create the list is stored, and can be retrieved later by the operations listed in 10.2-8--10.2-18.

    gap> # make a HalfInfList from 0 to inf which repeats the list [ 2, 4, 6 ]
    gap> list1 := MakeHalfInfList( 0, 1, [ "repeat", [ 2, 4, 6 ] ], false );
    <object>
    gap> list1^0;
    2
    gap> list1^5;
    6
    gap> # make a HalfInfList from 0 to inf with x^2 in position x
    gap> f := function(x) return x^2; end;;
    gap> list2 := MakeHalfInfList( 0, 1, [ "pos", f, false ], false );
    <object>
    gap> list2^0;
    0
    gap> list2^10;
    100
    gap> # make a HalfInfList from 0 to -inf where each new value adds 3
    gap> # to the previous and the value in position 0 is 10
    gap> g := function(x) return x+3; end;;
    gap> list3 := MakeHalfInfList( 0, -1, [ "next", g, 7 ], false );
    <object>
    gap> list3^0;
    10
    gap> list3^-10;
    40

##### 10.2-8 StartPosition

`‣ StartPosition`( list ) | ( operation )

list -- a half infinite list.

Returns: The start position of list.

##### 10.2-9 Direction

`‣ Direction`( list ) | ( operation )

list -- a half infinite list.

Returns: The direction of list (either 1 or -1).

##### 10.2-10 InfListType

`‣ InfListType`( list ) | ( operation )

list -- a half infinite list.

Returns: The type of list (either `"pos"`, `"repeat"` or `"next"`).

##### 10.2-11 RepeatingList

`‣ RepeatingList`( list ) | ( operation )

list -- a half infinite list.

Returns: The repeating list of list if list is of type `"repeat"`, and `fail` otherwise.

##### 10.2-12 ElementFunction

`‣ ElementFunction`( list ) | ( operation )

list -- a half infinite list.

Returns: The element function of list if list is of type `"next"` or `"pos"`, and `fail` otherwise.

##### 10.2-13 IsStoringValues

`‣ IsStoringValues`( list ) | ( operation )

list -- a half infinite list.

Returns: `true` if all elements of the list are stored, `false` otherwise.

##### 10.2-14 NewValueCallback

`‣ NewValueCallback`( list ) | ( operation )

list -- a half infinite list.

Returns: The callback function of the list.

##### 10.2-15 IsRepeating

`‣ IsRepeating`( list ) | ( operation )

list -- a half infinite list.

Returns: `true` if the type of the list is `"repeat"`.

##### 10.2-16 InitialValue

`‣ InitialValue`( list ) | ( operation )

list -- a half infinite list.

Returns: If the list is of type `"next"` then the initial value is returned, otherwise it fails.

##### 10.2-17 LowestKnownPosition

`‣ LowestKnownPosition`( list ) | ( operation )

list -- a half infinite list.

Returns: The lowest index i such that the value at position i is known without computation (that is, it is either stored, or the list has type `"repeat"`).

##### 10.2-18 HighestKnownValue

`‣ HighestKnownValue`( list ) | ( operation )

list -- a half infinite list.

Returns: The highest index i such that the value at position i is known without computation (that is, it is either stored, or the list has type `"repeat"`).

    gap> # we reuse the IsHalfInfLists from the previous example
    gap> HighestKnownPosition(list1);
    +inf
    gap> HighestKnownPosition(list2);
    "none"
    gap> HighestKnownPosition(list3);
    0

##### 10.2-19 Shift

`‣ Shift`( list, shift ) | ( operation )

Arguments: list -- a half infinite list, shift -- an integer.

Returns: A new half infinite list which is list with all values shifted shift positions to the right if shift is positive, and to the left if shift is negative.

##### 10.2-20 Cut

`‣ Cut`( list, pos ) | ( operation )

Arguments: list -- a half infinite list, pos -- an integer within the range of list.

Returns: A new half infinite list which is list with some part cut off.

If the direction of list is positive, then the new list has range from `cut` to ∞. If the direction of list is negative, then the new list has range from -∞ to `cut`. The values at position i of the new half infinite list is the same as the value at position i of list.

##### 10.2-21 HalfInfList

`‣ HalfInfList`( list, func ) | ( operation )

Arguments: list -- a half infinite list, func -- a function which takes an element of the list as argument.

Returns: A half infinite list with the same range as list, where the value at position i is the image of the value at position i of list under func.

##### 10.2-22 MakeInfListFromHalfInfLists

`‣ MakeInfListFromHalfInfLists`( basePosition, middle, positive, negative ) | ( function )

Arguments: basePosition -- an integer, middle -- a list, positive -- a half infinite list, negative -- a half infinite list.

Returns: An infinite list with middle as is middle part, positive as its positive part and negative as its negative part.

The starting position of positive must be `basePosition + Length( middle )`, and the starting position of negative must be `basePosition - 1`. The returned list has `middle[1]` in position basePosition, `middle[2]` in position basePosition + 1 and so on. Note that one probably wants the positive half infinite list to have direction 1, and the negative half infinite list to have direction -1.

    gap> # we want to construct an infinite list with 0 in position
    gap> # 0 to 5, and x^2 in position x where x goes from 6 to inf,
    gap> # and alternatingly 1 and -1 in position -1 to -inf.
    gap> #
    gap> basePosition := 0;;
    gap> middle := [0,0,0,0,0,0];;
    gap> f := function(x) return x^2; end;;
    gap> positive := MakeHalfInfList( 6, 1, [ "pos", f, false ], false );
    <object>
    gap> altList := [ 1, -1 ];;
    gap> negative := MakeHalfInfList( -1, -1, [ "repeat", altList ], false );
    <object>
    gap> inflist := MakeInfListFromHalfInfLists( basePosition, middle,
    >                                            positive, negative );
    <object>
    gap> inflist^0; inflist^5; inflist^6; inflist^-1; inflist^-4;
    0
    0
    36
    1
    -1

##### 10.2-23 MakeInfList

`‣ MakeInfList`( basePosition, middle, positive, negative, callback ) | ( function )

Argments: basePosition -- an integer, middle -- a list, positive -- a list describing the positive part, negative -- a list describing the negative part.

Returns: An infinite list with middle as is middle part, positive as its positive part and negative as its negative part.

The major difference between this construction and the previous is that here the half infinite lists that will make the positive and negative parts are not entered directly as arguments. Instead, one enters ``description lists'', which are of the same format as the argument typeWithArgs of `MakeHalfInfList` (10.2-7). If the positive and/or negative part is specified with type `"next/repeat"`, then it will initially be of type `"next"`, but will be replaced by a HalfInfList of type `"repeat"` if it is discovered that the values are repeating.

    gap> # we construct the same infinite list as in the previous example
    gap> basePosition := 0;;
    gap> middle := [0,0,0,0,0,0];;
    gap> f := function(x) return x^2; end;;
    gap> altList := [ 1, -1 ];;
    gap> inflist2 := MakeInfList( 0, middle, [ "pos", f, false ], [ "repeat",
    >                             altList ], false );
    <object>
    gap> inflist2^0; inflist2^5; inflist2^6; inflist2^-1; inflist2^-4;
    0
    0
    36
    1
    -1
    gap> n := function( x ) return ( x + 1 ) mod 5; end;;
    gap> list := MakeInfList( 0, [ 0 ], [ "next/repeat", n, 0 ],
    >                         [ "repeat", [ 0 ] ], false );;
    gap> list^2;
    2
    gap> IsRepeating( PositivePart( list ) );
    false
    gap> list^11;
    1
    gap> IsRepeating( PositivePart( list ) );
    true

##### 10.2-24 FunctionInfList

`‣ FunctionInfList`( func ) | ( function )

Arguments: func -- a function that takes an integer as argument.

Returns: An infinite list where the value at position i is the function func applied to i.

##### 10.2-25 ConstantInfList

`‣ ConstantInfList`( value ) | ( function )

Arguments: value -- an object.

Returns: An infinite list which has the object value in every position.

##### 10.2-26 FiniteInfList

`‣ FiniteInfList`( basePosition, list ) | ( function )

Arguments: basePosition -- an integer, list -- a list of length n.

Returns: An infinite list with mathttlist[1],...,mathttlist[n] in positions mathttbasePosition,..., mathttbasePosition + n.

The range of this list is [mathttbasePosition, mathttbasePosition + n].

##### 10.2-27 MiddleStart

`‣ MiddleStart`( list ) | ( operation )

Arguments: list -- an infinite list.

Returns: The starting position of the "middle" part of list.

##### 10.2-28 MiddleEnd

`‣ MiddleEnd`( list ) | ( operation )

Arguments: list -- an infinite list.

Returns: The ending position of the middle part of list.

##### 10.2-29 MiddlePart

`‣ MiddlePart`( list ) | ( operation )

Arguments: list -- an infinite list.

Returns: The middle part (as a list) of list.

##### 10.2-30 PositivePart

`‣ PositivePart`( list ) | ( operation )

Arguments: list -- an infinite list.

Returns: The positive part (as a half infinite list) of list.

##### 10.2-31 NegativePart

`‣ NegativePart`( list ) | ( operation )

Arguments: list -- an infinite list.

Returns: The negative part (as a halft infinite list) of list.

##### 10.2-32 HighestKnownPosition

`‣ HighestKnownPosition`( list ) | ( operation )

Arguments: list -- an infinite list.

Returns: The highest index i such that the value at position i is known withouth computation.

##### 10.2-33 LowestKnownPosition

`‣ LowestKnownPosition`( list ) | ( operation )

Arguments: list -- an infinite list.

Returns: The lowest index i such that the value at position i is known withouth computation.

##### 10.2-34 UpperBound

`‣ UpperBound`( list ) | ( operation )

Arguments: list -- an infinite list.

Returns: The highest index in the range of the list.

##### 10.2-35 LowerBound

`‣ LowerBound`( list ) | ( operation )

Arguments: list -- an infinite list.

Returns: The lowest index in the range of the list.

##### 10.2-36 FinitePartAsList

`‣ FinitePartAsList`( list, startPos, endPos ) | ( operation )

Arguments: list -- an infinite list, startPos -- an integer, endPos -- an integer.

Returns: A list containing the values of list in positions mathttendPos,...,mathttstartPos.

Note that both integers in the input must be within the index range of list.

##### 10.2-37 PositivePartFrom

`‣ PositivePartFrom`( list, pos ) | ( operation )

Arguments: list -- an infinite list, pos -- an integer.

Returns: An infinite list (not a half infinite list) with index range from `pos` to `UpperBound(list)`.

The value at position i of the new infinite list is the same as the value at position i of list.

##### 10.2-38 NegativePartFrom

`‣ NegativePartFrom`( list, pos ) | ( operation )

Arguments: list -- an infinite list, pos -- an integer.

Returns: An infinite list (not a half infinite list) with index range from `LowerBound(list)` to `pos`.

The value at position i of the new infinite list is the same as the value at position i of list.

##### 10.2-39 Shift

`‣ Shift`( list, shift ) | ( operation )

Arguments: list -- an infinite list, shift -- an integer.

Returns: A new infinite list which is list with all values shifted shift positions to the right if shift is positive, and to the left if shift is negative.

##### 10.2-40 Splice

`‣ Splice`( positiveList, negativeList, joinPosition ) | ( operation )

Arguments: positiveList -- an infinite list, negativeList -- an infinite list, joinPosition -- an integer.

Returns: A new infinite list which is identical to positiveList for indeces greater than joinPosition and identical to negativeList for indeces smaller than or equal to joinPosition.

##### 10.2-41 InfConcatenation

`‣ InfConcatenation`( arg ) | ( function )

Arguments: arg -- a number of infinite lists.

Returns: A new infinite list.

If the length of arg is greater than or equal to 2, then the new infinite list consists of the following parts: It has the positive part of `arg[1]`, and the middle part is the concatenation of the middle parts of all lists in arg, such that `MiddleEnd` of the new list is the same as `MiddleEnd( arg[1] )`. The negative part of the new list is the negative part of `arg[Length(arg)]`, although shiftet so that it starts in the correct position.

    gap> # we do an InfConcatenation of three lists.
    gap> f := function(x) return x; end;;
    gap> g := function(x) return x+1; end;;
    gap> h := function(x) return x^2; end;;
    gap> InfList1 := MakeInfList( 0, [ 10 ], [ "pos", f, false ],
    >                             [ "repeat", [ 10, 15 ] ], false );
    <object>
    gap> InfList2 := MakeInfList( 0, [ 20 ], [ "pos", g, false ],
    >                             [ "repeat", [ 20, 25 ] ], false );
    <object>
    gap> InfList3 := MakeInfList( 0, [ 30 ], [ "pos", h, false ],
    >                             [ "repeat", [ 30, 35 ] ], false );
    <object>
    gap> concList := InfConcatenation( InfList1, InfList2, InfList3 );
    <object>
    gap> MiddlePart(concList);
    [ 30, 20, 10 ]

The newly created `concList` looks as follows around the middle part:

\begin{array}{lrrrrrrrrrrr} \text{position} & \cdots & 3 & 2 & 1 & 0 & -1 & -2 & -3 & -4 & -5 & \cdots \\ \text{value} & \cdots & 3 & 2 & 1 & 10 & 20 & 30 & 30 & 35 & 30 & \cdots \\ \end{array}

##### 10.2-42 InfList

`‣ InfList`( list, func ) | ( operation )

Arguments: list -- an infinite list, func -- a function which takes an element of the list as argument.

Returns: An infinite list with the same range as list, where the value at position i is the image of the value at position i of list under func.

##### 10.2-43 IntegersList

`‣ IntegersList` | ( global variable )

An infinite list with range (-∞,∞) where the value at position i is the number i (that is, a representation of the integers).

#### 10.3 Representation of categories

A chain complex consists of objects and morphisms from some category. In QPA, this category will usually be the category of right modules over some quotient of a path algebra.

##### 10.3-1 IsCat

`‣ IsCat` | ( category )

The category for categories. A category is a record, storing a number of properties that is specified within each category. Two categories can be compared using `=`. Currently, the only implemented category is the one of right modules over a (quotient of a) path algebra.

##### 10.3-2 CatOfRightAlgebraModules

`‣ CatOfRightAlgebraModules`( A ) | ( operation )

Arguments: A -- a (quotient of a) path algebra.

Returns: The category mod A.

mod A has several properties, which can be accessed using the `.` mark. Some of the properties store functions. All properties are demonstrated in the following example.

- `zeroObj` -- returns the zero module of mod A.

- `isZeroObj` -- returns true if the given module is zero.

- `zeroMap` -- returns the ZeroMapping function.

- `isZeroMapping` -- returns the IsZero test.

- `composeMaps` -- returns the composition of the two given maps.

- `ker` -- returns the Kernel function.

- `im` -- returns the Image function.

- `isExact` -- returns true if two consecutive maps are exact.

    gap> alg;
    <algebra-with-one over Rationals, with 7 generators>
    gap> # L, M, and N are alg-modules
    gap> # f: L --> M and g: M --> N are non-zero morphisms
    gap> cat := CatOfRightAlgebraModules(alg);
    <cat: right modules over algebra>
    gap> cat.zeroObj;
    <right-module over <algebra-with-one over Rationals, with 7 generators>>
    gap> cat.isZeroObj(M);
    false
    gap> cat.zeroMap(M,N);
    <mapping: <3-dimensional right-module over AlgebraWithOne( Rationals,
    [ [(1)*v1], [(1)*v2], [(1)*v3], [(1)*v4], [(1)*a], [(1)*b], [(1)*c] ])> ->
      <1-dimensional right-module over AlgebraWithOne( Rationals,
      [ [(1)*v1], [(1)*v2], [(1)*v3], [(1)*v4], [(1)*a], [(1)*b], [(1)*c] ] )> >
    gap> cat.composeMaps(g,f);
    <mapping: <1-dimensional right-module over AlgebraWithOne( Rationals,
      [ [(1)*v1], [(1)*v2], [(1)*v3], [(1)*v4], [(1)*a], [(1)*b], [(1)*c]]
      -> <1-dimensional right-module over AlgebraWithOne( Rationals,
      [ [(1)*v1], [(1)*v2], [(1)*v3], [(1)*v4], [(1)*a], [(1)*b], [(1)*c] ] )> >
    gap> cat.ker(g);
    <2-dimensional right-module over <algebra-with-one over Rationals,
      with 7 generators>>
    gap> cat.isExact(g,f);
    false

#### 10.4 Making a complex

The most general constructor for complexes is the function `Complex` (10.4-3). In addition to this, there are constructors for common special cases:

- `ZeroComplex` (10.4-4)

- `StalkComplex` (10.4-6)

- `FiniteComplex` (10.4-5)

- `ShortExactSequence` (10.4-7)

##### 10.4-1 IsQPAComplex

`‣ IsQPAComplex` | ( category )

The category for chain complexes.

##### 10.4-2 IsZeroComplex

`‣ IsZeroComplex` | ( category )

Category for zero complexes, subcategory of `IsQPAComplex` (10.4-1).

##### 10.4-3 Complex

`‣ Complex`( cat, baseDegree, middle, positive, negative ) | ( function )

Returns: A newly created chain complex

The first argument, cat is an `IsCat` (10.3-1) object describing the category to create a chain complex over.

The rest of the arguments describe the differentials of the complex. These are divided into three parts: one finite ("middle") and two infinite ("positive" and "negative"). The positive part contains all differentials in degrees higher than those in the middle part, and the negative part contains all differentials in degrees lower than those in the middle part. (The middle part may be placed anywhere, so the positive part can -- despite its name -- contain some differentials of negative degree. Conversely, the negative part can contain some differentials of positive degree.)

The argument middle is a list containing the differentials for the middle part. The argument baseDegree gives the degree of the first differential in this list. The second differential is placed in degree baseDegree+1, and so on. Thus, the middle part consists of the degrees

baseDegree,\quad baseDegree + 1,\quad \ldots\quad baseDegree + \text{Length}(middle).

Each of the arguments positive and negative can be one of the following:

- The string `"zero"`, meaning that the part contains only zero objects and zero morphisms.

- A list of the form `[ "repeat", L ]`, where `L` is a list of morphisms. The part will contain the differentials in `L` repeated infinitely many times. The convention for the order of elements in `L` is that `L[1]` is the differential which is closest to the middle part, and `L[Length(L)]` is farthest away from the middle part.

- A list of the form `[ "pos", f ]` or `[ "pos", f, store ]`, where `f` is a function of two arguments, and `store` (if included) is a boolean. The function `f` is used to compute the differentials in this part. The function `f` is not called immediately by the `Complex` constructor, but will be called later as the differentials in this part are needed. The function call `f(C,i)` (where `C` is the complex and `i` an integer) should produce the differential in degree `i`. The function may use `C` to look up other differentials in the complex, as long as this does not cause an infinite loop. If `store` is `true` (or not specified), each computed differential is stored, and they are computed in order from the one closest to the middle part, regardless of which order they are requested in.

- A list of the form `[ "next", f, init ]`, where `f` is a function of one argument, and `init` is a morphism. The function `f` is used to compute the differentials in this part. For the first differential in the part (that is, the one closest to the middle part), `f` is called with `init` as argument. For the next differential, `f` is called with the first differential as argument, and so on. Thus, the differentials are

  f(\text{init}),\quad f^2(\text{init}),\quad f^3(\text{init}),\quad \ldots

  Each differential is stored when it has been computed.

- A list of the form `[ "next/repeat", f, init ]`. This works like the type `"next"`, but may be automatically converted to type `"repeat"` later, if it is discovered that the differentials are repeating.

    gap> A := PathAlgebra( Rationals, Quiver( 2, [ [ 1, 2, "a" ] ] ) );;
    gap> M := RightModuleOverPathAlgebra( A, [ 2, 2 ], [ [ "a", [ [ 1, 0 ], [ 0, 1 ] ] ] ] );;
    gap> d := RightModuleHomOverAlgebra( M, M, [ [ [ 0, 0 ], [ 1, 0 ] ], [ [ 0, 0 ], [ 1, 0 ] ] ] );;
    gap> IsZero( d * d );
    true
    gap> C := Complex( CatOfRightAlgebraModules( A ), 0, [ d ],
    >                  [ "next/repeat", function( x ) return d; end, d ], "zero" );
    --- -> 0:(2,2) -> -1:(2,2) -> 0
    gap> ObjectOfComplex( C, 3 );
    <[ 2, 2 ]>
    gap> C;
    --- -> [ 1:(2,2) -> ] 0:(2,2) -> -1:(2,2) -> 0

##### 10.4-4 ZeroComplex

`‣ ZeroComplex`( cat ) | ( function )

Returns: A newly created zero complex

This function creates a zero complex (a complex consisting of only zero objects and zero morphisms) over the category described by the `IsCat` (10.3-1) object cat.

##### 10.4-5 FiniteComplex

`‣ FiniteComplex`( cat, baseDegree, differentials ) | ( function )

Returns: A newly created complex

This function creates a complex where all but finitely many objects are the zero object.

The argument cat is an `IsCat` (10.3-1) object describing the category to create a chain complex over.

The argument differentials is a list of morphisms. The argument baseDegree gives the degree for the first differential in this list. The subsequent differentials are placed in degrees baseDegree+1, and so on.

This means that the differentials argument specifies the differentials in degrees

baseDegree,\quad baseDegree + 1,\quad \ldots \quad baseDegree + \text{Length}(differentials);

and thus implicitly the objects in degrees

baseDegree - 1,\quad baseDegree,\quad \ldots \quad baseDegree + \text{Length}(differentials).

All other objects in the complex are zero.

    gap> # L, M and N are modules over the same algebra A
    gap> # cat is the category mod A
    gap> # f: L --> M and g: M --> N maps
    gap> C := FiniteComplex(cat, 1, [g,f]);
    0 -> 2:(1,0) -> 1:(2,2) -> 0:(1,1) -> 0

##### 10.4-6 StalkComplex

`‣ StalkComplex`( cat, obj, degree ) | ( function )

Arguments: cat -- a category, obj -- an object in cat, degree -- the degree obj should be placed in.

Returns: a newly created complex.

The new complex is a stalk complex with obj in position degree, and zero elsewhere.

    gap> Ms := StalkComplex(cat, M, 3);
    0 -> 3:(2,2) -> 0

##### 10.4-7 ShortExactSequence

`‣ ShortExactSequence`( cat, f, g ) | ( function )

Arguments: cat -- a category, f and g -- maps in cat, where f: A \rightarrow B and g: B \rightarrow C.

Returns: a newly created complex.

If the sequence 0 \rightarrow A \rightarrow B \rightarrow C \rightarrow 0 is exact, this complex (with B in degree 0) is returned.

    gap> ses := ShortExactSequence(cat, f, g);
    0 -> 1:(0,0,1,0) -> 0:(0,1,1,1) -> -1:(0,1,0,1) -> 0

#### 10.5 Information about a complex

##### 10.5-1 CatOfComplex

`‣ CatOfComplex`( C ) | ( attribute )

Returns: The category the objects of the complex C live in.

##### 10.5-2 ObjectOfComplex

`‣ ObjectOfComplex`( C, i ) | ( operation )

Arguments: C -- a complex, i -- an integer.

Returns: The object at position i in the complex.

##### 10.5-3 DifferentialOfComplex

`‣ DifferentialOfComplex`( C, i ) | ( operation )

Arguments: C -- a complex, i -- an integer.

Returns: The map in C between objects at positions i and i-1.

##### 10.5-4 DifferentialsOfComplex

`‣ DifferentialsOfComplex`( C ) | ( attribute )

Arguments: C -- a complex

Returns: The differentials of the complex, stored as an `IsInfList` object.

##### 10.5-5 CyclesOfComplex

`‣ CyclesOfComplex`( C, i ) | ( operation )

Arguments: C -- a complex, i -- an integer.

Returns: The i-cycle of the complex, that is the subobject Ker(d_i) of `ObjectOfComplex(C,i)`.

##### 10.5-6 BoundariesOfComplex

`‣ BoundariesOfComplex`( C, i ) | ( operation )

Arguments: C -- a complex, i -- an integer.

Returns: The i-boundary of the complex, that is the subobject Im(d_{i+1}) of `ObjectOfComplex(C,i)`.

##### 10.5-7 HomologyOfComplex

`‣ HomologyOfComplex`( C, i ) | ( operation )

Arguments: C -- a complex, i -- an integer.

Returns: The ith homology of the complex, that is, Ker(d_i)/Im(d_{i+1}).

Note: this operation is currently not available. When working in the category of right kQ/I-modules, it is possible to "cheat" and use the following procedure to compute the homology of a complex:

    gap> C;
    0 -> 4:(0,1) -> 3:(1,0) -> 2:(2,2) -> 1:(1,1) -> 0:(2,2) -> 0
    gap> # Want to compute the homology in degree 2
    gap> f := DifferentialOfComplex(C,3);
    <mapping: <1-dimensional right-module over AlgebraWithOne( Rationals,
      [ [(1)*v1], [(1)*v2], [(1)*a], [(1)*b] ] )> ->
      < 4-dimensional right-module over AlgebraWithOne( Rationals,
      [ [(1)*v1], [(1)*v2], [(1)*a], [(1)*b] ] )> >
    gap> g := KernelInclusion(DifferentialOfComplex(C,2));
      <mapping: <2-dimensional right-module over AlgebraWithOne( Rationals,
      [ [(1)*v1], [(1)*v2], [(1)*a], [(1)*b] ] )> ->
      < 4-dimensional right-module over AlgebraWithOne( Rationals,
      [ [(1)*v1], [(1)*v2], [(1)*a], [(1)*b] ] )> >
    gap> # We know that Im f is included in Ker g, so can find the
    gap> # lifting morphism h from C_3 to Ker g.
    gap> h := LiftingInclusionMorphisms(g,f);
      <mapping: <1-dimensional right-module over AlgebraWithOne( Rationals,
      [ [(1)*v1], [(1)*v2], [(1)*a], [(1)*b] ] )> ->
      < 2-dimensional right-module over AlgebraWithOne( Rationals,
      [ [(1)*v1], [(1)*v2], [(1)*a], [(1)*b] ] )> >
    gap> # The cokernel of h is Ker g / Im f
    gap> Homology := CoKernel(h);
    <1-dimensional right-module over <algebra-with-one over Rationals, with
      4 generators>>

##### 10.5-8 IsFiniteComplex

`‣ IsFiniteComplex`( C ) | ( operation )

Arguments: C -- a complex.

Returns: true if C is a finite complex, false otherwise.

##### 10.5-9 UpperBound

`‣ UpperBound`( C ) | ( operation )

Arguments: C -- a complex.

Returns: If it exists: The smallest integer i such that the object at position i is non-zero, but for all j > i the object at position j is zero.

If C is not a finite complex, the operation will return fail or infinity, depending on how C was defined.

##### 10.5-10 LowerBound

`‣ LowerBound`( C ) | ( operation )

Arguments: C -- a complex.

Returns: If it exists: The greatest integer i such that the object at position i is non-zero, but for all j < i the object at position j is zero.

If C is not a finite complex, the operation will return fail or negative infinity, depending on how C was defined.

##### 10.5-11 LengthOfComplex

`‣ LengthOfComplex`( C ) | ( operation )

Arguments: C -- a complex.

Returns: the length of the complex.

The length is defined as follows: If C is a zero complex, the length is zero. If C is a finite complex, the lenght is the upper bound -- the lower bound + 1. If C is an inifinite complex, the lenght is infinity.

##### 10.5-12 HighestKnownDegree

`‣ HighestKnownDegree`( C ) | ( operation )

Arguments: C -- a complex.

Returns: The greatest integer i such that the object at position i is known (or computed).

For a finite complex, this will be infinity.

##### 10.5-13 LowestKnownDegree

`‣ LowestKnownDegree`( C ) | ( operation )

Arguments: C -- a complex.

Returns: The smallest integer i such that the object at position i is known (or computed).

For a finite complex, this will be negative infinity.

    gap> C;
    0 -> 4:(0,1) -> 3:(1,0) -> 2:(2,2) -> 1:(1,1) -> 0:(2,2) -> 0
    gap> IsFiniteComplex(C);
    true
    gap> UpperBound(C);
    4
    gap> LowerBound(C);
    0
    gap> LengthOfComplex(C);
    5
    gap> HighestKnownDegree(C);
    +inf
    gap> LowestKnownDegree(C);
    -inf

##### 10.5-14 IsExactSequence

`‣ IsExactSequence`( C ) | ( property )

Arguments: C -- a complex.

Returns: true if C is exact at every position.

If the complex is not finite and not repeating, the function fails.

##### 10.5-15 IsExactInDegree

`‣ IsExactInDegree`( C, i ) | ( operation )

Arguments: C -- a complex, i -- an integer.

Returns: true if C is exact at position i.

##### 10.5-16 IsShortExactSequence

`‣ IsShortExactSequence`( C ) | ( property )

Arguments: C -- a complex.

Returns: true if C is exact and of the form

\ldots \rightarrow 0 \rightarrow A \rightarrow B \rightarrow C \rightarrow 0 \rightarrow \ldots

This could be positioned in any degree (as opposed to the construction of a short exact sequence, where B will be put in degree zero).

    gap> C;
    0 -> 4:(0,1) -> 3:(1,0) -> 2:(2,2) -> 1:(1,1) -> 0:(2,2) -> 0
    gap> IsExactSequence(C);
    false
    gap> IsExactInDegree(C,1);
    true
    gap> IsExactInDegree(C,2);
    false

##### 10.5-17 ForEveryDegree

`‣ ForEveryDegree`( C, func ) | ( operation )

Arguments: C -- a complex, func -- a function operating on two consecutive maps.

Returns: true if func returns true for any two consecutive differentials, fail if this can not be decided, false otherwise.

#### 10.6 Transforming and combining complexes

##### 10.6-1 Shift

`‣ Shift`( C, i ) | ( operation )

Arguments: C -- a complex, i -- an integer.

Returns: A new complex, which is a shift of C.

If i > 0, the complex is shifted to the left. If i < 0, the complex is shifted to the right. Note that shifting might change the differentials: In the shifted complex, d_{new} is defined to be (-1)^i d_{old}.

    gap> C;
    0 -> 4:(0,1) -> 3:(1,0) -> 2:(2,2) -> 1:(1,1) -> 0:(2,2) -> 0
    gap> Shift(C,1);
    0 -> 3:(0,1) -> 2:(1,0) -> 1:(2,2) -> 0:(1,1) -> -1:(2,2) -> 0
    gap> D := Shift(C,-1);
    0 -> 5:(0,1) -> 4:(1,0) -> 3:(2,2) -> 2:(1,1) -> 1:(2,2) -> 0
    gap> dc := DifferentialOfComplex(C,3)!.maps;
    [ [ [ 1, 0 ] ], [ [ 0, 0 ] ] ]
    gap> dd := DifferentialOfComplex(D,4)!.maps;
    [ [ [ -1, 0 ] ], [ [ 0, 0 ] ] ]
    gap> MatricesOfPathAlgebraMatModuleHomomorphism(dc);
    [ [ [ 1, 0 ] ], [ [ 0, 0 ] ] ]
    gap> MatricesOfPathAlgebraMatModuleHomomorphism(dd);
    [ [ [ -1, 0 ] ], [ [ 0, 0 ] ] ]

##### 10.6-2 ShiftUnsigned

`‣ ShiftUnsigned`( C, i ) | ( operation )

Arguments: C -- a complex, i -- an integer.

Returns: A new complex, which is a shift of C.

Does the same as `Shift`, except it does not change the sign of the differential. Although this is a non-mathematical definition of shift, it is still useful for technical purposes, when manipulating and creating complexes.

##### 10.6-3 YonedaProduct

`‣ YonedaProduct`( C, D ) | ( operation )

Arguments: C, D -- complexes.

Returns: The Yoneda product of the two complexes, which is a complex.

To compute the Yoneda product, C and D must be such that the object in degree `LowerBound(C)` equals the object in degree `UpperBound(D)`, that is

\ldots \rightarrow C_{i+1} \rightarrow C_{i} \rightarrow A \rightarrow 0 \rightarrow \ldots

\ldots \rightarrow 0 \rightarrow A \rightarrow D_{j} \rightarrow D_{j-1} \rightarrow \ldots

The product is of this form:

\ldots \rightarrow C_{i+1} \rightarrow C_{i} \rightarrow D_{j} \rightarrow D_{j-1} \rightarrow \ldots

where the map C_{i} \rightarrow D_{j} is the composition of the maps C_{i} \rightarrow A and A \rightarrow D_{j}. Also, the object D_{j} is in degree j.

    gap> C2;
    0 -> 4:(0,1) -> 3:(1,0) -> 2:(2,2) -> 1:(1,1) -> 0:(0,0) -> 0
    gap> C3;
    0 -> -1:(1,1) -> -2:(2,2) -> -3:(1,1) -> 0
    gap> YonedaProduct(C2,C3);
    0 -> 1:(0,1) -> 0:(1,0) -> -1:(2,2) -> -2:(2,2) -> -3:(1,1) -> 0

##### 10.6-4 BrutalTruncationBelow

`‣ BrutalTruncationBelow`( C, i ) | ( operation )

Arguments: C -- a complex, i -- an integer.

Returns: A newly created complex.

Replace all objects with degree j < i with zero. The differentials affected will also become zero.

##### 10.6-5 BrutalTruncationAbove

`‣ BrutalTruncationAbove`( C, i ) | ( operation )

Arguments: C -- a complex, i -- an integer.

Returns: A newly created complex.

Replace all objects with degree j > i with zero. The differentials affected will also become zero.

##### 10.6-6 BrutalTruncation

`‣ BrutalTruncation`( C, i, j ) | ( operation )

Arguments: C -- a complex, i, j -- integers.

Returns: A newly created complex.

Brutally truncates in both ends. The integer arguments must be ordered such that i > j.

##### 10.6-7 SyzygyTruncation

`‣ SyzygyTruncation`( C, i ) | ( operation )

Arguments: C -- a complex, i -- an integer.

Returns: A newly created complex.

Replace the object in degree i with the kernel of d_i, and d_i+1 with the natural inclusion. All objects in degree j > i+1 are replaced with zero.

##### 10.6-8 CosyzygyTruncation

`‣ CosyzygyTruncation`( C, i ) | ( operation )

Arguments: C -- a complex, i -- an integer.

Returns: A newly created complex.

Replace the object in degree i-2 with the cokernel of d_i, and d_i-1 with the natural projection. All objects in degree j < i-2 are replaced with zero.

##### 10.6-9 SyzygyCosyzygyTruncation

`‣ SyzygyCosyzygyTruncation`( C, i, j ) | ( operation )

Arguments: C -- a complex, i -- an integer.

Returns: A newly created complex.

Performs both the above truncations. The integer arguments must be ordered such that i > j.

#### 10.7 Chain maps

An `IsChainMap` (10.7-1) object represents a chain map between two complexes over the same category.

##### 10.7-1 IsChainMap

`‣ IsChainMap` | ( category )

The category for chain maps.

##### 10.7-2 ChainMap

`‣ ChainMap`( source, range, basePosition, middle, positive, negative ) | ( function )

Arguments: source, range -- complexes, basePosition -- an integer, middle -- a list of morphisms, positive -- a list or the string `"zero"`, negative -- a list or the string `"zero"`.

Returns: A newly created chain map

The arguments source and range are the complexes which the new chain map should map between.

The rest of the arguments describe the individual morphisms which constitute the chain map, in a similar way to the last four arguments to the `Complex` (10.4-3) function.

The morphisms of the chain map are divided into three parts: one finite ("middle") and two infinite ("positive" and "negative"). The positive part contains all morphisms in degrees higher than those in the middle part, and the negative part contains all morphisms in degrees lower than those in the middle part. (The middle part may be placed anywhere, so the positive part can -- despite its name -- contain some morphisms of negative degree. Conversely, the negative part can contain some morphisms of positive degree.)

The argument middle is a list containing the morphisms for the middle part. The argument baseDegree gives the degree of the first morphism in this list. The second morphism is placed in degree baseDegree+1, and so on. Thus, the middle part consists of the degrees

baseDegree,\quad baseDegree + 1,\quad \ldots\quad baseDegree + \text{Length}(middle) - 1.

Each of the arguments positive and negative can be one of the following:

- The string `"zero"`, meaning that the part contains only zero morphisms.

- A list of the form `[ "repeat", L ]`, where `L` is a list of morphisms. The part will contain the morphisms in `L` repeated infinitely many times. The convention for the order of elements in `L` is that `L[1]` is the morphism which is closest to the middle part, and `L[Length(L)]` is farthest away from the middle part. (Using this only makes sense if the objects of both the source and range complex repeat in a compatible way.)

- A list of the form `[ "pos", f ]` or `[ "pos", f, store ]`, where `f` is a function of two arguments, and `store` (if included) is a boolean. The function `f` is used to compute the morphisms in this part. The function `f` is not called immediately by the `ChainMap` constructor, but will be called later as the morphisms in this part are needed. The function call `f(M,i)` (where `M` is the chain map and `i` an integer) should produce the morphism in degree `i`. The function may use `M` to look up other morphisms in the chain map (and to access the source and range complexes), as long as this does not cause an infinite loop. If `store` is `true` (or not specified), each computed morphism is stored, and they are computed in order from the one closest to the middle part, regardless of which order they are requested in.

- A list of the form `[ "next", f, init ]`, where `f` is a function of one argument, and `init` is a morphism. The function `f` is used to compute the morphisms in this part. For the first morphism in the part (that is, the one closest to the middle part), `f` is called with `init` as argument. For the next morphism, `f` is called with the first morphism as argument, and so on. Thus, the morphisms are

  f(\text{init}),\quad f^2(\text{init}),\quad f^3(\text{init}),\quad \ldots

  Each morphism is stored when it has been computed.

##### 10.7-3 ZeroChainMap

`‣ ZeroChainMap`( source, range ) | ( function )

Returns: A newly created zero chain map

This function creates a zero chain map (a chain map in which every morphism is zero) from the complex source to the complex range.

##### 10.7-4 FiniteChainMap

`‣ FiniteChainMap`( source, range, baseDegree, morphisms ) | ( function )

Returns: A newly created chain map

This function creates a complex where all but finitely many morphisms are zero.

The arguments source and range are the complexes which the new chain map should map between.

The argument morphisms is a list of morphisms. The argument baseDegree gives the degree for the first morphism in this list. The subsequent morphisms are placed in degrees baseDegree+1, and so on.

This means that the morphisms argument specifies the morphisms in degrees

baseDegree,\quad baseDegree + 1,\quad \ldots \quad baseDegree + \text{Length}(morphisms) - 1.

All other morphisms in the chain map are zero.

##### 10.7-5 ComplexAndChainMaps

`‣ ComplexAndChainMaps`( sourceComplexes, rangeComplexes, basePosition, middle, positive, negative ) | ( function )

Arguments: sourceComplexes -- a list of complexes, rangeComplexes -- a list of complexes, basePosition -- an integer, middle -- a list of morphisms, positive -- a list or the string `"zero"`, negative -- a list or the string `"zero"`.

Returns: A list consisting of a newly created complex, and one or more newly created chain maps.

This is a combined constructor to make one complex and a set of chain maps at the same time. All the chain maps will have the new complex as either source or range.

The argument sourceComplexes is a list of the complexes to be sources of the chain maps which have the new complex as range. The argument rangeComplexes is a list of the complexes to be ranges of the chain maps which have the new complex as source.

Let S and R stand for the lengths of the lists sourceComplexes and rangeComplexes, respectively. Then the number of new chain maps which are created is S+R.

The last four arguments describe the individual differentials of the new complex, as well as the inidividual morphisms which constitute each of the new chain maps. These arguments are treated in a similar way to the last four arguments to the `Complex` (10.4-3) and `ChainMap` (10.7-2) constructors. In those constructors, the last four arguments describe, for each degree, how to get the differential or morphism for that degree. Here, we for each degree need both a differential for the complex, and one morphism for each chain map. So for each degree i, we will have a list

L_i = [ d_i, m_i^1, \ldots, m_i^S, n_i^1, \ldots, n_i^R ],

where d_i is the differential for the new complex in degree i, m_i^j is the morphism in degree i of the chain map from `sourceComplexes[j]` to the new complex, and n_i^j is the morphism in degree i of the chain map from the new complex to `rangeComplexes[j]`.

The degrees of the new complex and chain maps are divided into three parts: one finite ("middle") and two infinite ("positive" and "negative"). The positive part contains all degrees higher than those in the middle part, and the negative part contains all degrees lower than those in the middle part.

The argument middle is a list containing the lists L_i for the middle part. The argument baseDegree gives the degree of the first morphism in this list. The second morphism is placed in degree baseDegree+1, and so on. Thus, the middle part consists of the degrees

baseDegree,\quad baseDegree + 1,\quad \ldots\quad baseDegree + \text{Length}(middle) - 1.

Each of the arguments positive and negative can be one of the following:

- The string `"zero"`, meaning that the part contains only zero morphisms.

- A list of the form `[ "repeat", L ]`, where `L` is a list of morphisms. The part will contain the morphisms in `L` repeated infinitely many times. The convention for the order of elements in `L` is that `L[1]` is the morphism which is closest to the middle part, and `L[Length(L)]` is farthest away from the middle part. (Using this only makes sense if the objects of both the source and range complex repeat in a compatible way.)

- A list of the form `[ "pos", f ]` or `[ "pos", f, store ]`, where `f` is a function of two arguments, and `store` (if included) is a boolean. The function `f` is used to compute the morphisms in this part. The function `f` is not called immediately by the `ChainMap` constructor, but will be called later as the morphisms in this part are needed. The function call `f(M,i)` (where `M` is the chain map and `i` an integer) should produce the morphism in degree `i`. The function may use `M` to look up other morphisms in the chain map (and to access the source and range complexes), as long as this does not cause an infinite loop. If `store` is `true` (or not specified), each computed morphism is stored, and they are computed in order from the one closest to the middle part, regardless of which order they are requested in.

- A list of the form `[ "next", f, init ]`, where `f` is a function of one argument, and `init` is a morphism. The function `f` is used to compute the morphisms in this part. For the first morphism in the part (that is, the one closest to the middle part), `f` is called with `init` as argument. For the next morphism, `f` is called with the first morphism as argument, and so on. Thus, the morphisms are

  f(\text{init}),\quad f^2(\text{init}),\quad f^3(\text{init}),\quad \ldots

  Each morphism is stored when it has been computed.

The return value of the `ComplexAndChainMaps` constructor is a list

[ C, M_1, \ldots, M_S, N_1, \ldots, N_R ],

where C is the new complex, M_1,...,M_S are the new chain maps with C as range, and N_1,...,N_R are the new chain maps with C as source.

##### 10.7-6 MorphismOfChainMap

`‣ MorphismOfChainMap`( M, i ) | ( operation )

Arguments: M -- a chain map, i -- an integer.

Returns: The morphism at position i in the chain map.

##### 10.7-7 MorphismsOfChainMap

`‣ MorphismsOfChainMap`( M ) | ( attribute )

Arguments: M -- a chain map.

Returns: The morphisms of the chain map, stored as an `IsInfList` (10.2-4) object.

##### 10.7-8 ComparisonLifting

`‣ ComparisonLifting`( f, PC, EC ) | ( operation )

Arguments: f -- a map between modules M and N, PC -- a chain complex, EC -- a chain complex.

Returns: The map f lifted to a chain map from PC to EC.

The complex PC must have M in some fixed degree i, it should be bounded with only zero objects in degrees smaller than i, and it should have only projective objects in degrees greater than i (or projective objects in degrees [i+1,j] and zero in degrees greater than j). The complex EC should also have zero in degrees smaller than i, it should have N in degree i and it should be exact for all degrees. The returned chain map has f in degree i.

##### 10.7-9 ComparisonLiftingToProjectiveResolution

`‣ ComparisonLiftingToProjectiveResolution`( f ) | ( operation )

Arguments: f -- a map between modules M and N.

Returns: The map f lifted to a chain map from the projective resolution of M to the projective resolution of N.

The returned chain map has f in degree -1 (the projective resolution of a module includes the module itself in degree -1).

##### 10.7-10 MappingCone

`‣ MappingCone`( f ) | ( operation )

Arguments: f -- a chain map between chain complexes A and B.

Returns: A list with the mapping cone of f and the inclusion of B into the cone, and the projection of the cone onto A[-1].

    gap> # Constructs a quiver and a quotient of a path algebra
    gap> Q := Quiver( 4, [ [1,2,"a"], [2,3,"b"], [3,4,"c"] ] );;
    gap> PA := PathAlgebra( Rationals, Q );;
    gap> rels := [ PA.a*PA.b ];;
    gap> gb := GBNPGroebnerBasis( rels, PA );;
    gap> I := Ideal( PA, gb );;
    gap> grb := GroebnerBasis( I, gb );;
    gap> alg := PA/I;;
    gap>
    gap> # Two modules M and N, and a map between them
    gap> M := RightModuleOverPathAlgebra( alg, [0,1,1,0], [["b", [[1]] ]] );;
    gap> N := RightModuleOverPathAlgebra( alg, [0,1,0,0], [] );;
    gap> f := RightModuleHomOverAlgebra(M, N, [ [[0]],[[1]],[[0]],[[0]] ]);;
    gap>
    gap> # Lifts f to a map between the projective resolutions of M and N
    gap> lf := ComparisonLiftingToProjectiveResolution(f);
    <chain map>
    gap>
    gap> # Computes the mapping cone of the chain map
    gap> H := MappingCone(lf);
    [ --- -> -1:(0,1,0,0) -> ---, <chain map>, <chain map> ]
    gap> cone := H[1];
    --- -> -1:(0,1,0,0) -> ---
    gap> ObjectOfComplex(Source(lf),0);
    <[ 0, 1, 1, 1 ]>
    gap> ObjectOfComplex(Range(lf),1);
    <[ 0, 0, 1, 1 ]>
    gap> ObjectOfComplex(cone,1);
    <[ 0, 1, 2, 2 ]>
    gap> Source(H[2]) = Range(lf);
    true

[Top of Book] [Contents] [Previous Chapter] [Next Chapter]
Goto Chapter: Top 1 2 3 4 5 6 7 8 9 10 11 12 13 Bib Ind

generated by GAPDoc2HTML