For reasons that shall soon become clear, I found myself faced with the task of sorting a list of 12 objects.

Usually one would choose an algorithm such as *quicksort* or *Timsort*. Conventional comparison-based sorting algorithms operate by comparing pairs of objects, and are otherwise unrestricted: the choices of objects to compare can depend on the results of previous comparisons.

A *sorting network* is a much more restricted sorting algorithm, where the only allowed operation is the compare-exchange instruction CMPX(*i*, *j*). This compares objects in positions *i* and *j*, swapping them if they are in the wrong order, and revealing no information. Here are the best known sorting networks on 9 and 12 elements, photographed from *The Art of Computer Programming* by Donald Knuth:

So, with straight-line code of 39 CMPX instructions it is possible to sort a collection of 12 objects without any need for loops, conditional branching, or any other form of control flow. This is especially useful when programming a GPU, where control flow is toxic for performance.

I proceeded to transcribe the sorting network from the above diagram into CUDA code. As a mere mortal, I was not totally convinced that I’d copied it flawlessly, so resorted to building a test to verify the correctness of the transcribed network. Preferring to do this in a high-level language such as Python, I resorted to my usual tricks of writing a single file which is valid in two languages and incorporating it into the source code by means of one innocuous line: **#include “sorting_network.py”**

(If you think this is bad, people have done much worse…)

Examining the Python component of the code, you may notice that it only tests the 2^12 different binary sequences, rather than the 12! different totally ordered sets. It is a general property of comparator networks that it suffices to only test binary sequences to prove that the network can sort arbitrary sequences; this is known as the 0-1 principle.

What is the minimum number of CMPX gates necessary to sort *n* objects? And what is the minimum circuit depth? The naive algorithm of bubble sort shows that a gate-count of O(*n*^2) and a circuit depth of O(*n*) are both attainable. Similarly, the gate-count must be at least the binary logarithm of *n*! (as with any comparison-based sorting algorithm) which gives a lower bound of Ω(*n log n*) for the gate-count and Ω(*log n*) for the depth.

Batcher found a recursive construction of sorting networks with a depth of ½*k*(*k*+1), where *k* is the ceiling of the binary logarithm of *n*, and each layer has ½*n* comparators. This is achieved by firstly Batcher-sorting the initial and final halves of the sequence, followed by interleaving them (diagram by User:Bitonic from Wikipedia):

The correctness of the algorithm follows from the aforementioned 0-1 principle. By the inductive hypothesis, it suffices to examine the rightmost blue box and suppose that the two halves of the input are correctly sorted, in which case the input would resemble:

[n/2 – m zeroes] [m ones] | [l zeroes] [n/2 – l ones]

The only ‘cross-lane’ operations are the comparators in the brown box. If l is no greater than m, the result of this is the following:

[n/2 – m zeroes] [m – l ones] [l zeroes] | [n/2 ones]

and otherwise we get the complementary arrangement:

[n/2 zeroes] | [m ones] [l – m zeroes] [n/2 – l ones]

Concentrating only on the non-constant half, our task is reduced to the simpler problem of sorting a binary sequence which switches at most twice between a run of zeroes and a run of ones. We can split the effect of the pink box into two modules: one which reverses one of the two halves (we get to decide which half!), followed by one which behaves identically to a brown box. Observe that, as before, one of the two halves of the pink box must therefore be constant, and the other must again be a binary sequence which switches at most twice. By induction, the result follows.

Owing to the low depth, simplicity, and efficiency, Batcher’s bitonic mergesort is often used for sorting large lists on GPUs.

But is the bitonic mergesort optimal? The circuit above takes 80 comparators to sort 16 inputs, whereas the best circuit in Knuth takes only 60 comparators (again with a depth of 10). It’s not even optimal for depth, as the next page of Knuth has a 61-comparator sorting network with a depth of 9.

What about asymptotics? The bitonic mergesort gives an upper bound on the depth of O((*log n*)^2) and basic information theory gives a lower bound of Ω(*log n*).

The next surprise was when Szemeredi, Komlos and Ajtai proved that the lower bound is tight: they exhibited a construction of sorting networks of optimal depth O(*log n*). As you can imagine from Szemeredi’s background in combinatorics and extremal graph theory, the construction relies on a family of graphs called *expanders*.

A simplified version of the construction (by Paterson, 1990) is described here. The original paper provides explicit constants, showing that a depth ~ 6100 log(*n*) is possible, compared with ~ ½ log(*n*)^2 for Batcher’s bitonic mergesort. In other words, the threshold for switching from bitonic mergesort to Paterson’s variant of AKS occurs when *n* is approximately 2^12200.

A further improvement by Chvatal reduces the asymptotic constant from 6100 to 1830, and actually provides an explicit (non-asymptotic) bound: provided *n* ≥ 2^78, there is a sorting network of depth 1830 log(*n*) − 58657. This reduces the crossover point to exactly *n* ≥ 2^3627. As Knuth remarked, this is still far greater than the number of atoms in the observable universe, so the practical utility of the AKS sorting algorithm is questionable.

