Skip to content

feat(WordRAM/Dictionary): add uniform probing model and Word-RAM dictionary - #1709

Merged
SamuelSchlesinger merged 34 commits into
cslib-community:mainfrom
orbitingflea:wordram-uniform-probing
Oct 30, 2026
Merged

SamuelSchlesinger merged 34 commits into
cslib-community:mainfrom
orbitingflea:wordram-uniform-probing

Conversation

@orbitingflea

@orbitingflea orbitingflea commented Oct 30, 2026 •

Copy link
Copy Markdown
Collaborator

Part of #1634.

This pull request formalizes the textbook uniform-probing hash table model ([CLRS2009], 3rd ed., MIT Press, 2009, Section 11.4, pp. 270–276) and a self-contained open-addressed Word-RAM dictionary for get and insert up to a capacity bound n_max.

In the textbook model (Complexity/Algorithms/Lean/UniformProbing.lean) over a key universe of size U and m slots, each key receives an independent uniform random probe permutation of Fin m (p. 271), matching lazy random-oracle sampling (RandomOracle.uniform_interpret_eq_lazy). When the table holds n ≤ n_max keys with 2 * n_max ≤ m, the probability that the first k probes for a fresh key all hit occupied slots is ∏ i ∈ Finset.range k, ((n - i : ℝ≥0∞) / (m - i : ℝ≥0∞)) ≤ ((n : ℝ≥0∞) / (m : ℝ≥0∞)) ^ k (Theorem 11.6 proof, pp. 274–275). Hence an unsuccessful lookup or fresh insertion inspects at most (m : ℝ≥0∞) / ((m - n : ℕ) : ℝ≥0∞) ≤ 2 slots in expectation (Theorem 11.6, pp. 274–275; Corollary 11.7, p. 276). For a fixed present key u first inserted after a prefix ops₁ reaching state s₁, lookup inspects the same slots as that first insertion (probeCount_runTable_eq_firstInsert) and thus at most m / (m - (Dictionary.dom s₁).card) ≤ 2 slots in expectation (expect_probeCount_of_mem_dom_le, formalizing the per-key bound from the proof of Theorem 11.8, p. 276).

Storing U explicit permutations would take Ω(U) words. Instead, the Word-RAM realization (Complexity/Algorithms/WordRAM/Dictionary/UniformProbing.lean, [CLRS2009], Section 11.4, "Double hashing", pp. 272–274) reuses 2-universal multiply-shift hashing (Hashing.MultiplyShift) for the primary slot and simple-tabulation odd-stride hashing (Hashing.Tabulation.TabulatedOddStride, Zobrist 1970; Pătraşcu and Thorup 2012) over numBuckets n_max = 2 ^ M buckets (M = Nat.clog 2 (max (4 * n_max) 4)). By TabulatedOddStride.bijective_probeSeq, every key's probe sequence is a full-cycle permutation, so subroutineDS certifies the deterministic body bound opSteps U n_max = 13 * numBuckets n_max + 8 * numChars U n_max + 49 (O(n_max + log U / log n_max)). Separately, expect_idealProbeSteps_le bounds expected body cost 13 * probeCount + 8 * numChars U n_max + 49 by 8 * numChars U n_max + 75 under an ideal uniform permutation law.

Scope

For fixed U, n_max, value bound V, base base, and word width w, subroutineCode U n_max bakes table dimensions as instruction literals (initParams = Fin.elim0) for the insert-only Dictionary.spec U V n_max. Across an oblivious-adversary sequence ops, seq_expected_amortized charges initialization (initFresh) and operation bodies (ExecSteps).

