Documentation

Complexity.Computability.Circuit.Boolean.CompareSwap

Boolean comparison and compare-exchange circuits #

The comparator reads key coordinates in selector order, with coordinate zero most significant. Its formula has 6 * k + 1 gates for k selected input bits. Compare-exchange computes the comparison once, retains it and its negation, and selects whole records using three gates per output bit. Ties preserve the input order, including payload bits outside the key.

For two nonempty records of width r, the circuit uses exactly 6 * k + 6 * r + 2 gates, including constants and negations. Empty records use no gates. Key positions may be arbitrary; the usual prefix key is Fin.castLE h for h : k ≤ r.

Main definitions #

Main results #

References #

def Cslib.Circuits.Formula.lexLt {n k : ℕ} :
(Fin k → Fin n) → (Fin k → Fin n) → Formula Boolean.signature n

Compare two selected input sequences, with coordinate zero most significant.

Instances For
    @[simp]
    theorem Cslib.Circuits.Formula.size_lexLt {n k : ℕ} (left right : Fin k → Fin n) :
    (lexLt left right).size = 6 * k + 1

    Lexicographic comparison of selected input leaves uses six gates per coordinate and one constant gate. Repeated or overlapping selections are allowed.

    @[simp]
    theorem Cslib.Circuits.Formula.eval_lexLt_iff {n k : ℕ} (left right : Fin k → Fin n) (x : BitString n) :
    (lexLt left right).eval Boolean.interpretation x = true ↔ toLex (x ∘ left) < toLex (x ∘ right)

    The comparison formula agrees with the lexicographic order, including empty keys.

    def Cslib.Circuits.Boolean.compareSwapCircuit {k r : ℕ} (key : Fin k → Fin r) :
    Circuit signature (r + r) (r + r)

    Compare two records by key, preserving their order when the keys agree. The comparison and its negation are shared across all output bits. Empty records use the identity wiring.

    Instances For

      Retain a flag and compute its negation once.

      Instances For

        Select one of two data wires using a stored flag and its stored negation.

        Instances For

          Swap the two blocks of record wires.

          Instances For

            Switch two payload blocks using a supplied flag and its supplied complement.

            Instances For

              Expose the shared flag and its complement before the exchanged records.

              Instances For

                Share a swap flag across every bit of the two records.

                Instances For

                  The control bits are supplied together: invalid pairs are not asserted to be swaps.

                  Recording returns both existing control wires without duplicating their computation.

                  Applying the same saved controls twice restores arbitrary payloads.

                  theorem Cslib.Circuits.Boolean.compareSwapCircuit.cost_switch (r : ℕ) (cost : signature.Op → ℕ) :
                  (switch r).program.cost cost = 2 * r * (2 * cost Op.and + cost Op.or)

                  Switching charges two ANDs and one OR for each output bit.

                  theorem Cslib.Circuits.Boolean.compareSwapCircuit.cost_record {r : ℕ} (flag : Circuit signature (r + r) 1) (cost : signature.Op → ℕ) :
                  (record flag).program.cost cost = flag.program.cost cost + cost Op.not + 2 * r * (2 * cost Op.and + cost Op.or)

                  The comparator and one shared negation are charged in addition to switching.

                  Exposing the controls adds no gates to exchange. Unlike compareSwapCircuit, exchange and record compute the flag even when the payload width is zero.

                  Compare-exchange swaps whole records precisely when the right key precedes the left key.

                  @[simp]
                  theorem Cslib.Circuits.Boolean.size_compareSwapCircuit {k r : ℕ} (key : Fin k → Fin r) :
                  (compareSwapCircuit key).size = if r = 0 then 0 else 6 * k + 6 * r + 2

                  Exact gate count, including the constant and the shared negation.

                  theorem Cslib.Circuits.Boolean.compareSwapCircuit_keys_ordered {k r : ℕ} (key : Fin k → Fin r) (x y : BitString r) :
                  have output := (compareSwapCircuit key).eval interpretation (Fin.append x y); (toLex fun (i : Fin k) => output (Fin.castAdd r (key i))) ≤ toLex fun (i : Fin k) => output (Fin.natAdd r (key i))

                  The selected keys of the two output records are in ascending order.

                  Equal keys preserve the entire pair, including payload coordinates outside the key.