Interestingly, this is not the first time there has been an asymptotically impressive algorithm named AKS after its authors: a set of three Indian Institute of Technology undergraduates {Agrawal, Kayal, Saxena} found the first unconditional deterministic polynomial-time algorithm for testing whether an *n*-digit number is prime. This O(*n*^(6+o(1)) algorithm tends not to be used in practice, because everyone believes the Generalised Riemann Hypothesis and its implication that the O(*n*^(4+o(1)) *deterministic Miller-Rabin algorithm* is correct.

- For Northern Ireland to have dual EU/UK status;
- For there to be a 10-mile ‘trade buffer zone’ between Northern Ireland and the Republic of Ireland.

The second is more interesting from a mathematical perspective: the 10-mile buffer zone means that (the closures of) Northern Ireland and the Republic of Ireland are disjoint compact subsets of a normal topological space. By Urysohn’s Lemma, this means that there exists a continuous function such that is identically 0 on Northern Ireland and identically 1 on the Republic of Ireland.

The proof of this proceeds as follows:

- By taking closures, assume without loss of generality that NI and ROI are both closed and disjoint (the interior 10-mile buffer zone is not considered to belong to either).
- Define U(1) and V(0) to be the complements of NI and ROI, respectively. These are overlapping open sets, whose intersection is the buffer zone.
- For each :
- For each dyadic rational with denominator and odd numerator:
- Let and , so are adjacent;
- By appealing to the normality of Ireland, let U(r) and V(r) be two disjoint open sets containing the complements of V(q) and U(s), respectively.

- For each dyadic rational with denominator and odd numerator:
- Now we have disjoint open sets U(r) and V(r) for each dyadic rational r, such that the U(r) form an ascending chain of nested spaces.
- Define (where the infimum of an empty set is taken to be 1).

With this interpolating function , it is easy to take convex combinations of EU and UK standards. For example, a road sign at a point x must be stated in ‘lengths per hour’, where one length is exactly 1 + 0.609344(1 – f(x)) kilometres.

]]>In other news, following on from Aubrey de Grey’s 5-chromatic unit-distance graph, there has been an effort to study the algebraic structure of the graphs. Specifically, viewing the vertices as points in the complex plane, one can ask what number fields contain the vertices of the unit-distance graphs.

In particular, it was noted that both Moser’s spindle and Golomb’s graph, the smallest examples of 4-chromatic unit-distance graphs, lie in the ring , where is a complex number with real part and absolute value 1. Ed Pegg Jr produced a beautiful demonstration of this:

Philip Gibbs showed that the entire ring, and consequently all graphs therein, can be coloured by a homomorphism to a four-element group. Consequently, Ed Pegg’s hope that the large unit-distance graph above is 5-chromatic was doomed to fail — but that is not too much of a worry now that we have de Grey’s 5-chromatic graph.

Several of Marijn Heule’s 5-chromatic graphs lie in . Apparently both this ring and have homomorphic 5-colourings, so we cannot find a 6-chromatic unit-distance graph lying in either of these rings.

Incidentally, the record is a 610-vertex example, again due to Heule:

]]>Aubrey de Grey (!!!) has found a unit-distance graph with 1567 vertices and a chromatic number of 5. This implies that the chromatic number of the plane is between 5 and 7, the latter bound obtainable from 7-colouring the cells of an appropriately-sized hexagonal lattice. Before, the best lower bound was 4 (from the Moser spindle).

There is now a polymath project to reduce the number of vertices from 1567. Marijn Heule, whom I mentioned last time for providing me with the incremental SAT solver used to find Sir Robin, has already reduced it down to 874 vertices and 4461 edges.

The results of the European Girls’ Mathematical Olympiad have been published. The UK came third worldwide, just behind Russia and the USA. Moreover, Emily Beatty was one of five contestants to gain all of the available marks, and apparently the first UK contestant to do so in any international mathematical competition since 1994.

It appears that EGMO has been following the example of the Eurovision Song Contest in determining which countries are European, rather than actually verifying this by looking at a map. Interesting additions include the USA, Canada, Saudi Arabia, Israel, Australia, Mongolia, Mexico and Brazil. The list of participating countries states that there are 52 teams, of which 36 are officially European (and a smaller number still are in the EU).

Restricting to the set of countries in the European Union, the UK won outright (three points ahead of Poland), which was the last opportunity to do so before the end of the Article 50 negotiations. Hungary and Romania put in a very strong performance, as expected.

]]>- Voevodsky’s
*univalence axiom*states that equivalent types are equal, and more specifically that the space of equivalences between two types is equivalent to the space of paths between two types; - The introduction of
*higher inductive types*which define not only their elements (vertices) but also paths, 2-cells (paths between paths), and so forth.

An advantage of intuitionistic type theory is that the lack of axioms mean that all proofs of constructive. Including the univalence axiom breaks this somewhat, which is why people have been searching for a way to adapt type theory to admit univalence not as an axiom, but as a theorem.

