Documentation

Complexitylib.Classes.Containments.NPSPACESubsetPSPACE

NPSPACE ⊆ PSPACE #

⚠️ Unreviewed by Bolton

Savitch's theorem, at the level of classes: NPSPACE ⊆ PSPACE.

The reachability predicate Reach(u, v, 2^i) — is v reachable from u in at most 2^i steps — satisfies Reach(u, v, 2^i) ↔ ∃ m, Reach(u, m, 2^(i-1)) ∧ Reach(m, v, 2^(i-1)). Recursing on i and reusing the same space for the two subcalls costs O(S) bits per level and O(S) levels, which in the textbook argument simulates a nondeterministic space-S machine deterministically in space O(S²).

This file proves only the class inclusion. The parametric bound NSPACE(S) ⊆ DSPACE(S²) is not formalized: the deterministic machine below comes from iterating a polynomial-time step function under a polynomial space window, and no O(S²) bound is stated or extracted from it.

How the proof runs #

Not as a machine, but as a pure function iterated in place, exactly as NL ⊆ P was done:

Main results #

theorem Complexity.savitch_halving {k : ℕ} (tm : NTM k) (i : ℕ) (c c' : Cfg k tm.Q) :
tm.ReachesCfgLe (2 ^ (i + 1)) c c' ↔ ∃ (mid : Cfg k tm.Q), tm.ReachesCfgLe (2 ^ i) c mid ∧ tm.ReachesCfgLe (2 ^ i) mid c'

The recursion Savitch's machine runs. A step bound of 2 ^ (i + 1) is met exactly when some midpoint configuration is reachable within 2 ^ i steps and reaches the target within 2 ^ i steps. Recursing on i costs one stored midpoint per level and bottoms out at i = 0, where the question is a single step of the configuration graph.

theorem Complexity.savitch_reaches_within_codes {k : ℕ} {α : Type} [Fintype α] (tm : NTM k) (c₀ : Cfg k tm.Q) (g : Cfg k tm.Q → α) (hinj : ∀ {c c' : Cfg k tm.Q}, tm.ReachesCfg c₀ c → tm.ReachesCfg c₀ c' → g c = g c' → c = c') {N : ℕ} (hN : Fintype.card α ≤ N) (c : Cfg k tm.Q) :
tm.ReachesCfg c₀ c ↔ tm.ReachesCfgLe N c₀ c

Reachability is witnessed within the number of configuration codes. Any coding map that separates the reachable configurations bounds the length of a walk that has to be searched: a longer walk repeats a configuration and the repetition can be cut out. This is what makes the recursion depth of savitch_halving finite.

theorem Complexity.NPSPACE_bounded_reachability {L : Language} (hL : L ∈ NPSPACE) :
∃ (k : ℕ) (tm : NTM k) (q : Polynomial ℕ), ∀ (x : List Bool), x ∈ L ↔ ∃ (c : Cfg k tm.Q), tm.ReachesCfgLe (2 ^ Polynomial.eval x.length q) (tm.initCfg x) c ∧ tm.halted c ∧ c.output.cells 1 = Γ.one

A language in NPSPACE is reachability within 2 ^ poly steps. This is what savitch_halving is applied to: the step bound 2 ^ q(|x|) halves q(|x|) times before reaching a single step, so the recursion has polynomial depth, and each of its levels stores one configuration of a polynomially space-bounded machine.

NPSPACE ⊆ PSPACE (Savitch): halving the path length recursively decides a polynomially space-bounded nondeterministic machine deterministically in polynomial space. Only this class inclusion is stated; the quantitative O(S²) space bound of Savitch's theorem is not.

PSPACE = NPSPACE. Savitch's theorem settles the equality: the reverse inclusion is immediate, since a deterministic machine is a nondeterministic one that ignores its choices.