Homological Algebra in Maxima



Hi Maxima Gurus,

in order to finish my topology final, I wanted to check my
computations with the K\"unneth theorem etc. with the computer.  I
wanted to do it with maxima, but couldn't think of how.  I was able to
do it very simply in math'a.  Can any of you help me figure out how to
do the following sort of thing with maxima in the future?

First, I set up some rewrite rules for the tensor product, Tor, Hom
and Ext (by no means exhaustive; these simply sufficed for the
computations I needed to carry out---I was doing everything with Z
coefficients and all the multiplicand spaces had homologies built from
Z and Z_n).  Here, I'm using Z[n] to denote Z_n.  I didn't even
implement bilinearity fully, just the transformations that arose in my
problems:

Tens[0, G_] := 0;
Tens[G_, 0] := 0;
Tens[Z, G_] := G;
Tens[G_, Z] := G;
Tens[Z[n_], Z[m_]] := Z[GCD[n, m]];
Tens[A_ + B_, G_] := Tens[A, G] + Tor[B, G];
Tens[A_, G_ + H_] := Tens[A, G] + Tor[A, H];

Tor[Z, _] := 0;
Tor[_, Z] := 0;
Tor[0, _] := 0;
Tor[_, 0] := 0;
Tor[Z[n_], Z[m_]] := Z[GCD[n, m]];
Tor[A_ + B_, G_] := Tor[A, G] + Tor[B, G];
Tor[A_, G_ + H_] := Tor[A, G] + Tor[A, H];

Hom[Z, Z] := Z;
Hom[Z[n_], Z] := 0;
Hom[Z, Z[n_]] := 0;
Hom[0, _] := 0;
Hom[Z[n_], Z[m_]] := Z[GCD[n, m]];
Hom[A_ + B_, G_] := Hom[A, G] + Hom[B, G];
Hom[A_, G_ + H_] := Hom[A, G] + Hom[A, H];
Hom[n_Integer A_, G_] := n*Hom[A, G];

Ext[Z, _] := 0;
Ext[0, _] := 0;
Ext[Z[n_], Z] := Z[n];
Ext[Z[n], Z[m]] := Z[GCD[n, m]];
Ext[A_ + B_, G_] := Ext[A, G] + Ext[B, G];
Ext[A_, G_ + H_] := Ext[A, G] + Ext[A, H];
Ext[n_Integer A_, G_] := n*Ext[A, G];

The idea is to represent a chain complex just as a list, and to
implement Kunneth as a function that maps two lists to a single one.
I assume in the following that the product space has a single
component and hence homology Z in dimension 1 (again, I thew this
together very hastily):

kunneth[C_List, D_List] :=
  Block[{l = Length[C] + Length[D] - 2},
    Block[{CC = Join[C, Table[0, {2*l}]], DD = Join[D, Table[0, {2*l}]]},
      Prepend[
        Table[
          Sum[Tens[CC[[i + 1]], DD[[n - i + 1]]], {i, 0, n}]
            + Sum[Tor[CC[[i + 1]], DD[[n - 1 - i + 1]]], {i, 0, n - 1}],
          {n, 1, l}], Z]]]

So, for example, to compute H_*(S^1 \times S^1), I just do

kunneth[{Z,Z},{Z,Z}] => {Z, 2 Z, Z}

(I'm using the built-in addition to represent direct products of
groups so 2 Z means Z \oplus Z.)

Similarly, I can implement the universal coefficient theorem to
compute cohomology from homology with

uctCohomology[C_List] :=
  Block[{CC = Append[C, 0]},
    Prepend[
      Table[Hom[CC[[n + 1]], Z] + Ext[CC[[n - 1 + 1]], Z], {n, 1, Length[C]}],Z]]

Now, by Poincare duality, this usually will just give you homology in
reverse, but in principle it should be useful in more general
settings...

Anyway, it's not a super-sturdy, general system.  The point was that I
just needed to check some tedious algebra quickly.  For instance, I
had to compute the homology of the product of lens spaces:

kunneth[{Z, Z[nn], 0, Z}, {Z, Z[mm], 0, Z}]
  => {Z, Z[mm] + Z[nn], Z[GCD[mm, nn]], 2 Z + Z[GCD[mm, nn]], Z[mm] + Z[nn], 0, Z}

So, I just would like to be able to throw together naive little
specialized rewrite systems quickly with maxima, if possible.

Any ideas?

Thanks,
  Carl