Cubical type theory was introduced as a constructive formulation which includes univalence and has limited support for certain higher inductive types. A recent paper by Thierry Coquand (after whom the automated theorem-prover Coq is named), Simon Huber, and Anders Mörtberg goes further towards constructing higher inductive types in cubical type theory.

]]>He also produced a video describing the relationship between the Voronoi cells of the diamond and related lattices.

Mathematically, the set of centres of atoms in a diamond form a structure called . It has a natural *n*-dimensional generalisation, which can be viewed as follows:

- Take the integer lattice ;
- Partition it into two subsets, called E and O, consisting of the points whose coordinate-sums are even and odd, respectively;
- Translate the set O such that it contains the point (½, ½, ½, …, ½), and leave E where it is.

This construction makes it adamantly* clear that the ‘hyperdiamond’ has the same density as the integer lattice, and therefore the Voronoi cells have unit volume. A lattice with this property (such as the hyperdiamonds of even dimension) is described as *unimodular*.

*bizarrely, this word has the same etymology as ‘diamond’, namely the Greek word *adamas* meaning ‘indestructible’. I often enjoy claiming that my own given name is also derived from this same etymology.

In the special case where *n* = 8, this is the remarkable E8 lattice, which Maryna Viazovska proved is the densest way to pack spheres in eight-dimensional space. One could imagine that if beings existed in eight-dimensional space, they would have very heavy diamond engagement rings! It is an *even unimodular lattice*, meaning that the inner product of any two vectors is an even integer, and is the unique such lattice in eight dimensions. They can only exist in dimensions divisible by 8, and are enumerated in A054909.

If *n* = 16, the hyperdiamond gives one of two even unimodular 16-dimensional lattices, the other being the Cartesian product of E8 with itself. These two lattices have the same theta series (sequence giving the number of points at each distance from the origin), but are nonetheless distinct. If you take the quotients of 16-dimensional space by each of these two lattices, you get two very similar (but non-isometric) tori which Milnor gave as a solution to the question of whether two differently-shaped drums could produce the same sound when reverberated.

John Baez elaborates on the sequence of ‘hyperdiamonds’, together with mentioning an alternative three-dimensional structure called the triamond, here.

There are 24 even unimodular lattices in 24 dimensions, the so-called Niemeier lattices, of which the most famous and stunning is the Leech lattice. This was also proved by Viazovska and collaborators to be the densest sphere packing in its dimension. Unlike the hyperdiamonds, however, the Leech lattice is remarkably complicated to construct.

Whereas the shortest nonzero vectors in the Leech lattice have squared norm of 4, the other 23 Niemeier lattices have *roots* (elements of squared norm 2). The Dynkin diagrams of these root systems identify the lattices uniquely, and conversely all Dynkin diagrams with certain properties give rise to Niemeier lattices.

The 23 other Niemeier lattices correspond exactly to the equivalence classes of *deep holes* in the Leech lattice, points at a maximum distance from any of the lattice points.

Naturally, you are probably already aware of many of her contributions to mathematics and theoretical physics, including Noetherian rings and Noether’s theorem. I was pleasantly surprised to hear that she also laid the foundations of homology theory, which is especially pertinent as my research in topological data analysis is built upon these ideas.

For more information, see the wonderful Wikipedia article entitled List of things named after Emmy Noether. It appears that it is incomplete, omitting the Emmy Noether Society of Cambridge.

Finally, even at the age of five her surname anticipated the result of the Michelson-Morley experiment which proved that there was, in fact, no ether…

]]>(I thank Avi Wigderson for telling me about it.) Serge Vlăduţ just arxived a paper with examples of lattices in such that the kissing number is exponential in . The existence of such a…]]>

Conway and Sloane’s excellent tome, Sphere Packings, Lattices and Groups, is now due a fourth edition. Maryna Viakovska’s proofs of optimality of the E8 and Leech lattices should go in the fourth edition as well…

(I thank Avi Wigderson for telling me about it.) Serge Vlăduţ just arxived a paper with examples of lattices in $latex R^n$ such that the kissing number is exponential in $latex n$. The existence of such a lattice is a very old open problem and the best record was an example where the kissing number is $latex n^{log n}$. (This is based on a 1959 construction of Barnes and Wall and can be found in the famous book by Conway and Sloane.) Noga Alon found in 1997 collections of spheres so that each one touches subexponentially many others. Vlăduţ’s result is very exciting!

A crucial step was a result by Ashikhmin, Barg, and Vlăduţ from 2001 showing that certain algebraic-geometry binary linear codes have exponentially many minimal weight vectors. (This result disproved a conjecture by Nati Linial and me.) This follows by applying in a very clever way early 80s…

View original post 129 more words

Academic papers, however, typically feature a polished proof which omits all of the insights and attempts and failures which led to its discovery. This post attempts to remedy that by presenting a chronological itemisation of the journey; the technical details will be largely reserved for the paper.

The previous term I had been supervising a lecture course on Graph Theory for the university. One of the questions on the final example sheet was the following:

