Documentation

Complexitylib.Classes.Containments.Internal.SavitchReach

What Savitch's recursion computes #

⚠️ Unreviewed by Bolton

Complexity.Sav.rchB and Complexity.Sav.accB are the values the abstract machine returns, defined purely on bitstrings: a level-n reachability question is answered by trying every string of the enumeration's width as a midpoint. This file identifies them with reachability in the configuration graph, for as long as the strings involved are codes of configurations reachable from the start.

The two directions are both easy once the statement is right. Soundness follows because a midpoint that passes the first half is itself the code of a reachable configuration, so the induction hypothesis applies to it; completeness follows because the enumeration is every string of the code width, and a code has exactly that width.

Main results #

The bottom of the enumeration #

@[simp]

The base tests as propositions #

theorem Complexity.baseReachB_eq_true_iff {k : } (tm : NTM k) (R u v : List Bool) :
baseReachB tm R u v = true u = v nstepFn tm false R u = v nstepFn tm true R u = v

One step of the graph #

theorem Complexity.NTM.eq_of_reachesCfgIn_of_halted {k : } {tm : NTM k} {s : } {c c' : Cfg k tm.Q} (h : tm.ReachesCfgIn s c c') (hh : c.state = tm.qhalt) :
c' = c
theorem Complexity.NTM.eq_of_reachesCfgLe_of_halted {k : } {tm : NTM k} {t : } {c c' : Cfg k tm.Q} (h : tm.ReachesCfgLe t c c') (hh : c.state = tm.qhalt) :
c' = c
theorem Complexity.NTM.reachesCfg_of_reachesCfgIn {k : } {tm : NTM k} {s : } {c c' : Cfg k tm.Q} (h : tm.ReachesCfgIn s c c') :
tm.ReachesCfg c c'
theorem Complexity.NTM.reachesCfg_of_reachesCfgLe {k : } {tm : NTM k} {t : } {c c' : Cfg k tm.Q} (h : tm.ReachesCfgLe t c c') :
tm.ReachesCfg c c'
theorem Complexity.NTM.reachesCfgLe_one_iff {k : } (tm : NTM k) (c c' : Cfg k tm.Q) :
tm.ReachesCfgLe 1 c c' c' = c c.state tm.qhalt ∃ (b : Bool), c' = tm.stepCfg b c

The recursion against the graph #

theorem Complexity.baseReachB_cfgCode {k : } (tm : NTM k) {L : Language} {S : } (hdec : tm.DecidesInSpace L S) (x : List Bool) (W : ) (hq : Fintype.card tm.Q Cobham.blockWidth W) (hW : x.length + S x.length + 1 W) {c : Cfg k tm.Q} (hc : tm.ReachesCfg (tm.initCfg x) c) (v : List Bool) :
baseReachB tm (Cobham.blockRuler W) (Cobham.cfgCode W c) v = true ∃ (c' : Cfg k tm.Q), tm.ReachesCfgLe 1 c c' v = Cobham.cfgCode W c'
theorem Complexity.baseAccB_cfgCode {k : } (tm : NTM k) {L : Language} {S : } (hdec : tm.DecidesInSpace L S) (x : List Bool) (W : ) (hq : Fintype.card tm.Q Cobham.blockWidth W) (hW : x.length + S x.length + 1 W) {c : Cfg k tm.Q} (hc : tm.ReachesCfg (tm.initCfg x) c) :
theorem Complexity.rchB_cfgCode {k : } (tm : NTM k) {L : Language} {S : } (hdec : tm.DecidesInSpace L S) (x : List Bool) (W : ) (hq : Fintype.card tm.Q Cobham.blockWidth W) (hW : x.length + S x.length + 1 W) (n : ) (c : Cfg k tm.Q) :
tm.ReachesCfg (tm.initCfg x) c∀ (v : List Bool), Sav.rchB (baseReachB tm (Cobham.blockRuler W)) (savZero k (Cobham.blockRuler W)) n (Cobham.cfgCode W c) v = true ∃ (c' : Cfg k tm.Q), tm.ReachesCfgLe (2 ^ n) c c' v = Cobham.cfgCode W c'

The recursion decides bounded reachability.

theorem Complexity.accB_cfgCode {k : } (tm : NTM k) {L : Language} {S : } (hdec : tm.DecidesInSpace L S) (x : List Bool) (W : ) (hq : Fintype.card tm.Q Cobham.blockWidth W) (hW : x.length + S x.length + 1 W) (n : ) (c : Cfg k tm.Q) :
tm.ReachesCfg (tm.initCfg x) c → (Sav.accB (baseReachB tm (Cobham.blockRuler W)) (fun (u : List Bool) => baseAccB tm (Cobham.blockRuler W) (savRuler k (Cobham.blockRuler W)) u) (savZero k (Cobham.blockRuler W)) n (Cobham.cfgCode W c) = true ∃ (c' : Cfg k tm.Q), tm.ReachesCfgLe (2 ^ n) c c' c'.state = tm.qhalt c'.output.cells 1 = Γ.one)

The recursion decides bounded acceptance.