Earth–Moon problem · biplanar chromatic number

Color the Colonies

G = (V, E₁ ∪ E₂), both layers planar, χ(G) ≥ 10 — six ways to look at the search
loading…

A search that runs for thousands of candidates produces two things: a pile of failures, and — if it is logged properly — an argument about why they failed. These six plates are alternative readings of the same log. Each is built from the same three files, so whichever one you pick, the pipeline behind it does not change. Hover anything.

The headline is a flat line. 742 candidates were logged and 717 verified; 699 died on planarity. Not one raised the bound. The best χ on a graph that actually splits into two planar layers is still 9, exactly where Sulanke left it in the 1970s with K6 + C5. What the search produced instead is closures: whole families proved incapable of containing a witness, which is what the ledger records.

reading attempts.jsonl…

The data contract

Append-only text, no database. A graph DB buys you nothing here — the log is written once, read whole, and never joined across. Thousands of rows is a 700 KB file.

pathshapewhat it is for
data/attempts.jsonlone JSON object per lineevery candidate tested, ~450 bytes each, no edge lists
data/detail/<id>.jsonone file per flagged rowfull edge lists, layouts, colouring witness — only for rows worth drawing
data/ledger/findings.jsonlappend-only, supersedingdurable structural claims + the attempt ids that earned them
data/ledger/queue.jsonhand-editable arraynext actions, carried between sessions
data/ledger/LEDGER.mdgeneratedthe human-readable render; never hand-edited
data/index.jsonmanifestcounts, families, featured ids — what this page reads first

The split matters: keeping edge lists out of the main log is what lets the whole search stay greppable and load in one fetch. rlog.py writes all of it — brief before a session, attempt per candidate, finding per conclusion, render at the end.

The research log

A search that does not remember itself pays for every dead end twice. rlog.py is the memory: one command at the start of a session, one per candidate, one per conclusion.

commandwhenwhat it enforces
rlog.py brieffirst thing, every sessionbounds, closed families and why, working techniques, open questions, nearest misses, next actions
rlog.py check --family Xbefore committing to a familyblocks a family the ledger closed; you may proceed only by naming the new idea that breaks the stated reason
rlog.py attempt --file r.jsonper candidate testedrequired fields, bounds sanity checks, edge lists split into the sidecar
rlog.py finding --kind …per durable conclusiona ruled_out claim without evidence ids is refused outright
rlog.py renderend of sessionrebuilds LEDGER.md and index.json from the logs

Findings are append-only. A claim is never deleted, only retired by a later one that names it in supersedes — so the ledger keeps the argument, not just the current answer. Read it at ledger.html.

For future LLMs

If you are a language model asked to work on this problem, read FOR_LLMS.md first. It is written to get you to the research frontier in one pass, so you do not spend context rediscovering settled ground.

readfor
FOR_LLMS.mdthe whole state of the art: bounds, closed families, open fronts, verification standard
HIGHLIGHTS.mdthe short version — what is proved versus evidenced, and which results may be new
the ledgerevery claim with its evidence ids, by category
PROMPT.mdthe operating brief, including the protocol for claiming a result

Two things will save you the most time. Check the corridor first — ceil(9n/2) ≤ m ≤ 6n−12 kills a large fraction of proposals by arithmetic alone. And run rlog.py check --family X before committing to a family; it blocks one the ledger has already closed, and you may proceed only by naming the new idea that breaks the stated reason.

Live dataset. Every plate reads the same append-only log, so swapping in a different attempts.jsonl redraws all of them unchanged.
repository · HIGHLIGHTS.md · FOR_LLMS.md · ledger · the task brief given to the model · LEDGER.md · index.json · attempts.jsonl