11. Let G be a graph in which every edge is in a unique triangle and every non-edge is a diagonal of a unique 4-cycle. Show that |G| ∈ {3, 9, 99, 243, 6273, 494019}.

The usual method of solving this problem is to show that the graph must be regular, and therefore strongly regular; the resulting finite set of possibilities drops out from considering the eigenvalues of the adjacency matrix and observing that their multiplicities must be integers.

It is interesting to ask whether there actually exist suitable graphs with these numbers of vertices. For 3 vertices, a triangle obviously works; for 9 vertices, the toroidal 3-by-3 grid graph is a solution. There is also a known example with 243 vertices, related to the remarkable ternary Golay code. For 99, 6273, or 494019 vertices, however, it is unknown whether there is such a graph.

I mentioned in the supervision that John Conway had offered $1000 for a resolution of whether the 99-vertex graph exists, still unclaimed. One of my supervisees asked whether it could be amenable to computer search, and I responded that it might be within reach of a *SAT solver*: an algorithm for determining whether a set of Boolean equations has a solution.

The 99-graph problem is of a similar size to the Boolean Pythagorean Triples Problem, recently defeated by Marijn Heule and an army of SAT solvers. The UNSAT certificate (proof generated by the machine) is 200 terabytes in length, making it the largest proof of any mathematical problem in history. (The 13-gigabyte Erdös discrepancy proof, also found by SAT solvers, pales in comparison!)

At this point, I thought I would have a go at attacking the 99-graph problem myself. I’d done roughly as much exploration of the necessary structure of the graph as could be accomplished within a single side of A4 paper, and felt it was in a form amenable to SAT solving. I read several academic papers about SAT solvers, and closely monitored the competition results, to reach the conclusion that the state-of-the-art technique for approaching large SAT problems proceeds along lines similar to the following:

- Initially simplify the problem using
**lingeling -S**; - Split the problem space using
**march-cc**into thousands of separate ‘cubes’; - Share the cubes amongst parallel instances of the incremental SAT solver
**iglucose**.

I started to develop a framework, which I called MetaSAT, for automating this process. Coincidentally, at the same time, someone else also became interested in SAT solvers…

In his Odyssean epic *The Art of Computer Programming*, Donald Knuth dedicates a large section to SAT solvers with a particular emphasis on applying them to Conway’s Game of Life. This left the realms of theory and entered practice when Oscar Cunningham, who studied mathematics in Cambridge at roughly the same time as I did (and taught me how to play frisbee), wrote a Python script to search for patterns using Knuth’s ideas.

*Logic Life Search*, or LLS, is a sophisticated Python search program capable of using one of many different SAT solvers as backends to find patterns in various cellular automata.

This drove me to attempt to integrate these ideas into the MetaSAT project, so that I could search larger spaces than is possible with a single SAT solver. What I ended up doing was creating a simplified Golly-compatible version of LLS, called GRILLS. Whilst LLS is strictly more powerful, GRILLS has a more user-friendly graphical interface, and allows for loading results from previous runs:

I departed slightly from Donald Knuth’s binary-tree approach of counting neighbours, instead opting for a ‘split-radix’ binary-ternary tree. This reduced the number of variables needed by the SAT solver by 40%, without affecting the number of clauses, thereby making the problem slightly easier to digest (at least in principle).

The pinnacle of its success was being able to find an already-known c/4 orthogonal spaceship. Whilst showing that SAT solvers could replicate existing discoveries, there was no evidence that they could find anything new — in other words, they seemed to be trailing behind discoveries found with special-purpose CA search programs.

This changed at the end of the month. Tomas Rokicki had also implemented a Perl script to search for spaceships in cellular automata, and came across a new discovery. It is tiny, completely asymmetric, fits in a 13-by-13 box, and remains to be named anything other than its systematic name of xq3_co410jcsg448gz07c4klmljkcdzw71066.

He then turned to attempting to find *knightships*: elusive ships which move parallel to a knight in chess, rather than orthogonally or diagonally. Prior to 2010, oblique spaceships had never been built, and the only examples since then were huge slow constructions. The smallest two, Chris Cain’s *parallel HBK* and Brett Berger’s *waterbear*, are approximately 30000 cells in length. The waterbear is the only one which moves at a respectable speed, and its creator produced a video of it:

Finding a small knightship has been considered one of the holy grails of cellular automata. The closest attempt was Eugene Langvagen’s 2004 near-miss, which has a slight defect causing its tail to burn up:

In six generations, it almost translates itself by (2, 1), but differs in two cells from its original state. Very soon, this error propagates throughout the entire pattern and destroys it. In the 14 years following that, no-one has been able to find a perfect knightship.

Tom’s search, however, did yield increasingly long and increasingly promising partials. He found four further 2-cells-away near-misses, but no 1-cell-away or perfect solution, and statistical analysis (modelling the distribution of errors as a Poisson distribution) suggested that we would need another 2 years of searching to find a result.

On 3rd February, Oscar Cunningham cast doubts on the efficacy of his search program for finding a knightship, remarking the following:

