# Chain and Cochain Complexes

The general OSCAR type ComplexOfMorphisms{T} allows one to model both chain complexes and cochain complexes (the T refers to the type of the differentials of the complex). In the context of commutative algebra, we handle complexes of modules and module homomorphisms over multivariate polynomial rings. In this section, we first show how to create such complexes. Then we discuss functionality for dealing with the constructed complexes, mainly focusing on chain complexes. Cochain complexes can be handled similarly.

## Constructors

chain_complexMethod
chain_complex(V::ModuleFPHom...; seed::Int = 0)

Given a tuple V of module homorphisms between successive modules over a multivariate polynomial ring, return the chain complex defined by these homomorphisms.

chain_complex(V::Vector{<:ModuleFPHom}; seed::Int = 0)

Given a vector V of module homorphisms between successive modules over a multivariate polynomial ring, return the chain complex defined by these homomorphisms.

Note

The integer seed indicates the lowest homological degree of a module in the complex.

Note

The function checks whether successive homomorphisms indeed compose to zero.

source
cochain_complexMethod
cochain_complex(V::ModuleFPHom...; seed::Int = 0)

Given a tuple V of module homorphisms between successive modules over a multivariate polynomial ring, return the cochain complex defined by these homomorphisms.

cochain_complex(V::Vector{<:ModuleFPHom}; seed::Int = 0)

Given a vector V of module homorphisms between successive modules over a multivariate polynomial ring, return the cochain complex defined by these homomorphisms.

Note

The integer seed indicates the lowest cohomological degree of a module of the complex.

Note

The function checks whether successive homomorphisms indeed compose to zero.

source

## Data Associated to Complexes

Given a complex C,

• range(C) refers to the range of C,
• obj(C, i) and C[i] to the i-th module of C, and
• map(C, i) to the i-th differential of C.
##### Examples
julia> R, (x,) = PolynomialRing(QQ, ["x"]);

julia> F = free_module(R, 1);

julia> A, _ = quo(F, [x^4*F[1]]);

julia> B, _ = quo(F, [x^3*F[1]]);

julia> a = hom(A, B, [x^2*B[1]]);

julia> b = hom(B, B, [x^2*B[1]]);

julia> C = chain_complex([a, b]; seed = 3);

julia> range(C)
5:-1:3

julia> C[5]
Subquotient of Submodule with 1 generator
1 -> e[1]
by Submodule with 1 generator
1 -> x^4*e[1]

julia> map(C, 5)
Map with following data
Domain:
=======
Subquotient of Submodule with 1 generator
1 -> e[1]
by Submodule with 1 generator
1 -> x^4*e[1]
Codomain:
=========
Subquotient of Submodule with 1 generator
1 -> e[1]
by Submodule with 1 generator
1 -> x^3*e[1]

## Operations on Complexes

shift(C::ComplexOfMorphisms{T}, d::Int) where T

Return the complex obtained from C by shifting the homological degrees d steps, with maps multiplied by $(-1)^d$.

##### Examples
julia> R, (x,) = PolynomialRing(QQ, ["x"]);

julia> F = free_module(R, 1);

julia> A, _ = quo(F, [x^4*F[1]]);

julia> B, _ = quo(F, [x^3*F[1]]);

julia> a = hom(A, B, [x^2*B[1]]);

julia> b = hom(B, B, [x^2*B[1]]);

julia> C = chain_complex([a, b]; seed = 3);

julia> range(C)
5:-1:3

julia> D = shift(C, 3);

julia> range(D)
8:-1:6
homMethod
hom(C::ComplexOfMorphisms{ModuleFP}, M::ModuleFP)

Return the complex obtained by applying $\text{Hom}(-,$ M$)$ to C.

If C is a chain complex, return a cochain complex. If C is a cochain complex, return a chain complex.

Examples

julia> R, (x,) = PolynomialRing(QQ, ["x"]);

julia> F = free_module(R, 1);

julia> A, _ = quo(F, [x^4*F[1]]);

julia> B, _ = quo(F, [x^3*F[1]]);

julia> a = hom(A, B, [x^2*B[1]]);

julia> b = hom(B, B, [x^2*B[1]]);

julia> C = chain_complex([a, b]; seed = 3);

julia> range(C)
5:-1:3

julia> D = hom(C, A);

julia> range(D)
3:5
source
hom_without_reversing_directionMethod
hom_without_reversing_direction(C::ComplexOfMorphisms{ModuleFP}, M::ModuleFP)

Return the complex obtained by applying $\text{Hom}(-,$ M$)$ to C.

If C is a chain complex, return a chain complex. If C is a cochain complex, return a cochain complex.

Examples

julia> R, (x,) = PolynomialRing(QQ, ["x"]);

julia> F = free_module(R, 1);

julia> A, _ = quo(F, [x^4*F[1]]);

julia> B, _ = quo(F, [x^3*F[1]]);

julia> a = hom(A, B, [x^2*B[1]]);

julia> b = hom(B, B, [x^2*B[1]]);

julia> C = chain_complex([a, b]; seed = 3);

julia> range(C)
5:-1:3

julia> D = hom_without_reversing_direction(C, A);

julia> range(D)
-3:-1:-5
source
homMethod
hom(M::ModuleFP, C::ComplexOfMorphisms{ModuleFP})

Return the complex obtained by applying $\text{Hom}($M, $-)$ to C.

source
tensor_productMethod
tensor_product(C::ComplexOfMorphisms{ModuleFP}, M::ModuleFP)

Return the complex obtained by applying $\bullet\;\! \otimes$ M to C.

source
tensor_productMethod
tensor_product(M::ModuleFP, C::ComplexOfMorphisms{ModuleFP})

Return the complex obtained by applying M $\otimes\;\! \bullet$ to C.

source

## Tests on Complexes

The functions below check properties of complexes:

is_chain_complex(C::ComplexOfMorphisms{ModuleFP})
is_cochain_complex(C::ComplexOfMorphisms{ModuleFP})
is_exact(C::ComplexOfMorphisms{ModuleFP})
##### Examples
julia> R, (x,) = PolynomialRing(QQ, ["x"]);

julia> F = free_module(R, 1);

julia> A, _ = quo(F, [x^4*F[1]]);

julia> B, _ = quo(F, [x^3*F[1]]);

julia> a = hom(A, B, [x^2*B[1]]);

julia> b = hom(B, B, [x^2*B[1]]);

julia> R, (x,) = PolynomialRing(QQ, ["x"]);

julia> C = chain_complex([a, b]);

julia> is_cochain_complex(C)
false