maps between chain complexes

One way to make maps between chain complexes is by lifting maps between modules to resolutions of those modules. First we make some modules.
 i1 : R = QQ[x,y]; i2 : M = coker vars R o2 = cokernel | x y | 1 o2 : R-module, quotient of R i3 : N = coker matrix {{x}} o3 = cokernel | x | 1 o3 : R-module, quotient of R
Let's construct the natural map from N to M.
 i4 : f = inducedMap(M,N) o4 = | 1 | o4 : Matrix
Let's lift the map to a map of free resolutions.
 i5 : g = res f 1 1 o5 = 0 : R <--------- R : 0 | 1 | 2 1 1 : R <------------- R : 1 {1} | 1 | {1} | 0 | 1 2 : R <----- 0 : 2 0 o5 : ChainComplexMap
We can check that it's a map of chain complexes this way.
 i6 : g * (source g).dd == (target g).dd * g o6 = true
We can form the mapping cone of g.
 i7 : F = cone g 1 3 2 o7 = R <-- R <-- R <-- 0 0 1 2 3 o7 : ChainComplex
Since f is surjective, we know that F is quasi-isomorphic to (kernel f)[-1]. Let's check that.
 i8 : prune HH_0 F o8 = 0 o8 : R-module i9 : prune HH_1 F o9 = cokernel {1} | x | 1 o9 : R-module, quotient of R i10 : prune kernel f o10 = cokernel {1} | x | 1 o10 : R-module, quotient of R
There are more elementary ways to make maps between chain complexes. The identity map is available from id.
 i11 : C = res M 1 2 1 o11 = R <-- R <-- R <-- 0 0 1 2 3 o11 : ChainComplex i12 : id_C 1 1 o12 = 0 : R <--------- R : 0 | 1 | 2 2 1 : R <--------------- R : 1 {1} | 1 0 | {1} | 0 1 | 1 1 2 : R <------------- R : 2 {2} | 1 | 3 : 0 <----- 0 : 3 0 o12 : ChainComplexMap i13 : x * id_C 1 1 o13 = 0 : R <--------- R : 0 | x | 2 2 1 : R <--------------- R : 1 {1} | x 0 | {1} | 0 x | 1 1 2 : R <------------- R : 2 {2} | x | 3 : 0 <----- 0 : 3 0 o13 : ChainComplexMap
We can use inducedMap or ** to construct natural maps between chain complexes.
 i14 : inducedMap(C ** R^1/x,C) 1 o14 = 0 : cokernel | x | <--------- R : 0 | 1 | 2 1 : cokernel {1} | x 0 | <--------------- R : 1 {1} | 0 x | {1} | 1 0 | {1} | 0 1 | 1 2 : cokernel {2} | x | <------------- R : 2 {2} | 1 | o14 : ChainComplexMap i15 : g ** R^1/x o15 = 0 : cokernel | x | <--------- cokernel | x | : 0 | 1 | 1 : cokernel {1} | x 0 | <------------- cokernel {1} | x | : 1 {1} | 0 x | {1} | 1 | {1} | 0 | o15 : ChainComplexMap
There is a way to make a chain complex map by calling a function for each spot that needs a map.
 i16 : q = map(C,C,i -> (i+1) * id_(C_i)) 1 1 o16 = 0 : R <--------- R : 0 | 1 | 2 2 1 : R <--------------- R : 1 {1} | 2 0 | {1} | 0 2 | 1 1 2 : R <------------- R : 2 {2} | 3 | 3 : 0 <----- 0 : 3 0 o16 : ChainComplexMap
Of course, the formula we used doesn't yield a map of chain complexes.
 i17 : C.dd * q == q * C.dd o17 = false