FP Mods

As part of my masters thesis, I worked with Bob Bruner to develop a Sage package for working with Finitely Presented
Modules over the Steenrod Algebra. This is currently being developed to be included with current versions of sage. A
full introduction can be found at Finitely Presented modules over the Steenrod Algebra in Sage.
The code itself can be found here: fpmods.py If you find any bugs, which is likely, please send me a brief email
with a code snippet.

Note: The current code was written with Sage version 4.7.1 and is not yet fully compatible with newer versions.

Quick Summary

This is a very brief introduction to the Sage package FPMods. Here is a full introduction including a discussion of all
implemented functions and their algorithms. After placing the source file in your current working directory, start sage
and type

sage: load fpmods.py

to load the FPMods package. With this, you can define

  • finitely presented modules,
  • their elements, and
  • homomorphisms between them

over the Steenrod Algebra. These correspond to the classes

  • FP_Module
  • FP_Element
  • FP_Hom

Modules

A finitely presented module is completely defined by a list of degrees (of generators) and a list of relations. This is
all that is needed to define an FP_Module at the prime 2, as in

sage: M = FP_Module([2,3],[[Sq(2),Sq(1)],[0,Sq(2)]])
sage: x = M.gen(0)
sage: y = M.gen(1)

This defines M to be the left A-module on two generators, and gives them the names x (in degree 2) and y
(in degree 3), with two relations: Sq(2)*x = Sq(1)*y and 0 = Sq(2)*y (here A is the mod 2 Steenrod Algebra).
For modules over an odd primary Steenrod Algebra, an optional char parameter or algebra parameter must
be passed. All object classes (FP_Module, FP_Element, and FP_Hom) have an alg() method, keeping
track of the smallest sub-Hopf algebra B of A over which the object is defined. This does not force the object
into the category of B-modules. For example, a resolution of

sage: N = FP_Module([0],[[Sq(1)],[Sq(2)]])

can be interpreted as a resolution of F_2 over A(1) or as a resolution of A//A(1) over A (or the
corresponding module over some sub-Hopf algebra in between).

Elements

An element can be defined by passing a list of coefficients (elements of the Steenrod Algebra) to the element
constructor of an FP_Module, as in

sage: z = M([Sq(1),1])

This defines z to be Sq(1)*x + y.

Elements must be homogeneous, and summands must belong to the same module. The above definitions of x
and y show another way of defining FP_Elements using the gen() method of FP_Modules.

WARNING: For some reason, the action must be written as a right action, although we stress that it
really is a left action
. So to express Sq(1) acting on x, at the prompt we type x*Sq(1), and think about
this as Sq(1)*x.

Morphisms

Morphisms are defined with the FP_Hom class. A homomorphism must be well-defined, i.e. it must send the
relations to zero. So the following would be fine

sage: f = FP_Hom(N,M,[0,Sq(1)])

to define the map f which sends the generator of N to Sq(1)*y (which also happens to be Sq(2)*x).
However, the attempts to define maps

sage: g = FP_Hom(N,M,[x*Sq(1)])
sage: h = FP_Hom(N,M,M([0,1]))

would raise errors: the map g does not preserve degree and the map h does not send the relation Sq(1) to 0.

Resolutions

FP_Modules have a resolution method, allowing free resolutions to be computed. For example,

sage: N = FP_Module([0],[[Sq(1)],[Sq(2)]])
sage: R = N.resolution(5)

defines R to a free resolution of N of length 5. The list R is the list of maps; the (free) modules in the
resolution will be R[i].domain for i in [0,…,length(R) -1]. To compute syzygies, one could re-compute the
kernels of these maps, or call the associated function

sage: R,K = N.resolution_kernels(5)

which defines R as above, and sets K to a list of pairs. The n-th entry is (K_n,i_n). K_n is the kernel of
the n-th map, and i_n is the inclusion of this module into the domain of R_n.

Chain Maps

Given two chain complexes L and R, and a map f from the codomain of L_0 to the codomain of R_0,

F = chain_map(L,R,f)

sets F to a chain map lifting f between the complexes.

Extensions

Given a cocycle e in Ext^1(M3,M1) and a resolution R of M3,

M,i,j = extension(R,e)

computes the associated extension:

0 –> M3 –i–> M –j–> M1 –> 0