I’m under the impression that programs called -find are just much better at finding ships than programs called -search. Is that true? If so then there’s not much point looking for a knightship with LLS.

He was referring to David Eppstein’s *gfind* search program, which conducts a depth-first row-by-row brute-force backtracking search. This, and its descendants, have been responsible for the vast majority of new spaceships discovered in cellular automata. David Eppstein wrote a paper detailing the methodology, which I suggest reading before proceeding with this post. (If you’re impatient, then take a cursory glance now and read the paper properly later.)

This gave me an idea: what if somehow Tom Rokicki’s partial-extending approach could be hybridised with the row-by-row tree-searching approach in gfind? I sent an e-mail to Tom to this effect:

Good news: I’ve realised that the methodologies of knightsearch and gfind

are entirely compatible. In particular:(a) Represent the search pattern as a two-dimensional lattice of unknown

cells by interleaving rows of different generations. (The way to do this for

a (2, 1)c/6 knightship is to take Z^3 and quotient by (2, 1, 6), giving a

two-dimensional lattice of unknown cells. Unlike in gfind, the ‘rows’ are

exactly perpendicular to the direction of travel, even for knightships.)Specifically, we map cell (x, y, t) to lattice coordinates (2x-y, 3y+t).

(b) The ‘state’ of the search is a 6-tuple of consecutive rows of length W.

The ‘search grid’ is a width-W height-(K+7) grid of lattice points, where

the first 6 rows are populated by the state, the next row is the ‘target’,

and the following K rows are for lookahead purposes. There are a few columns

of forced-dead cells on either side of the search grid. Pass this problem to

an incremental SAT solver to find all possibilities for the 7th row which

are consistent with the remaining K rows (I think gfind uses K = 1 or 2; SAT

solvers can clearly go much deeper). Each time the incremental SAT solver

gives a solution, provide the clause given by the negation of the 7th row

so that the next run gives a new possible 7th row. Repeat until UNSAT. The

‘child states’ are the 6-tuples obtained by taking the last 5 elements of

the parent 6-tuple and appending one of the possible 7th rows.(c) Run a breadth-first search starting with a small partial, using (b) each

time a new 6-tuple appears. We can canonise 6-tuples by doing a horizontal

shift to centre the non-zero columns into the middle of the search grid.

This means that the knightship needs only be *locally* thin, and is thereby

permitted to drift in various directions (similar to in knightsearch). The

narrowness of [the bitwise disjunction of the members of] a 6-tuple may

be a good heuristic to decide which nodes to attempt to extend first.(d) If you hit a dead-end, you can always rerun the already-found tuples

using higher values of W. Hence, the width need not be known in advance

when commencing the search. (If W increases particularly high, then it

may be necessary to decrease K to avoid overloading the SAT solver.)

Within the next few days, I implemented the aforementioned search program. It used the same backend (iglucose with named pipes for communication) as Tom’s search, but was otherwise very different.

Over the coming weeks, the search program grew in complexity, gaining various features and heuristics. In programs such as gfind, the search-width is set as a constant, and it either finds a solution or exhausts the search space to no avail. I implemented *adaptive widening*, where the latter causes the width to increment and the completed search to act as a backbone for the new (higher width) search.

Another approach, borrowed from cryptanalysis, is meet-in-the-middle: separately grow search trees of fronts and backs, and compare them to see whether they can join to form a complete solution.

One of the later changes I made, which logically should have been the first feature, is to save progress to disk and restore it. That way, I no longer needed to start the search afresh whenever I added a new optimisation to the program. I spent the next week running a width-35 search, saving the tree to disk every hour.

I resumed the search at width-0 to allow adaptive widening to take over, as smaller search widths lead to faster SAT solving. I also decided to adjoin one of Tom Rokicki’s partial results to the search tree to make things more interesting: this way, it would be able to piggy-back from his independent research. I watched the search width gradually increase as each completed without success, and as the night was drawing to a close it looked as though width-24 would finish as the queue gradually emptied:

