Repository navigation
feat(Algorithms/Lean/Dijkstra): Dijkstra with a binary heap over the memory oracle - #2238
Conversation
…eld arrays Memory.spec w is the memory oracle of #2205 (decision D7): read, write, and zeroed or dirty allocation at a frontier, with admissibility carrying the allocated-address and word-fit preconditions. Field arrays are WordRAM Blocks accessed by Block.get/Block.set programs over the oracle. 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
…ions with stacked potentials Refinement D E is a Module whose representation is an invariant plus an abstraction function (#2205 D2). Refinement.Amortized is the per-method physicist's inequality (D3); potentials stack across comp, add across non-interfering products, and yield an Amortized certificate for a realized module with a functional native representation (R2 gap 5). CostIsBigO is the exported asymptotic form (D6). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015DLg8kwPs8yi7ePPdtoNvG
…inements Amortized.mono and Amortized.mul_left (exchange at a constant rate, #2205 D4), productCharge_const, and transcript-cost monotonicity and scaling. 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
…t, outside Refinement 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
…structure A Prop-valued def whose body starts with an implicit binder is unfolded and auto-introduced during elaboration against an expected type, which broke term-mode uses such as Amortized.prod. A one-field structure, like the existing DataStructure.Amortized, avoids this. 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
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
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
….elim With a match, the answer types of product D E mention D and E through the matcher's parameters, so the elaborator cannot identify clients of two products whose components differ only in admissibility (for example the pair of stacks and the pair of bounded stacks). Sum.elim D.Result E.Result depends only on the component answer types. Queue.Spec: factor the dequeue computation into runClient_dequeue_nil and the behaviour of the methods into stepFn_methods, which the module and the potential argument now use; repair transfer_run. 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
The M1 slice of #2205. Stack.Memory implements the bounded stack by three memory programs over named fields, with a three-unit worst-case certificate, its frame, a non-interfering pair, and allocation. Queue.Memory reuses the two-stack queue methods over the bounded pair, then composes with the pair of array stacks; the potentials stack to nine memory units per queue operation. run allocates both stacks and runs a client: correct, at most 6 + 9 m memory units, and O(m). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015DLg8kwPs8yi7ePPdtoNvG
…queue spec Dijkstra's algorithm as an oracle program over three interfaces, the indexed min-priority queue, a distance map (the existing Dictionary spec) and a new read-only adjacency-list interface, combined with `product`. Correctness against the specs' own transition functions reuses `Dijkstra/Invariant.lean` and `decode_edgesWord` unchanged. The same induction counts operations by kind, which gives a CostHoare triple for any priority-queue charges, its transport through any Module with a ChargeBound, and O((n + m) log n) and O(m + n log n) exports for binary-heap-style and Fibonacci-heap-style abstract charges. Part of #2205 (M3 pilot, hops 1-2). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015DLg8kwPs8yi7ePPdtoNvG
…vertices Generalize the amortized run judgment to a potential with a per-unreached and a per-queued vertex part. With the first, the counts are bounded by `n`; with the second, insertions and rounds are paid for by edges, giving `min n (m + 1)` insertions, `min n (m + 2)` extractions and `min (n + m) (2 m + 1)` graph queries. The asymptotic exports sharpen to `O((m + 1) log n)` and `O(m + min(n, m + 1) log n)`, the shapes of `LogLinearSpec` and `FibonacciSpec`. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015DLg8kwPs8yi7ePPdtoNvG
…op 3 Products over a shared memory (#2205 hop 3): - `Memory.Framed`: a refinement over `Memory.spec w` with a footprint of allocated cells, read by its invariant and abstraction, outside which its methods change no allocated cell. `Framed.ofStatic` for fixed layouts. - `Framed.prod`: two framed refinements with disjoint footprints implement the product of their specifications; the product is framed again, so products iterate. `Framed.amortized_prod` adds charges and potentials that read only their own footprints; zero potentials give a `ChargeBound`. - `Framed.of_fresh`, `Framed.prod_of_fresh`: allocation preserves structures and sets up products. - `Refinement.prod` takes a joint invariant (here, disjointness), and its methods are the new `Methods.prod`. The array stack is now `Stack.Memory.framed`, and the queue's pair of stacks is the generic product; the hand-written frame and pair lemmas are gone. Glue charges: `Refinement.Amortized.add`, `Amortized.glue` (glue at most `K` times a call's charge plus `K`), `Amortized.glue_of_one_le`, `StateTransitionSpec.totalCost_glue_le` and `Memory.one_le_charge`. `Queue.Memory.run_cost_glue` bounds memory charges and glue together by `(2K + 1)(6 + 9m)`. `link_eq_interpret` (D1) in a leaf module, so the state-transition layer does not import probability. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015DLg8kwPs8yi7ePPdtoNvG
…y oracle The indexed min-priority queue indexedMinPQSpec n K is implemented as a binary heap by programs over Memory.spec w, in the layout and with the abstraction (stateOfMem) and invariant (HeapInv) of BinaryHeap.Model. siftUp and siftDown are recursive memory programs whose proofs move one order defect per level with the order lemmas of BinaryHeap.Order, copied from the private lemmas of the word-RAM Sift.lean. Every operation costs at most 10 log n + 14 memory units; the heap is a Memory.Framed with its layout as footprint and starts empty when allocated in memory that is zero above the frontier. Memory.Triple packages CostHoare at one initial state with forward rules for reads, writes, dirty allocation and bind; Memory.ZeroAbove records that the input convention is zero past the input. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015DLg8kwPs8yi7ePPdtoNvG
…mory test Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015DLg8kwPs8yi7ePPdtoNvG
…roduct answers #2212 states the answer types of product as Sum.elim, which simp does not unfold when it unifies the bind type of a declared call (Option ℕ, Fin n × ℕ) with StateTransitionSpec.runClient_lift_bind'. Evaluate each kind of call by its own definitional equation instead. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015DLg8kwPs8yi7ePPdtoNvG
…memory oracle Memory modules for the other two interfaces of the Dijkstra client: a direct-address table for Dictionary.spec (one cell per key, one memory unit per operation) and compressed adjacency arrays for AdjacencyList.spec (the input layout of a word RAM; at most three memory units per query). With the binary heap they form one Memory.Framed product implementing Dijkstra.spec. Dijkstra.Memory.run is one memory program for every graph: it reads n, the source and m from the input convention, allocates the distance table and the heap past the input, and runs the linked client. run_spec: every memory operation is admissible, the cells past the input hold the encoded distances (the output convention of LogLinearSpec), and the run costs at most 52 (m + 1) (log n + 1) memory units; exists_run_logLinear exports this as O((m + 1) log n). 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
…parately inv_input: after allocation past the input, the heap, the distance table and the input's adjacency arrays represent Dijkstra's initial state. run_triple uses it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015DLg8kwPs8yi7ePPdtoNvG
|
Active review — |
edemaine
left a comment
There was a problem hiding this comment.
APPROVE — reviewer-codex-edemaine, independent non-author worker review of a9e0b2ec6db748394bc9a3fa8a86fd9bfbbaf7bc.
Read the complete six-file own layer over dependency merge 4d59fe80, whose parents are the reviewed #2237/#2220 heads. Named call equations repair the product-answer elaboration without changing the client. The table’s 0/v+1 encoding matches encodeDist; adjacency offsets and edge cells match ListInstance.encode. Disjoint heap/table/input footprints justify composition. One run is chosen before graph and width; the type-level zero bounds are replaced only in its admissibility proof. The fitting envelope covers allocation, handles and stored distances. The 52·(m+1)·(floor(log₂ n)+1) bound counts memory operations, including setup, and uses the disclosed zero-above-input convention. It is not a native runtime result. The checked parallel-edge example exercises distances, validity and exact charge 75. No blocking finding or selected-abstract impact.
Whitespace, hygiene/simp and the canonical 3,815-module aggregate pass. At one inspection, library CI was running; Guide/title passed. The author reports focused warning-strict builds; no reviewer Lean build. Agent review, not human approval.
edemaine
left a comment
There was a problem hiding this comment.
APPROVE — reviewer-codex-edemaine, independent non-author delta review of 9a20b2fa2171e842728bbb14d14d7ea509a4ee01, reusing the full memory-client review.
Read the complete one-file delta and affected reasoning. inv_input extracts the same zero-above-input, disjoint-footprint and initial-abstraction argument, now at general interface bounds. run_triple supplies its original fitting bounds and reuses that helper. The post-state lemma is not an allocation-validity theorem. The program, all other payload/test files, output convention, resource statements and abstract impact are unchanged; no blocking finding.
Whitespace and hygiene/simp pass; the aggregate is unchanged. At one inspection, current-head library CI was running; Guide/title passed. No reviewer Lean build; the existing concrete client remains the regression evidence. Agent review, not human approval.
Ordinary merge of approved #2220 b2ebc4a with fixed actual main 5b5b4be. Reuse Claude Code Opus 5.5's exact proof repair from #2238 commit b417144: six private rfl equations evaluate calls with the declared product-answer types, and the four affected private proofs use those equations. Every public declaration in Client, all operation-count bounds, all remaining feature files and all unrelated main entries are unchanged. The fixed Client is byte-identical to the existing #2238 source. Full binary-patch forward/inverse tests recover the original feature, neutral merge and exact main. All five main pins and the canonical 3877/75/2 import inventories are preserved. Strict focused Client, Cost and Dijkstra regression validation passed on this exact combined tree (session 34419, 3550 jobs); hygiene passed. All four formerly failing proof sites were elaborated in this context. Full-six validation is requested separately; no full-six claim yet. No selected-abstract scope or rendering impact. Original source and mathematical ownership/credit are retained. AI-assisted bounded coordinator fix under #2220, session codex-fix-2220-bpl-20261102; root retains publication authority and LogsQ retains integration. No new mathematics or machine bound. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Complexity.lean: union of the aggregate imports. 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
…tic's frontier_eq and Apart The binary heap (#2237), the adjacency arrays and the direct-address table (#2238) keep the frontier, so each supplies Framed.ofStatic's frontier_eq from its existing run lemma. Dijkstra.Memory.inv_input now assumes that the frontier after allocation fits a word, which the product invariant Memory.Framed.Apart requires; run_triple supplies it from its fitting bound. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015DLg8kwPs8yi7ePPdtoNvG
…growing structures (cslib-community#2239) * feat(DataStructure/Memory): word-addressed memory oracle and named field arrays Memory.spec w is the memory oracle of cslib-community#2205 (decision D7): read, write, and zeroed or dirty allocation at a frontier, with admissibility carrying the allocated-address and word-fit preconditions. Field arrays are WordRAM Blocks accessed by Block.get/Block.set programs over the oracle. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015DLg8kwPs8yi7ePPdtoNvG * doc(bib): add Guéneau, Charguéraud and Pottier (ESOP 2018) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015DLg8kwPs8yi7ePPdtoNvG * feat(DataStructure/StateTransition): refinements by abstraction functions with stacked potentials Refinement D E is a Module whose representation is an invariant plus an abstraction function (cslib-community#2205 D2). Refinement.Amortized is the per-method physicist's inequality (D3); potentials stack across comp, add across non-interfering products, and yield an Amortized certificate for a realized module with a functional native representation (R2 gap 5). CostIsBigO is the exported asymptotic form (D6). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015DLg8kwPs8yi7ePPdtoNvG * feat(DataStructure/StateTransition): weaken and rescale amortized refinements Amortized.mono and Amortized.mul_left (exchange at a constant rate, cslib-community#2205 D4), productCharge_const, and transcript-cost monotonicity and scaling. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015DLg8kwPs8yi7ePPdtoNvG * fix(DataStructure/StateTransition): place productCharge beside product, outside Refinement Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015DLg8kwPs8yi7ePPdtoNvG * refactor(DataStructure/StateTransition): make Refinement.Amortized a structure A Prop-valued def whose body starts with an implicit binder is unfolded and auto-introduced during elaboration against an expected type, which broke term-mode uses such as Amortized.prod. A one-field structure, like the existing DataStructure.Amortized, avoids this. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015DLg8kwPs8yi7ePPdtoNvG * wip: array stack over memory and queue method lemmas Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015DLg8kwPs8yi7ePPdtoNvG * feat(Foundations): affine cost bounds are O(size) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015DLg8kwPs8yi7ePPdtoNvG * wip: queue over memory Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015DLg8kwPs8yi7ePPdtoNvG * refactor(DataStructure/StateTransition): product answer types via Sum.elim With a match, the answer types of product D E mention D and E through the matcher's parameters, so the elaborator cannot identify clients of two products whose components differ only in admissibility (for example the pair of stacks and the pair of bounded stacks). Sum.elim D.Result E.Result depends only on the component answer types. Queue.Spec: factor the dequeue computation into runClient_dequeue_nil and the behaviour of the methods into stepFn_methods, which the module and the potential argument now use; repair transfer_run. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015DLg8kwPs8yi7ePPdtoNvG * feat(DataStructure): queue over two array stacks over the memory oracle The M1 slice of cslib-community#2205. Stack.Memory implements the bounded stack by three memory programs over named fields, with a three-unit worst-case certificate, its frame, a non-interfering pair, and allocation. Queue.Memory reuses the two-stack queue methods over the bounded pair, then composes with the pair of array stacks; the potentials stack to nine memory units per queue operation. run allocates both stacks and runs a client: correct, at most 6 + 9 m memory units, and O(m). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015DLg8kwPs8yi7ePPdtoNvG * feat(DataStructure): products over one memory, and glue charges for hop 3 Products over a shared memory (cslib-community#2205 hop 3): - `Memory.Framed`: a refinement over `Memory.spec w` with a footprint of allocated cells, read by its invariant and abstraction, outside which its methods change no allocated cell. `Framed.ofStatic` for fixed layouts. - `Framed.prod`: two framed refinements with disjoint footprints implement the product of their specifications; the product is framed again, so products iterate. `Framed.amortized_prod` adds charges and potentials that read only their own footprints; zero potentials give a `ChargeBound`. - `Framed.of_fresh`, `Framed.prod_of_fresh`: allocation preserves structures and sets up products. - `Refinement.prod` takes a joint invariant (here, disjointness), and its methods are the new `Methods.prod`. The array stack is now `Stack.Memory.framed`, and the queue's pair of stacks is the generic product; the hand-written frame and pair lemmas are gone. Glue charges: `Refinement.Amortized.add`, `Amortized.glue` (glue at most `K` times a call's charge plus `K`), `Amortized.glue_of_one_le`, `StateTransitionSpec.totalCost_glue_le` and `Memory.one_le_charge`. `Queue.Memory.run_cost_glue` bounds memory charges and glue together by `(2K + 1)(6 + 9m)`. `link_eq_interpret` (D1) in a leaf module, so the state-transition layer does not import probability. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015DLg8kwPs8yi7ePPdtoNvG * feat(DataStructure/StateTransition): instance search for nested products The product instances index their specification with `no_index`, so `product (product D E) F` and deeper products find `HasStepFn`, `Total` and `Deterministic` without a named instance. The test of three stacks in one memory drops its named instance. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015DLg8kwPs8yi7ePPdtoNvG * feat(DataStructure/Memory): allocators, and a shared room budget for growing structures `Memory.Allocator` packages an allocation program, the methods it sets up and their framed refinement, with generic `run_correct`, `run_cost` and `run_cost_isBigO` for any client. `Allocator.prod` allocates structures one after the other and `Allocator.comp` puts a refinement on top, with cost certificates combining alongside. `Memory.Framed` gains a room: the cells a structure reserves for its future allocations. A product's invariant keeps the frontier plus all rooms fitting a word, so a structure may allocate inside its operations while the others do too. `Framed.comp` frames a refinement over a framed one, by the frame of a whole linked client (`Framed.modifies_demonic`). The queue over two stacks is restated through the allocator, with no setup proof of its own. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015DLg8kwPs8yi7ePPdtoNvG * feat(DataStructure/Memory): structures already in memory, and a growth test An allocator may now take over allocated cells instead of allocating them: `Allocator.owned` names them, `Allocates.of_mem_footprint` lets the footprint lie in them as well as in fresh cells, and `Allocator.ProdPre` asks a product's two structures to take over disjoint cells. Fresh allocators default to taking over none. `Allocator.resident` takes over a framed structure already in memory, such as an input graph, with an allocation that does nothing, and `Amortized.resident` carries its certificate over. `pre_fresh` and `owned_fresh` may assume the room still fits, so a resident structure's precondition may hold its invariant. `Framed.prod_of_fresh` now asks for disjoint footprints rather than a fresh second footprint. The new test `DataStructureMemoryAlloc` checks two write-once cells that each reserve one cell and allocate it inside their first `set`, with the footprints, abstractions and frontier plus room after each step and the tight word-size boundary; and stacks held by the input, taken over beside stacks allocated from scratch in the Dijkstra shape. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015DLg8kwPs8yi7ePPdtoNvG * feat(DataStructure/Memory): allocations keep the memory beyond the frontier An admissible run changes no cell at or above its final frontier (`Memory.mem_run_of_frontier_le`, `mem_clientState_of_frontier_le`). `Allocator.pre_fresh` and `owned_fresh` may now assume this of the runs they are applied to, and `Allocator.prod` supplies it from the first allocation's admissibility. So an allocator may require the memory beyond the frontier to be zero, as the input convention leaves it, and take its storage with `allocDirty` for one unit; the product keeps that precondition for the structures allocated after it. The test's write-once cells now take their headers this way, and a test over a nonzero cell shows that the precondition is needed. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015DLg8kwPs8yi7ePPdtoNvG * fix(DataStructure/PriorityQueue): the binary heap's frame keeps the frontier (Framed.ofStatic) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015DLg8kwPs8yi7ePPdtoNvG * fix(DataStructure): migrate the landed memory clients to Framed.ofStatic's frontier_eq and Apart The binary heap (cslib-community#2237), the adjacency arrays and the direct-address table (cslib-community#2238) keep the frontier, so each supplies Framed.ofStatic's frontier_eq from its existing run lemma. Dijkstra.Memory.inv_input now assumes that the frontier after allocation fits a word, which the product invariant Memory.Framed.Apart requires; run_triple supplies it from its fitting bound. 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>
… Karger.spec through a simulation lemma (cslib-community#2269) * refactor(Algorithms/WordRAM/Karger): derive contraction survival from Karger.spec `contractDownTo` now simulates the client `Lean.Karger.contractTimes`: `contractDownTo_law` states, as an `ExecRandLaw`, that the graph the machine holds (`heldGraph`) has the law of the client's final state. Each step's `rand` call has the law of the client's coin, and `postRandStep_exec` contracts the pair sampled there. `contractDownTo_spec` keeps its statement. Its contraction invariant and its survival bound now come from `isContractionOf_of_mem_support_contractTimes` and `survives_contractTimes` through that law. The machine-state survival induction `contractLoop_spec` (379 proof lines) is replaced by `contractLoop_law` (147), and `survivalPost_two_mem_eq` uses `cutWeight_fin_two`. `ExecRandLaw` is exposed so that clients can read the law off its witness, and `run_contractStep_bind` and `run_contractStep_bind_of_eq_zero` become public. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015DLg8kwPs8yi7ePPdtoNvG * ci(integration): report canonical aggregate-only merges (cslib-community#2276) Add a report-only verifier with independent temporary Git storage, exact reviewed-feature forward/inverse recovery, and ordinary tracked-attribute tree equality. No queue or source mutation by the verifier. Validation: 16 focused real-Git fixtures; check_hygiene.py --check-simp; git diff --cached --check. Historical 2244 reconstruction returned exact d218e3e tree in 3.29s. Full validation and independent review remain before PR integration. No Lean or selected-abstract impact. AI assistance: OpenAI Codex. Refs cslib-community#2274. * feat(Classes/Promise): explicit-time sample-and-verify for PromiseBPTIME (cslib-community#2084 M1) (cslib-community#2086) * feat(Classes/Time): explicit-time verifier characterization of NTIME (cslib-community#1572) Guess and verify within explicit time (`setOf_exists_mem_NTIME`), through a closed fair-coin composition with the new framed sampler `pairSampler`, and a linear-time verifier for every problem in `NTIME` (`exists_verifier_of_mem_NTIME`). Infrastructure toward the nondeterministic time hierarchy. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015DLg8kwPs8yi7ePPdtoNvG * refactor(Machines/PTM): make the pair sampler's proof configurations private The induction configurations `PairSampler.config` and the intermediate run lemmas are facts about a module-local construction. Only the output law `eval_pairSampler` and the halting contract `pairSampler_halted` remain public. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015DLg8kwPs8yi7ePPdtoNvG * feat(Classes/Promise): PromiseBPTIME with explicit-time sample-and-verify (cslib-community#2084 M1) Define bounded-error probabilistic time for promise problems (Turing.MultiTapePTM.SolvesWithBoundedErrorInTime, Cslib.Complexity.PromiseBPTIME), with the bridge ofSet A ∈ PromiseBPTIME ↔ A ∈ BPTIME and the inclusion of the lift of BPTIME. Characterize the class by verifiers within explicit time: sample and verify (mem_PromiseBPTIME_of_verifier) and a linear-time coin-replay verifier (exists_verifier_of_mem_PromiseBPTIME). The sample-and-verify machine is extracted from the guess-and-verify proof of cslib-community#2025 into Classes/Time/SampleVerify (exists_machine_sampleVerify), and setOf_exists_mem_NTIME now uses it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015DLg8kwPs8yi7ePPdtoNvG * doc(Classes/Promise): cite Goldreich's survey without an unverified locator; test a concrete member Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015DLg8kwPs8yi7ePPdtoNvG * refactor(Foundations): share the two-thirds dyadic fraction lemma `Classes/Time` and `Classes/Promise/Time` each proved the same private `two_thirds_le_div_iff`. Keep one public copy, `ENNReal.two_div_three_le_natCast_div_two_pow_iff`, in a small Foundations companion and use it from both modules. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015DLg8kwPs8yi7ePPdtoNvG * docs(PromiseBPTIME): move hierarchy reference past shared link gap --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> * feat(DataStructure): Fibonacci heap over a record, part 2 (decreaseKey with cascading cuts) (cslib-community#2233) * feat(DataStructure/Memory): word-addressed memory oracle and named field arrays Memory.spec w is the memory oracle of cslib-community#2205 (decision D7): read, write, and zeroed or dirty allocation at a frontier, with admissibility carrying the allocated-address and word-fit preconditions. Field arrays are WordRAM Blocks accessed by Block.get/Block.set programs over the oracle. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015DLg8kwPs8yi7ePPdtoNvG * doc(bib): add Guéneau, Charguéraud and Pottier (ESOP 2018) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015DLg8kwPs8yi7ePPdtoNvG * feat(DataStructure/StateTransition): refinements by abstraction functions with stacked potentials Refinement D E is a Module whose representation is an invariant plus an abstraction function (cslib-community#2205 D2). Refinement.Amortized is the per-method physicist's inequality (D3); potentials stack across comp, add across non-interfering products, and yield an Amortized certificate for a realized module with a functional native representation (R2 gap 5). CostIsBigO is the exported asymptotic form (D6). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015DLg8kwPs8yi7ePPdtoNvG * feat(DataStructure/StateTransition): weaken and rescale amortized refinements Amortized.mono and Amortized.mul_left (exchange at a constant rate, cslib-community#2205 D4), productCharge_const, and transcript-cost monotonicity and scaling. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015DLg8kwPs8yi7ePPdtoNvG * fix(DataStructure/StateTransition): place productCharge beside product, outside Refinement Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015DLg8kwPs8yi7ePPdtoNvG * refactor(DataStructure/StateTransition): make Refinement.Amortized a structure A Prop-valued def whose body starts with an implicit binder is unfolded and auto-introduced during elaboration against an expected type, which broke term-mode uses such as Amortized.prod. A one-field structure, like the existing DataStructure.Amortized, avoids this. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015DLg8kwPs8yi7ePPdtoNvG * wip: array stack over memory and queue method lemmas Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015DLg8kwPs8yi7ePPdtoNvG * feat(Foundations): affine cost bounds are O(size) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015DLg8kwPs8yi7ePPdtoNvG * wip: queue over memory Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015DLg8kwPs8yi7ePPdtoNvG * refactor(DataStructure/StateTransition): product answer types via Sum.elim With a match, the answer types of product D E mention D and E through the matcher's parameters, so the elaborator cannot identify clients of two products whose components differ only in admissibility (for example the pair of stacks and the pair of bounded stacks). Sum.elim D.Result E.Result depends only on the component answer types. Queue.Spec: factor the dequeue computation into runClient_dequeue_nil and the behaviour of the methods into stepFn_methods, which the module and the potential argument now use; repair transfer_run. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015DLg8kwPs8yi7ePPdtoNvG * feat(DataStructure): queue over two array stacks over the memory oracle The M1 slice of cslib-community#2205. Stack.Memory implements the bounded stack by three memory programs over named fields, with a three-unit worst-case certificate, its frame, a non-interfering pair, and allocation. Queue.Memory reuses the two-stack queue methods over the bounded pair, then composes with the pair of array stacks; the potentials stack to nine memory units per queue operation. run allocates both stacks and runs a client: correct, at most 6 + 9 m memory units, and O(m). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015DLg8kwPs8yi7ePPdtoNvG * feat(DataStructure): Fibonacci heap insert over a record of named cells Add Record.spec, a generic record of named cells over the memory oracle with a weakest-precondition calculus (Record.wp) and a one-unit-per-operation refinement into Memory.spec. Start the Fibonacci heap over such a record: the cells are the existing struct of arrays, read as RawState, so FibRawInv and the forest lemmas apply unchanged. isEmpty, getKey and insert are record programs with specifications against IndexedMinPQ.step, the invariant, and the amortized cost with potential credit * (numRoots + 2 * numMarked). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015DLg8kwPs8yi7ePPdtoNvG * feat(DataStructure): Fibonacci heap decreaseKey with cascading cuts over a record decreaseKey cuts v from its parent when heap order breaks, cascades up the marked ancestors (fuel bounded by the number of marks), then stores the key and updates the minimum root. Program evaluation (wp_cut, wp_cascade, wp_setKey, wp_decreaseKey) is separated from forest mathematics on RawState (cutsNode_cutState, CutsNode.cascading, Cascading.mark, ...), which reuses ValidSubtree.exists_cut, mark_pending, lower_key_no_cut and CutInv.to_fibRawInv unchanged. Amortized cost: 104 record operations. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015DLg8kwPs8yi7ePPdtoNvG * fix(DataStructure): credit Renfei Zhou in the record Fibonacci heap; test records and insert Retain the original authorship of the native WordRAM Fibonacci heap that Basic.lean adapts, and add ComplexityTests/FibonacciHeapRecord: a concrete Record.Layout with a program run through Record.wp and Record.refinement, the all-zero heap record satisfying Inv, and three insertions checked by evaluation and through wp_insert. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015DLg8kwPs8yi7ePPdtoNvG * fix(DataStructure): credit Renfei Zhou in the record decreaseKey; test a cut and cascading cut Retain the original authorship of the native Cut.lean development that DecreaseKey.lean adapts, and add ComplexityTests/FibonacciHeapDecreaseKey: a three-node chain with a marked middle node proved to satisfy Inv (and hence Cascading), on which decreaseKey cuts the leaf and the cascade cuts the marked parent; checked by evaluation and through wp_decreaseKey. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015DLg8kwPs8yi7ePPdtoNvG * fix(DataStructure): name the adapted module without a slash path 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> * feat(DataStructure/Memory): allocators, and a shared room budget for growing structures (cslib-community#2239) * feat(DataStructure/Memory): word-addressed memory oracle and named field arrays Memory.spec w is the memory oracle of cslib-community#2205 (decision D7): read, write, and zeroed or dirty allocation at a frontier, with admissibility carrying the allocated-address and word-fit preconditions. Field arrays are WordRAM Blocks accessed by Block.get/Block.set programs over the oracle. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015DLg8kwPs8yi7ePPdtoNvG * doc(bib): add Guéneau, Charguéraud and Pottier (ESOP 2018) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015DLg8kwPs8yi7ePPdtoNvG * feat(DataStructure/StateTransition): refinements by abstraction functions with stacked potentials Refinement D E is a Module whose representation is an invariant plus an abstraction function (cslib-community#2205 D2). Refinement.Amortized is the per-method physicist's inequality (D3); potentials stack across comp, add across non-interfering products, and yield an Amortized certificate for a realized module with a functional native representation (R2 gap 5). CostIsBigO is the exported asymptotic form (D6). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015DLg8kwPs8yi7ePPdtoNvG * feat(DataStructure/StateTransition): weaken and rescale amortized refinements Amortized.mono and Amortized.mul_left (exchange at a constant rate, cslib-community#2205 D4), productCharge_const, and transcript-cost monotonicity and scaling. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015DLg8kwPs8yi7ePPdtoNvG * fix(DataStructure/StateTransition): place productCharge beside product, outside Refinement Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015DLg8kwPs8yi7ePPdtoNvG * refactor(DataStructure/StateTransition): make Refinement.Amortized a structure A Prop-valued def whose body starts with an implicit binder is unfolded and auto-introduced during elaboration against an expected type, which broke term-mode uses such as Amortized.prod. A one-field structure, like the existing DataStructure.Amortized, avoids this. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015DLg8kwPs8yi7ePPdtoNvG * wip: array stack over memory and queue method lemmas Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015DLg8kwPs8yi7ePPdtoNvG * feat(Foundations): affine cost bounds are O(size) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015DLg8kwPs8yi7ePPdtoNvG * wip: queue over memory Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015DLg8kwPs8yi7ePPdtoNvG * refactor(DataStructure/StateTransition): product answer types via Sum.elim With a match, the answer types of product D E mention D and E through the matcher's parameters, so the elaborator cannot identify clients of two products whose components differ only in admissibility (for example the pair of stacks and the pair of bounded stacks). Sum.elim D.Result E.Result depends only on the component answer types. Queue.Spec: factor the dequeue computation into runClient_dequeue_nil and the behaviour of the methods into stepFn_methods, which the module and the potential argument now use; repair transfer_run. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015DLg8kwPs8yi7ePPdtoNvG * feat(DataStructure): queue over two array stacks over the memory oracle The M1 slice of cslib-community#2205. Stack.Memory implements the bounded stack by three memory programs over named fields, with a three-unit worst-case certificate, its frame, a non-interfering pair, and allocation. Queue.Memory reuses the two-stack queue methods over the bounded pair, then composes with the pair of array stacks; the potentials stack to nine memory units per queue operation. run allocates both stacks and runs a client: correct, at most 6 + 9 m memory units, and O(m). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015DLg8kwPs8yi7ePPdtoNvG * feat(DataStructure): products over one memory, and glue charges for hop 3 Products over a shared memory (cslib-community#2205 hop 3): - `Memory.Framed`: a refinement over `Memory.spec w` with a footprint of allocated cells, read by its invariant and abstraction, outside which its methods change no allocated cell. `Framed.ofStatic` for fixed layouts. - `Framed.prod`: two framed refinements with disjoint footprints implement the product of their specifications; the product is framed again, so products iterate. `Framed.amortized_prod` adds charges and potentials that read only their own footprints; zero potentials give a `ChargeBound`. - `Framed.of_fresh`, `Framed.prod_of_fresh`: allocation preserves structures and sets up products. - `Refinement.prod` takes a joint invariant (here, disjointness), and its methods are the new `Methods.prod`. The array stack is now `Stack.Memory.framed`, and the queue's pair of stacks is the generic product; the hand-written frame and pair lemmas are gone. Glue charges: `Refinement.Amortized.add`, `Amortized.glue` (glue at most `K` times a call's charge plus `K`), `Amortized.glue_of_one_le`, `StateTransitionSpec.totalCost_glue_le` and `Memory.one_le_charge`. `Queue.Memory.run_cost_glue` bounds memory charges and glue together by `(2K + 1)(6 + 9m)`. `link_eq_interpret` (D1) in a leaf module, so the state-transition layer does not import probability. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015DLg8kwPs8yi7ePPdtoNvG * feat(DataStructure/StateTransition): instance search for nested products The product instances index their specification with `no_index`, so `product (product D E) F` and deeper products find `HasStepFn`, `Total` and `Deterministic` without a named instance. The test of three stacks in one memory drops its named instance. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015DLg8kwPs8yi7ePPdtoNvG * feat(DataStructure/Memory): allocators, and a shared room budget for growing structures `Memory.Allocator` packages an allocation program, the methods it sets up and their framed refinement, with generic `run_correct`, `run_cost` and `run_cost_isBigO` for any client. `Allocator.prod` allocates structures one after the other and `Allocator.comp` puts a refinement on top, with cost certificates combining alongside. `Memory.Framed` gains a room: the cells a structure reserves for its future allocations. A product's invariant keeps the frontier plus all rooms fitting a word, so a structure may allocate inside its operations while the others do too. `Framed.comp` frames a refinement over a framed one, by the frame of a whole linked client (`Framed.modifies_demonic`). The queue over two stacks is restated through the allocator, with no setup proof of its own. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015DLg8kwPs8yi7ePPdtoNvG * feat(DataStructure/Memory): structures already in memory, and a growth test An allocator may now take over allocated cells instead of allocating them: `Allocator.owned` names them, `Allocates.of_mem_footprint` lets the footprint lie in them as well as in fresh cells, and `Allocator.ProdPre` asks a product's two structures to take over disjoint cells. Fresh allocators default to taking over none. `Allocator.resident` takes over a framed structure already in memory, such as an input graph, with an allocation that does nothing, and `Amortized.resident` carries its certificate over. `pre_fresh` and `owned_fresh` may assume the room still fits, so a resident structure's precondition may hold its invariant. `Framed.prod_of_fresh` now asks for disjoint footprints rather than a fresh second footprint. The new test `DataStructureMemoryAlloc` checks two write-once cells that each reserve one cell and allocate it inside their first `set`, with the footprints, abstractions and frontier plus room after each step and the tight word-size boundary; and stacks held by the input, taken over beside stacks allocated from scratch in the Dijkstra shape. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015DLg8kwPs8yi7ePPdtoNvG * feat(DataStructure/Memory): allocations keep the memory beyond the frontier An admissible run changes no cell at or above its final frontier (`Memory.mem_run_of_frontier_le`, `mem_clientState_of_frontier_le`). `Allocator.pre_fresh` and `owned_fresh` may now assume this of the runs they are applied to, and `Allocator.prod` supplies it from the first allocation's admissibility. So an allocator may require the memory beyond the frontier to be zero, as the input convention leaves it, and take its storage with `allocDirty` for one unit; the product keeps that precondition for the structures allocated after it. The test's write-once cells now take their headers this way, and a test over a nonzero cell shows that the precondition is needed. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015DLg8kwPs8yi7ePPdtoNvG * fix(DataStructure/PriorityQueue): the binary heap's frame keeps the frontier (Framed.ofStatic) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015DLg8kwPs8yi7ePPdtoNvG * fix(DataStructure): migrate the landed memory clients to Framed.ofStatic's frontier_eq and Apart The binary heap (cslib-community#2237), the adjacency arrays and the direct-address table (cslib-community#2238) keep the frontier, so each supplies Framed.ofStatic's frontier_eq from its existing run lemma. Dijkstra.Memory.inv_input now assumes that the frontier after allocation fits a word, which the product invariant Memory.Framed.Apart requires; run_triple supplies it from its fitting bound. 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> * feat(Algorithms/Lean/Karger): Karger's contraction algorithm as a randomized client, survival proved on the specification (cslib-community#2241) * feat(DataStructure/Memory): word-addressed memory oracle and named field arrays Memory.spec w is the memory oracle of cslib-community#2205 (decision D7): read, write, and zeroed or dirty allocation at a frontier, with admissibility carrying the allocated-address and word-fit preconditions. Field arrays are WordRAM Blocks accessed by Block.get/Block.set programs over the oracle. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015DLg8kwPs8yi7ePPdtoNvG * doc(bib): add Guéneau, Charguéraud and Pottier (ESOP 2018) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015DLg8kwPs8yi7ePPdtoNvG * feat(DataStructure/StateTransition): refinements by abstraction functions with stacked potentials Refinement D E is a Module whose representation is an invariant plus an abstraction function (cslib-community#2205 D2). Refinement.Amortized is the per-method physicist's inequality (D3); potentials stack across comp, add across non-interfering products, and yield an Amortized certificate for a realized module with a functional native representation (R2 gap 5). CostIsBigO is the exported asymptotic form (D6). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015DLg8kwPs8yi7ePPdtoNvG * feat(DataStructure/StateTransition): weaken and rescale amortized refinements Amortized.mono and Amortized.mul_left (exchange at a constant rate, cslib-community#2205 D4), productCharge_const, and transcript-cost monotonicity and scaling. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015DLg8kwPs8yi7ePPdtoNvG * fix(DataStructure/StateTransition): place productCharge beside product, outside Refinement Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015DLg8kwPs8yi7ePPdtoNvG * refactor(DataStructure/StateTransition): make Refinement.Amortized a structure A Prop-valued def whose body starts with an implicit binder is unfolded and auto-introduced during elaboration against an expected type, which broke term-mode uses such as Amortized.prod. A one-field structure, like the existing DataStructure.Amortized, avoids this. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015DLg8kwPs8yi7ePPdtoNvG * wip: array stack over memory and queue method lemmas Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015DLg8kwPs8yi7ePPdtoNvG * feat(Foundations): affine cost bounds are O(size) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015DLg8kwPs8yi7ePPdtoNvG * wip: queue over memory Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015DLg8kwPs8yi7ePPdtoNvG * refactor(DataStructure/StateTransition): product answer types via Sum.elim With a match, the answer types of product D E mention D and E through the matcher's parameters, so the elaborator cannot identify clients of two products whose components differ only in admissibility (for example the pair of stacks and the pair of bounded stacks). Sum.elim D.Result E.Result depends only on the component answer types. Queue.Spec: factor the dequeue computation into runClient_dequeue_nil and the behaviour of the methods into stepFn_methods, which the module and the potential argument now use; repair transfer_run. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015DLg8kwPs8yi7ePPdtoNvG * feat(DataStructure): queue over two array stacks over the memory oracle The M1 slice of cslib-community#2205. Stack.Memory implements the bounded stack by three memory programs over named fields, with a three-unit worst-case certificate, its frame, a non-interfering pair, and allocation. Queue.Memory reuses the two-stack queue methods over the bounded pair, then composes with the pair of array stacks; the potentials stack to nine memory units per queue operation. run allocates both stacks and runs a client: correct, at most 6 + 9 m memory units, and O(m). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015DLg8kwPs8yi7ePPdtoNvG * feat(DataStructure): distributional refinements and a random table over memory `RandomizedSpec` gives each operation a law, a stateful `PMF` handler. A `RandomizedRefinement` extends a relational `Refinement` of the supports with one distributional obligation per method; `run_link` lifts it to every adaptive client. The identical-until-bad step reuses `OracleComp.IdenticalUntilBad`, and `ExpectedAmortized` telescopes expected charges along clients and across composition. `withCoins` adds private coins (`ProbOracleComp`) to a lower interface. Pilot: a random table stored in a field array over `Memory.spec w` with coins refines the seed-level hash-family spec `HashFamily.seedSpec`; its run from allocation has transcript law `HashFamily.evalOps` (decision D10 of cslib-community#2205). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015DLg8kwPs8yi7ePPdtoNvG * feat(DataStructure): stack coin-using distributional hops; deterministic hops as distributional Follow-ups to cslib-community#2232 for cslib-community#2205. - `RandomizedRefinement.withCoins`: coins pass through a refinement unchanged. - `RandomizedRefinement.mergeCoins`: two layers of private coins are one. - `RandomizedRefinement.compCoins`: a hop with coins of its own composes over a lower hop with coins; `ExpectedAmortized.withCoins`/`.compCoins` stack expected potentials across it. - `Refinement.toRandomized`, `Refinement.Amortized.toRandomized`: deterministic refinements and their pathwise amortized costs as distributional ones. - `Probability.isKWiseIndependentHash_id` moves from a private lemma of `CuckooHashing` to `Probability/KWiseIndependent.lean`; the memory random table gets its `kWiseSpec` contract (`RandomTable.kWiseSpec_contract_run`). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015DLg8kwPs8yi7ePPdtoNvG * feat(Algorithms/Lean/Karger): Karger's contraction algorithm as a randomized client, with its survival bound on the specification For cslib-community#2205 (decision D10). Karger's contraction algorithm becomes a client with coins of a deterministic contraction structure (`Karger.spec`: size, total doubled weight, the pair sampled at a prefix-sum offset, and contraction by `contractMatrix`). Its survival bound `t (t - 1) / ((t + s) (t + s - 1))`, Karger's success probability `2 / (n (n - 1))`, the one-sided error, admissibility and call counts are proved on the specification, reusing `Karger/Graph.lean` and the `Probability.PMF` event-composition bounds unchanged. Supporting lemmas: `RandomizedSpec.withCoins_run_sample_bind`, `StateTransitionSpec.run_withCoins_query_bind`, `demonicValid_withCoins_query_bind`, and `WeightedCut.cutWeight_fin_two`, `totalDoubledWeight_fin_two`. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015DLg8kwPs8yi7ePPdtoNvG * fix(StateTransition): use OracleComp.sumHandler after cslib-community#2201 cslib-community#2201 retired `ProbOracleComp.handler` and `handler_eq_sumHandler`. The coin interface `withCoins` now uses the canonical `OracleComp.sumHandler`, which `ProbOracleComp.handler` was equal to. 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> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
worker-claude-015dlg8k-binheap(Claude Code, Opus), for #2205 (M3 pilot, hop 3). Stacked on #2237 (binary heap) and #2220 (Dijkstra client). The base branchinteg/ram-binheap-dijkstra-clientis only the merge of those two, so the diff here shows just this PR. Retarget it when they land.What. Dijkstra's algorithm with a binary heap, from spec down to
Memory:Dictionary/Memory.lean: a direct-address table forDictionary.spec(the distance map). One cell per key holds0orv + 1, and each operation costs one memory unit.AdjacencyList/Memory.lean: compressed adjacency arrays forAdjacencyList.spec: offsets plus(target, weight)pairs, which is the word RAM's input layout. A query costs at most three units. The interface is read-only, so the refinement is indexed by the graph it holds (Holds), and its abstraction is constant.Algorithms/Lean/Dijkstra/Memory.lean: the heap, table and arrays as oneMemory.Framedproduct (feat(DataStructure): products over one memory, and glue charges for hop 3 #2229), andrun, a single memory program for every graph.runreadsn, the source andmfromListInstance.encode, allocates the table and heap past the input with dirty allocations (memory there is zero), and runs the linked client. Main results:run_spec: on the input words ofG, at every word size that holds8 (n + m + 2) (W + 2), every memory operation is admissible,G.outAddr vholdsencodeDist (G.dist G.source v), and the run costs at most52 (m + 1) (⌊log₂ n⌋ + 1)memory units. This is the hypotheses and output convention ofLogLinearSpec, at memory level.inv_input: after allocation, the three structures represent Dijkstra's initial state.exists_run_logLinear: the same with∃ fmonotone,f =O[comap Prod.fst atTop] (m + 1) log n(D6). So the targetO((n + m) log n)holds, in factO((m + 1) log n).Correctness is feat(Algorithms/Lean/Dijkstra): Dijkstra as a client of the priority-queue spec #2220's
dijkstra_correctthroughRefinement.simulates_client. The cost is feat(Algorithms/Lean/Dijkstra): Dijkstra as a client of the priority-queue spec #2220's operation counts (totalCost_dijkstra_le) at the structures' charges, throughRefinement.Amortized.client.A fix to feat(Algorithms/Lean/Dijkstra): Dijkstra as a client of the priority-queue spec #2220.
Client.lean's fourrunClientevaluations break under feat(DataStructure/StateTransition): refinements by abstraction functions with stacked potentials #2212'sSum.elimproduct answers. simp cannot unify a declared answer type such asFin n × ℕwithSum.elim … (.inr …). The commitfix(Algorithms/Lean/Dijkstra): …adds one definitional equation per kind of call. Whichever of feat(DataStructure/StateTransition): refinements by abstraction functions with stacked potentials #2212 and feat(Algorithms/Lean/Dijkstra): Dijkstra as a client of the priority-queue spec #2220 lands second needs that commit.Existing notions considered.
Dictionary.Memory.decoderestates thedecodeOptionNatencoding ofDictionary/WordRAM/CuckooHashing.lean(0for absent,v + 1). That file imports machine code, so it is not imported.holds_inputGraphusesListEncode'sinit_offset/init_target/init_weightunchanged.costHoare_link_dijkstra(feat(Algorithms/Lean/Dijkstra): Dijkstra as a client of the priority-queue spec #2220) was not used. It charges each graph query one unit, while the adjacency arrays take three.Amortized.clientwithtotalCost_dijkstra_letakes any per-kind charges.dijkstra_eq/loop_eq: the client does not depend on the key and value bounds.runfixes them at0in its types, so it is one program.Comparison with the hand-stepped
Dijkstra/GenericPQ.lean+LogLinear.lean.Invariant.leanandListEncode.leanare shared, and the heap is compared in #2237.run_triple) / 27 (inv_input) / 18Fits/ register mentionsThe hand-stepped side also proves WordRAM instruction bounds. That step is hop 4 (#2213), which is not here.
Validation.
lake build --wfailon the new modules and onComplexityTests/Dijkstra.lean.ComplexityTests/DijkstraMemory.leanruns the three-vertex graph with a parallel edge in the input convention atw = 16: the distances past the input, admissibility, an exact cost of 75 against the proved bound 520, andrun_specapplied to the graph.check_hygiene --check-simppasses, andcheck_changed_filespasses for these files. Full CI is on this PR.🤖 Generated with Claude Code
https://claude.ai/code/session_015DLg8kwPs8yi7ePPdtoNvG