feat(Circuit): prove Lupanov upper bound - #890
Conversation
Add Boolean synthesis with sharing and prove the uniform (1 + ε) 2^n/n upper bound for De Morgan circuits.
| variable {n : ℕ} {ι : Type u} | ||
|
|
||
| /-- Functions available on the input or gate wires of a program. -/ | ||
| def available (p : Σ g, Program signature n g) : Set (BooleanFunction n) := |
There was a problem hiding this comment.
I'm a bit confused by the sum type here, also in Synthesis.
What about the following:
/-- Functions available on the input or gate wires of a program. -/
def available {g : Nat} (p : Program signature n g) : Set (BooleanFunction n) :=
{f | ∃ w, ∀ x, p.trace interpretation x w = f x}
/-- At most `cost` additional gates suffice to compute `targets` from `sources`, while
preserving all functions already available in the starting program. -/
def Synthesis (sources targets : Set (BooleanFunction n)) (cost : ℕ) : Prop :=
∀ g₁ (p₁ : Program _ _ g₁), sources ⊆ available p₁ →
∃ g₂, ∃ (p₂ : Program _ _ g₂), g₂ ≤ g₁ + cost ∧
available p₁ ⊆ available p₂ ∧ targets ⊆ available p₂Maybe Program could also have a function that returns its gate count (even if it is part of the type) - then we would not need g₁ and g₂?
There was a problem hiding this comment.
Adopted your definition. The ∃ g₂ stays since the gate count is a type index, but available now takes a Program directly and is just Set.range (p.wireFunction interpretation).
| def available (p : Σ g, Program signature n g) : Set (BooleanFunction n) := | ||
| {f | ∃ w, ∀ x, p.2.trace interpretation x w = f x} | ||
|
|
||
| /-- At most `cost` additional gates suffice to compute `targets` from `sources`, while |
There was a problem hiding this comment.
This docstring reads super compressed and the definition is rather tricky. Maybe it's better to spell out the exact definition in english terms than trying to simplify it?
There was a problem hiding this comment.
Rewrote the docstring to spell out the quantifier structure and why the starting program is arbitrary. Module doc expanded likewise.
| /-! | ||
| # Lupanov's block construction | ||
|
|
||
| Split the truth table into address rows and data columns, and divide the rows into blocks. |
There was a problem hiding this comment.
Could you also explain what the purpose of this file is and not just what it does?
There was a problem hiding this comment.
Rewrote the module doc to lead with the purpose of the file, then the truth-table picture, then where the gate count comes from. Lupanov.lean got a matching section on the parameter choice.
Address review on leanprover#890: - `available` takes a `Program` directly and is the range of `Program.wireFunction`; `Synthesis` quantifies over the gate count explicitly instead of through a sigma type. - Spell out the `Synthesis` definition in its docstring and expand the module doc. - Add `mem_available` and `inputs_subset_available`, and reuse the latter in `Synthesis.exists_circuit` and the test. - Add `Program.fanInAtMost_two` and `Circuit.fanInAtMost_two`, and state the fan-in bound in the Boolean module doc. - Remove the now-unused sigma-pair remark from the circuit module doc.
Address review on leanprover#890: - Lead the construction module doc with the purpose of the file, the truth-table picture (address rows, data columns, blocks, patterns, and the `left`/`right` split), and where the `2 ^ n / s` leading term comes from; add docstrings and section headers for every declaration. - Explain the parameter choice `k = 3 log n`, `d = n - 3 log n`, `s = n - 5 log n` in the asymptotic module doc and document each lemma's contribution to the argument. - Wrap two over-long declaration headers.
|
|
||
| /-- `left` is true exactly at inputs whose address is a row of the block, at an offset where | ||
| the pattern is `1`. -/ | ||
| private theorem left_eq_true (block : ℕ) (pattern : Assignment s) (x : Assignment (k + d)) : |
There was a problem hiding this comment.
Maybe move these closer to the definition so that the meaning is clear earlier on?
There was a problem hiding this comment.
Moved left_eq_true and right_eq_true directly after their respective definitions.
| open Filter | ||
|
|
||
| /-- Polynomials are eventually dominated by `2 ^ n`. -/ | ||
| private theorem polynomial_le_pow (c r : ℕ) : |
There was a problem hiding this comment.
If mathlib does not have this, this should go into some very fundamental foundations library in cslib and be very public :)
There was a problem hiding this comment.
Added public Nat.eventually_mul_pow_le_pow in Foundations/Data/Nat/Asymptotics.lean, using Mathlib’s existing little-o result and generalizing to natural bases greater than one.
| exact_mod_cast (by simpa using hn : (c : ℝ) * n ^ r ≤ (2 : ℝ) ^ n) | ||
|
|
||
| /-- Any constant multiple of `log₂ n` is eventually at most `n`. -/ | ||
| private theorem log_le (c : ℕ) : ∀ᶠ n : ℕ in atTop, c * Nat.log 2 n ≤ n := by |
There was a problem hiding this comment.
Moved this alongside the polynomial bound as public Nat.eventually_mul_log_le, with a Nat.eventually_mul_log2_le corollary used here.
| minterms, the per-pattern overhead of every block (`left` parts, constants, conjunctions and | ||
| ORs), and the final constant. -/ | ||
| private theorem bound_le (n : ℕ) (hn : 5 * Nat.log 2 n < n) : | ||
| bound (3 * Nat.log 2 n) (n - 3 * Nat.log 2 n) (n - 5 * Nat.log 2 n) ≤ |
There was a problem hiding this comment.
Could use Nat.log2 throughout here, it might make it a bit more readable.
There was a problem hiding this comment.
Switched the asymptotic file to Nat.log2 and its corresponding lemmas.
| let k := 3 * l | ||
| let d := n - 3 * l | ||
| let s := n - 5 * l | ||
| let B := 2 ^ k / s + 1 |
There was a problem hiding this comment.
Should be lowercase, but I assume this is the letter chose in the exposition, right?
There was a problem hiding this comment.
Renamed it to blockCount.
| let d := n - 3 * l | ||
| let s := n - 5 * l | ||
| let B := 2 ^ k / s + 1 | ||
| have hn0 : 0 < n := by omega |
There was a problem hiding this comment.
I wonder if some of these could be removed and replaced by grind at the place where they are used.
There was a problem hiding this comment.
Removed the five routine opening facts and used grind where needed, keeping the main estimates named for readability.
crei
left a comment
There was a problem hiding this comment.
Great contribution, I would only request some minor changes.
Add Boolean synthesis with sharing and prove the uniform (1 + ε) 2^n/n upper bound for De Morgan circuits.
Assisted by Codex, adapted from https://github.com/samuelSchlesinger/algebraic-circuits.