Documentation

Complexity.Computability.Circuit.Boolean.AltFormula

Alternating formulas #

An alternating formula of depth d over n variables is a formula in negation normal form whose unbounded fan-in AND and OR gates alternate along every path from the root, with d gates on each path and literals at the bottom (AltFormula n d): a literal (i, b) holds when bit i is b, as in Logic.PL.Literal. Its root operation is given when it is evaluated (AltFormula.eval), and its size counts the AND and OR gates; literals are free (AltFormula.size). This is the model of constant-depth circuits in which negations are free and only at the inputs. At depth two, alternating formulas are formulas in conjunctive or disjunctive normal form (AltFormula.eval_and_eq_cnf_eval, AltFormula.eval_or_eq_dnf_eval).

Substituting literals for the inputs costs nothing (AltFormula.mapInputs), and negating every input computes the negation with the dual root operation (AltFormula.eval_neg). Every function has alternating formulas of depth two of size 2 ^ n + 1 (AltFormula.exists_depth_two). An alternating formula of depth d is a circuit over the unbounded fan-in basis of AND/OR depth at most d, and of depth at most d + 1 counting negations, with at most n more gates, computing the negated inputs first (AltFormula.exists_circuit).

Main definitions #

Main results #

The operation at the root of an alternating formula.

Instances For

    De Morgan duality swaps conjunction and disjunction.

    Instances For
      @[reducible, inline]

      Alternating formulas of depth d over n variables: literals at depth zero, and a list of alternating formulas of depth d below each gate of depth d + 1. It is reducible, so that an alternating formula of depth two is a formula in conjunctive or disjunctive normal form.

      Instances For

        The number of AND and OR gates; literals are free.

        Instances For

          Evaluate an alternating formula with op at the root.

          Instances For

            Substitute literals for the inputs. This changes no gates.

            Instances For

              Negate every input; with the dual root operation, this computes the negation (AltFormula.eval_neg).

              Instances For
                @[simp]

                Substituting literals for the inputs preserves the number of gates.

                theorem Cslib.Circuits.Boolean.AltFormula.eval_mapInputs {n m d : ℕ} (ρ : Fin n → Logic.PL.Literal (Fin m)) (f : AltFormula n d) (op : AltOp) (x : BitString m) :
                eval op (mapInputs ρ f) x = eval op f fun (i : Fin n) => Logic.PL.Literal.eval x (ρ i)

                Evaluating an alternating formula after substituting literals is equivalent to evaluating the original formula on the evaluated literals.

                @[simp]

                Negating every input of an alternating formula preserves its size.

                theorem Cslib.Circuits.Boolean.AltFormula.eval_neg {n d : ℕ} (f : AltFormula n d) (op : AltOp) (x : BitString n) :
                eval op.dual f.neg x = !eval op f x

                De Morgan's law: negating every input and dualizing the root operation negates the value.

                An alternating formula of depth two with a conjunction at the root is a formula in conjunctive normal form.

                An alternating formula of depth two with a disjunction at the root is a formula in disjunctive normal form.

                Building alternating formulas #

                noncomputable def Cslib.Circuits.Boolean.AltFormula.gate {n d : ℕ} {ι : Type u_1} [Fintype ι] (fs : ι → AltFormula n d) :
                AltFormula n (d + 1)

                One gate over a finite family of alternating formulas.

                Instances For
                  theorem Cslib.Circuits.Boolean.AltFormula.size_gate {n d : ℕ} {ι : Type u_1} [Fintype ι] (fs : ι → AltFormula n d) :
                  (gate fs).size = 1 + ∑ i : ι, (fs i).size

                  The size of a single gate over a family of alternating formulas is one plus the sum of the child sizes.

                  theorem Cslib.Circuits.Boolean.AltFormula.eval_gate_and {n d : ℕ} {ι : Type u_1} [Fintype ι] (fs : ι → AltFormula n d) (x : BitString n) :
                  eval AltOp.and (gate fs) x = true ↔ ∀ (i : ι), eval AltOp.or (fs i) x = true

                  Evaluating gate fs with .and at the root holds iff every child evaluates to true with .or at its root.

                  theorem Cslib.Circuits.Boolean.AltFormula.eval_gate_or {n d : ℕ} {ι : Type u_1} [Fintype ι] (fs : ι → AltFormula n d) (x : BitString n) :
                  eval AltOp.or (gate fs) x = true ↔ ∃ (i : ι), eval AltOp.and (fs i) x = true

                  Evaluating gate fs with .or at the root holds iff some child evaluates to true with .and at its root.

                  noncomputable def Cslib.Circuits.Boolean.AltFormula.merge {n d : ℕ} {ι : Type u_1} [Fintype ι] (fs : ι → AltFormula n (d + 1)) :
                  AltFormula n (d + 1)

                  Merge the roots of a finite family of alternating formulas into one, without adding a gate layer.

                  Instances For
                    theorem Cslib.Circuits.Boolean.AltFormula.eval_merge_and {n d : ℕ} {ι : Type u_1} [Fintype ι] (fs : ι → AltFormula n (d + 1)) (x : BitString n) :
                    eval AltOp.and (merge fs) x = true ↔ ∀ (i : ι), eval AltOp.and (fs i) x = true

                    Evaluating merge fs with .and at the root holds iff every formula in the family evaluates to true with .and at its root.

                    theorem Cslib.Circuits.Boolean.AltFormula.eval_merge_or {n d : ℕ} {ι : Type u_1} [Fintype ι] (fs : ι → AltFormula n (d + 1)) (x : BitString n) :
                    eval AltOp.or (merge fs) x = true ↔ ∃ (i : ι), eval AltOp.or (fs i) x = true

                    Evaluating merge fs with .or at the root holds iff some formula in the family evaluates to true with .or at its root.

                    theorem Cslib.Circuits.Boolean.AltFormula.size_merge_le {n d : ℕ} {ι : Type u_1} [Fintype ι] (fs : ι → AltFormula n (d + 1)) :
                    (merge fs).size ≤ 1 + ∑ i : ι, (fs i).size

                    Merging a finite family of alternating formulas uses at most one plus the sum of their sizes.

                    A constant, as an alternating formula of any depth at least two.

                    Instances For
                      theorem Cslib.Circuits.Boolean.AltFormula.eval_constant (n d : ℕ) (op : AltOp) (b : Bool) (x : BitString n) :
                      eval op (constant n d op b) x = b

                      constant n d op b evaluates to b on every input when evaluated with root operation op.

                      A constant alternating formula has size at most 2.

                      The clause excluding exactly the input y.

                      Instances For

                        The clause excludingClause y evaluates to true on x with root .or iff x ≠ y.

                        noncomputable def Cslib.Circuits.Boolean.AltFormula.cnf {n : ℕ} (f : BitString n → Bool) :

                        The formula in conjunctive normal form excluding every false input of f.

                        Instances For

                          cnf f evaluates to f x on every input x with root operation .and.

                          The canonical CNF formula cnf f has size at most 2 ^ n + 1.

                          theorem Cslib.Circuits.Boolean.AltFormula.exists_depth_two {n : ℕ} (f : BitString n → Bool) (op : AltOp) :
                          ∃ (g : AltFormula n 2), g.size ≤ 2 ^ n + 1 ∧ ∀ (x : BitString n), eval op g x = f x

                          Normal forms: every Boolean function has alternating formulas of depth two, with either root operation, of size at most 2 ^ n + 1.

                          Alternating formulas as circuits #

                          An alternating formula as a formula over the unbounded fan-in basis, on the positive inputs 0, …, n - 1 followed by the negated inputs n, …, 2 n - 1.

                          Instances For

                            The positive inputs followed by the negated inputs.

                            Instances For

                              Evaluating toFormula op f on the literal vector literals x agrees with eval op f x.

                              Translating an alternating formula to an unbounded fan-in formula preserves its gate count.

                              An alternating formula of depth d translates to a formula of depth at most d.

                              An alternating formula of depth d translates to a formula of AND/OR depth at most d.

                              The circuit computing the positive and the negated inputs, with one negation gate per input.

                              Instances For

                                literalsCircuit n evaluates to the vector literals x of positive and negated inputs.

                                literalsCircuit n uses n gates (one negation per input).

                                The circuit computing the positive and the negated inputs over the De Morgan basis, with one negation gate per input.

                                Instances For

                                  Negations are free in the AND/OR depth, so the literals have AND/OR depth zero.

                                  Alternating formulas are circuits: an alternating formula of depth d computing f with root op is a circuit over the unbounded fan-in basis of AND/OR depth at most d, and of depth at most d + 1 counting negations, with at most n more gates, negating every input first.