Skip to content
The Lumenary

Math laboratory

Laver tables and the period of their first row

Builds the Laver tables A_n (n <= 9), checks left self-distributivity exhaustively for n <= 5, and computes the period of the first row (1, 1, 2, 4, 4, 8, 8, 8, 8, 16). Laver proved from the large cardinal axiom I3 that this period tends to infinity; exact computation for small n only, which says nothing about that limit.

Back to the labExact computationExhaustive finite check
Laver tables and the period of their first rowPythonExact computationExhaustive finite checkComputationally tested
"""Laver tables: finite algebras that large cardinals know about.

For n >= 0 let N = 2^n. The Laver table A_n is the unique operation * on
{1, ..., N} with p * 1 = p + 1 (mod N, so N * 1 = 1) that is left
self-distributive: p * (q * r) = (p * q) * (p * r). Richard Laver discovered
these tables in the study of elementary embeddings j : V_lambda -> V_lambda
(the rank-into-rank axiom I3). Each row is periodic, and Laver proved, assuming
I3, that the period of the first row tends to infinity as n grows. No proof
of this purely finite statement without large cardinals is known.

We build A_n for n <= 9 with the recursion p * (q + 1) = (p * q) * (p + 1),
filling rows from p = N downwards, check left self-distributivity
exhaustively for small n, and print the period of the first row.

Runs unchanged in the browser (Pyodide) using only the standard library.
"""

import textwrap

def laver_table(n):
    """The table of A_n as a dict of rows: rows[p][q - 1] = p * q."""
    size = 2 ** n
    rows = {size: list(range(1, size + 1))}
    for p in range(size - 1, 0, -1):
        row = [p + 1]
        for _ in range(size - 1):
            row.append(rows[row[-1]][p])  # (p * q) * (p + 1)
        rows[p] = row
    return rows

def star(rows, p, q):
    """p * q in the table."""
    return rows[p][q - 1]

def is_left_distributive(rows):
    """Check p * (q * r) = (p * q) * (p * r) for all p, q, r."""
    size = len(rows)
    return all(
        star(rows, p, star(rows, q, r)) == star(rows, star(rows, p, q),
                                                star(rows, p, r))
        for p in range(1, size + 1)
        for q in range(1, size + 1)
        for r in range(1, size + 1)
    )

def period(row):
    """The least period of a list that repeats exactly."""
    for d in range(1, len(row) + 1):
        if len(row) % d == 0 and row == row[:d] * (len(row) // d):
            return d
    return len(row)

def main():
    print("  n   size   left-distributive   period of row 1   row 1 (start)")
    periods = []
    for n in range(10):
        rows = laver_table(n)
        check = str(is_left_distributive(rows)) if n <= 5 else "(not run)"
        per = period(rows[1])
        periods.append(per)
        start = " ".join(map(str, rows[1][:per][:6]))
        print(f"{n:>3}   {2 ** n:>4}   {check:>17}   {per:>15}   {start}")
    print()
    print(f"Periods of row 1 for n = 0..9: {periods}")
    a3 = laver_table(2)
    print("The table A_2 (rows p = 1..4, columns q = 1..4):")
    for p in range(1, 5):
        print("   " + " ".join(str(v) for v in a3[p]))
    print()
    print(textwrap.fill(
        "Epistemic status: exact computation of finitely many finite tables, "
        "with distributivity checked exhaustively for n <= 5. It cannot show "
        "that the period of row 1 tends to infinity. Laver proved that from "
        "the rank-into-rank axiom I3; Dougherty showed that the period first "
        "reaches 32 only for astronomically large n; whether ZFC alone proves "
        "that the period is unbounded is not known.",
        width=78,
    ))

if __name__ == "__main__":
    main()
Runs entirely in your browser, in an isolated worker. Nothing is sent to a server.

Used in