
The structure of lifelib
------------------------

The idea behind `lifelib` is a universal framework in which different
high-level **algorithms** such as Bill Gosper's Hashlife can seamlessly
integrate with different low-level **iterators** for running specific
rules on various architectures. There are currently three algorithms
supported by `lifelib`:

 - **Hashlife**: This is the celebrated algorithm by Bill Gosper used
   to gain exponential speedups by exploiting repeated structure in both
   space and time. It operates directly on a compressed representation
   called a 'hashed quadtree'. Due to its efficiency, simplicity and
   generality, this is recommended as the default algorithm.

 - **Streamlife**: This is a new (2018) modification of Hashlife designed
   to work efficiently on patterns containing antiparallel streams of
   information-carrying gliders, such as certain self-replicating
   machines. Streamlife works by disentangling a pattern into provably
   non-interacting parts which can be run in separate 'universes'. This
   algorithm is inspired by China Mieville's novel, 'The City and The
   City', and borrows much of its terminology.

 - **Tile-based**: Whereas the other algorithms are best for patterns
   exhibiting regular behaviour, this is well-suited for running random
   patterns. It is only available in the C++ version of `lifelib` and
   is aimed at [apgsearch](https://gitlab.com/apgoucher/apgmera), which
   runs random soups in a Monte Carlo fashion and logs their eventual
   decay products. The tile-based algorithm optimises for areas of the
   universe that do not change, excluding them from future calculations
   until necessary.

Whereas the Streamlife implementation is only suited to Conway's Game of
Life and close variants thereof, the other two algorithms (Hashlife and
tile-based) are fully compatible with every `lifelib` iterator.

In `lifelib`, an **iterator** is an efficient low-level implementation of
a cellular automaton, which runs on a $`32 \times 32`$ grid and returns
the central $`16 \times 16`$ subgrid after one or more generations. The
philosophy behind `lifelib` is that any of these iterators can seamlessly
plug into either the Hashlife or tile-based algorithm, 'upgrading' it
from a small $`32 \times 32`$ universe to an unbounded universe.

The iterators themselves are written mostly in C and inline assembly
language, specifically tailored to your machine's instruction set and to
the cellular automaton being simulated. Iterators are generated by Python
modules called **genera** (singular: genus), each one of which targets a
specific family of related rules. At the moment, `lifelib` contains nine
different genera, but there is nothing to prevent you from adding more
of your own:

 - **b3s23life**: This genus supports only one rule, namely Conway's Game
   of Life, and produces iterators with remarkably low instruction counts
   (and concomitantly high speed!). It can yield iterators compatible with
   either AVX-512, AVX2, AVX, or SSE, and chooses the most advanced
   instruction set supported by your processor.

 - **lifelike**: This genus is more general, and supports any 2-state
   outer-totalistic cellular automaton on the Moore neighbourhood. It can
   produce optimised code for either AVX2, AVX, or SSE. As with b3s23life,
   this genus uses bitwise parallelism and vectorisation to compute many
   cells simultaneously.

 - **isotropic**: This is again more general, supporting any isotropic
   2-state Moore-neighbourhood cellular automaton. It is not as fast as
   the lifelike genus, as it is not vectorised and instead computes 8 cells
   at a time using a lookup table.

 - **ltl**: A SSSE3-based byte-parallel implementation of Kellie Evans'
   'Larger than Life' cellular automata. It supports square neighbourhoods
   with a radius up to 7 (i.e. $`15 \times 15`$).

 - **generations**: A multistate generalisation of lifelike. Internally, it
   uses the vectorised lifelike iterator as a subroutine.

 - **isogeny**: A multistate generalisation of isotropic.

 - **gltl**: A multistate generalisation of Larger than Life.

 - **bsfkl**: Brian Prentice's 3-state BSFKL rules generalise both 3-state
   Generations rules and outer-totalistic cellular automata.

 - **hrot**: Higher-range outer-totalistic rules, a common generalisation of
   Lifelike and 'Larger than Life' rulesets. This genus supports square
   neighbourhoods with a radius up to 5 (i.e. $`11 \times 11`$).

The design of `lifelib` restricts iterators to have a maximum neighbourhood
radius of 8 and a maximum of $`2^{64}`$ states. (Note that this is a proper
superset of the custom rules supported by Golly's RuleLoader, which are
restricted to a radius of 1 and a maximum of 256 states.)