Increasing head search width to 24... 280700 head edges traversed (qsize ~= 47966). 280800 head edges traversed (qsize ~= 47616). 280900 head edges traversed (qsize ~= 47369). 281000 head edges traversed (qsize ~= 47200). 281100 head edges traversed (qsize ~= 46993). 281200 head edges traversed (qsize ~= 46516). 281300 head edges traversed (qsize ~= 46180). 281400 head edges traversed (qsize ~= 45471). 281500 head edges traversed (qsize ~= 44632). 281600 head edges traversed (qsize ~= 44364). 281700 head edges traversed (qsize ~= 44036). 281800 head edges traversed (qsize ~= 43808). 281900 head edges traversed (qsize ~= 43231). 282000 head edges traversed (qsize ~= 43021). 282100 head edges traversed (qsize ~= 42759). 282200 head edges traversed (qsize ~= 42272). 282300 head edges traversed (qsize ~= 41795). 282400 head edges traversed (qsize ~= 41256). 282500 head edges traversed (qsize ~= 40706). 282600 head edges traversed (qsize ~= 40428). 282700 head edges traversed (qsize ~= 39523). 282800 head edges traversed (qsize ~= 38931). Saving backup backup_head_odd.pkl.gz Saved backup backup_head_odd.pkl.gz Saving backup backup_tail_even.pkl.gz Saved backup backup_tail_even.pkl.gz Backup process took 53.0 seconds. 282900 head edges traversed (qsize ~= 38000). 283000 head edges traversed (qsize ~= 37268). 283100 head edges traversed (qsize ~= 37023). 283200 head edges traversed (qsize ~= 36598). 283300 head edges traversed (qsize ~= 35869). Increasing tail search width to 11... ...adaptive widening completed. 283400 head edges traversed (qsize ~= 35024). 283500 head edges traversed (qsize ~= 33950). 283600 head edges traversed (qsize ~= 32596). 283700 head edges traversed (qsize ~= 31262). 283800 head edges traversed (qsize ~= 29728). 527600 tail edges traversed (qsize ~= 149949). 283900 head edges traversed (qsize ~= 28707). 284000 head edges traversed (qsize ~= 26488). 284100 head edges traversed (qsize ~= 24744). Saving backup backup_head_even.pkl.gz Saved backup backup_head_even.pkl.gz Saving backup backup_tail_odd.pkl.gz Saved backup backup_tail_odd.pkl.gz Backup process took 61.7 seconds. 284200 head edges traversed (qsize ~= 21792). 284300 head edges traversed (qsize ~= 19753). 284400 head edges traversed (qsize ~= 17345). 284500 head edges traversed (qsize ~= 14687). 284600 head edges traversed (qsize ~= 14041). 527700 tail edges traversed (qsize ~= 128776). 284700 head edges traversed (qsize ~= 12097). 284800 head edges traversed (qsize ~= 9503). 284900 head edges traversed (qsize ~= 8984). 285000 head edges traversed (qsize ~= 8388). 285100 head edges traversed (qsize ~= 6719). 285200 head edges traversed (qsize ~= 6670). 285300 head edges traversed (qsize ~= 6606). 285400 head edges traversed (qsize ~= 6548). 285500 head edges traversed (qsize ~= 6409). 285600 head edges traversed (qsize ~= 6463). 285700 head edges traversed (qsize ~= 6405). 285800 head edges traversed (qsize ~= 5271). 285900 head edges traversed (qsize ~= 5047). 286000 head edges traversed (qsize ~= 5030). 286100 head edges traversed (qsize ~= 5027). 286200 head edges traversed (qsize ~= 5089). 286300 head edges traversed (qsize ~= 5066). 286400 head edges traversed (qsize ~= 5056). 286500 head edges traversed (qsize ~= 5142). 286600 head edges traversed (qsize ~= 5241). 286700 head edges traversed (qsize ~= 5326). 286800 head edges traversed (qsize ~= 5344). 286900 head edges traversed (qsize ~= 5394). 287000 head edges traversed (qsize ~= 5298). 287100 head edges traversed (qsize ~= 4950). 287200 head edges traversed (qsize ~= 4618). 287300 head edges traversed (qsize ~= 4601). 287400 head edges traversed (qsize ~= 4646).

But then, something remarkable happened. It spewed out a series of long partials, which had extended from about two-thirds of the way along Tom Rokicki’s input partial and overtaken it! I then saw something which caught my eye:

