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 #

    def Complexity.ShannonUpper.mkGate2' (op : AndOrOp) {W : } (w₀ w₁ : Fin W) (n₀ n₁ : Bool) (bound : ) (hw₀ : w₀ < bound) (hw₁ : w₁ < bound) :
    { g : Gate Basis.andOr2 W // ∀ (k : Fin g.fanIn), (g.inputs k) < bound }

    Build a fan-in-2 gate bundled with an acyclicity proof.

    Equations
    • One or more equations did not get rendered due to their size.
    Instances For
      def Complexity.ShannonUpper.remap₂ (N G₁ G₂ : ) (w : Fin (N + G₂)) :
      Fin (N + (G₁ + G₂ + 2))

      Remap a wire from c₂'s space into the combined space.

      Equations
      Instances For
        def Complexity.ShannonUpper.gw (idx : ) {W : } (g : Gate Basis.andOr2 W) :
        autoParam (idx < 2) gw._auto_1Fin W

        The input wire at idx of a binary AND/OR gate.

        Equations
        Instances For

          Whether the input at idx of a binary AND/OR gate is negated.

          Equations
          Instances For

            Binary Circuit Composition #

            def Complexity.ShannonUpper.binopGWP {N G₁ G₂ : } [NeZero N] (c₁ : Circuit Basis.andOr2 N 1 G₁) (c₂ : Circuit Basis.andOr2 N 1 G₂) (i : Fin (G₁ + G₂ + 2)) :
            { g : Gate Basis.andOr2 (N + (G₁ + G₂ + 2)) // ∀ (k : Fin g.fanIn), (g.inputs k) < N + i }

            Gate + acyclicity proof for the binary composition, bundled as a subtype.

            Equations
            • One or more equations did not get rendered due to their size.
            Instances For
              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.