Carlos Toledo · cert-machine · audit

Two claimed refutations of the Exponential Time Hypothesis: what was decided, and what was only read

OpenAI and Anthropic each published a Lean proof meant to show that ETH is false. Here both proofs were replayed from their pinned bytes, and two kernels accepted each one against its own statement. A kernel cannot say what a statement means. Whether each statement says “ETH is false” was read by two independent readers, and the page keeps the two kinds of check apart.

tl;dr
  • The finding. Both proofs check: Comparator accepts each against its own challenge statement, Lean’s kernel and nanoda both accept, and only propext, Classical.choice, Quot.sound are used. Anthropic’s statement is ETH’s negation itself, s₃ = 0 for Mathlib’s Turing machines. OpenAI’s statement is a running-time bound, the paper’s weaker Proposition 6.4: it defines no ETH, and the step from it to “ETH is false” is prose. Our Lean bridge closes that gap: the textbook ETH written once, and a proof that each lab’s statement refutes it in that lab’s own machine model. A third party’s Lean join of the two models (OpenAI’s statement implies Anthropic’s ETHIsFalse), replayed here by both kernels, checks too.
  • The mechanism. Every file pinned by sha256 before any run (3,991 and 1,066); Comparator, the Lean FRO’s judge, on one rented CPU machine; nanoda, a second kernel written independently of Lean’s, switched on for both. Two readings of the statements against the papers, each written without the other.
  • Check it. certs/eth-kernel.json (the decision), the first reading, the second reading, and the pod script tools/runpod-eth.sh to run it again.
proofs decided
2 of 2
CERTIFIED, each against its own statement
kernels that accept each
2
Lean’s, inside Comparator, and nanoda
Comparator, OpenAI
3,076 s
peak 80 GiB in the container
Comparator, Anthropic
388 s
peak 24 GiB in the container
bridge theorems, ours
34
proved in Lean, one kernel; §5
§1 · decided

Both proofs check against their own statements

claimtoolchaintheoremsverdictaxiomsnanoda
openai/math @ 7ef5c0ccLean v4.34.1exact_count_and_satCERTIFIEDthe three standardoff as shipped; switched on here
anthropics/formal-math @ 16a5ce41Lean v4.33.1ethIsFalse
mainTheorem
CERTIFIEDthe three standardon, as shipped

What CERTIFIED means here. Comparator exit 0 with "Your solution is okay!", Lean's kernel and nanoda both accept, and #print axioms (our file) names only propext, Classical.choice, Quot.sound for every main theorem. It does not mean that a Lean statement is its paper’s theorem, nor that ETH is false. No machine checks that, and both claimants say so.

