Documentation

LeanPool.CircuitComplexity.Internal.Simulation

Internal: Completeness of fan-in-2 AND/OR #

This module proves CompleteBasis Basis.andOr2 using the generic simulation lemma CompleteBasis.of_simulation. The proof compiles any circuit over Basis.unboundedAON into one over Basis.andOr2 by decomposing each unbounded fan-in gate into a chain of fan-in-2 gates.

Strategy #

Given a circuit c : Circuit Basis.unboundedAON N M G, we construct c' : Circuit Basis.andOr2 N M G' with c'.eval = c.eval.

Each original gate with fan-in k is replaced by a chain of chainLen k fan-in-2 gates:

The new circuit's internal gates consist of chains for all original internal gates followed by chains for all original output gates. The new output gates are trivial passthroughs reading the last wire of each output chain.

AONOp extensions #

Dual operation: swaps AND ↔ OR. Used for constant-gate construction.

Equations
Instances For

    Identity element for fold: true for AND, false for OR.

    Equations
    Instances For

      The binary operation corresponding to an AONOp.

      Equations
      Instances For
        theorem CircuitComplexity.AONOp.eval_eq_foldl (op : AONOp) (n : ) (v : BitString n) :
        op.eval n v = Fin.foldl n (fun (acc : Bool) (i : Fin n) => op.binOp acc (v i)) op.identity
        theorem CircuitComplexity.AONOp.binOp_assoc (op : AONOp) (a b c : Bool) :
        op.binOp (op.binOp a b) c = op.binOp a (op.binOp b c)
        theorem CircuitComplexity.AONOp.dual_const (op : AONOp) (b : Bool) :
        (op.dual.eval 2 fun (i : Fin 2) => (if i = 0 then false else true) ^^ b) = op.identity

        The dual-op trick for constants: OR(b, ¬b) = true, AND(b, ¬b) = false.

        theorem CircuitComplexity.AONOp.passthrough_eq (op : AONOp) (v : Bool) :
        (op.eval 2 fun (x : Fin 2) => v) = v

        A passthrough evaluates to the input value.

        eval on 0 inputs gives the identity.

        theorem CircuitComplexity.AONOp.eval_one (op : AONOp) (v : Fin 1Bool) :
        op.eval 1 v = op.binOp op.identity (v 0)

        eval on 1 input gives identity op input.

        Chain length and prefix sums #

        Number of fan-in-2 gates needed to simulate one gate with k inputs.

        Equations
        Instances For

          Segment lookup #

          def CircuitComplexity.CompileAON.segLookup (n : ) (f : ) (idx : ) (h : idx < prefixSum f n) :

          Given a flat index into a segmented array, find the segment and position.

          Equations
          Instances For
            theorem CircuitComplexity.CompileAON.segLookup_fst_lt (n : ) (f : ) (idx : ) (h : idx < prefixSum f n) :
            (segLookup n f idx h).1 < n
            theorem CircuitComplexity.CompileAON.segLookup_snd_lt (n : ) (f : ) (idx : ) (h : idx < prefixSum f n) :
            (segLookup n f idx h).2 < f (segLookup n f idx h).1
            theorem CircuitComplexity.CompileAON.segLookup_sum (n : ) (f : ) (idx : ) (h : idx < prefixSum f n) :
            prefixSum f (segLookup n f idx h).1 + (segLookup n f idx h).2 = idx

            Wire layout definitions #

            Chain size function for internal gates (0-padded beyond G).

            Equations
            Instances For

              Chain size function for output gates (0-padded beyond M).

              Equations
              Instances For

                Total number of compiled gates contributed by the internal gates.

                Equations
                Instances For

                  Total number of compiled gates contributed by the output gates.

                  Equations
                  Instances For
                    theorem CircuitComplexity.CompileAON.iChainF_eq {N M G : } [NeZero N] [NeZero M] (c : Circuit Basis.unboundedAON N M G) {i : } (hi : i < G) :
                    theorem CircuitComplexity.CompileAON.oChainF_eq {N M G : } [NeZero N] [NeZero M] (c : Circuit Basis.unboundedAON N M G) {j : } (hj : j < M) :
                    theorem CircuitComplexity.CompileAON.iOffset_succ {N M G : } [NeZero N] [NeZero M] (c : Circuit Basis.unboundedAON N M G) {i : } (hi : i < G) :
                    iOffset c (i + 1) = iOffset c i + chainLen (c.gates i, hi).fanIn
                    theorem CircuitComplexity.CompileAON.oOffset_succ {N M G : } [NeZero N] [NeZero M] (c : Circuit Basis.unboundedAON N M G) {j : } (hj : j < M) :
                    oOffset c (j + 1) = oOffset c j + chainLen (c.outputs j, hj).fanIn

                    Wire remapping #

                    def CircuitComplexity.CompileAON.remapWire {N M G : } [NeZero N] [NeZero M] (c : Circuit Basis.unboundedAON N M G) (w : Fin (N + G)) :
                    Fin (N + G' c)

                    Map an old wire index to its new position. Input wires are unchanged; internal gate i maps to the last gate of its chain.

                    Equations
                    • One or more equations did not get rendered due to their size.
                    Instances For
                      theorem CircuitComplexity.CompileAON.remapWire_input {N M G : } [NeZero N] [NeZero M] (c : Circuit Basis.unboundedAON N M G) (w : Fin (N + G)) (hw : w < N) :
                      (remapWire c w) = w
                      theorem CircuitComplexity.CompileAON.remapWire_gate {N M G : } [NeZero N] [NeZero M] (c : Circuit Basis.unboundedAON N M G) {i : } (hi : i < G) :
                      (remapWire c N + i, ) = N + iOffset c i + chainLen (c.gates i, hi).fanIn - 1
                      theorem CircuitComplexity.CompileAON.remapWire_lt_of_lt {N M G : } [NeZero N] [NeZero M] (c : Circuit Basis.unboundedAON N M G) (w : Fin (N + G)) {i : } (hi : i G) (hw : w < N + i) :
                      (remapWire c w) < N + iOffset c i

                      If w < N + i in the old circuit, remapWire w < N + iOffset i in the new.

                      theorem CircuitComplexity.CompileAON.remapWire_lt_oOffset {N M G : } [NeZero N] [NeZero M] (c : Circuit Basis.unboundedAON N M G) (w : Fin (N + G)) (j : ) :
                      (remapWire c w) < N + oOffset c j

                      remapWire maps to a wire that comes before any output chain.

                      Chain gate construction #

                      def CircuitComplexity.CompileAON.fin2 {α : Sort u_1} (a b : α) :
                      Fin 2α

                      Helper: construct a function Fin 2 → α from two values.

                      Equations
                      Instances For
                        @[simp]
                        theorem CircuitComplexity.CompileAON.fin2_zero {α : Sort u_1} (a b : α) :
                        fin2 a b 0 = a
                        @[simp]
                        theorem CircuitComplexity.CompileAON.fin2_one {α : Sort u_1} (a b : α) :
                        fin2 a b 1 = b
                        def CircuitComplexity.CompileAON.mkChainGate {W : } (hW : 0 < W) (op : AONOp) (k : ) (ri : Fin kFin W) (rn : Fin kBool) (base j : ) (hj : j < chainLen k) (hbase : base + chainLen k W) :

                        Build the j-th fan-in-2 gate in a chain for an original gate. Components are split out so projections reduce without unfolding dite.

                        Equations
                        • One or more equations did not get rendered due to their size.
                        Instances For

                          Compiled circuit #

                          Gate function for the compiled circuit. Components are separated so projections reduce without going through dite.

                          Equations
                          • One or more equations did not get rendered due to their size.
                          Instances For

                            Output gates: passthroughs reading the last wire of each output chain.

                            Equations
                            • One or more equations did not get rendered due to their size.
                            Instances For

                              The compiled circuit over Basis.andOr2.

                              Equations
                              Instances For

                                Eval equivalence #

                                theorem CircuitComplexity.CompileAON.segLookup_of_prefixSum (n : ) (f : ) (i j : ) (hi : i < n) (hj : j < f i) (h : prefixSum f i + j < prefixSum f n) :
                                segLookup n f (prefixSum f i + j) h = (i, j)

                                segLookup inverts prefixSum: if idx = prefixSum f i + j and j < f i, then segLookup returns (i, j).

                                theorem CircuitComplexity.CompileAON.wireValue_remapWire {N M G : } [NeZero N] [NeZero M] (c : Circuit Basis.unboundedAON N M G) (input : BitString N) (w : Fin (N + G)) :
                                (compileFn c).wireValue input (remapWire c w) = c.wireValue input w

                                Key lemma: remapWire values in the compiled circuit match the original.

                                Fan-in-2 AND/OR is functionally complete.