Found partial head of length 249. As plaintext: .......................................* .....................................*** ....................................***** ...................................******.* ...................................***.*..* .................................**.*..*.* .................................**....*** ................................*.**....*.** ................................*....*.*..** .................................*...*.**..*.* .................................*...****** ................................*.......*.*.*...*.* ..............................***..........*....*.** .............................****.*...*.*.*..*.***** .............................*******.*.*..****..*.*** ...........................**.*.*.*....*....*.*.**..* ...........................**...*.*......*..***.**** .........................****..**.**........**...*.* ..........................**.......*..*...*.**......* ........................***........**.*.*.*.*....*.*.* .........................*..*.....**........*....**.** .......................**...*.*.*..*.......**..*..*** .......................*.**.*.*.**.*.*....***......*** .....................*..*.***.*.*.........*.***.....* ......................*......*..*.*.......**.***.*** .....................**.*.......*.*.....**** ....................*..*.*.*..**....*.*..*.**.....* ....................*.***.*...**....*.**....*...* .....................***.*....**.......*.*.....* .....................*...*.*.*..*.**.*..*...**.* ......................**.**...**..*.....*..***.*.* ........................*...*..***.**...**.**.*..* .......................**.*...**.**.*...**.*....* ......................*.*.......*..*...**..*.*..* ......................*.*..........*.*..*..*.*....* ................................*..*.*..**.*.**...* ..............................*.*......*.*.***.*..*.* ................................*..........*...*.*..* ..................................*..*.*.*....**.*.* ..................................*.*.*....*.***.*.** ....................................*.*..*.*...*....** ....................................*.**.***.....*.*.* ....................................*....***.*...*..** .....................................****..*.*.*..** .......................................*...***.**.**.* ...................................**..*...*.* ..................................***..*...**....*** .................................***...**......*.*.* ................................****.**.**......*.** ................................***..**....*.*..* ...............................****..*..*..*..*** ................................*....*....***** ................................*.....*...**..*..* ..............................*.*..*.******......* .................................*.**.*...**.**..* ...............................*.*.**.*...*...*.** ...............................*....***...**...** ................................*....*....*****.** ................................**..**..*..*.*..* ..............................****..**..***..*..*.* ..............................*.**..**.....*....* ..............................*.*....*.**..*...** .................................*..**.*.* ..............................******.**..*.*.** .............................***...*.*.*.*.****.* .............................*..............***** ...............................*.*....*.....**.** ................................*.*.*.*.*...* ..............................*.*...........**.* ..............................*.*.*.......***..** ............................*..............*...*** ...............................*...*.*.....*...*.* .............................*.*.*.......*.**.*..* ...........................*..*....*......*...*.** ...........................*.*............**.....** ...........................***.*..*.......**..*.** ............................**..........*.******* ..........................****.**.........***.*.* .............................*..................* ...........................***.*..............*.*.* ...........................*.*.......*.*.*.*.* ............................*......***.........* ..................................****.......* ..........................*......*****.......* ........................*........***......* ........................*..*.*.**.*..* ........................**.*..*......* ......................******..*.***..* ......................**.****.**.**..* .....................*.**..*......*.* .....................*.*...**.....*.*.* ...................*..*....**.*.**....* ...................*.***.****....*..*.** ....................***....*..*..*....** ....................*.........*.**..*.*** ........................**.*...*.*.**** .......................*.*.*.*...*..****...** ......................**.***.*...**.......**** .....................*.*.............*..****** .....................***.*....*.**..*******.** .....................**..**.*.*.*........**.** ...................*.**..*.*....*.**.....**.* ....................*.*.............**..*...* ....................*...*........**.*...* ...........................*.*.*.*..*...*.* .............................*....*.*...*.* ..................................*..*..*.* ................................*.**** ............................*......***.* .................................*.* .................................*.........* .......................................**..*.* .................................**.*.***** ................................***********.* ...............................**.*.*.*..*.* ................................*.*...*..*.** ..............................*.*.*.***..**** .............................**......*....*.*** ............................***.*........*...** ............................***.*.......*.**.* .............................**.*.*...*.****** .............................**.***......*...** ..............................*.**...........* ..............................*.***..*.*.*.* ..........................*.......*.......* ..........................*.*...*****.....* ........................**********..*.*.*.*.* ........................***.*...**.**.......* ......................*****......*.*...*.* .......................**....*......*...*** .....................***............**..*.*.* ......................*...*....***..**.***.** .....................**..****..*.*.*.*..**** ....................*.**.**.*.*..*....*.**.** ....................*..*.**.****.*.***..*....* .....................*.......*......*..*...*.* .......................**.*.***.....**.*..** ......................*.*....*.**....***..* .........................*..*..*....**.* ......................*.*..***.......* ......................**....** .....................*.*.**.* .......................*** ........................*..* .........................*.*.* ....................*..*.**..* ....................**.*.** ....................**.*.* ....................**.*.* ..................**.*.*.*.* ..................**.*.*.*** .................***.*.*.** .................*...*.*.* ................*..*...*.* ................*....*....* ...............*.*...*....* ...............*.*...****.* .............*****..****.*..* .............**.*...*.*....* ...........***.*......*.**.* ...........**..**.*.*.*.*..* ..........***..***...*..** ..........***..*..*...*.* ..........**..........* ..........*....*..**.** ........*.*..*.*.......* ...........*.***.*.*.*.* .........*.*.*.*******.* .......*.*...*.***...*.* .....*....*....*.*.*.*..* ........*............*.** ......*.**.*.*.*.***.*.*..* .........*.******.**.**** ......***.*.**.......***.* ......**.*........*..*..*..* .....*.****........*....* .......***.*.*.*...*...**.* .............*....**...* ...........*.*.*.***..**.* ......*..........*.***.*.* ......*...*.*.....*****....* ..........*.*...*.......** ..........*........*.....** ................*******.* ................**...**** .............*....*.....* ...........*............*.* ..............*.****.**.*.* ............**.*.***.*.*..* ...........*.*.........* ..........****.........* ........*...*.*...* .........*.**.....*...* .......***.**.*.*.*...** ......***...*.....*...** .....****......*.*..***** .....*.*....*.**.*..**.** .....***...*....*.*.**.** .....****..*.*.**...**.* .....*....**.*.**..**..* .......*....*..**..* .....*.***..*..*...* ......*.*..**..*..**.* ......*.**.*...*..**.** ......*...*.*..*..**.* .........**..**....*.* .......****..**..*** .....**..*...**...*.* .........*..**** .......***..*****.*.* .....*......**...*..* ...*.*.**.....*..* ...*..****.....** ....**.*.......** ..*.***....*.*..* .....*.***.*...* ...**.*.*.**...*.* ...***....*..***.* .*..*.*.*.**..*..* ....*....*.*.* ....***...*.** ..*.......****.* .....*.****.* .....*.*......* .........*..*.* .........*.* ....*......* ....****.*.* ..***.*......* ..*.*.*.* .****.*.* .**.......* *** .** .**.** ..**.......*.* .*.........**** ..........***** ........**.*.*** .......***..*..* ......****.**.** ......***...*.* ....**.*......** ....** ...*.**.***.*.* ...*..*.*.*.* ....*.....***..* ....*.*...*.* .......*..*.*.* .....*....**..* ...*.*....**.** ........**...**......* ....*..***...***..*.** ....**...*..**.*.**.*** ..****.......***.***.** ..*.**.***....*...**.** ..*.**.*.*.*.....***.** ...*.*.**.**.**..**...** .*.....*.***.*.....*..* .*.***.*..*......*..*..* ....*.....*....*.*.* .....*.*.**.*.....*.*.* ..*...........*....*.*.* *.**.***........*****..* *******.***...****..*.* *...***.....*...**.*..*