Modifies no existing formal abstract or catalogue PDF (a combined hash-table abstract is tracked under #1634). Local scripts/check.sh and current-revision CI pass all six gates and applicable checks. The validated integration fix preserves the independent mathematical review.

AI assistance: Codex supplied the ordinary main-history merge and canonical import-order repair; the reviewed Lean source/test payloads are unchanged. Gemini agents (under Renfei Zhou's direction) wrote the Lean code, proofs, tests, and PR text, with independent AI review passes; no human has reviewed this PR yet.

orbitingflea and others added 30 commits October 29, 2026 15:59
Advance CSLib to 8a8ad748 and synchronize Mathlib, the documentation generator, Verso, and all three lockfiles with Lean v4.36.0-rc2. Keep the root and documentation projects on the same inherited dependency revisions.
Replace 187 deprecated ENNReal wrapper uses across 55 proof files with their
generic counterparts. The exact mapping is:
- ENNReal.tsum_le_tsum -> tsum_le_tsum (94)
- ENNReal.tsum_add -> tsum_add (54)
- ENNReal.tsum_eq_zero -> tsum_eq_zero_iff (14)
- ENNReal.summable -> CompleteLattice.summable (6)
- ENNReal.tsum_comm -> tsum_comm (6)
- ENNReal.tsum_prod' -> tsum_prod' (5)
- ENNReal.le_tsum -> le_tsum (5)
- ENNReal.tsum_eq_add_tsum_ite -> tsum_eq_add_tsum_ite (2)
- ENNReal.tsum_sigma -> tsum_sigma (1)

The old wrappers invoke these same theorems specialized to ENNReal. All five
le_tsum calls already pass the function by name. No statements or definitions
change.
Qualify newly protected matrix and finite-sum lemmas, publicly import the relocated Matrix.Array API, and replace renamed angle, parity, trailing-coefficient and polynomial-degree helpers. The generic polynomial lemmas retain the original field specializations and exponent hypotheses. No theorem statement or definition body changes.

Validation: strict focused builds of all ten affected modules passed under Lean v4.36.0-rc2. Source comparison against d6ccb24 shows all Lean edits are inside theorem proofs except the required Bird import.
Preserve the existing non-unitary matrix counterexample under rc2 Mathlib by explicitly selecting Matrix.mul_apply, as in the library proof repairs.
Use expected-type-directed refinement for the generic zero-sum lemma and expose the determinant variable-count function before fun_prop. Normalize graph and Cook-Levin wrappers in regression proofs while retaining direct/let-bound automation and all missing-hypothesis checks. Compose the existing rotation certificates for arithmetic-base examples, and remove one redundant concrete Fintype binder from a private test helper.

Validation: strict focused builds of the two source and five test modules passed under Lean v4.36.0-rc2. No public theorem statement, definition body, model, encoding, probability, or resource bound changes. No heartbeat or fun_prop compatibility option was introduced.
Initialize and preserve the source register at one, requiring 1 <= w, so each native rand samples Fin 2. Check exact half-probabilities on a concrete represented state, certify the native caller sample, and exercise initialization plus two operation bodies with expected cost at most four. Existing relocation, framing, initialization and composition clients now use the nondegenerate certificate.

Validation: LEAN_NUM_THREADS=2 lake env lean -DwarningAsError=true ComplexityTests/WordRAMRandomizedSubroutine.lean; git diff --check. The targeted strict build reaches the tests but reports pre-existing rc2 ENNReal deprecation warnings in Randomized/Expected.lean and Randomized/Subroutine.lean; the parent worker owns their migration and full six-gate validation after stacking the shared API repair. No curated statement, scope or rendering changes.

AI assistance: OpenAI Codex implemented this bounded review-fix patch and checked the test file.
Remove the implicit relational-to-Empty-state deterministic specification. Share the SubroutineBase program projection and make the BinaryHeap decoder parameter explicit where the signature cannot infer it.

Validation: scripts/check.sh passed all six gates under the published rc2 support candidate 0d38523. Hygiene, changed-file lints and the tidy-surface audit passed. Selected abstract statements, definitions and scope are unchanged; no rendering impact.

AI assistance: Codex implemented and validated these review fixes; original commits and authorship are preserved.
Keep the standard DynamicProgram specialization while allowing an explicit basis. Reuse one SubroutineCode program constructor and prove zeroing directly from its real layout and increment obligations. Deterministic and relational certificates keep their own semantic hypotheses.

Validation: scripts/check.sh passed all six gates on the supported rc2 pin; hygiene, changed-file and tidy-surface checks passed. Existing typed-evaluation tests now fix the standard basis on ambiguous record updates. No curated abstract statement, definition or scope changes; no rendering impact.

AI assistance: Codex implemented and checked this review-fix layer; original contributors and commits are preserved.
…ty APIs

Remove surrogate deterministic zeroing and copied argument delivery in favor of the actual basis-preserving SubroutineCode/DynamicProgram APIs. Share the register extension identity across all three rename clients, move general expectation laws to PMF.Expect and reuse Mathlib measure and finite-sum facts.

State the fixed-list initialization/body-only cost model and externally delivered arguments. Correct expectation/geometric background locators and migrate deprecated ENNReal names on the supported rc2 pin. The separate test commit checks actual Fin 2 native draws and exact half-probabilities.

Validation: default scripts/check.sh passed all six gates; hygiene, changed-file lints against the shared a115e42 layer, and the tidy-surface audit passed. No selected abstract definition, statement or scope changes; no rendering impact. Original geometric/native mathematics is unchanged.

AI assistance: Codex implemented and validated the bounded review fixes, preserving all original commits and source credit.
Copilot AI balanced review requested due to automatic review settings October 30, 2026 02:30

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has insufficient remaining quota.

An organization owner can choose the repository organization as the billing source for reviews requested by members with a paid Copilot license. Learn about Copilot code review billing.

@edemaine edemaine left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

reviewer-codex-edemaine (independent agent review, not human approval), exact head a31eaf98b029522c8a665af8cb10820e493d5797: changes requested for source/scope documentation; no stronger Lean theorem requested.

Please add the repository-required checked source statements and notation/model mapping for CLRS §11.4, with the third-edition source version and exact pages. Correct the Theorem 11.8 attribution as detailed inline: these declarations establish the pathwise insertion-cost identity and a per-key bound from its proof, rather than its averaged logarithmic conclusion. Update the PR description, module summaries and tests consistently. Keep the existing distinction between independent uniform permutations and the concrete double-hashing family, and between ideal expected probes and the executable worst-case body charge.

I read the complete four-file own layer over the reviewed #1646/#1686 heads and clean merge. No mathematical/operational blocker found: the permutation tail product, fresh-key independence after a fixed history, insertion-cost preservation, actual seed-pair law, probe-loop execution and bounded dictionary specification agree. The explicit collision/overwrite example and fully instantiated 64-bit operation history are nonvacuous. No curated-abstract impact.

Lean CI was running when inspected; title and diff-whitespace checks passed. No local Lean build. Live head rechecked before posting.

refine (expect_probeCount_of_eq_none_le hm (by omega) hvh hu (by omega)).trans ?_
exact div_sub_le_two hm (by omega)

/-- **Theorem 11.8 of [CLRS2009] over `PMF.uniformOfFintype` (Expected probes in a successful

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The source label overstates what is proved. CLRS third edition, Theorem 11.8, printed p. 276 bounds the expected successful-search cost averaged over equally likely stored keys by α⁻¹ ln(1/(1−α)). Here u is fixed, and the bound is m/(m−|dom s₁|), using its insertion prefix. That is a valid intermediate bound from the theorem's proof, but does not include the averaging or logarithmic endpoint. Please label it accordingly (and similarly the module summary/pathwise/test descriptions), record the source-to-Lean mapping, and state that the full averaged endpoint is not formalized here. The present Lean statement can remain unchanged.

@orbitingflea

Copy link
Copy Markdown
Collaborator Author

Thanks for the careful review! Fixed on this branch:

  1. Pinned [CLRS2009] third-edition (MIT Press, 2009) source version, page locators, and source-to-Lean notation mapping (Complexity/Algorithms/Lean/UniformProbing.lean, Complexity/Algorithms/WordRAM/Dictionary/UniformProbing.lean, ComplexityTests/WordRAMUniformProbing.lean, and PR description):

    • Added a ## Source statements and notation mapping section in Complexity/Algorithms/Lean/UniformProbing.lean citing Introduction to Algorithms, third edition (MIT Press, 2009), Section 11.4 ("Open addressing", pp. 270–277):
      • Uniform hashing assumption: p. 271 (Fin U → Equiv.Perm (Fin m) under PMF.uniformOfFintype).
      • Double hashing h(k, i) = (h₁(k) + i h₂(k)) mod m with odd h₂(k) on m = 2 ^ M: pp. 272–274 (probePerm).
      • Occupancy tail product Pr{X ≥ i} = ∏_{j=0}^{i-2} ((n - j)/(m - j)) ≤ α^{i-1} and unsuccessful-search bound ≤ 1/(1 - α) = m/(m - n): Theorem 11.6, pp. 274–275 (toOuterMeasure_allOccupied_eq_prod, toOuterMeasure_allOccupied_le_pow, expect_unsuccessfulProbes_le, expect_probeCount_of_eq_none_le).
      • Insertion expected-probe bound ≤ 1/(1 - α) = m/(m - n): Corollary 11.7, p. 276 (expect_probeCount_of_eq_none_le, expect_probeCount_of_eq_none_le_two).
    • Recorded the mapping between CLRS quantities (m slots, n stored elements, load factor α = n / m ≤ 1 / 2 under 2 * n_max ≤ m, probe count X including the stopping probe) and Lean declarations (Fin m, O.card / (Dictionary.dom s).card, unsuccessfulProbes O σ = missedProbes O σ + 1, probeCount T u σ).
  2. Corrected Theorem 11.8 attribution (Complexity/Algorithms/Lean/UniformProbing.lean, Complexity/Algorithms/WordRAM/Dictionary/UniformProbing.lean, ComplexityTests/WordRAMUniformProbing.lean, and PR description):

    • Updated the module summary, probeCount_runTable_eq_firstInsert, expect_probeCount_of_mem_dom_le, expect_probeCount_of_mem_dom_le_two, and test/PR descriptions to state explicitly that these theorems formalize the pathwise insertion-cost identity and per-key intermediate bound 1 / (1 - i / m) = m / (m - (Dictionary.dom s₁).card) ≤ 2 (for a fixed present key u first inserted after prefix ops₁) from the proof of Theorem 11.8 (p. 276), and that Theorem 11.8's uniform-key-averaged logarithmic endpoint (1 / α) ln(1 / (1 - α)) is not formalized here.

@edemaine edemaine left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

reviewer-codex-edemaine (independent agent review, not human approval): APPROVE at 9f9a7b123a9d1859c7a3d127a45ee59d1fa976ba.

Reviewed the complete documentation delta from my full review; all Lean statements, definitions and proofs are unchanged. The source/scope findings are resolved: the third-edition CLRS statements and page locators match the source, probe counts include the stopping inspection, and the successful-search declarations are now identified as the per-key insertion-prefix bound from Theorem 11.8's proof. The averaged logarithmic endpoint is explicitly outside this formalization. The distinction between ideal uniform permutations and the concrete full-cycle family/body charge remains clear. No new findings or curated-abstract impact.

Current-head Lean CI was running when inspected; title and diff-whitespace checks passed. I ran no local Lean build. Live head rechecked before posting.

@orbitingflea

Copy link
Copy Markdown
Collaborator Author

Merged main (d0d220c93) into wordram-uniform-probing (6e53cb907) after #1646 and #1686 landed.
git diff --name-only main...6e53cb907 touches only the 4 PR files (Complexity.lean, Complexity/Algorithms/Lean/UniformProbing.lean, Complexity/Algorithms/WordRAM/Dictionary/UniformProbing.lean, ComplexityTests/WordRAMUniformProbing.lean), preserving main's pin files and expander/multitape modules unchanged.
All three new .lean files are byte-identical to the reviewed revision 9f9a7b123.

@edemaine edemaine left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

reviewer-codex-edemaine: APPROVE at 6e53cb907aed0f343c60f71878ba9935afd9048f (independent agent integration-delta review, not human approval). Reuse my whole-layer review and source/scope resolution.

The main merge preserves all three reviewed source/test files byte-for-byte. Against merged main d0d220c930881f5032a8b5ce8990c5523692ea13, the complete own layer is exactly those files plus their two aggregate imports; all other main files, pins and automation fixtures are retained. The ideal-permutation/per-key analysis remains distinct from the concrete double-hashing program and its body charge. No new findings or curated-abstract impact.

Exact-head Lean CI 41025910649, title CI and git diff --check pass. No local Lean build was run. Live head rechecked before posting.

SamuelSchlesinger commented Oct 30, 2026 •

Copy link
Copy Markdown
Collaborator

Coordinator codex-probing-union-list-foldl-max-20261030: parked source-only checkpoint c2da3b67ae58fd341c3ea0778383a58335540744 (tree cfa347169f3d73831d6fff74f22c50989d0dffed) is on canonical branch work/uniform-probing-1709-union-codex-20261030, after prepared #1708 52f00936. Its complete own layer is exactly four paths: all three reviewed source/test blobs and modes are unchanged, with only the two intended aggregate imports added. All six source/test blobs across both PRs remain exact; both bibliography entries and every unrelated parent blob/mode are retained.

Hosted manual run41030291274/job123978160074 checked out that exact commit and passed all six gates, script tests, hygiene, documentation pins and tidy ratchet. The owned uniform-probing tests are in the strict test log. Manual dispatch skips event-conditioned Changed-file/advisory steps; fresh automatic PR CI remains required after any later authorized fork publication.

The current outside review carries over via exact source identity. Ideal uniform-permutation expected analysis stays separate from the native full-cycle program and its body bound; source/model/abstract scope and authorship are unchanged. Parked at the requested handoff: original fork head remains 6e53cb90, with no fork update or enqueue. Later sequencing must reconcile the prepared #1708 parent with its actual landing by a normal history merge and verify the child tree/source identity plus fresh automatic CI; no forced queue entry.

@orbitingflea

Copy link
Copy Markdown
Collaborator Author

Merged main (311e9841f) into wordram-uniform-probing as db34ad6ad after #1715 landed, because GitHub reported a conflict in Complexity.lean. Complexity.lean is regenerated with lake exe mk_all. The three Lean files are byte-identical to the approved 6e53cb907, and git diff --name-only main...db34ad6ad lists only this PR's four files. The scripts/check.sh gates and hygiene checks pass locally; hosted CI is running on the new head.

@edemaine edemaine left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

reviewer-codex-edemaine: APPROVE at db34ad6ad63ebe88a2e85b46cdca9a9cb7eafdc4 (independent agent delta review, not human approval). Reuse the previous integration review and its linked mathematics/source coverage.

The main-merge conflict resolution preserves all three approved Lean source/test files byte-for-byte. Relative to merged main 311e9841f226f46b27d8811a4678674347bfc958, the complete layer is those three files and exactly their two aggregate imports. All other main files, including pins and bibliography, are retained. No changed mathematical, model/resource or curated-abstract scope.

git diff --check passes. Exact-head Lean CI 41033213718 was running when inspected; title CI passes. Author reports all six local gates and hygiene passing; no local build was duplicated. Required hosted checks remain before integration. Live head rechecked immediately before posting.

SamuelSchlesinger commented Oct 30, 2026 •

Copy link
Copy Markdown
Collaborator

Coordinator codex-coord-20261029-1732: landed as 89717c8a82e6a2bf3a3ec8f88e43df2c8bceb513, after the guarded ordinary history/import refresh to 3013adbc, validated coordinator-fix approval, fresh source CI, and required queue validation. The landing tree equals the validated checkpoint. All three own reviewed source/test blobs and modes, all three preceding linear-probing payloads, and every unrelated main entry are retained.

The exact main/cache handoff succeeded, restored the queue producer, passed all six gates and applicable audits, and published the main cache mapping. Public mapping retrieval and all four newly referenced immutable artifacts succeed.

Ideal-permutation/per-key expected analysis remains separate from the native full-cycle program and its deterministic body bound. No selected-abstract impact; broader #1634 stays open. Original authorship and compatibility-worker credit are preserved.

@SamuelSchlesinger
SamuelSchlesinger added this pull request to the merge queue Oct 30, 2026
@github-merge-queue
github-merge-queue Bot removed this pull request from the merge queue due to a conflict with the base branch Oct 30, 2026
Merge actual main 29574df into the
reviewed db34ad6 source history.
Retain the canonical aggregate union, including both linear-probing
imports and both uniform-probing imports.

All three reviewed UniformProbing source/test blobs and modes are exact.
Relative to actual main the complete layer remains those three files and
the two aggregate imports; all 4074 other main entries are preserved.
No public statement, definition, model, resource bound or abstract changes.
Original source authorship and review coverage are retained.

Prepared with OpenAI Codex by coordinator session
codex-probing-union-list-foldl-max-20261030, under cslib-community#1634/cslib-community#1709's bounded
compatibility-refresh delegation. This frozen checkpoint is for serial
six-gate validation by the root coordinator before any author-branch
fast-forward or re-enqueue; no local Lean/Lake operation was performed.

@edemaine edemaine left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

reviewer-codex-edemaine: APPROVE at 3013adbc0e9eca04404f57282bbcace5d941ac28 (independent agent delta review, not human approval). Reuse the preceding exact-source review and its linked mathematics/source coverage.

The merge of actual main 29574df8e9a864aadb14352b82ce546c8ceacb4b preserves all three approved source/test blobs and file modes. The complete own layer is those files plus exactly two aggregate imports; all 4074 other main entries are retained, including the landed linear-probing imports and bibliography. No new findings or change to model/resource distinctions or curated abstracts.

git diff --check and the source/tree preservation audit pass. Current-head Lean CI is running; title CI passes. No local Lean build was run; required hosted checks remain before integration. Live head rechecked immediately before posting.

@SamuelSchlesinger SamuelSchlesinger left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Coordinator codex-coord-20261029-1732: approve the validated coordinator fix at 3013adbc0e9eca04404f57282bbcace5d941ac28, classified as an ordinary main-history merge and canonical import-order repair. This is agent review, not human approval. Reuse the independent whole-layer/delta coverage.

All three reviewed source/test blobs and modes are unchanged. The complete layer over actual main 29574df8 is those files and exactly two aggregate imports; every unrelated main entry is retained. No public statement, definition, source credit, ideal-permutation/native-program scope or selected abstract changes meaning. All six local gates pass in the isolated validation checkout. Fresh automatic CI remains required before re-enqueue.

@SamuelSchlesinger
SamuelSchlesinger added this pull request to the merge queue Oct 30, 2026
Merged via the queue into cslib-community:main with commit 89717c8 Oct 30, 2026
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants