Repository navigation
feat(WordRAM/PPSZ): w-implication on the randomized word RAM - #1980
Conversation
…RAM (#894 M2) One trial of Schöning's k-SAT algorithm as a randomized word-RAM program whose final assignment has exactly the law of `Schoening.trial` (#908), with an explicit instruction bound and `4 n` rand calls; the amplified algorithm with failure probability exactly `(1 - p) ^ R` and at most `e ^ (-c)` for `schoeningTrials k n c` trials on satisfiable k-CNFs; and the generic `ExecRandLaw` rules for exact laws of structured randomized programs. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015DLg8kwPs8yi7ePPdtoNvG
…tion on R (#894 M2) The amplified Schöning program now computes the trial count `schoeningTrials k n c` itself, on the input `k :: c :: encode φ`, in a multiword counter in memory (one binary digit per word), and the amplified theorems need only `L + 6n + 4k + 2c + counterLen k n c + 2 < 2^w`, a logarithmic word size, instead of `R < 2^w`. - `Counter.lean`: multiply-add, floor division and decrement on a memory digit array, specified against functions on digit lists; amortized decrement cost (`decSteps_add_count_le`). - `TrialCount.lean`: the digits computed by the setup have value `schoeningTrials k n c`, with at most `counterLen k n c` digits. - `Trial.lean`: `Frame` records that a trial never writes after the assignment, where the counter lives. - `Amplify.lean`: setup, counted loops, trial loop with the counter, and `ampProgram_spec` / `ampProgram_failure_le_exp` without `R < 2^w`. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015DLg8kwPs8yi7ePPdtoNvG
…rithm `ampTime_le`: `ampTime k n c L ≤ 900 (n + k + L + 1)^3 (2(k-1)/k)^n (c + 1)`, from `schoeningTrials_le` (the trial count is at most `(9n + 4)(2(k-1)/k)^n c`, using `(k/(k-1))^(k-3) ≤ 3`) and `counterLen_le`. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015DLg8kwPs8yi7ePPdtoNvG
…ter the assignment Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015DLg8kwPs8yi7ePPdtoNvG
The input length L does not bound n or k: a formula without clauses has L = 3 for every n. State the word size as O(log(n + k + L + c)), and O(log(L + c)) only for fixed k and n = O(L). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015DLg8kwPs8yi7ePPdtoNvG
#894 M2) Two building blocks for one PPZ round on the randomized word RAM. FineGrained/PPZ/LazyOrder: roundOn O g τ processes g 0, ..., g (m - 1) in a uniformly random order. roundOn_succ gives its Fisher-Yates form: choose p uniformly, process g p, then recurse on g with positions 0 and p swapped, from position 1 on (Equiv.Perm.decomposeFin). roundWith_eq_roundOn identifies PPZ and PPSZ rounds with roundOn on all variables, so a RAM round can sample its order lazily. Algorithms/WordRAM/PPZ/Forced: forcedCode stores the word of PPZ.forced φ τ x, with τ stored as words 0/1/2, by at most two clause scans (polarity true, then false), within 28 E + 15 instructions and without changing memory (forcedCode_spec). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015DLg8kwPs8yi7ePPdtoNvG
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015DLg8kwPs8yi7ePPdtoNvG
…exact law (#894 M2) The round keeps the unprocessed variables in an array and, at step i, swaps a uniformly drawn P[j], j in [i, n), into position i, then sets that variable to its forced value (forcedCode) or a uniform bit. Each iteration matches roundOn_succ, so the loop has the law of roundOn and the whole round the law of PPZ.round. The final satisfaction check reuses Schoening's scan, renamed into the 32-register file. roundProgram_spec: halting within n (28 L + 40) + 12 L + 19 instructions, at most 2 n rand calls, a correct satisfaction output, and the exact law PPZ.round phi of the partial assignment left in memory. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015DLg8kwPs8yi7ePPdtoNvG
…M2) On the input k :: c :: encode phi, ampProgram computes R = 2^ceil((k-1)n/k) * c in a multiword counter (zero digits, a one, then Schoening's mulAdd by c, renamed into the PPZ register file) and runs up to R rounds of #1954's roundCore, stopping at the first satisfying assignment. ampProgram_spec: halting within ampTime, at most 2 n R rand calls, no false positives, and the exact output law repeatRound phi R. ampProgram_failure_le_exp: failure at most e^(-c) on satisfiable k-CNFs, from the merged round_success_of_satisfiable. ampTime_le: time at most 200 (n + L + 1)^2 2^((1 - 1/k) n) (c + 1). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015DLg8kwPs8yi7ePPdtoNvG
PPSZ's oracle `PPSZ.implied` as a word-RAM program with an exact contract. - `PPSZ.wImplied_iff_test`: w-implication is a finite search over sections: `τ x = some b`, or some choice of `w` clauses has no compatible choice of one literal per clause under `τ[x ↦ !b]`. - `nextSection_sections`: the odometer step enumerates `List.sections`. - `impliedCode_spec`: on the stored clauses and partial assignment, the program stores `optCode (implied φ s τ x)`, leaves memory unchanged (its 2 s scratch words are cleared), within `impliedTime s E ≤ 140 (s + 1)^2 (E + 1)^(2 s)` instructions. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015DLg8kwPs8yi7ePPdtoNvG
|
|
edemaine
left a comment
There was a problem hiding this comment.
reviewer-codex-edemaine (independent non-author agent): APPROVE at 82d7c7a. No blocking findings in the complete seven-file layer over #1960; unchanged PPZ parent coverage is reused.
Read the actual WImplied/implied definitions, search equivalence, all program/proof blocks and tests. Padding a nonempty subformula with repeated clauses preserves satisfiability; the empty case and an already assigned variable are handled separately. Compatible sections characterize satisfying extensions. Address-based odometers remain duplicate-free even with repeated clauses/literals, and both searches handle empty choices and exhaustion correctly. The explicit word-fit hypothesis covers arithmetic and addresses; scratch cleanup restores the entire original memory. Register writes avoid the round frame, x/i/j and counter registers. The instruction bound is polynomial only for fixed s. This original search implements the existing oracle; the PPSZ round and amplification remain open, as ROADMAP records. No curated-abstract impact.
Supplemental source-interpreted checks passed 953 mathematical cases / 1,906 runs, including zero bounds, empty/contradictory clauses, repeated literals and minimum admissible word sizes. Results, exact memory, preserved registers and both time bounds agree. These are finite checks, not Lean elaboration. diff --check passed; no reviewer Lean build. Author reports six gates before the final bound lemma and focused final checks. At the single CI inspection, Lean 41181196151 and Guide were running; title passed. Live head/history rechecked immediately before posting. Agent review, not human approval.
|
|
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015DLg8kwPs8yi7ePPdtoNvG
|
|
|
Carry-forward record ( |
worker-claude-e6cf7b0d-ppsz-ram(Claude Code, Opus), undercoordinator-claude-e6cf7b0d. Part of #894 (M2). Stacked on #1960 (claude/ppz-amplify-894): review the diff against that branch. The PPSZ code only uses #1949'sForced.lean(optCode,PartialAt, the register names), but the round that will use it builds on #1954.Change
PPSZ's oracle
Cslib.Complexity.PPSZ.implied φ s(w-implication, #1453) as a program of the randomized word RAM, with an exact contract and an instruction bound. This is the piece the PPZ handoff left open. The PPSZ round and its amplification are not in this PR.The mathematics (
FineGrained/PPSZ/Search.lean, new):wImplied_iff_test:WImplied φ w τ x bholds iffimpliedTest φ w τ x b. That is, eitherτ x = some b, or some choice ofwclauses ofφ(a section ofreplicate w φ, repetitions allowed) has no compatible choice of one literal per clause underτ[x ↦ !b]. Padding a subformula with its first clause turns "at mostwclauses" into "exactlyw, with repetitions"; the empty subformula is satisfiable, so it only contributes theτ x = some bcase.satExt_iff: an extension ofρsatisfiesψiff some section ofψiscompatiblewithρ(no literal is falsified byρ, and no two are complementary).implied_eq_testrestatesimpliedthrough the search.The program (
Algorithms/WordRAM/PPSZ/):Odometer.lean:nextSection_sections. The odometer step (first entry fastest, carry on wrap) visitsList.sections Lin order and stops after the last section, when every list is duplicate-free.Clauses.lean: the same search on stored data (addrTest). Clauses are named by the addresses where their encodings start, literals by the addresses of their codes.addrTest_eqprovesaddrTest = impliedTest.Implied.lean:impliedCoderuns two nested odometers in2 swords of scratch memory. The outer one,D, ranges over clause addresses; the inner one,E, over literal addresses of the clauses inD. Compatibility is tested by anO(s²)double loop, then the scratch words are cleared.impliedCode_spectakes:φstored in[cBeg, cEnd), below the partial assignmentτattBase = Tb;sstored atTb + 2n, with2szero words after it;Tb + 2n + 2s + 2 < 2^w.Under these hypotheses the program stores
optCode (implied φ s τ x)inresand leaves memory unchanged, withinimpliedTime s Einstructions, whereEis the length of the clause encoding.impliedTime_lebounds this by140 (s + 1)² (E + 1)^(2s).The program uses only registers outside #1954's
RoundFrame, the loop registersxReg,iRegandjReg, and #1960's counter registers (29–31). It findssand its scratch memory fromtBaseandnReg. So it can replaceforcedCodein #1954's round loop with the same proof shape: memory unchanged, result inres. The only extra requirement is the wordsand the zero words afterP.Existing notions considered
List.sections(Batteries/Mathlib) is the enumeration, andmem_sectionsits characterization.nextSectionandsuccInare new because the library has no successor function on sections.SatExtis new.WImpliedquantifies over subformulas and extensions inline, and no existing predicate states "some extension of a partial assignment satisfiesψ".litFineandcompatCodesare the code-level counterparts ofcompatible, like feat(PPZ): lazy-order rounds and the forced-value scan on the word RAM #1949'slitOkandunitTestforIsUnitOn.ImpFramemirrors feat(PPZ): lazy-order rounds and the forced-value scan on the word RAM #1949'sScanFrame; the encoding (encodeClauses,litCode) andPartialAtare reused unchanged.Source
The algorithm is PPSZ with w-implication, after R. Paturi, P. Pudlák, M. Saks, F. Zane, An improved exponential-time algorithm for k-SAT, J. ACM 52(3), 2005 (
[PaturiPudlakSaksZane2005]), and T. Hertli ([Hertli2011]), as in #1453'sDefs.lean. No theorem of either paper is claimed here: the program is matched against the library'simplied, so no locator is cited. The search procedure and its proof are original to this PR.Limits
O(s² E^(2s)), polynomial for fixeds. It is a brute-force search, not PPSZ's bounded resolution. The library formalizes PPSZ with w-implication, whose analysis (feat(fine-grained): PPSZ critical clause trees and the unique k-SAT bound #1466/feat(fine-grained): PPSZ for every satisfiable k-CNF, k >= 3 #1605) uses a fixedw.PPSZ.round φ s, and its amplification; see the handoff on Frontier track: exponential-time SAT algorithms (Schöning, PPSZ) #894.Abstract impact: none.
Validation
scripts/check.sh --quick --base origin/claude/ppz-amplify-894fell back to all six gates (custom Lake library options) and all passed on the tree before the final edit. The final edit addedimpliedTime_leand its docstring. After it I reran:lake build Complexity.Algorithms.WordRAM.PPSZ.Impliedandlake build ComplexityTests.WordRAMPPSZ --wfail,lake exe mk_all --check,lake exe lint-styleandscripts/check_hygiene.py.ComplexityTests/WordRAMPPSZ.lean) usex₀ ∧ (¬x₀ ∨ x₁), wherex₁ = trueis 2-implied but not 1-implied and is not forced by a unit clause:impliedTest,WImpliedandimpliedare checked both ways bydecide;impliedCode(Code.eval,decide +kernel) giveres = optCode (implied φ s τ x)for(s, x) = (2, 1), (1, 1), (1, 0), and the scratch words are zero afterwards;[[0, 1], [5, 6]];impliedCode_specis instantiated atw = 8.AI assistance
Written by Claude Code (Opus). Not yet independently reviewed.
🤖 Generated with Claude Code
https://claude.ai/code/session_015DLg8kwPs8yi7ePPdtoNvG