Near the bottom of the terminal screen (highlighted in red above), I saw that the partial solution had a slanted fissure! It looked as though one partial had completed and another had begun immediately below and to the right of it! It seemed too good to be true, but I tried running it through ikpx2golly to convert it into a runnable Life pattern. Sure enough, the back partial burned away to leave, emerging unscathed from the ash, a perfectly self-contained knightship:

I checked the stdout logs of the search program, and it transpires that it had also found the completion; it just so happened that it was hidden under the barrage of following pseudo-partials that I didn’t notice it until several minutes later.

The first thing to calculate was the attribution: since it grew from Tom Rokicki’s partial, there was the issue of determining who ‘discovered’ it. Fortunately, the row-by-row approach used by the search program made this exactly calculable: Tom found the front 62% of the pattern, and I found the rear 38%.

Nomenclature was the next thing to consider. Again, the knightship has a long systematic name, but something more catchy was in order. The name ‘seahorse’ was suggested by Dave Greene as a clever pun; the pattern resembles a seahorse, and ‘horse’ is an informal term for a knight in a game of chess. A pseudonymous user named Apple Bottom suggested the alternative name of Sir Robin, after the character in Monty Python and the Holy Grail. As this discovery is a knightship, considered a ‘holy grail’ in CA searching, and was found by a program written in Python, that name stuck.

Even though I wanted to hold back the publication until this article was published, it was beyond my control at this point. The discovery soon found its way onto Hacker News where it accumulated 727 up-votes and a horde of comments.

After 48 hours, the surprise gradually settled and the cellular automata community became accustomed to this new discovery and using it as a component of larger constructions. In particular, Martin Grant found a configuration capable of eating Sir Robins, and there has been talk of trying to create a knightpuffer (arrangement of Sir Robins which leave behind sporadic debris).

Soon afterwards, on the 10th March, Dave Greene published an article on Sir Robin.

It is not too difficult to prove that a pattern in Conway’s Life can translate itself by (a, b) in p generations only if |a| + |b| <= p/2. For all periods p up to 7, we now have such examples, but there is currently no known (2,1)c/7 knightship. It may be possible to find such a pattern using these search methods, but both Tom Rokicki and I are busy with a backlog of other things. I’m preparing a paper as part of my PhD research to submit to NIPS before the deadline in May, which means I won’t have time in the next 10 weeks to commit to searching for spaceships.

Consequently, you are just as likely as anyone else to find a period-7 knightship — 10 weeks is nearly twice as long as the total chronology of this post, and it’s unclear how many more CPU-hours and ideas would be sufficient to yield this gem.

As for SAT solvers more generally, I am investigating whether they can be applied to my own area of research (topological data analysis, which might just be combinatorial enough to be susceptible to these ideas). If not, there’s always that 99-vertex graph problem…

]]>- Three of the four team members for the European Girls’ Mathematical Olympiad made the top 10 in the leaderboard, which I think is record-breakingly high. This bodes very well for the competition taking place in Florence this April. Good luck to Emily, Alevtina, Naomi and Melissa!
- Joseph Myers has made an eighth release of his open-source software for organising mathematical olympiads, as used in the EGMO.
- Congratulations to Agnijo Banerjee, Nathan Creighton and Harvey Yau on their double-perfect-scores in the BMO, and best of luck in the forthcoming
*Romanian Master of Mathematics*competition.

I thought I should mention that the aforementioned Agnijo Banerjee, who is amongst the readership of Complex Projective 4-Space, recently coauthored a book about some of the more bizarre and pathological aspects of mathematics. I’ve been meaning to mention this for a while, but waited until it was launched at the beginning of this month. If you’re interested in this excellent book, which you should be, then download the trailer (PDF) or visit the website.

The other author, David Darling, is a prolific science writer who was apparently born in the same county as I was.

]]>