What was changed, and declared before the run.

  • enable_nanoda: true on each claim's own Comparator config (OpenAI ships false; Anthropic ships true); nothing else in either config changes
  • GLIBC_TUNABLES=glibc.malloc.mmap_max=0:glibc.malloc.arena_max=1 for every Lean step of both claims (each row's env says so): the workaround OpenAI's own lean/README.md prescribes when vm.max_map_count is too low (the pod's is 65,530), which lane K needed on RunPod (amendments 15 and 16). A malloc setting: it changes how Lean allocates memory, never what it checks
  • nanoda as lane K builds it: the ammkrn/nanoda_lib#44 patch (src/tc.rs) and the worker stack raised to 1 GiB (src/lib.rs); the diff is kept with the run (_nanoda.patch)
  • for Anthropic (Lean v4.33.1): Comparator v4.34.0 built with v4.34.1, so Comparator's Lean kernel is v4.34.1 replaying a v4.33.1 export (the v4.33.0 tag lacks the quotient post-check and the issue-68 fix, which v4.34.0 has); the export is made by lean4export v4.33.0 built with the claim's own v4.33.1, whose format differs from v4.34.0's only in omitting partial definitions (neither tree has one: census.json); leanchecker --fresh replays with the claim's own v4.33.1 kernel. Anthropic's own CI uses Comparator 57567492 and robsimmons/nanoda_lib 68d5ca9d; neither is used here

Not run: leanchecker --fresh, an optional third replay, on either claim. The machine was deleted after the two kernels had decided, because it was billing unattended (corpus/eth-refutation/POD.txt).

§2 · what it rests on

From “the proofs check” to “ETH is false”

The proofs are decided by two kernels, and the step from each statement to “ETH is false in that lab’s own model” is proved in Lean here (§5, one kernel). What still stands between them and the sentence “ETH is false” is a premise, listed in the order the claim travels through it, each with where its checking stopped:

  1. assumed
    Our Lean ETH says what Impagliazzo and Paturi say read: s_k is the infimum of the δ for which k-SAT has an O(2^{δn}) algorithm, and ETH is s_k > 0 for every k ≥ 3, transcribed from CCC 1999, p. 1. A model fixes the machine, the formulas and the input word; the four definitions then read the same in every model (ETHBridge/Generic.lean, byte-identical in both projects).
  2. assumed
    A machine step costs O(1) in the textbook’s model textbook, in neither lab’s Lean: a PrimitiveMachine or FinTM2 step is a bounded number of tape or stack operations, so a word RAM or a multitape machine simulates it at constant cost per step. Both papers state it in prose.
  3. assumed
    A textbook 3-CNF becomes each input word in polynomial time textbook, in neither lab’s Lean: deduplicate, sort, pad and write the word. A polynomial factor keeps 2^{o(n)} at 2^{o(n)}.
  4. assumed
    What the decision itself trusts the two kernels (Lean's, inside Comparator; nanoda), leanchecker, lean4export, Comparator's comparison code, landrun's Landlock sandbox (Comparator calls it with --best-effort; the pod's LSM list is in each row's env), the Mathlib cache fetched by lake exe cache get, the claimants' lakefiles (OpenAI's applies dependency patches at lake update; none touches Mathlib, census.json), and RunPod's machine. The sandbox ran best-effort: Landlock was unreadable inside the container.

The weakest premise is assumed. Our Lean ETH is a transcription of the textbook’s, read, and the model and encoding steps are textbook and in no one’s Lean. So this page decides that both proofs check, proves that each statement refutes ETH in its own lab’s model, and reads, without deciding, that ETH is false in the textbook’s model-free sense.

§3 · read

What each Lean statement says, in plain mathematics

OpenAI (exact_count_and_sat). For every k ≥ 2 there is one machine of the file’s own design (a standard multitape Turing machine with a three-letter alphabet) and constants C, A, d, such that on every set F of clauses of width at most k over n variables, written in the file’s canonical unary encoding of length L, it halts after T ≤ C·(L+1)^d·2^{A·n(ln ln(n+16))²/√ln(n+16)} steps with the exact number of satisfying assignments on one tape and the answer “satisfiable” as its halting state, in polynomial space. Because clauses are sets, L is polynomial in n, so for k = 3 the time is 2^{o(n)}. It does not appear: OAI-C defines no ETH, no s₃ and no reduction. Our bridge supplies it (§5). The exponent is the paper’s Proposition 6.4, weaker by a factor log log n than its headline Theorem 1.1, as OpenAI’s scope note says.

Anthropic (ETHIsFalse, MainTheorem). ETH is 0 < s₃, where s₃ is the infimum of the δ for which some finite machine of Mathlib’s FinTM2 kind and some c ∈ ℕ decide every duplicate-free 3-CNF list within ⌊c·2^{δn}⌋ steps, for every n and any number of clauses. ETHIsFalse is its negation. The Main Theorem gives one machine and one constant C counting the satisfying assignments within ⌊2^{C·min(km/√lg m, k²n lg lg n/√lg n)}⌋ steps, for k ≥ 1, m ≥ 2, n ≥ 4 with every variable occurring.

Both readers, separately: each statement, if proved, implies the textbook ETH (Impagliazzo–Paturi) is false, under the two textbook steps of §2 and nothing else. Neither found a loophole: no padding (the input length is polynomial in n in both), no hidden power in either machine (finite control, finite alphabets, one bounded step at a time), exact halting times, and promises that only restrict where a bound is claimed.

§4 · compared

The two statements side by side

OpenAIAnthropic
Lean boundC(L+1)^d·2^{A·n(ln ln(n+16))²/√ln(n+16)}, constants per k⌊2^{C·min(km/√lg m, k²n lg lg n/√lg n)}⌋, one absolute C
Lean bound against the paper’sweaker: Proposition 6.4, not Theorem 1.1the same, with ranges
ETH in Leanabsent from OpenAI’s files (ours: §5)defined, and its negation proved
Machine in Leanits own multitape machine on Mathlib’s tapesMathlib’s FinTM2 (multi-stack)
Input in Leana set of sets of literals, canonical sorted unary worda duplicate-free list, fixed-width binary slots
Uniform in kno: for each k a machineyes: one machine for every k
Spaceproved polynomialnot stated
nanoda in the shipped configoffon

Both papers reach the same shapes, n log log n/√log n for any formula and n/√log n for linearly many clauses, and both get their sharpest bound by recursively contracting Boolean tensor networks (OpenAI’s Appendix D, Anthropic’s §2). The two Lean developments formalize different routes: OpenAI’s the interpolation route of its §6.4, Anthropic’s the eight-square recursion.

One computed check. Anthropic’s key identity, eq. (12), the eight-square identity of Degen (1818) and Graves (1843), re-run at this build from the printed formula in exact integer arithmetic: it holds at all 4,096 settings (0 failures). The control, the same formula with i < j in place of i ≤ j, fails at 256, so the check can fail. This decides one printed line of the paper. It decides nothing about the proof.

§5 · the bridge

One textbook ETH in Lean, and each statement against it

The textbook definition is written once, in Generic.lean (sha256 78554f883f6c…, byte-identical in both projects). A model fixes four things: what a machine is, which formulas are k-SAT instances, the input word a formula is written as, and what “halts within t steps with answer b” means. Then s_k, the infimum of the δ for which k-SAT is decided within ⌊c·2^{δn}⌋ steps for every n, and ETH, s_k > 0 for every k ≥ 3, read the same in every model. Each lab’s statement is then proved to refute ETH in that lab’s own model:

  • OpenAI. its PrimitiveMachine, sets of clauses of width ≤ k, encodeCNF: theorem not_eth_of_claim (h : SqrtLogSpace.OpenAIClaim) : ¬ ETHBridge.ETH model — the three standard axioms; Lean v4.34.1, built in 18 s.
  • Anthropic. Mathlib’s FinTM2, duplicate-free clause lists, encClauses: theorem not_eth_of_ethIsFalse (h : MainResults.ETHIsFalse) : ¬ ETHBridge.ETH model — the three standard axioms; Lean v4.33.1, built in 15 s.

OpenAI. If OpenAI's challenge statement exact_count_and_sat holds, then ETH (s_k > 0 for every k ≥ 3) is false for PrimitiveMachines on encodeCNF; indeed s_k = 0 for every k ≥ 2 (s_eq_zero_of_claim). The three steps both readers did by hand are Lean lemmas now: the input word is polynomial in n, bitLength_succ_le {n k : ℕ} (F : SAT.CNF (Fin n)) (hF : SAT.WidthAtMost k F) : Encoding.formulaBitLength F + 1 ≤ (3 + (k + 1) * 2 ^ k * (4 + 8 * k)) * (n + 1) ^ (k + 1); the halting answer decides satisfiability, count_pos_iff {n : ℕ} (F : SAT.CNF (Fin n)) : 0 < SAT.count F ↔ IsSatisfiable F; and the running-time bound is at most c·2^{δn} for every n, bound_le (B A : ℝ) (p : ℕ) {δ : ℝ} (hδ : 0 < δ) : ∃ c : ℕ, ∀ n : ℕ, B * ((n : ℝ) + 1) ^ p * (2 : ℝ) ^ (A * SqrtLog.Statement.runtimeScale n) ≤ c * (2 : ℝ) ^ (δ * n).

Anthropic. Anthropic's ETHIsFalse implies that ETH (s_k > 0 for every k ≥ 3) is false for FinTM2 machines on encClauses; the generic DecidesKSat, InTime and s ARE Anthropic's, by definition (decidesKSat_iff, inTime_iff, s_eq). In Lean: s_eq (k : ℕ) : ETHBridge.s model k = MainResults.s k.

How the statements were copied. OpenAI’s challenge file is carried with one declared change: its open theorem exact_count_and_sat becomes the proposition OpenAIClaim, and undoing that change gives back the pinned sha256 4183b2057cff…. Anthropic’s MainResults.lean is carried unchanged (47f78a9550d9…). §1 decided that OpenAI’s proof proves exactly that statement, so the two together give ¬ETH in OpenAI’s model. The join is the identity of the statement’s bytes, not one Lean term: the bridge does not import OpenAI’s proof.

Checked by one kernel. Lean’s, inside lake build on GitHub’s runners (run 40772430556); no sorry, no axiom declared, no native_decide (certs/eth-bridge.json, the README). No second kernel has replayed the bridge.

Not proved, and said so:

  • The cross-model bridges stay prose for both claimants and here: that a PrimitiveMachine (OpenAI) or a FinTM2 machine (Anthropic) is simulated by a word RAM or a multitape Turing machine with polynomial overhead (first.md B1, B1′), and that a textbook 3-CNF is rewritten into encodeCNF / encClauses in time polynomial in its length (B2, B2′). ETH is proved false here in each claimant's own model, not in a model-free sense.
  • MainResults.ETH → ETHBridge.ETH (the converse of eth_of_eth) is not proved: it needs s_3 ≤ s_k for k ≥ 3, and Anthropic's encoding depends on k (k slots per clause), so a machine for 3-SAT does not run on a k-SAT word without a re-encoding machine. It is not needed for the bridge.
  • Nothing here re-checks either claimant's proof: certs/eth-kernel.json is that lane.

The step between the two models, joined by someone else, and replayed here: CERTIFIED. TSavo/eth-bridge @ 34f9ca20 (TSavo; written with Claude, per its README) proves Bridge.ethIsFalse_of_claim : OAI.Algorithms.SubexponentialSAT.SqrtLogSpace.Claim → MainResults.ETHIsFalse: OpenAI’s machine compiled into Anthropic’s, and OpenAI’s input word produced from Anthropic’s, so OpenAI’s statement refutes ETH in Anthropic’s FinTM2 model too. Replayed on GitHub’s runners (run 40789891989): the statement checks pass on the run's bytes; Comparator exit 0 with "Your solution is okay!" on TSavo's config (with the declared lakefile amendment); Lean's kernel and nanoda both accept; lake build Bridge exit 0; both theorems' axioms are among propext, Classical.choice, Quot.sound (certs/eth-tsavo-bridge.json).

Its gaps, first:

  • TSavo's README build does not run Comparator on TSavo's own config: on the README's lakefile (Anthropic's, plus [[lean_lib]] Bridge, srcDir "bridge", globs ["Bridge.+"]) Comparator stops at "Building BridgeChallenge" because Lake reports unknown target BridgeChallenge (exit 1): the glob Bridge.+ names Bridge and its submodules, and BridgeChallenge is neither. The replay declares ONE amendment, a [[lean_lib]] named BridgeChallenge with srcDir "bridge" appended to the lakefile (no Lean byte and no config byte changes), and decides on the run with it. TSavo's README says Anthropic's CI script accepted the bridge on 2026-10-27; the lakefile that run used must have made BridgeChallenge resolvable, and the README does not show how.
  • The seam between the two lanes is the Lean and Mathlib version: the bridge's Claim is OpenAI's challenge text re-elaborated on Lean v4.33.1 and Anthropic's Mathlib 0df444a3, while OpenAI's proof (certs/eth-kernel.json) is of exact_count_and_sat on Lean v4.34.1 and Mathlib d13f23b7. The source text is the same byte for byte (the statement check); that the two elaborate to the same term is not checked here, so OpenAI's theorem and TSavo's implication compose by reading, not by one kernel.
  • Comparator decides Bridge.ethIsFalse_of_claim only (the config's one theorem). Bridge.two_proofs_one_statement = ⟨MainResults.ethIsFalse, ethIsFalse_of_claim⟩ is checked by one kernel (Lean's, in lake build) and by its axiom print.
  • A stale comment: bridge/Bridge/Main.lean's header still says "Each sorry below is one of the four lemmas named in the plan"; no sorry remains outside comments (the census).
  • leanchecker --fresh was not run (as in the eth-kernel lane's rows); the rule stands on Lean's kernel and nanoda inside Comparator.
§6 · open

What this page does not say

§7 · prior art

Sources the first reading opened