Documentation

Complexity.Computability.Circuit.Boolean.SemiCircuit.Gate

Gates over the full binary basis #

The gates of fair semi-circuits (Cslib.Circuits.Boolean.SemiCircuit). An argument is a constant or an internal value named by a natural number, a literal is an argument, possibly negated, and a gate applies an operation Bool → Bool → Bool of the full binary basis B₂ to two arguments. Rerouting the internal value v to a literal (Gate.subst) absorbs the negation into the operation and preserves the value of the gate on assignments giving v the value of the literal (Gate.eval_subst).

A gate with a constant argument or two equal arguments is degenerate and computes a constant or a literal of an argument (Gate.eval_lit). Of the sixteen operations of B₂, the affine ones (IsAffineOp) have no product term; every other operation, an AND-type one, has the form (a + α)(b + β) + γ (exists_and_form), takes both values (exists_eq_of_not_isAffineOp'), and is constant on a line of 𝔽₂² on which any other operation is constant (exists_line_const). An affine operation that is neither constant nor a projection is XOR-type (exists_xor_form).

Main definitions #

Main results #

References #

Arguments, literals and gates #

An argument of a gate: a constant or the internal value with the given name.

  • const (b : Bool) : Arg

    A constant.

  • node (i : ℕ) : Arg

    An internal value.

Instances For

    The value of an argument under an assignment of the internal values.

    Instances For
      @[simp]
      theorem Cslib.Circuits.Boolean.SemiCircuit.Arg.eval_node (val : ℕ → Bool) (i : ℕ) :
      eval val (node i) = val i

      The argument node v replaced by the argument of the literal ℓ.

      Instances For
        theorem Cslib.Circuits.Boolean.SemiCircuit.Arg.eval_congr {a : Arg} {val val' : ℕ → Bool} (h : ∀ (i : ℕ), a = node i → val i = val' i) :
        eval val a = eval val' a

        Changing the assignment away from the internal values an argument reads keeps its value.

        A literal: an argument, negated when neg holds. Outputs and reroutings are literals.

        • arg : Arg

          The argument.

        • neg : Bool

          Whether the argument is negated.

        Instances For

          The value of a literal.

          Instances For

            The constant literal b.

            Instances For

              The literal t ⊕ c of the internal value t.

              Instances For
                @[simp]
                theorem Cslib.Circuits.Boolean.SemiCircuit.Lit.eval_node (t : ℕ) (c : Bool) (val : ℕ → Bool) :
                (node t c).eval val = (val t ^^ c)

                Reroute the internal value v in a literal to the literal ℓ.

                Instances For
                  theorem Cslib.Circuits.Boolean.SemiCircuit.Lit.eval_subst {o : Lit} {v : ℕ} {ℓ : Lit} {val : ℕ → Bool} (h : val v = ℓ.eval val) :
                  (o.subst v ℓ).eval val = o.eval val

                  The literal reads the internal value t.

                  Instances For
                    theorem Cslib.Circuits.Boolean.SemiCircuit.Lit.eval_congr {o : Lit} {val val' : ℕ → Bool} (h : ∀ (i : ℕ), o.Reads i → val i = val' i) :
                    o.eval val = o.eval val'
                    theorem Cslib.Circuits.Boolean.SemiCircuit.Lit.not_reads_subst {o : Lit} {v : ℕ} {ℓ : Lit} (hℓ : ¬ℓ.Reads v) :
                    ¬(o.subst v ℓ).Reads v
                    theorem Cslib.Circuits.Boolean.SemiCircuit.Lit.reads_of_reads_subst {o : Lit} {v : ℕ} {ℓ : Lit} {z : ℕ} (h : (o.subst v ℓ).Reads z) :
                    o.Reads z ∨ o.Reads v ∧ ℓ.Reads z
                    theorem Cslib.Circuits.Boolean.SemiCircuit.Lit.eval_subst_update {o : Lit} {v : ℕ} {ℓ : Lit} (hℓ : ¬ℓ.Reads v) (val : ℕ → Bool) :
                    (o.subst v ℓ).eval val = o.eval (Function.update val v (ℓ.eval val))

                    A literal with v rerouted to a literal not reading v evaluates as the literal on the assignment giving v the value of the rerouting literal.

                    A gate of the acyclic part: an operation of the full binary basis B₂ applied to two arguments.

                    • op : Bool → Bool → Bool

                      The operation of the gate.

                    • left : Arg

                      The first argument.

                    • right : Arg

                      The second argument.

                    Instances For

                      The value of a gate, given the values of its arguments.

                      Instances For

                        The gate reads the internal value t.

                        Instances For
                          theorem Cslib.Circuits.Boolean.SemiCircuit.Gate.eval_congr {g : Gate} {val val' : ℕ → Bool} (h : ∀ (i : ℕ), g.Reads i → val i = val' i) :
                          g.eval val = g.eval val'

                          A gate's value depends only on the internal values it reads.

                          The negation absorbed into the operation when the argument a is rerouted.

                          Instances For

                            Reroute the internal value v to the literal ℓ: arguments node v read the argument of ℓ, and the negation of ℓ is absorbed into the operation.

                            Instances For
                              theorem Cslib.Circuits.Boolean.SemiCircuit.Gate.eval_substArg {a : Arg} {v : ℕ} {ℓ : Lit} {val : ℕ → Bool} (h : val v = ℓ.eval val) :
                              (Arg.eval val (a.substArg v ℓ.arg) ^^ substNeg a v ℓ) = Arg.eval val a
                              theorem Cslib.Circuits.Boolean.SemiCircuit.Gate.eval_subst {g : Gate} {v : ℕ} {ℓ : Lit} {val : ℕ → Bool} (h : val v = ℓ.eval val) :
                              (g.subst v ℓ).eval val = g.eval val

                              Rerouting v to a literal with the value of v preserves the value of every gate.

                              theorem Cslib.Circuits.Boolean.SemiCircuit.Gate.substArg_eq_node_of_ne {a : Arg} {v z : ℕ} {target : Arg} (hzv : z ≠ v) (hzt : target ≠ Arg.node z) :
                              a.substArg v target = Arg.node z ↔ a = Arg.node z
                              theorem Cslib.Circuits.Boolean.SemiCircuit.Gate.reads_subst_of_ne {g : Gate} {v : ℕ} {ℓ : Lit} {z : ℕ} (hzv : z ≠ v) (hzℓ : ℓ.arg ≠ Arg.node z) :
                              (g.subst v ℓ).Reads z ↔ g.Reads z
                              theorem Cslib.Circuits.Boolean.SemiCircuit.Gate.reads_of_reads_subst {g : Gate} {v : ℕ} {ℓ : Lit} {z : ℕ} (h : (g.subst v ℓ).Reads z) :
                              g.Reads z ∨ g.Reads v ∧ ℓ.arg = Arg.node z
                              theorem Cslib.Circuits.Boolean.SemiCircuit.Gate.eval_subst_of_not_reads {g : Gate} {v : ℕ} {ℓ : Lit} (h : ¬g.Reads v) (val : ℕ → Bool) :
                              (g.subst v ℓ).eval val = g.eval val
                              theorem Cslib.Circuits.Boolean.SemiCircuit.Gate.eval_subst_update {g : Gate} {v : ℕ} {ℓ : Lit} (hℓ : ℓ.arg ≠ Arg.node v) (val : ℕ → Bool) :
                              (g.subst v ℓ).eval val = g.eval (Function.update val v (ℓ.eval val))

                              A gate with v rerouted to a literal not reading v evaluates as the gate on the assignment giving v the value of the literal.

                              @[simp]
                              theorem Cslib.Circuits.Boolean.SemiCircuit.Gate.eval_subst_const (g : Gate) (v : ℕ) (b : Bool) (val : ℕ → Bool) :
                              (g.subst v (Lit.const b)).eval val = g.eval (Function.update val v b)
                              theorem Cslib.Circuits.Boolean.SemiCircuit.Gate.args_of_reads {g : Gate} {z z' : ℕ} (hzz : z ≠ z') (hz : g.Reads z) (hz' : g.Reads z') :

                              A gate reading two distinct internal values reads exactly them.

                              A gate whose arguments are x and y, in either order, reads both.

                              theorem Cslib.Circuits.Boolean.SemiCircuit.Gate.eq_or_eq_of_reads {g : Gate} {a b i : ℕ} (hab : a ≠ b) (ha : g.Reads a) (hb : g.Reads b) (hi : g.Reads i) :
                              i = a ∨ i = b

                              A gate reading two distinct internal values reads nothing else.

                              A gate reads at most two internal values.

                              theorem Cslib.Circuits.Boolean.SemiCircuit.Gate.eval_of_args {g : Gate} {a b : ℕ} (ha : g.left = Arg.node a) (hb : g.right = Arg.node b) (val : ℕ → Bool) :
                              g.eval val = g.op (val a) (val b)

                              The value of a gate reading the internal values a and b.

                              Degenerate gates #

                              The literal computed by a gate with a constant argument or two equal arguments.

                              Instances For

                                The gate has a constant argument or two equal arguments.

                                Instances For

                                  A Boolean function of one bit is a constant or a literal.

                                  The literal computing the Boolean function h of one bit applied to the argument a.

                                  Instances For
                                    theorem Cslib.Circuits.Boolean.SemiCircuit.eval_unaryLit (h : Bool → Bool) (a : Arg) (val : ℕ → Bool) :
                                    h (Arg.eval val a) = (unaryLit h a).eval val

                                    Operations of the full binary basis #

                                    An operation of B₂ is affine when its multilinear expression has no product term.

                                    Instances For
                                      theorem Cslib.Circuits.Boolean.SemiCircuit.exists_eq_of_not_isAffineOp {op : Bool → Bool → Bool} (h : ¬IsAffineOp op) :
                                      (∃ (b : Bool), op b false = op b true) ∧ ∃ (b : Bool), op false b = op true b

                                      An AND-type operation becomes constant when either argument takes a suitable value.

                                      theorem Cslib.Circuits.Boolean.SemiCircuit.Gate.exists_const_of_not_isAffineOp {g : Gate} (hg : ¬IsAffineOp g.op) {a w : ℕ} (hargs : g.left = Arg.node a ∧ g.right = Arg.node w ∨ g.left = Arg.node w ∧ g.right = Arg.node a) :
                                      ∃ (b : Bool) (c : Bool), ∀ (val : ℕ → Bool), val w = b → g.eval val = c

                                      An AND-type gate reading two internal values becomes constant once the value w is fixed suitably.

                                      The operation is a projection or a negated projection: x ↦ c + x or y ↦ c + y.

                                      Instances For
                                        theorem Cslib.Circuits.Boolean.SemiCircuit.exists_diag_const (op : Bool → Bool → Bool) :
                                        ((∃ (c : Bool), op c false = op (!c) true) ∧ ∃ (c : Bool), op false c = op true !c) ∨ IsUnaryOp op

                                        An operation that is not a projection or a negated projection is constant on a diagonal {(c + a, a)} for a suitable c, and likewise on {(a, c + a)}.

                                        theorem Cslib.Circuits.Boolean.SemiCircuit.Gate.exists_const_of_diag {g : Gate} (hg : ¬IsUnaryOp g.op) {p r : ℕ} (hargs : g.left = Arg.node p ∧ g.right = Arg.node r ∨ g.left = Arg.node r ∧ g.right = Arg.node p) :
                                        ∃ (c : Bool) (d : Bool), ∀ (val : ℕ → Bool), val p = (val r ^^ c) → g.eval val = d

                                        An operation that is not a projection or a negated projection is constant on a diagonal: a gate with such an operation reading p and r is constant once p = r + c for a suitable c.

                                        theorem Cslib.Circuits.Boolean.SemiCircuit.exists_and_form {op : Bool → Bool → Bool} (h : ¬IsAffineOp op) :
                                        ∃ (α : Bool) (β : Bool) (γ : Bool), ∀ (a b : Bool), op a b = ((a ^^ α) && (b ^^ β) ^^ γ)

                                        Every AND-type operation has the form (a + α)(b + β) + γ.

                                        theorem Cslib.Circuits.Boolean.SemiCircuit.exists_eq_of_not_isAffineOp' {op : Bool → Bool → Bool} (h : ¬IsAffineOp op) (δ : Bool) :
                                        ∃ (a : Bool) (b : Bool), op a b = δ

                                        An AND-type operation takes both values.

                                        theorem Cslib.Circuits.Boolean.SemiCircuit.exists_xor_form {op : Bool → Bool → Bool} (h : IsAffineOp op) (hu : ¬IsUnaryOp op) (hc : ∃ (a : Bool) (b : Bool), op a b ≠ op false false) :
                                        ∃ (c : Bool), ∀ (a b : Bool), op a b = (a ^^ b ^^ c)

                                        An affine operation that is neither constant nor a projection or a negated projection is XOR-type: a + b + c.

                                        theorem Cslib.Circuits.Boolean.SemiCircuit.exists_line_const {g h : Bool → Bool → Bool} (hg : ¬IsAffineOp g) :
                                        (∃ (c : Bool), (∀ (b : Bool), g c b = g c false) ∧ ∀ (b : Bool), h c b = h c false) ∨ (∃ (c : Bool), (∀ (a : Bool), g a c = g false c) ∧ ∀ (a : Bool), h a c = h false c) ∨ ∃ (c : Bool), (∀ (b : Bool), g (b ^^ c) b = g c false) ∧ ∀ (b : Bool), h (b ^^ c) b = h c false

                                        Of two operations of two bits, one AND-type, both are constant on a common line of 𝔽₂²: a = c, b = c or a = b + c for a suitable constant c.

                                        theorem Cslib.Circuits.Boolean.SemiCircuit.Gate.exists_op_of_args {g : Gate} {x y : ℕ} (h : g.left = Arg.node x ∧ g.right = Arg.node y ∨ g.left = Arg.node y ∧ g.right = Arg.node x) :
                                        ∃ (φ : Bool → Bool → Bool), (IsAffineOp φ ↔ IsAffineOp g.op) ∧ ∀ (val : ℕ → Bool), g.eval val = φ (val x) (val y)

                                        A gate reading the internal values x and y computes an operation of their values, which is affine exactly when the operation of the gate is.