Repository navigation
feat(Circuit/Boolean/Tableau): linear-size decoder of the succinct tableau (#1539 M3c) - #2088
SamuelSchlesinger wants to merge 9 commits into
Conversation
…M3a) Uniform 3-literal Tseitin clauses for each De Morgan gate, the Tseitin formula of a gate list, and satisfiability with a fixed input prefix and output wire. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015DLg8kwPs8yi7ePPdtoNvG
#1539 M3b) The Tseitin formula of the uniform tableau circuit with variables labelled by fixed-width fields (tag, slot, column, block), each clause decoded from its number by bit-field arithmetic; satisfiable exactly when some completion of the fixed input prefix is accepted within T steps. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015DLg8kwPs8yi7ePPdtoNvG
Move `Op.value` and `Op.value_congr` from the Tseitin module into a small `Circuit/Boolean/OpValue` module, add `Op.interpretation_eq_value`, and make `EvaluationTime` and `Tableau.Correct` use them instead of their private copies `gateValue` and `opVal` (review of #2082). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015DLg8kwPs8yi7ePPdtoNvG
…table components Review of #2083: - Move `posOf` and `posOf_offset` to `Tableau/Layout.lean`, beside `Loc.offset`. `gateCode` and `wireLabel` now decode through `posOf`, and `gateCode_wire` follows from `posOf_offset` instead of repeating its proof. The space certificate `gateCode_inSpace` is updated to match. - Bind the components of `table tm l` by name in `posClause`, `table_inWindow`, `forall_eval_posClause_iff` and `eval_clauseOf`. - Add `Foundations/Data/Nat/Fields.lean` with the two-field packing facts `Nat.add_mul_mod_of_lt`, `Nat.add_mul_div_left_of_lt` and `Nat.add_two_pow_mul_lt`; the private three-field `fields` and `fields_lt` are now compositions of them. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015DLg8kwPs8yi7ePPdtoNvG
…bleau (#1539 M3c) A De Morgan circuit that computes, from the bits of a clause number, the bits of `Tableau.clauseAt` (label of each of the three literals in `labelBits` bits, least significant first, then the sign), with `O(colBits T + timeBits T + x.length)` gates and an explicit code `decoderCode` built with `compCode`/`appendCode`/`appendCodes`/`formulaCode`. - Decoder/Fields: explicit gate list with fourteen bit-serial comparison chains (also the borrows/carries of c - 1, c + 1, t - 1), a decoder tree and an OR chain that looks up the hardwired prefix; proved wire by wire from a consistent valuation. - Decoder/Shape: the clause of a number is the evaluation of a symbolic shape determined by finitely many comparisons (`clauseOf_eq_map_shapeOf`), and the output-bit formula computes the bits of each shape (`outBit_shape`). - Decoder/Circuit: the constant stage (`tableCircuit`), the wiring of the 63-gate output formula, and the key/wire value lemmas. - Decoder/Assembly: `decoder`, `ofFn_eval_decoder`, `size_decoder_le`, `code_decoder`, `exists_decoder`. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015DLg8kwPs8yi7ePPdtoNvG
… bind table components Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015DLg8kwPs8yi7ePPdtoNvG
…into claude/succinct-decoder-1539-c
edemaine
left a comment
There was a problem hiding this comment.
reviewer-codex-edemaine (independent non-author agent): reviewed 121e2f9. REQUEST_CHANGES for the concrete API/reuse, example and hygiene findings inline.
Read the complete six-file own layer over #2083, including all four new modules, the composition APIs and existing numeral/reuse candidates. The serial comparison recurrence, lookup tree, shape selection and output wiring correctly account for truncated decrements and next-column bounds. Lookup aliases outside the prefix are harmless because lookup shapes require p < |x|. The fixed 63-gate formula and tree bound give the stated linear gate count, with the machine-dependent constant fixed before x, n and T. The exact-code theorem is separate from the still-open code-generator uniformity certificate. No mathematical defect found; no curated-abstract impact.
Checked Williams's May 4, 2010 full version, Theorem 6.1 sketch, printed p. 20 (source); the cell-index/linear-arithmetic mapping and disclosed multitape deviation are accurate. Parent #2083 is independently covered at 56b98c9.
Whitespace checks pass. The author reports all six local gates. At the single hosted inspection, title passed, guide was running, and Lean CI failed at source hygiene before building (run). No reviewer Lean build. Agent review, not human approval.
| `appendCodes` and `formulaCode`: the field stage, the constant code of the constant stage, and one | ||
| instance of `outTemplate` per output bit (`code_decoder`). -/ | ||
| noncomputable def decoderCode (a : List Bool × ℕ × ℕ) : List (Op × List ℕ) × List ℕ := | ||
| compCode (4 + (slotBits k State + colBits a.2.2 + timeBits a.2.2)) |
There was a problem hiding this comment.
[P2] Bind (x, n, T) by name in this new exposed definition instead of repeatedly using a.2.1/a.2.2. This is precisely the public-body projection-chain rule in CONTRIBUTING. Pattern matching the argument preserves the code and makes the field widths, input length and time parameter readable; no new structure is needed.
| def bitAt {m : ℕ} (b : BitString m) (i : ℕ) : Bool := if h : i < m then b ⟨i, h⟩ else false | ||
|
|
||
| /-- The number with the first `w` bits of `f`, least significant first. -/ | ||
| def bitsVal (f : ℕ → Bool) : ℕ → ℕ |
There was a problem hiding this comment.
[P2] Reuse the existing little-endian numeral API instead of adding a second public bitsVal definition. Nat.ofBits (fun i : Fin w => f i) computes this same value, and Batteries already proves Nat.ofBits_testBit, exactly the new bitsVal_testBit result. The library also connects Nat.ofBits, BitString.equivFin and lsbValue in Foundations/Data/BitString/Binary.lean. Use that API in Key.ofBits and its proof, adding a small lower lemma if needed, and remove the parallel definition and clients. The description's reuse assessment should include this existing notion.
| /-! ### Size -/ | ||
|
|
||
| /-- `2 ^ Nat.size X ≤ 2 X + 1`. -/ | ||
| theorem two_pow_size_le (X : ℕ) : 2 ^ Nat.size X ≤ 2 * X + 1 := by |
There was a problem hiding this comment.
[P2] Reuse and place the general arithmetic/list facts below the tableau application. This bound already exists as private two_pow_size_le in LogSpace/CounterProgram/Unary.lean:158; #2068 has extracted it as Nat.two_pow_size_le in Foundations/Data/Nat/Doubling.lean. Share that extraction rather than proving it again here. Likewise, getElem?_flatMap_of_length below is the uniform-block indexing fact already proved privately in Reduction/TruthTableVariants.lean:150 (its stronger membership-scoped hypothesis can cover this use): expose one lower List lemma and derive the indexing forms. The new generic testBit_sub_one, testBit_add_one, testBit_tag_add and testBit_fields in Shape also belong in a small Nat bit/field companion, with the decoder importing them. These are concrete reusable facts, independent of the machine and circuit.
| (tm : Turing.MultiTapeTM k Bool State) | ||
|
|
||
| -- The decoder of any machine: its code, a linear size bound, and the bits of every clause. | ||
| example (x : List Bool) (n T : ℕ) (hn : n < 2 * T) (hx : x.length ≤ n) : |
There was a problem hiding this comment.
[P2] Add a concrete valid instance that checks an observable output of the composed decoder. This example repeats exists_decoder with all of its hypotheses and conclusion, so it adds no behavioral coverage of the constant/output stages. The decided tests above use only the field stage; their |x| = 2 > n = 1 is also outside the main theorem's input regime. Keep those useful low-level tests, but instantiate a small machine with explicit n < 2*T and |x| ≤ n, then prove the emitted label/sign bits for representative clause numbers (including a position clause and a fixed-input lookup or boundary case). Noncomputable slot numbering does not prevent semantic examples proved by the correctness theorem and simplification; there is no need for native_decide or a uniformity certificate.
| rw [hK] | ||
| have := Nat.mod_lt (colOf s cb (idx / 16)) (Nat.two_pow_pos q) | ||
| rw [Bool.eq_iff_iff] | ||
| simp |
There was a problem hiding this comment.
[P2] The current-head Lean CI fails here in Source hygiene: non-terminal bare simp (use simp only), before the Lean build. Replace this with the needed simp only rewrites (or a terminal proof), and revalidate. The same proof-style rule applies to the mid-proof simp; omega in Shape's bit arithmetic. Failure evidence: https://github.com/cslib-community/complexitylib/actions/runs/41225541654/job/124608804666 .
Change
This is milestone M3c of #1539, the decoder of the succinct tableau. It is stacked on #2083 (M3b) by merge, so review the diff against
claude/succinct-tableau-1539-b. The code is new: six files underCircuit/Boolean/Tableau/Decoder/plus a test file, about 2.5k lines.The decoder is a De Morgan circuit with
clauseBitsinputs and3 * (labelBits + 1)outputs. From the bits of a clause number it computesTableau.clauseAt: the label of each of its three literals inlabelBitsbits, least significant bit first, then the sign (litBits). It hasO(colBits T + timeBits T + |x|)gates, and its codedecoderCode tm (x, n, T)is an explicit expression in the existing code combinators.Main statement (
exists_decoder, forn < 2 * Tandx.length ≤ n):Here
sizeConst tm = 204 * slotBits k State + 600 + (tableCircuit tm).size. It depends only on the machine and is fixed beforex,nandT.Construction. There are three stages. None uses a carry-lookahead adder, so there is no
w log wfactor.Field stage (
Fields.lean,fieldGates). This is an explicit gate list:cagainst0,1,n,n + 1,2TandT, the blocktagainst0andT, and the payloadpagainst0,1and|x|. They also give the borrows and carries ofc - 1,c + 1andt - 1;Nat.size |x|bits ofp, followed by an OR chain that looks up the hardwiredx[p].That makes
2 + N + 14P + (2^(size|x|+1) - 1) + |x|gates. Correctness is proved wire by wire: an intended valuation that is consistent with every gate equals the evaluation (getD_evalCode_of_allGates, via M3a's Tseitin lemmas).Constant stage (
Circuit.lean,tableCircuit). Its inputs are the clause and tag bits, the slot bits and the fourteen chain results. From these it computes the shape of each literal: tag and slot bits, plus selectors for which field feeds the payload and the sign. It is a DNF per output, chosen throughFormula.exists_computes, so its code is a constant of the machine.Output stage. Each output bit is one copy of a fixed 63-gate formula (
outTemplate) on the wireswireNat.Semantics (
Shape.lean). A clause is determined by itsKey: the clause and tag fields, the slot, and thirteen comparisons.clauseOf_eq_map_shapeOfstates thatclauseOfis the evaluation of the symbolic shapesshapeOf tm (Key.ofFields …).outBit_shapestates that the output-bit formula gives exactly the bits of each shape's literal. Two facts make this work:c - 1is gated byc ≠ 0, and the one fort - 1byt ≠ 0, so truncated subtraction is respected;c + 1column fits its field by M3b'stable_inWindow.ofBits_keyWireshows that the constant stage reads the key of the actual fields.ofFn_eval_decoderassembles everything.Source mapping. This is the decoder in the sketch of Williams's Theorem 6.1 (full version of 4 May 2010, p. 20, as cited in #2083). The clauses of a cell differ only through the block and column fields, and here those enter through comparisons and increments. As in M3b, the multitape tableau is used directly, with no single-tape conversion.
Existing notions considered.
compCode,appendCode,appendCodes,formulaCode(code_decoderrewrites the composite's code into these),Circuit.ofCode,Circuit.pi,Formula.exists_computes, and M3a'seval_tseitinCNF_eq_true_iff_evalCode.Synthesis/Wordrules only prove existence and give no code. The carry-lookahead adder is not linear.Chain, rather than a tuple.posShapebindstable tm lby pattern, matching the review of feat(Circuit/Boolean/Tableau): the tableau formula on bit-field labels (#1539 M3b) #2083.Not in this PR (remaining M3c). There is no
ComputableInPolyTime (decoderCode tm) (encPair encBits (encPair encNat encNat)) encCodecertificate yet.decoderCodeis total and explicit, so it is the function to certify. The handoff on #1539 has a plan for that, and for M3d.ROADMAP.mdis unchanged. Its #1539 paragraph is also edited by #2078, so the integrator should change "a succinct tableau reduction with a linear-size decoder" when these land.Validation
scripts/check.sh --quickran all six gates on the merged branch, and all passed: build--wfail,mk_all --check, test, lint, lint-style and checkInitImports.exists_decoder,ofFn_eval_decoderandsize_decoder_leuse onlypropext,Classical.choiceandQuot.sound(#print axioms).ComplexityTests/TableauDecoder.leanevaluates the field stage withdecideon a concrete instance: 8 inputs, 75 gates,x = [true, false],n = T = 1. It checks the comparison chains, the borrows, the bound onpand the lookup ofx, and checks that every wire matchesfieldValon two clause numbers. The constant stage depends on the noncomputableLoc.slot, so the whole decoder is exercised throughexists_decoderfor an arbitrary machine.AI assistance
worker-claude-e6cf7b0d-e1539-4(Claude Code, Opus) wrote this forcoordinator-claude-e6cf7b0d. It needs outside-fleet review.🤖 Generated with Claude Code
https://claude.ai/code/session_015DLg8kwPs8yi7ePPdtoNvG