Quantified Boolean formulas #
Syntax and semantics of quantified Boolean formulas (QBF) — the canonical
PSPACE object, and the target of the TQBF PSPACE-completeness theorem and the
IP = PSPACE development (roadmap tracks N3, M4, L1).
A QBF is a Boolean formula over variables x_i (i : ℕ) closed under ¬, ∧,
∨, and the quantifiers ∃ x_i and ∀ x_i. Semantics are given by
QBF.eval relative to an assignment α : ℕ → Bool; a quantifier over x_i
ranges over the two Boolean values substituted for x_i via Function.update.
Main definitions and results #
QBF— the formula syntaxQBF.eval— evaluation under an assignmentQBF.eval_ex_iff,QBF.eval_all_iff— the defining substitution semantics of the quantifiers, phrased as existence/universality over the substituted value
Quantified Boolean formulas over variables indexed by ℕ.
- var
(i : ℕ)
: QBF
The variable
x_i. - tru : QBF
The constant
⊤. - fls : QBF
The constant
⊥. - neg
(φ : QBF)
: QBF
Negation
¬ φ. - conj
(φ ψ : QBF)
: QBF
Conjunction
φ ∧ ψ. - disj
(φ ψ : QBF)
: QBF
Disjunction
φ ∨ ψ. - ex
(i : ℕ)
(φ : QBF)
: QBF
Existential quantifier
∃ x_i, φ. - all
(i : ℕ)
(φ : QBF)
: QBF
Universal quantifier
∀ x_i, φ.
Instances For
Equations
- Complexity.instReprQBF = { reprPrec := Complexity.instReprQBF.repr }
Equations
- One or more equations did not get rendered due to their size.
- Complexity.instReprQBF.repr Complexity.QBF.tru prec✝ = Repr.addAppParen (Std.Format.nest (if prec✝ ≥ 1024 then 1 else 2) (Std.Format.text "Complexity.QBF.tru")).group prec✝
- Complexity.instReprQBF.repr Complexity.QBF.fls prec✝ = Repr.addAppParen (Std.Format.nest (if prec✝ ≥ 1024 then 1 else 2) (Std.Format.text "Complexity.QBF.fls")).group prec✝
Instances For
Equations
- One or more equations did not get rendered due to their size.
- Complexity.instDecidableEqQBF.decEq (Complexity.QBF.var a) (Complexity.QBF.var b) = if h : a = b then h ▸ isTrue ⋯ else isFalse ⋯
- Complexity.instDecidableEqQBF.decEq (Complexity.QBF.var i) Complexity.QBF.tru = isFalse ⋯
- Complexity.instDecidableEqQBF.decEq (Complexity.QBF.var i) Complexity.QBF.fls = isFalse ⋯
- Complexity.instDecidableEqQBF.decEq (Complexity.QBF.var i) φ.neg = isFalse ⋯
- Complexity.instDecidableEqQBF.decEq (Complexity.QBF.var i) (φ.conj ψ) = isFalse ⋯
- Complexity.instDecidableEqQBF.decEq (Complexity.QBF.var i) (φ.disj ψ) = isFalse ⋯
- Complexity.instDecidableEqQBF.decEq (Complexity.QBF.var i) (Complexity.QBF.ex i_1 φ) = isFalse ⋯
- Complexity.instDecidableEqQBF.decEq (Complexity.QBF.var i) (Complexity.QBF.all i_1 φ) = isFalse ⋯
- Complexity.instDecidableEqQBF.decEq Complexity.QBF.tru (Complexity.QBF.var i) = isFalse ⋯
- Complexity.instDecidableEqQBF.decEq Complexity.QBF.tru Complexity.QBF.tru = isTrue ⋯
- Complexity.instDecidableEqQBF.decEq Complexity.QBF.tru Complexity.QBF.fls = isFalse Complexity.instDecidableEqQBF.decEq._proof_12
- Complexity.instDecidableEqQBF.decEq Complexity.QBF.tru φ.neg = isFalse ⋯
- Complexity.instDecidableEqQBF.decEq Complexity.QBF.tru (φ.conj ψ) = isFalse ⋯
- Complexity.instDecidableEqQBF.decEq Complexity.QBF.tru (φ.disj ψ) = isFalse ⋯
- Complexity.instDecidableEqQBF.decEq Complexity.QBF.tru (Complexity.QBF.ex i φ) = isFalse ⋯
- Complexity.instDecidableEqQBF.decEq Complexity.QBF.tru (Complexity.QBF.all i φ) = isFalse ⋯
- Complexity.instDecidableEqQBF.decEq Complexity.QBF.fls (Complexity.QBF.var i) = isFalse ⋯
- Complexity.instDecidableEqQBF.decEq Complexity.QBF.fls Complexity.QBF.tru = isFalse Complexity.instDecidableEqQBF.decEq._proof_19
- Complexity.instDecidableEqQBF.decEq Complexity.QBF.fls Complexity.QBF.fls = isTrue ⋯
- Complexity.instDecidableEqQBF.decEq Complexity.QBF.fls φ.neg = isFalse ⋯
- Complexity.instDecidableEqQBF.decEq Complexity.QBF.fls (φ.conj ψ) = isFalse ⋯
- Complexity.instDecidableEqQBF.decEq Complexity.QBF.fls (φ.disj ψ) = isFalse ⋯
- Complexity.instDecidableEqQBF.decEq Complexity.QBF.fls (Complexity.QBF.ex i φ) = isFalse ⋯
- Complexity.instDecidableEqQBF.decEq Complexity.QBF.fls (Complexity.QBF.all i φ) = isFalse ⋯
- Complexity.instDecidableEqQBF.decEq φ.neg (Complexity.QBF.var i) = isFalse ⋯
- Complexity.instDecidableEqQBF.decEq φ.neg Complexity.QBF.tru = isFalse ⋯
- Complexity.instDecidableEqQBF.decEq φ.neg Complexity.QBF.fls = isFalse ⋯
- Complexity.instDecidableEqQBF.decEq a.neg b.neg = if h : a = b then h ▸ have inst := Complexity.instDecidableEqQBF.decEq a a; isTrue ⋯ else isFalse ⋯
- Complexity.instDecidableEqQBF.decEq φ.neg (φ_1.conj ψ) = isFalse ⋯
- Complexity.instDecidableEqQBF.decEq φ.neg (φ_1.disj ψ) = isFalse ⋯
- Complexity.instDecidableEqQBF.decEq φ.neg (Complexity.QBF.ex i φ_1) = isFalse ⋯
- Complexity.instDecidableEqQBF.decEq φ.neg (Complexity.QBF.all i φ_1) = isFalse ⋯
- Complexity.instDecidableEqQBF.decEq (φ.conj ψ) (Complexity.QBF.var i) = isFalse ⋯
- Complexity.instDecidableEqQBF.decEq (φ.conj ψ) Complexity.QBF.tru = isFalse ⋯
- Complexity.instDecidableEqQBF.decEq (φ.conj ψ) Complexity.QBF.fls = isFalse ⋯
- Complexity.instDecidableEqQBF.decEq (φ.conj ψ) φ_1.neg = isFalse ⋯
- Complexity.instDecidableEqQBF.decEq (φ.conj ψ) (φ_1.disj ψ_1) = isFalse ⋯
- Complexity.instDecidableEqQBF.decEq (φ.conj ψ) (Complexity.QBF.ex i φ_1) = isFalse ⋯
- Complexity.instDecidableEqQBF.decEq (φ.conj ψ) (Complexity.QBF.all i φ_1) = isFalse ⋯
- Complexity.instDecidableEqQBF.decEq (φ.disj ψ) (Complexity.QBF.var i) = isFalse ⋯
- Complexity.instDecidableEqQBF.decEq (φ.disj ψ) Complexity.QBF.tru = isFalse ⋯
- Complexity.instDecidableEqQBF.decEq (φ.disj ψ) Complexity.QBF.fls = isFalse ⋯
- Complexity.instDecidableEqQBF.decEq (φ.disj ψ) φ_1.neg = isFalse ⋯
- Complexity.instDecidableEqQBF.decEq (φ.disj ψ) (φ_1.conj ψ_1) = isFalse ⋯
- Complexity.instDecidableEqQBF.decEq (φ.disj ψ) (Complexity.QBF.ex i φ_1) = isFalse ⋯
- Complexity.instDecidableEqQBF.decEq (φ.disj ψ) (Complexity.QBF.all i φ_1) = isFalse ⋯
- Complexity.instDecidableEqQBF.decEq (Complexity.QBF.ex i φ) (Complexity.QBF.var i_1) = isFalse ⋯
- Complexity.instDecidableEqQBF.decEq (Complexity.QBF.ex i φ) Complexity.QBF.tru = isFalse ⋯
- Complexity.instDecidableEqQBF.decEq (Complexity.QBF.ex i φ) Complexity.QBF.fls = isFalse ⋯
- Complexity.instDecidableEqQBF.decEq (Complexity.QBF.ex i φ) φ_1.neg = isFalse ⋯
- Complexity.instDecidableEqQBF.decEq (Complexity.QBF.ex i φ) (φ_1.conj ψ) = isFalse ⋯
- Complexity.instDecidableEqQBF.decEq (Complexity.QBF.ex i φ) (φ_1.disj ψ) = isFalse ⋯
- Complexity.instDecidableEqQBF.decEq (Complexity.QBF.ex i φ) (Complexity.QBF.all i_1 φ_1) = isFalse ⋯
- Complexity.instDecidableEqQBF.decEq (Complexity.QBF.all i φ) (Complexity.QBF.var i_1) = isFalse ⋯
- Complexity.instDecidableEqQBF.decEq (Complexity.QBF.all i φ) Complexity.QBF.tru = isFalse ⋯
- Complexity.instDecidableEqQBF.decEq (Complexity.QBF.all i φ) Complexity.QBF.fls = isFalse ⋯
- Complexity.instDecidableEqQBF.decEq (Complexity.QBF.all i φ) φ_1.neg = isFalse ⋯
- Complexity.instDecidableEqQBF.decEq (Complexity.QBF.all i φ) (φ_1.conj ψ) = isFalse ⋯
- Complexity.instDecidableEqQBF.decEq (Complexity.QBF.all i φ) (φ_1.disj ψ) = isFalse ⋯
- Complexity.instDecidableEqQBF.decEq (Complexity.QBF.all i φ) (Complexity.QBF.ex i_1 φ_1) = isFalse ⋯
Instances For
Evaluate a QBF under an assignment α : ℕ → Bool. A quantifier over x_i
substitutes both Boolean values for x_i (via Function.update) and combines
the results disjunctively (ex) or conjunctively (all).
Equations
- Complexity.QBF.eval α (Complexity.QBF.var i) = α i
- Complexity.QBF.eval α Complexity.QBF.tru = true
- Complexity.QBF.eval α Complexity.QBF.fls = false
- Complexity.QBF.eval α φ.neg = !Complexity.QBF.eval α φ
- Complexity.QBF.eval α (φ.conj ψ) = (Complexity.QBF.eval α φ && Complexity.QBF.eval α ψ)
- Complexity.QBF.eval α (φ.disj ψ) = (Complexity.QBF.eval α φ || Complexity.QBF.eval α ψ)
- Complexity.QBF.eval α (Complexity.QBF.ex i φ) = (Complexity.QBF.eval (Function.update α i false) φ || Complexity.QBF.eval (Function.update α i true) φ)
- Complexity.QBF.eval α (Complexity.QBF.all i φ) = (Complexity.QBF.eval (Function.update α i false) φ && Complexity.QBF.eval (Function.update α i true) φ)
Instances For
The quantifier nesting depth of a QBF — an upper bound on the number of quantifier alternations, used to stratify QBF (and hence the polynomial hierarchy) by bounded alternation.
Equations
- (Complexity.QBF.var i).quantDepth = 0
- Complexity.QBF.tru.quantDepth = 0
- Complexity.QBF.fls.quantDepth = 0
- φ.neg.quantDepth = φ.quantDepth
- (φ.conj ψ).quantDepth = max φ.quantDepth ψ.quantDepth
- (φ.disj ψ).quantDepth = max φ.quantDepth ψ.quantDepth
- (Complexity.QBF.ex i φ).quantDepth = φ.quantDepth + 1
- (Complexity.QBF.all i φ).quantDepth = φ.quantDepth + 1
Instances For
A QBF is quantifier-free when it has no quantifiers (depth 0).
Equations
- φ.QuantifierFree = (φ.quantDepth = 0)
Instances For
A conjunction is quantifier-free iff both conjuncts are.
The free variables of a QBF: variables not captured by an enclosing
quantifier. A quantifier ∃ x_i / ∀ x_i removes i from the free set.
Equations
- (Complexity.QBF.var i).freeVars = {i}
- Complexity.QBF.tru.freeVars = ∅
- Complexity.QBF.fls.freeVars = ∅
- φ.neg.freeVars = φ.freeVars
- (φ.conj ψ).freeVars = φ.freeVars ∪ ψ.freeVars
- (φ.disj ψ).freeVars = φ.freeVars ∪ ψ.freeVars
- (Complexity.QBF.ex i φ).freeVars = φ.freeVars \ {i}
- (Complexity.QBF.all i φ).freeVars = φ.freeVars \ {i}
Instances For
Semantic locality of QBF. Evaluation depends only on the free variables:
if two assignments agree on freeVars φ, they give φ the same value. In
particular a closed formula (empty freeVars) has an assignment-independent
truth value. The quantifier cases use that updating the bound variable makes
the two assignments agree on the quantified subformula.
A closed QBF is true when it evaluates to true. By eval_closed_eq
the choice of assignment is immaterial; this uses the all-false one. The
set of true closed QBFs is the canonical PSPACE-complete problem TQBF.