Documentation

Complexitylib.Algebraic.LowerBound.KarchmerWigderson.Sharing

Khrapchenko's bound for circuits with few shared gates #

A SharedProgram n k is a sequence of k + 1 De Morgan formulas on n inputs in which each formula also reads the values of the earlier ones: share G P computes the formula G, appends its value to the inputs as a new last variable, and continues with P, and output F returns the value of the formula F. A shared value is read through literals of either sign, any number of times. Unfolded, this is a circuit of fan-in-two AND and OR gates with negations free on wires in which only the k shared gates can have fan-out at least two. Conversely, cutting a circuit at its gates of fan-out at least two gives a program with the same AND and OR gates; KarchmerWigderson.Sharing.Circuit proves this for the library's De Morgan circuits (exists_sharedProgram_of_circuit) and transfers the bounds below to them. SharedProgram.gates counts the AND and OR gates and SharedProgram.inputLeaves the literal leaves that read an input rather than a shared value.

Theorem. If a program with k shared gates is 1 on A and 0 on B, and X is its number of input leaves, then |edges A B|² ≤ (k + 1) · X · |A| · |B| (SharedProgram.sq_card_edges_le). For k = 0 this is Khrapchenko's theorem.

The proof extends the inductive proof of Khrapchenko's theorem. Call an edge of A × B uncut when its endpoints agree on every shared value computed so far. For a single formula, |uncut edges|² ≤ X · |A| · |B|, where X counts input literals only: a literal on a shared variable separates only pairs that the shared value cuts, so it contributes no uncut edge (Formula.sq_card_uncutEdges_le). For share G P, an uncut edge on which G is constant stays uncut for P, and the others are separated by G or by its De Morgan dual on the rectangles {G = 1} × {G = 0} and {G = 0} × {G = 1}, which together contain at most √(X_G · |A| · |B|) of them by the Cauchy–Schwarz inequality. Summing over the k + 1 formulas, Cauchy–Schwarz gives the factor k + 1 (SharedProgram.sq_card_uncutEdges_le).

Through KhrapchenkoBound the theorem inherits Khrapchenko's corollaries. For all n ≥ 1 and k, every program with k shared gates computing the parity of n bits satisfies n² ≤ (k + 1) · (gates + k + 1), so it has at least n² / (k + 1) - (k + 1) gates (SharedProgram.parity_sq_le_gates). If (k + 1) · (C + 1) ≤ n it has at least C · n gates (SharedProgram.mul_le_gates_of_parity), so parity needs superlinear size whenever k = o(n) (SharedProgram.isLittleO_gates_of_parity). The threshold and majority bounds transfer the same way (SharedProgram.threshold_mul_le_gates, SharedProgram.majority_mul_le_gates).

Counting gates and input leaves of a formula #

The number of literal leaves on the variables 0, …, m - 1. Constants and literals on later variables are not counted.

