Documentation

Complexitylib.Circuits.Nondeterminism.Defs

Nondeterministic Quantification of Boolean Functions #

This module defines existential and universal quantification over inputs of Boolean functions, corresponding to nondeterministic computation.

Given f : BitString (k + m) → Bool, existential quantification over the first k variables produces g : BitString m → Bool defined by g(y) = true iff there exists an assignment x : BitString k such that f(x ++ y) = true. This models a nondeterministic circuit that guesses the first k input bits.

Main definitions #

Main results #

def Complexity.existsQuantify {k m : } (f : BitString (k + m)Bool) :

Existential quantification over the first k inputs of a Boolean function. Given f : BitString (k + m) → Bool, produces g : BitString m → Bool where g(y) = true iff ∃ x : BitString k, f(x ++ y) = true.

This models a nondeterministic circuit that guesses the first k inputs.

Equations
Instances For
    def Complexity.forallQuantify {k m : } (f : BitString (k + m)Bool) :

    Universal quantification over the first k inputs of a Boolean function.

    Equations
    Instances For
      @[simp]
      theorem Complexity.existsQuantify_eq_true {k m : } {f : BitString (k + m)Bool} {y : BitString m} :
      existsQuantify f y = true ∃ (x : BitString k), f (Fin.append x y) = true

      Characterization: existsQuantify f y = true iff some assignment x to the first k inputs makes f (x ++ y) = true.

      @[simp]
      theorem Complexity.forallQuantify_eq_true {k m : } {f : BitString (k + m)Bool} {y : BitString m} :
      forallQuantify f y = true ∀ (x : BitString k), f (Fin.append x y) = true

      Characterization: forallQuantify f y = true iff every assignment x to the first k inputs makes f (x ++ y) = true.

      theorem Complexity.forallQuantify_eq_not_existsQuantify_not {k m : } (f : BitString (k + m)Bool) (y : BitString m) :
      forallQuantify f y = !existsQuantify (fun (z : BitString (k + m)) => !f z) y

      De Morgan duality: universal quantification equals negated existential of negation.

      theorem Complexity.existsQuantify_eq_not_forallQuantify_not {k m : } (f : BitString (k + m)Bool) (y : BitString m) :
      existsQuantify f y = !forallQuantify (fun (z : BitString (k + m)) => !f z) y

      De Morgan duality: existential quantification equals negated universal of negation.

      theorem Complexity.existsQuantify_mono {k m : } {f g : BitString (k + m)Bool} (h : ∀ (z : BitString (k + m)), f z = trueg z = true) {y : BitString m} :

      Monotonicity: if f implies g pointwise, existential quantification preserves this.

      theorem Complexity.forallQuantify_mono {k m : } {f g : BitString (k + m)Bool} (h : ∀ (z : BitString (k + m)), f z = trueg z = true) {y : BitString m} :

      Monotonicity for universal quantification.

      @[simp]
      theorem Complexity.existsQuantify_const_true {k m : } :
      (existsQuantify fun (x : BitString (k + m)) => true) = fun (x : BitString m) => true

      Constant true: existential quantification is always true.

      @[simp]
      theorem Complexity.existsQuantify_const_false {k m : } :
      (existsQuantify fun (x : BitString (k + m)) => false) = fun (x : BitString m) => false

      Constant false: existential quantification is always false.

      @[simp]
      theorem Complexity.forallQuantify_const_true {k m : } :
      (forallQuantify fun (x : BitString (k + m)) => true) = fun (x : BitString m) => true

      Constant true: universal quantification is always true.

      @[simp]
      theorem Complexity.forallQuantify_const_false {k m : } :
      (forallQuantify fun (x : BitString (k + m)) => false) = fun (x : BitString m) => false

      Constant false: universal quantification is always false.

      def Complexity.restrictFirst {k m : } (f : BitString (k + 1 + m)Bool) (b : Bool) :
      BitString (k + m)Bool

      Restrict a Boolean function by fixing its first input to a constant. Reduces the input size from (k + 1) + m to k + m.

      Equations
      Instances For

        Decomposition: quantifying over k + 1 variables factors as quantifying over k variables for each value of the first variable.

        (∃ a ∈ {0,1}^{k+1}, f(a,y)) ↔ (∃ x ∈ {0,1}^k, f(0∷x,y)) ∨ (∃ x ∈ {0,1}^k, f(1∷x,y))