Documentation

Complexity.Computability.Circuit.Boolean.CodeComposition

Combining circuit codes on shared inputs #

appendCode n c d runs both codes on the same n inputs, keeping the outputs of c before those of d. It shifts the gate references of d past the gates of c, while preserving its input references. On codes of circuits, the result is the code of Circuit.append. appendCodes combines any list of blocks by repeated append; each block is relocated by the number of preceding gates. bundleCode uses a fixed block size and agrees with appendCodes when its blocks have that size. All three constructors are computable in polynomial time with binary layout parameters.

compCode n d c instead feeds c's output wires to d's inputs. Its polynomial-time constructor performs binary-indexed lookup and gate relocation, and agrees exactly with Circuit.comp.

Main definitions #

Main results #

References #

def Cslib.Circuits.Program.appendWireCode (n m s : ℕ) (feed : Fin m → Wire n s) (i : ℕ) :

The wire-number map when continuing a program with another program.

Instances For
    theorem Cslib.Circuits.Program.appendedWire_toNat {n m s t : ℕ} (feed : Fin m → Wire n s) (w : Wire m t) :
    (appendedWire feed w).toNat = appendWireCode n m s feed w.toNat

    Numbering a continued wire agrees with the raw wire-number map.

    theorem Cslib.Circuits.Program.code_append {σ : Signature} {n m s t : ℕ} (p : Program σ n s) (feed : Fin m → Wire n s) (q : Program σ m t) :
    (p.append feed q).code = p.code ++ List.map (fun (g : σ.Op × List ℕ) => (g.1, List.map (appendWireCode n m s feed) g.2)) q.code

    Program continuation acts on codes by appending the rewired gate list.

    Retain an input wire, or shift a gate wire past offset preceding gates.

    Instances For

      Run two raw codes on shared inputs, listing the first code's outputs before the second's. Malformed codes are transformed as data; semantic correctness is asserted on typed circuits.

      Instances For

        Raw shared-input composition agrees with ordinary typed circuit append.

        The outputs of combined codes are the two output lists in order, on every input.

        Shifting wire numbers is polynomial-time with all quantities encoded in binary.

        Shift the gate references and output references of a raw code. Input wires are preserved.

        Instances For

          Relocating a circuit-code block is polynomial-time with binary offsets.

          Combining circuit codes is polynomial-time, including binary input and wire counts.

          Combine a list of raw codes on shared inputs, preserving block and output order. Blocks may have different gate counts and any number of outputs.

          Instances For

            Adding a final block is ordinary shared-input append.

            @[simp]

            The combined code retains every gate, without padding the individual blocks.

            @[simp]

            The combined code retains all outputs, including repeated outputs and zero-gate blocks.

            Combining arbitrary raw blocks is polynomial-time in their complete encodings. Input and wire numbers are binary; no uniform block-size or well-formedness premise is needed.

            theorem Cslib.Circuits.Boolean.appendCodes_code {k n : ℕ} (cs : Fin k → Circuit signature n 1) :
            appendCodes n (List.ofFn fun (j : Fin k) => (cs j).code) = (Circuit.pi cs).code

            Combining single-output circuit codes agrees exactly with Circuit.pi, with no restriction on the gate counts of its components.

            Combine equal-sized gate blocks on shared inputs. Block j is relocated by j * blockSize. The construction is total on raw data; its append semantics requires the stated block sizes.

            Instances For

              Bundling raw blocks is polynomial-time in their encodings and binary layout parameters.

              theorem Cslib.Circuits.Boolean.length_bundleCode (n blockSize : ℕ) (codes : List (List (Op × List ℕ) × List ℕ)) (hlen : ∀ c ∈ codes, c.1.length = blockSize) :
              (bundleCode n blockSize codes).1.length = codes.length * blockSize

              Equal-sized blocks occupy exactly their number times their common gate count.

              theorem Cslib.Circuits.Boolean.bundleCode_append_singleton (n blockSize : ℕ) (codes : List (List (Op × List ℕ) × List ℕ)) (code : List (Op × List ℕ) × List ℕ) (hlen : ∀ c ∈ codes, c.1.length = blockSize) :
              bundleCode n blockSize (codes ++ [code]) = appendCode n (bundleCode n blockSize codes) code

              Adding the next equal-sized block is shared-input append.

              theorem Cslib.Circuits.Boolean.bundleCode_eq_foldl_appendCode (n blockSize : ℕ) (codes : List (List (Op × List ℕ) × List ℕ)) (hlen : ∀ c ∈ codes, c.1.length = blockSize) :
              bundleCode n blockSize codes = List.foldl (appendCode n) ([], []) codes

              For equal-sized blocks, direct relocation agrees with repeated shared-input append.

              theorem Cslib.Circuits.Boolean.bundleCode_eq_appendCodes (n blockSize : ℕ) (codes : List (List (Op × List ℕ) × List ℕ)) (hlen : ∀ c ∈ codes, c.1.length = blockSize) :
              bundleCode n blockSize codes = appendCodes n codes

              Fixed-size bundling is a specialization of the varying-size constructor.

              theorem Cslib.Circuits.Boolean.bundleCode_code {k n : ℕ} (cs : Fin k → Circuit signature n 1) (blockSize : ℕ) (hs : ∀ (j : Fin k), (cs j).size = blockSize) :
              bundleCode n blockSize (List.ofFn fun (j : Fin k) => (cs j).code) = (Circuit.pi cs).code

              The typed and raw bundles have exactly the same code when component sizes agree.

              theorem Cslib.Circuits.Boolean.exists_circuit_bundleCode {k n : ℕ} (cs : Fin k → Circuit signature n 1) (blockSize : ℕ) (hs : ∀ (j : Fin k), (cs j).size = blockSize) :
              ∃ (c : Circuit signature n k), bundleCode n blockSize (List.ofFn fun (j : Fin k) => (cs j).code) = c.code ∧ ∀ (x : Fin n → Bool) (j : Fin k), c.eval interpretation x j = (cs j).eval interpretation x 0

              Equal-sized single-output codes form one typed circuit with the corresponding output order.

              Route a later circuit's inputs through c's outputs and shift its gates past c's gates.

              Instances For

                Feed the outputs of c to the inputs of d, matching the argument order of Circuit.comp. The constructor is total on raw data, including malformed circuit codes.

                Instances For

                  Raw sequential composition is exactly the code of typed circuit composition.

                  @[simp]

                  Sequential composition retains both gate lists.

                  @[simp]

                  Sequential composition retains the later circuit's number of outputs.

                  Resolve a composed wire in polynomial time, including binary output lookup and offsets.

                  Construct sequential circuit codes in polynomial time. All wire indices and input counts are binary; list lengths, input lookup, gate relocation and the whole output code are charged.