Documentation

Complexitylib.Circuits.Internal.ShannonUpper

Internal: Shannon Upper Bound Construction #

The Shannon (1949) upper bound: every Boolean function on N variables can be computed by a fan-in-2 AND/OR circuit of size at most C * 2^N / N, for a fixed constant C and all sufficiently large N.

This is the full-column-library variant (C = 18). The tighter (1 + o(1)) · 2^N / N bound due to Lupanov (1958) uses column grouping and is not yet formalized.

Construction #

Split N inputs into k = ⌊log₂ N⌋ - 1 address variables and q = N - k data variables. Decompose any f : {0,1}^N → {0,1} as f(a,y) = ⋁ᵧ [mintermᵧ(data) ∧ colᵧ(addr)] where colᵧ(a) = f(a,y).

Build shared minterm trees for both variable groups, a pattern library for column functions, AND/OR combining layers. Total ≤ 18 · 2^N / N gates for N ≥ 16.

Parameters #

Number of address variables: ⌊log₂ N⌋ - 1.

Equations
Instances For

    Gate Construction Helpers #

    Binary Circuit Composition #

    def Complexity.ShannonUpper.binopCircuit (op : AndOrOp) {N G₁ G₂ : } [NeZero N] (c₁ : Circuit Basis.andOr2 N 1 G₁) (c₂ : Circuit Basis.andOr2 N 1 G₂) :
    Circuit Basis.andOr2 N 1 (G₁ + G₂ + 2)

    Compose two circuits with a binary AND/OR.

    Equations
    • One or more equations did not get rendered due to their size.
    Instances For
      theorem Complexity.ShannonUpper.binopCircuit_or_correct {N G₁ G₂ : } [NeZero N] (c₁ : Circuit Basis.andOr2 N 1 G₁) (c₂ : Circuit Basis.andOr2 N 1 G₂) (f₁ f₂ : BitString NBool) (hf₁ : (fun (x : BitString N) => c₁.eval x 0) = f₁) (hf₂ : (fun (x : BitString N) => c₂.eval x 0) = f₂) :
      (fun (x : BitString N) => (binopCircuit AndOrOp.or c₁ c₂).eval x 0) = fun (x : BitString N) => f₁ x || f₂ x

      binopCircuit correctly computes the OR of two circuits' outputs.

      The output gate of binopCircuit applies OR to wires N + G₁ and N + G₁ + G₂ + 1, which replicate the output gates of c₁ and c₂. The proof shows that wire values in the combined circuit agree with wire values in the original circuits (via binop_wireValue_c₁ and binop_wireValue_c₂), then combines.

      Arithmetic #

      Nat.log helpers #

      For N ≥ 16 there are at least three address variables.

      theorem Complexity.ShannonUpper.dataBits_pos (N : ) (hN : 16 N) :

      For N ≥ 16 there is at least one data variable.

      For N ≥ 16 there are at least two data variables.

      Key identities #

      N² ≤ 2^N for N ≥ 16 #

      Term-by-term bounds #

      theorem Complexity.ShannonUpper.shannon_arithmetic (N : ) (hN : 16 N) :
      (4 * 2 ^ dataBits N + 2 * 2 ^ addrBits N + 2 ^ (2 ^ addrBits N + addrBits N)) * N 18 * 2 ^ N

      Core counting bound: the total Shannon gate budget times N is at most 18 · 2^N, for N ≥ 16.

      theorem Complexity.ShannonUpper.shannon_size_le (N : ) (hN : 16 N) (G : ) (hG : G + 1 4 * 2 ^ dataBits N + 2 * 2 ^ addrBits N + 2 ^ (2 ^ addrBits N + addrBits N)) :
      G + 1 18 * 2 ^ N / N

      Any gate count within the Shannon budget is at most 18 · 2^N / N (with the +1 accounting for the output gate), for N ≥ 16.

      Circuit Construction #

      Gate construction helper #

      Circuit layout #

      Total gate count of the Shannon circuit for kk address and qq data variables: one constant-false gate, the data minterm tree (2^(qq+1) - 4), the address minterm tree (2^(kk+1) - 4), the column library (2^(2^kk) OR chains of length 2^kk - 1), the AND layer (2^qq), and the final OR chain (2^qq - 1).

      Equations
      Instances For

        The Shannon gate array is nonempty.

        Section offsets (not private so they can be unfolded after set) #

        Gate-index offset of Section C (address minterm tree): after the constant-false gate and the data minterm tree.

        Equations
        Instances For

          Gate-index offset of Section D (column library): after Section C.

          Equations
          Instances For

            Gate-index offset of Section E (AND layer): after the column library.

            Equations
            Instances For

              Gate-index offset of Section F (final OR chain): after the AND layer.

              Equations
              Instances For

                Power-of-2 helpers #

                Minterm tree level #

                Level of node j in a minterm tree, where level l occupies indices 2^(l+1) - 4, …, 2^(l+2) - 5: equals ⌊log₂ (j + 4)⌋ - 1.

                Equations
                Instances For

                  Minterm-tree nodes with index ≥ 4 sit at level 2 or deeper.

                  theorem Complexity.ShannonUpper.treeLevel_lt (j n : ) (hj : j < 2 ^ (n + 1) - 4) (hn : 2 n) :

                  Nodes within an n-variable minterm tree (index < 2^(n+1) - 4) sit at level < n.

                  Index of the first minterm-tree node at level l: 2^(l+1) - 4.

                  Equations
                  Instances For

                    Position of node j within level l of a minterm tree.

                    Equations
                    Instances For

                      Index of the parent (at level l - 1) of the level-l node at position m: the parent's level position is m % 2^l.

                      Equations
                      Instances For

                        Every node with index ≥ 4 lies at or beyond the base of its level.

                        theorem Complexity.ShannonUpper.treeParentIndex_lt_j (l m j : ) (hl : 2 l) (hm : m = treePosition j l) (hbase : treeBase l j) :

                        A minterm-tree node's parent has a strictly smaller index, so tree wiring is acyclic.

                        Column pattern encoding #

                        noncomputable def Complexity.ShannonUpper.encodeColumn (k : ) (col : Fin (2 ^ k)Bool) :

                        Encode a column function col : Fin (2^k) → Bool as a natural number whose j-th bit is col j; used to index the column pattern library.

                        Equations
                        Instances For
                          theorem Complexity.ShannonUpper.encodeColumn_lt (k : ) (col : Fin (2 ^ k)Bool) :
                          encodeColumn k col < 2 ^ 2 ^ k

                          Column encodings are indices into the library of 2^(2^k) patterns.

                          noncomputable def Complexity.ShannonUpper.columnFunction (N : ) (f : BitString NBool) (k q : ) (_hkq : k + q = N) (y : Fin (2 ^ q)) :
                          Fin (2 ^ k)Bool

                          The column function of f at data row y: maps an address a to f(a, y), reading the first k input bits from a and the remaining q bits from y.

                          Equations
                          Instances For
                            noncomputable def Complexity.ShannonUpper.columnPatternIndex (N : ) (f : BitString NBool) (k q : ) (hkq : k + q = N) (y : Fin (2 ^ q)) :

                            Pattern-library index of the column of f at data row y: encodeColumn applied to columnFunction.

                            Equations
                            Instances For
                              theorem Complexity.ShannonUpper.columnPatternIndex_lt (N : ) (f : BitString NBool) (k q : ) (hkq : k + q = N) (y : Fin (2 ^ q)) :
                              columnPatternIndex N f k q hkq y < 2 ^ 2 ^ k

                              Column pattern indices are bounded by the library size 2^(2^k).

                              Shannon gate array #

                              Correctness #

                              Bit-vector testBit lemma #

                              columnFunction reconstruction lemma #

                              Circuit correctness #

                              Key identity #
                              Connecting the last wire to the OR chain #
                              Semantic decomposition of the circuit #

                              The OR chain accumulates AND-layer semantic values.

                              This is the key wire-level fact: by induction on r, the OR-chain gate
                              at position r in Section F evaluates to the foldl-OR of AND-layer
                              semantic values for y = 0, ..., r+1.
                              
                              The proof requires tracing wireValue through the gate array, showing:
                              - The gate at index orChainOffset(k,q) + r is in Section F
                              - Section F gates are OR gates with inputs pointing to:
                                * For r=0: AND gates at andLayerOffset+0 and andLayerOffset+1
                                * For r>0: previous OR-chain gate and AND gate at andLayerOffset+(r+1)
                              - Each AND gate at andLayerOffset+y evaluates to andLayerSem (by wireValue_andLayer_sem)
                              - The OR of the accumulated value and the new AND output gives
                                the extended foldl
                              
                              The data tree leaf and column library output wire-value proofs
                              trace wireValue through Sections B and D respectively via
                              tree-level induction. 
                              

                              OR chain induction #

                              The deep wireValue unfolding through all 6 sections (required for
                              wireValue_andLayer_sem) and the gate array branch analysis make this
                              the most technically challenging part of the formalization. 
                              
                              Main correctness theorem #
                              theorem Complexity.ShannonUpper.shannon_assembly (N : ) [NeZero N] (hN : 16 N) (f : BitString NBool) :
                              ∃ (G : ) (c : Circuit Basis.andOr2 N 1 G), (fun (x : BitString N) => c.eval x 0) = f G + 1 4 * 2 ^ dataBits N + 2 * 2 ^ addrBits N + 2 ^ (2 ^ addrBits N + addrBits N)

                              Assembled Shannon construction: for N ≥ 16, every Boolean function on N variables has a fan-in-2 AND/OR circuit whose gate count (plus output gate) is within the explicit section-by-section budget.

                              Main Theorem #

                              theorem Complexity.ShannonUpper.shannon_construction (N : ) [NeZero N] (hN : 16 N) (f : BitString NBool) :
                              ∃ (G : ) (c : Circuit Basis.andOr2 N 1 G), (fun (x : BitString N) => c.eval x 0) = f c.size 18 * 2 ^ N / N

                              Shannon circuit construction: For N ≥ 16, every Boolean function has a fan-in-2 AND/OR circuit of size ≤ 18 · 2^N / N.