Equations
Instances For

    The number of binary AND and OR gates.

    Equations
    Instances For
      @[simp]
      @[simp]
      theorem Algebraic.KW.Formula.gates_mapIndex {N M : ℕ} (φ : Fin N → Fin M) (F : Formula N) :

      Programs with shared gates #

      A De Morgan program on n inputs with k shared gates: k + 1 De Morgan formulas, where each formula reads the inputs and the values of the earlier ones. output F returns the formula F. share G P computes the formula G, appends its value to the inputs as the new last variable n, and runs P on the n + 1 resulting variables. Unfolded, this is a circuit in which only the roots of the k shared formulas can have fan-out at least two: inputs and shared values are read through literals of either sign, and every other gate lies inside one formula.

      Instances For

        Evaluate a program.

        Equations
        Instances For
          @[simp]
          theorem Algebraic.KW.SharedProgram.eval_output {n : ℕ} (F : Formula n) (x : Fin n → Bool) :
          (output F).eval x = F.eval x
          @[simp]
          theorem Algebraic.KW.SharedProgram.eval_share {n k : ℕ} (G : Formula n) (P : SharedProgram (n + 1) k) (x : Fin n → Bool) :
          (share G P).eval x = P.eval (Fin.snoc x (G.eval x))

          The number of binary AND and OR gates, summed over the formulas.

          Equations
          Instances For

            The number of literal leaves on the variables 0, …, m - 1, summed over the formulas. For a program on n inputs, inputLeaves n counts the leaves reading an input rather than a shared value.

            Equations
            Instances For

              A program computes f when it agrees with f everywhere.

              Equations
              Instances For

                A program separates A from B when it is 1 on A and 0 on B.

                Equations
                Instances For

                  The input leaves number at most the gates plus one leaf per formula.

                  Uncut edges #

                  noncomputable def Algebraic.KW.uncutEdges {n N : ℕ} (val : (Fin n → Bool) → Fin N → Bool) (A B : Finset (Fin n → Bool)) :
                  Finset ((Fin n → Bool) × (Fin n → Bool))

                  The edges of A × B whose endpoints agree, under val, on every variable from n on. When val appends shared values to the inputs, these are the edges no shared value cuts.

                  Equations
                  Instances For
                    theorem Algebraic.KW.mem_uncutEdges {n N : ℕ} {val : (Fin n → Bool) → Fin N → Bool} {A B : Finset (Fin n → Bool)} {p : (Fin n → Bool) × (Fin n → Bool)} :
                    p ∈ uncutEdges val A B ↔ (p.1 ∈ A ∧ p.2 ∈ B) ∧ (diff p.1 p.2).card = 1 ∧ ∀ (i : Fin N), n ≤ ↑i → val p.1 i = val p.2 i
                    theorem Algebraic.KW.card_uncutEdges_split_right {n N : ℕ} (val : (Fin n → Bool) → Fin N → Bool) (A B : Finset (Fin n → Bool)) (p : (Fin n → Bool) → Prop) [DecidablePred p] :
                    (uncutEdges val A B).card = (uncutEdges val A (Finset.filter p B)).card + (uncutEdges val A ({y ∈ B | ¬p y})).card

                    Splitting the zero side of a rectangle splits its uncut edges.

                    theorem Algebraic.KW.card_uncutEdges_split_left {n N : ℕ} (val : (Fin n → Bool) → Fin N → Bool) (A B : Finset (Fin n → Bool)) (p : (Fin n → Bool) → Prop) [DecidablePred p] :
                    (uncutEdges val A B).card = (uncutEdges val (Finset.filter p A) B).card + (uncutEdges val ({x ∈ A | ¬p x}) B).card

                    Splitting the one side of a rectangle splits its uncut edges.

                    theorem Algebraic.KW.sq_add_le_add_mul_add {x y p q r s : ℕ} (h₁ : x ^ 2 ≤ p * q) (h₂ : y ^ 2 ≤ r * s) :
                    (x + y) ^ 2 ≤ (p + r) * (q + s)

                    The Cauchy–Schwarz inequality for two terms, without square roots: if x² ≤ p · q and y² ≤ r · s then (x + y)² ≤ (p + r) · (q + s).

                    theorem Algebraic.KW.Formula.sq_card_uncutEdges_le {n N : ℕ} (val : (Fin n → Bool) → Fin N → Bool) (hval : ∀ (x : Fin n → Bool) (i : Fin N) (hi : ↑i < n), val x i = x ⟨↑i, hi⟩) (F : Formula N) (A B : Finset (Fin n → Bool)) :
                    (∀ x ∈ A, F.eval (val x) = true) → (∀ y ∈ B, F.eval (val y) = false) → (uncutEdges val A B).card ^ 2 ≤ F.inputLeaves n * A.card * B.card

                    Khrapchenko's theorem with shared variables. Let val extend each input by further variables, keeping the first n variables equal to the input. If a formula F over the extended variables is 1 on val '' A and 0 on val '' B, the edges of A × B that agree on the extra variables satisfy |uncut edges|² ≤ X · |A| · |B|, where X counts only the literal leaves on the first n variables.

                    theorem Algebraic.KW.isLittleO_of_forall_mul_le {k s : ℕ → ℕ} (hk : (fun (n : ℕ) => ↑(k n)) =o[Filter.atTop] fun (n : ℕ) => ↑n) (h : ∀ (n C : ℕ), (k n + 1) * (C + 1) ≤ n → C * n ≤ s n) :
                    (fun (n : ℕ) => ↑n) =o[Filter.atTop] fun (n : ℕ) => ↑(s n)

                    Superlinearity from a quantitative bound. If k n = o(n) and C · n ≤ s n whenever (k n + 1) · (C + 1) ≤ n, then n = o(s n).

                    theorem Algebraic.KW.SharedProgram.sq_card_uncutEdges_le {n N k : ℕ} (P : SharedProgram N k) (val : (Fin n → Bool) → Fin N → Bool) :
                    n ≤ N → (∀ (x : Fin n → Bool) (i : Fin N) (hi : ↑i < n), val x i = x ⟨↑i, hi⟩) → ∀ (A B : Finset (Fin n → Bool)), (∀ x ∈ A, P.eval (val x) = true) → (∀ y ∈ B, P.eval (val y) = false) → (uncutEdges val A B).card ^ 2 ≤ (k + 1) * P.inputLeaves n * A.card * B.card

                    Khrapchenko's theorem for programs, with shared variables. Let val extend each input by further variables, keeping the first n variables equal to the input. If a program P with k shared gates over the extended variables is 1 on val '' A and 0 on val '' B, the edges of A × B that agree on the extra variables satisfy |uncut edges|² ≤ (k + 1) · X · |A| · |B|, where X counts the literal leaves on the first n variables.

                    theorem Algebraic.KW.SharedProgram.sq_card_edges_le {n k : ℕ} (P : SharedProgram n k) (A B : Finset (Fin n → Bool)) (h : P.Separates A B) :
                    (edges A B).card ^ 2 ≤ (k + 1) * P.inputLeaves n * A.card * B.card

                    Khrapchenko's theorem for circuits with k shared gates. If a program with k shared gates is 1 on A and 0 on B, then |edges A B|² ≤ (k + 1) · X · |A| · |B|, where X is the number of literal leaves reading an input.

                    A program with k shared gates computing f bounds the Khrapchenko measure of f by (k + 1) · X, where X is its number of input leaves.

                    Parity, threshold functions, and majority #

                    Parity with k shared gates, input leaves. Every program with k shared gates computing the parity of n ≥ 1 bits has at least n² / (k + 1) literal leaves reading an input.

                    Parity with k shared gates. Every De Morgan program with k shared gates computing the parity of n ≥ 1 bits has at least n² / (k + 1) - (k + 1) binary gates: n² ≤ (k + 1) · (gates + k + 1).

                    theorem Algebraic.KW.SharedProgram.mul_le_gates_of_parity {n k C : ℕ} (hkn : (k + 1) * (C + 1) ≤ n) {P : SharedProgram n k} (hP : P.Computes GateElimination.Xor.parity) :
                    C * n ≤ P.gates

                    Superlinear size for parity with few shared gates. If (k + 1) · (C + 1) ≤ n, every program with k shared gates computing the parity of n bits has at least C · n gates.

                    theorem Algebraic.KW.SharedProgram.threshold_mul_le_gates {n k t : ℕ} (ht : 1 ≤ t) (htn : t ≤ n) {P : SharedProgram n k} (hP : P.Computes (threshold t)) :
                    (n + 1 - t) * t ≤ (k + 1) * (P.gates + k + 1)

                    Threshold functions with k shared gates. For 1 ≤ t ≤ n, every program with k shared gates computing "at least t of n inputs are one" satisfies t · (n + 1 - t) ≤ (k + 1) · (gates + k + 1).

                    theorem Algebraic.KW.SharedProgram.majority_mul_le_gates {n k : ℕ} (hn : 1 ≤ n) {P : SharedProgram n k} (hP : P.Computes majority) :
                    (n - n / 2) * (n / 2 + 1) ≤ (k + 1) * (P.gates + k + 1)

                    Majority with k shared gates. Every program with k shared gates computing strict majority of n ≥ 1 inputs satisfies (n - ⌊n/2⌋) · (⌊n/2⌋ + 1) ≤ (k + 1) · (gates + k + 1).

                    theorem Algebraic.KW.SharedProgram.isLittleO_gates_of_parity {k : ℕ → ℕ} (hk : (fun (n : ℕ) => ↑(k n)) =o[Filter.atTop] fun (n : ℕ) => ↑n) (P : (n : ℕ) → SharedProgram n (k n)) (hP : ∀ (n : ℕ), (P n).Computes GateElimination.Xor.parity) :
                    (fun (n : ℕ) => ↑n) =o[Filter.atTop] fun (n : ℕ) => ↑(P n).gates

                    Parity needs superlinear size when k = o(n). If k n = o(n) and, for every n, P n is a program with k n shared gates computing the parity of n bits, then the number of gates of P n grows faster than n.