Documentation

CslibFrontier.Computability.Machines.Turing.MultiTape.Complexity.LogSpace.Savitch

Savitch's theorem for general space bounds #

A nondeterministic machine whose computation paths on an input of length n visit at most S work cells is simulated by a deterministic machine within space O((S + log₂ n + 1) ^ 2): this is Savitch's theorem [Sav70]. No constructibility of S is assumed; as in Sipser's proof of Theorem 8.5 [Sip13], the machine tries growing bounds. The simulation runs Savitch's midpoint recursion with an explicit stack (Cslib.Reachability.Savitch.step) on the compact configuration graph of the machine (Turing.MultiTapeNTM.ConfigurationGraph), whose vertices omit the input. A vertex of the graph of radix B is stored as a word of W = O(log B) bits, so the stack of at most W frames has O(W ^ 2) bits. The input is never copied: the simulation is a query machine (Turing.QueryMachine), which reads one input bit per step, and the edge test at the bottom of the recursion needs exactly one input bit, at the input head of its source vertex.

The space bound S is not computed. The machine counts the input in binary and then tries the radices roundRadix State n j = 4 ^ j * startRadix State n of Turing.MultiTapeNTM.ConfigurationGraph.roundRadix in turn, the radices of Immerman's inductive counting for nondeterministic space; Sipser's proof of Theorem 8.5 likewise tries the space bounds 1, 2, 3, … and checks whether the machine uses more. In round j, a first recursion asks whether an overflowing vertex, one with a step leaving the radix, is reachable from the start vertex; if it is, the machine moves on to round j + 1. Otherwise every reachable view fits the radix, and a second recursion on the same graph asks whether an accepting halted vertex is reachable, which decides acceptance. A machine within space S has no reachable overflow from round 4 * S + 1 on (Turing.MultiTapeNTM.ConfigurationGraph.fits_roundRadix_of_runsInSpace), so every round has vertices of O(S + log₂ n + 1) bits. To have a single target, the graph on words gains a sink, the word of W ones: every target vertex steps to it (Turing.MultiTapeNTM.SquareSavitch.sinkReach_eq_true_iff).

The sublinear form of Savitch's theorem is the extension stated in the final paragraph of Section 8.4 of Sipser's third edition, just before Section 8.5 (p. 351): "We can extend Savitch's theorem to hold for sublinear space bounds down to f(n) ≥ log n." Sipser's Theorem 8.5 itself assumes f(n) ≥ n, and Arora and Barak's Theorem 4.14 assumes a space-constructible bound S(n) ≥ log n. In the extension, the machine has a read-only input tape, and the configurations of the machine on the input w record the state, the work tapes and the head positions but not w. Here these are the vertices of the compact configuration graph, and the query machine reads the one input bit an edge test needs. The sources state the theorem for languages decided by nondeterministic machines whose branches all halt; the statement here also covers machines that only recognize the problem (branches may run forever), arbitrary per-instance bounds without constructibility, and arbitrary instances under an encoding into List Bool.

Main definitions #

Main results #

References #

The graph on words #

noncomputable def Turing.MultiTapeNTM.SquareSavitch.target {k : ℕ} {State : Type} [Fintype State] (ntm : MultiTapeNTM k Bool State) (overflowMode : Bool) (B n : ℕ) (symbol : Option Bool) (u : ℕ) :

The targets of a round, given the input bit symbol at the vertex: the overflowing vertices in overflow mode, and the accepting halted vertices otherwise.

Instances For
    noncomputable def Turing.MultiTapeNTM.SquareSavitch.wordEdge {k : ℕ} {State : Type} [Fintype State] (ntm : MultiTapeNTM k Bool State) (overflowMode : Bool) (B n : ℕ) (symbol : Option Bool) (u v : List Bool) :

    The edges of the graph on words, given the round mode and the input bit symbol at the source: the edges of the compact configuration graph between the values of the words, and an edge from every target vertex to the sink, the word of ones.

    Instances For
      noncomputable def Turing.MultiTapeNTM.SquareSavitch.paramEdge {k : ℕ} {State : Type} [Fintype State] (ntm : MultiTapeNTM k Bool State) (p : Bool × ℕ × ℕ × Option Bool) :

      The edges of the graph on words, with the round mode, the radix, the input length and the input bit as one parameter.

      Instances For
        noncomputable def Turing.MultiTapeNTM.SquareSavitch.inputEdge {k : ℕ} {State : Type} [Fintype State] (ntm : MultiTapeNTM k Bool State) (overflowMode : Bool) (B : ℕ) (w u v : List Bool) :

        The edges of the graph on words on the input w: the input bit is read at the input head of the source.

        Instances For
          def Turing.MultiTapeNTM.SquareSavitch.Target {k : ℕ} {State : Type} [Fintype State] (ntm : MultiTapeNTM k Bool State) (overflowMode : Bool) (B : ℕ) (w : List Bool) (u : ℕ) :

          The target test on an actual input, reading the bit at queryIndex.

          Instances For
            noncomputable def Turing.MultiTapeNTM.SquareSavitch.sinkReach {k : ℕ} {State : Type} [Fintype State] (ntm : MultiTapeNTM k Bool State) (overflowMode : Bool) (B : ℕ) (w : List Bool) :

            The recursion of a round: Savitch's midpoint recursion at depth W = vertexWidth k B on the graph on words of width W, from the start vertex to the sink.

            Instances For
              def Turing.MultiTapeNTM.SquareSavitch.OverflowReachable {k : ℕ} {State : Type} [Fintype State] (ntm : MultiTapeNTM k Bool State) (B : ℕ) (w : List Bool) :

              Some overflowing vertex is reachable in the graph of radix B.

              Instances For

                Reachability of the sink #

                theorem Turing.MultiTapeNTM.SquareSavitch.lt_vertexBound_of_target {k : ℕ} {State : Type} [Fintype State] {ntm : MultiTapeNTM k Bool State} {B : ℕ} {overflowMode : Bool} {n u : ℕ} {symbol : Option Bool} (h : target ntm overflowMode B n symbol u = true) :

                Every target is a vertex of the graph.

                The sink is reachable exactly when a target is. Along the graph on words of width W = vertexWidth k B, from the start vertex to the word of W ones.

                theorem Turing.MultiTapeNTM.SquareSavitch.sinkReach_eq_true_iff {k : ℕ} {State : Type} [Fintype State] {ntm : MultiTapeNTM k Bool State} {B : ℕ} {w : List Bool} {overflowMode : Bool} (hB : Fintype.card (Option State) + 1 < B) :
                sinkReach ntm overflowMode B w = true ↔ ∃ (u : ℕ), Relation.ReflTransGen (ConfigurationGraph.Edge ntm B w) (ConfigurationGraph.startID ntm B) u ∧ Target ntm overflowMode B w u

                The recursion of a round decides whether a target is reachable, for every radix above the finite tags.

                theorem Turing.MultiTapeNTM.SquareSavitch.sinkReach_true_iff {k : ℕ} {State : Type} [Fintype State] {ntm : MultiTapeNTM k Bool State} {B : ℕ} {w : List Bool} (hB : Fintype.card (Option State) + 1 < B) :

                The overflow round decides reachable overflow.

                theorem Turing.MultiTapeNTM.SquareSavitch.sinkReach_false_iff {k : ℕ} {State : Type} [Fintype State] {ntm : MultiTapeNTM k Bool State} {B : ℕ} {w : List Bool} (hB : Fintype.card (Option State) + 1 < B) (hno : ¬OverflowReachable ntm B w) :

                Without reachable overflow, the acceptance round decides acceptance.

                theorem Turing.MultiTapeNTM.SquareSavitch.not_overflowReachable_of_runsInSpace {k : ℕ} {State : Type} [Fintype State] {ntm : MultiTapeNTM k Bool State} {w : List Bool} {S j : ℕ} (hs : ntm.RunsInSpace w S) (hj : 4 * S + 1 ≤ j) :

                The late rounds have no reachable overflow: for a machine within space S, from round 4 * S + 1 on.

                The query machine #

                @[reducible, inline]

                The encoding of the parameter of the edge test: the round mode, the radix and the input length in binary, and the input bit read last.

                Instances For

                  Edge-test parameters, with the input bit read last.

                  • overflowMode : Bool

                    Whether the round searches for overflow, rather than for acceptance.

                  • radix : ℕ

                    Radix used to encode the simulated machine registers.

                  • inputLength : ℕ

                    Length of the original read-only input.

                  • symbol : Option Bool

                    Input bit just read, or none beyond the input.

                  Instances For

                    The parameters and unary vertex width share one frame.

                    • params : EdgeParams

                      Parameters shared by all edge tests in this round.

                    • width : ℕ

                      Bit width of vertices, stored in unary.

                    Instances For

                      A round of midpoint recursion.

                      Instances For

                        The input counter, startup flag, and current simulation round.

                        • counter : ℕ

                          Number of input bits counted; the input length after startup.

                        • started : Bool

                          Whether input counting has finished and recursion has started.

                        • Current midpoint-recursion round.

                        Instances For
                          theorem Turing.MultiTapeNTM.SquareSavitch.encEdgeParams_mk_polyTime {γ : Type} {encIn : γ ↪ List Bool} {x0 : γ → Bool} {x1 x2 : γ → ℕ} {x3 : γ → Option Bool} (h0 : MultiTapeTM.ComputableInPolyTime x0 encIn MultiTapeTM.encBool) (h1 : MultiTapeTM.ComputableInPolyTime x1 encIn MultiTapeTM.encNat) (h2 : MultiTapeTM.ComputableInPolyTime x2 encIn MultiTapeTM.encNat) (h3 : MultiTapeTM.ComputableInPolyTime x3 encIn (MultiTapeTM.encOption MultiTapeTM.encBool)) :
                          MultiTapeTM.ComputableInPolyTime (fun (x : γ) => { overflowMode := x0 x, radix := x1 x, inputLength := x2 x, symbol := x3 x }) encIn encEdgeParams
                          theorem Turing.MultiTapeNTM.SquareSavitch.encEdgeParams_radix_budget {γ✝ : Type} {encIn✝ : γ✝ ↪ List Bool} {S✝ : γ✝ → ℕ} {g✝ : γ✝ → EdgeParams} :
                          MultiTapeTM.ComputableInSpace g✝ encIn✝ encEdgeParams S✝ → MultiTapeTM.ComputableInSpace (fun (a : γ✝) => (g✝ a).radix) encIn✝ MultiTapeTM.encNat S✝
                          theorem Turing.MultiTapeNTM.SquareSavitch.encEdgeParams_mk_budget {γ : Type} {encIn : γ ↪ List Bool} {budget : γ → ℕ} {x0 : γ → Bool} {x1 x2 : γ → ℕ} {x3 : γ → Option Bool} (h0 : MultiTapeTM.ComputableInSpace x0 encIn MultiTapeTM.encBool budget) (h1 : MultiTapeTM.ComputableInSpace x1 encIn MultiTapeTM.encNat budget) (h2 : MultiTapeTM.ComputableInSpace x2 encIn MultiTapeTM.encNat budget) (h3 : MultiTapeTM.ComputableInSpace x3 encIn (MultiTapeTM.encOption MultiTapeTM.encBool) budget) :
                          MultiTapeTM.ComputableInSpace (fun (x : γ) => { overflowMode := x0 x, radix := x1 x, inputLength := x2 x, symbol := x3 x }) encIn encEdgeParams budget
                          theorem Turing.MultiTapeNTM.SquareSavitch.encEdgeParams_inputLength_budget {γ✝ : Type} {encIn✝ : γ✝ ↪ List Bool} {S✝ : γ✝ → ℕ} {g✝ : γ✝ → EdgeParams} :
                          MultiTapeTM.ComputableInSpace g✝ encIn✝ encEdgeParams S✝ → MultiTapeTM.ComputableInSpace (fun (a : γ✝) => (g✝ a).inputLength) encIn✝ MultiTapeTM.encNat S✝
                          theorem Turing.MultiTapeNTM.SquareSavitch.encEdgeParams_mk_deg :
                          MultiTapeTM.ComputableInDegree (fun (p : Bool × ℕ × ℕ × Option Bool) => { overflowMode := p.1, radix := p.2.1, inputLength := p.2.2.1, symbol := p.2.2.2 }) encEdgeParamsFields encEdgeParams 1 1
                          @[reducible, inline]

                          The tuple of the fields of encEdgeParams.

                          Instances For
                            theorem Turing.MultiTapeNTM.SquareSavitch.encEdgeParams_overflowMode_budget {γ✝ : Type} {encIn✝ : γ✝ ↪ List Bool} {S✝ : γ✝ → ℕ} {g✝ : γ✝ → EdgeParams} :
                            MultiTapeTM.ComputableInSpace g✝ encIn✝ encEdgeParams S✝ → MultiTapeTM.ComputableInSpace (fun (a : γ✝) => (g✝ a).overflowMode) encIn✝ MultiTapeTM.encBool S✝
                            theorem Turing.MultiTapeNTM.SquareSavitch.encEdgeParams_mk_inO {γ : Type} {encIn : γ ↪ List Bool} {x0 : γ → Bool} {T0 S0 x1 T1 S1 x2 T2 S2 : γ → ℕ} {x3 : γ → Option Bool} {T3 S3 : γ → ℕ} (h0 : MultiTapeTM.ComputableInO x0 encIn MultiTapeTM.encBool T0 S0) (h1 : MultiTapeTM.ComputableInO x1 encIn MultiTapeTM.encNat T1 S1) (h2 : MultiTapeTM.ComputableInO x2 encIn MultiTapeTM.encNat T2 S2) (h3 : MultiTapeTM.ComputableInO x3 encIn (MultiTapeTM.encOption MultiTapeTM.encBool) T3 S3) :
                            MultiTapeTM.ComputableInO (fun (x : γ) => { overflowMode := x0 x, radix := x1 x, inputLength := x2 x, symbol := x3 x }) encIn encEdgeParams (fun (x : γ) => T0 x + (T1 x + (T2 x + T3 x))) fun (x : γ) => S0 x + (S1 x + (S2 x + S3 x))

                            Round mode, binary radix and input length followed by the optional input bit, in field order.

                            Instances For
                              theorem Turing.MultiTapeNTM.SquareSavitch.encEdgeParams_symbol_budget {γ✝ : Type} {encIn✝ : γ✝ ↪ List Bool} {S✝ : γ✝ → ℕ} {g✝ : γ✝ → EdgeParams} :
                              theorem Turing.MultiTapeNTM.SquareSavitch.encRoundSetup_mk_budget {γ : Type} {encIn : γ ↪ List Bool} {budget : γ → ℕ} {x0 : γ → EdgeParams} {x1 : γ → ℕ} (h0 : MultiTapeTM.ComputableInSpace x0 encIn encEdgeParams budget) (h1 : MultiTapeTM.ComputableInSpace x1 encIn MultiTapeTM.encUnary budget) :
                              MultiTapeTM.ComputableInSpace (fun (x : γ) => { params := x0 x, width := x1 x }) encIn encRoundSetup budget
                              theorem Turing.MultiTapeNTM.SquareSavitch.encRoundSetup_mk_inO {γ : Type} {encIn : γ ↪ List Bool} {x0 : γ → EdgeParams} {T0 S0 x1 T1 S1 : γ → ℕ} (h0 : MultiTapeTM.ComputableInO x0 encIn encEdgeParams T0 S0) (h1 : MultiTapeTM.ComputableInO x1 encIn MultiTapeTM.encUnary T1 S1) :
                              MultiTapeTM.ComputableInO (fun (x : γ) => { params := x0 x, width := x1 x }) encIn encRoundSetup (fun (x : γ) => T0 x + T1 x) fun (x : γ) => S0 x + S1 x
                              theorem Turing.MultiTapeNTM.SquareSavitch.encRoundSetup_params_budget {γ✝ : Type} {encIn✝ : γ✝ ↪ List Bool} {S✝ : γ✝ → ℕ} {g✝ : γ✝ → RoundSetup} :
                              MultiTapeTM.ComputableInSpace g✝ encIn✝ encRoundSetup S✝ → MultiTapeTM.ComputableInSpace (fun (a : γ✝) => (g✝ a).params) encIn✝ encEdgeParams S✝
                              theorem Turing.MultiTapeNTM.SquareSavitch.encRoundSetup_width_budget {γ✝ : Type} {encIn✝ : γ✝ ↪ List Bool} {S✝ : γ✝ → ℕ} {g✝ : γ✝ → RoundSetup} :
                              MultiTapeTM.ComputableInSpace g✝ encIn✝ encRoundSetup S✝ → MultiTapeTM.ComputableInSpace (fun (a : γ✝) => (g✝ a).width) encIn✝ MultiTapeTM.encUnary S✝

                              Framed edge parameters followed by the unary vertex width.

                              Instances For
                                @[reducible, inline]

                                The tuple of the fields of encRoundSetup.

                                Instances For
                                  theorem Turing.MultiTapeNTM.SquareSavitch.encSimulationRound_setup_budget {γ✝ : Type} {encIn✝ : γ✝ ↪ List Bool} {S✝ : γ✝ → ℕ} {g✝ : γ✝ → SimulationRound} :
                                  MultiTapeTM.ComputableInSpace g✝ encIn✝ encSimulationRound S✝ → MultiTapeTM.ComputableInSpace (fun (a : γ✝) => (g✝ a).setup) encIn✝ encRoundSetup S✝
                                  theorem Turing.MultiTapeNTM.SquareSavitch.encSimulationRound_mk_inO {γ : Type} {encIn : γ ↪ List Bool} {x0 : γ → RoundSetup} {T0 S0 : γ → ℕ} {x1 : γ → Cslib.Reachability.Savitch.State} {T1 S1 : γ → ℕ} (h0 : MultiTapeTM.ComputableInO x0 encIn encRoundSetup T0 S0) (h1 : MultiTapeTM.ComputableInO x1 encIn Cslib.Reachability.Savitch.encState T1 S1) :
                                  MultiTapeTM.ComputableInO (fun (x : γ) => { setup := x0 x, recursion := x1 x }) encIn encSimulationRound (fun (x : γ) => T0 x + T1 x) fun (x : γ) => S0 x + S1 x

                                  Framed round setup followed by the encoded recursion state.

                                  Instances For
                                    theorem Turing.MultiTapeNTM.SquareSavitch.encSimulationRound_mk_budget {γ : Type} {encIn : γ ↪ List Bool} {budget : γ → ℕ} {x0 : γ → RoundSetup} {x1 : γ → Cslib.Reachability.Savitch.State} (h0 : MultiTapeTM.ComputableInSpace x0 encIn encRoundSetup budget) (h1 : MultiTapeTM.ComputableInSpace x1 encIn Cslib.Reachability.Savitch.encState budget) :
                                    MultiTapeTM.ComputableInSpace (fun (x : γ) => { setup := x0 x, recursion := x1 x }) encIn encSimulationRound budget
                                    theorem Turing.MultiTapeNTM.SquareSavitch.encSimulationRound_recursion_budget {γ✝ : Type} {encIn✝ : γ✝ ↪ List Bool} {S✝ : γ✝ → ℕ} {g✝ : γ✝ → SimulationRound} :
                                    theorem Turing.MultiTapeNTM.SquareSavitch.encRuntime_round_polyTime {γ✝ : Type} {encIn✝ : γ✝ ↪ List Bool} {g✝ : γ✝ → Runtime} :
                                    theorem Turing.MultiTapeNTM.SquareSavitch.encRuntime_mk_inO {γ : Type} {encIn : γ ↪ List Bool} {x0 T0 S0 : γ → ℕ} {x1 : γ → Bool} {T1 S1 : γ → ℕ} {x2 : γ → SimulationRound} {T2 S2 : γ → ℕ} (h0 : MultiTapeTM.ComputableInO x0 encIn MultiTapeTM.encNat T0 S0) (h1 : MultiTapeTM.ComputableInO x1 encIn MultiTapeTM.encBool T1 S1) (h2 : MultiTapeTM.ComputableInO x2 encIn encSimulationRound T2 S2) :
                                    MultiTapeTM.ComputableInO (fun (x : γ) => { counter := x0 x, started := x1 x, round := x2 x }) encIn encRuntime (fun (x : γ) => T0 x + (T1 x + T2 x)) fun (x : γ) => S0 x + (S1 x + S2 x)
                                    theorem Turing.MultiTapeNTM.SquareSavitch.encRuntime_counter_budget {γ✝ : Type} {encIn✝ : γ✝ ↪ List Bool} {S✝ : γ✝ → ℕ} {g✝ : γ✝ → Runtime} :
                                    MultiTapeTM.ComputableInSpace g✝ encIn✝ encRuntime S✝ → MultiTapeTM.ComputableInSpace (fun (a : γ✝) => (g✝ a).counter) encIn✝ MultiTapeTM.encNat S✝
                                    theorem Turing.MultiTapeNTM.SquareSavitch.encRuntime_round_budget {γ✝ : Type} {encIn✝ : γ✝ ↪ List Bool} {S✝ : γ✝ → ℕ} {g✝ : γ✝ → Runtime} :
                                    MultiTapeTM.ComputableInSpace g✝ encIn✝ encRuntime S✝ → MultiTapeTM.ComputableInSpace (fun (a : γ✝) => (g✝ a).round) encIn✝ encSimulationRound S✝
                                    @[reducible, inline]

                                    The tuple of the fields of encRuntime.

                                    Instances For
                                      theorem Turing.MultiTapeNTM.SquareSavitch.encRuntime_mk_polyTime {γ : Type} {encIn : γ ↪ List Bool} {x0 : γ → ℕ} {x1 : γ → Bool} {x2 : γ → SimulationRound} (h0 : MultiTapeTM.ComputableInPolyTime x0 encIn MultiTapeTM.encNat) (h1 : MultiTapeTM.ComputableInPolyTime x1 encIn MultiTapeTM.encBool) (h2 : MultiTapeTM.ComputableInPolyTime x2 encIn encSimulationRound) :
                                      MultiTapeTM.ComputableInPolyTime (fun (x : γ) => { counter := x0 x, started := x1 x, round := x2 x }) encIn encRuntime
                                      theorem Turing.MultiTapeNTM.SquareSavitch.encRuntime_mk_budget {γ : Type} {encIn : γ ↪ List Bool} {budget x0 : γ → ℕ} {x1 : γ → Bool} {x2 : γ → SimulationRound} (h0 : MultiTapeTM.ComputableInSpace x0 encIn MultiTapeTM.encNat budget) (h1 : MultiTapeTM.ComputableInSpace x1 encIn MultiTapeTM.encBool budget) (h2 : MultiTapeTM.ComputableInSpace x2 encIn encSimulationRound budget) :
                                      MultiTapeTM.ComputableInSpace (fun (x : γ) => { counter := x0 x, started := x1 x, round := x2 x }) encIn encRuntime budget
                                      theorem Turing.MultiTapeNTM.SquareSavitch.encRuntime_started_budget {γ✝ : Type} {encIn✝ : γ✝ ↪ List Bool} {S✝ : γ✝ → ℕ} {g✝ : γ✝ → Runtime} :
                                      MultiTapeTM.ComputableInSpace g✝ encIn✝ encRuntime S✝ → MultiTapeTM.ComputableInSpace (fun (a : γ✝) => (g✝ a).started) encIn✝ MultiTapeTM.encBool S✝

                                      Binary counter, startup bit and simulation round, in field order.

                                      Instances For

                                        Enter the named runtime representation at the generic Savitch round boundary.

                                        Instances For
                                          noncomputable def Turing.MultiTapeNTM.SquareSavitch.initRound {k : ℕ} {State : Type} [Fintype State] (ntm : MultiTapeNTM k Bool State) (overflowMode : Bool) (B n : ℕ) :

                                          The first state of a round of the given mode and radix, on inputs of length n: the call at depth W from the start vertex to the sink. The start vertex is written as the binary digits of its value plus 2 ^ W, without the last one (Turing.MultiTapeTM.bits_add_two_pow).

                                          Instances For

                                            The round held while the input is counted.

                                            Instances For

                                              The source of the pending call, if any.

                                              Instances For

                                                The recursion has returned its value.

                                                Instances For

                                                  The round has returned, and it is an overflow round: the next round starts.

                                                  Instances For

                                                    The input bit to read: the next input position while counting, then the input head of the source of the pending call.

                                                    Instances For
                                                      noncomputable def Turing.MultiTapeNTM.SquareSavitch.next {k : ℕ} {State : Type} [Fintype State] (ntm : MultiTapeNTM k Bool State) (p : Runtime × Option Bool) :

                                                      A step of the machine, given the input bit read: count the input until its end, then start the overflow round of the first radix. An overflow round that returns true starts the overflow round of the next radix; one that returns false starts the acceptance round of the same radix. Other steps run the recursion, with the bit read as the input bit of the edge test.

                                                      Instances For

                                                        The machine halts once an acceptance round has returned.

                                                        Instances For

                                                          The answer: the value returned by the recursion.

                                                          Instances For
                                                            noncomputable def Turing.MultiTapeNTM.SquareSavitch.machine {k : ℕ} {State : Type} [Fintype State] (ntm : MultiTapeNTM k Bool State) :

                                                            The deterministic simulation, as a query machine: count the input, then run Savitch's recursion on the graphs on words of growing radix, reading the input bit of each edge test.

                                                            Instances For

                                                              The runs of the machine #

                                                              The step of the recursion only uses the edge test at a call at level 0.

                                                              theorem Turing.MultiTapeNTM.SquareSavitch.output_eq {k : ℕ} {State : Type} [Fintype State] {ntm : MultiTapeNTM k Bool State} (w : List Bool) (t : ℕ) :
                                                              (machine ntm).output w t = finish ((machine ntm).run w t)

                                                              The machine emits nothing before its final answer.

                                                              theorem Turing.MultiTapeNTM.SquareSavitch.run_of_le {k : ℕ} {State : Type} [Fintype State] {ntm : MultiTapeNTM k Bool State} (w : List Bool) {t : ℕ} (ht : t ≤ w.length) :
                                                              (machine ntm).run w t = { counter := t, started := false, round := SimulationRound.ofRound idle }

                                                              While counting, the machine holds the number of input bits read.

                                                              theorem Turing.MultiTapeNTM.SquareSavitch.run_length_succ {k : ℕ} {State : Type} [Fintype State] {ntm : MultiTapeNTM k Bool State} (w : List Bool) :
                                                              (machine ntm).run w (w.length + 1) = { counter := w.length, started := true, round := SimulationRound.ofRound (initRound ntm true (ConfigurationGraph.startRadix State w.length) w.length) }

                                                              At the end of the input, the machine starts the overflow round of the first radix.

                                                              The value of a returned recursion is the value of its register.

                                                              A step of a round that has not returned runs the recursion, with the input bit at the source of the pending call.

                                                              theorem Turing.MultiTapeNTM.SquareSavitch.step_restart {k : ℕ} {State : Type} [Fintype State] {ntm : MultiTapeNTM k Bool State} (w : List Bool) {B : ℕ} {symbol : Option Bool} {b : Bool} :
                                                              (machine ntm).step w { counter := w.length, started := true, round := SimulationRound.ofRound (((true, B, w.length, symbol), ConfigurationGraph.vertexWidth k B), { stack := [], reg := Cslib.Reachability.Savitch.Reg.ret b }) } = { counter := w.length, started := true, round := SimulationRound.ofRound (initRound ntm b (if b = true then 4 * B else B) w.length) }

                                                              A returned overflow round starts the next round: the overflow round of the next radix if it returned true, and the acceptance round of the same radix otherwise.

                                                              A returned acceptance round has halted.

                                                              The first state of a round, once the start vertex is known to have a word.

                                                              theorem Turing.MultiTapeNTM.SquareSavitch.ret_eq_sinkReach {k : ℕ} {State : Type} [Fintype State] {ntm : MultiTapeNTM k Bool State} (w : List Bool) {mode : Bool} {B : ℕ} (hB : Fintype.card (Option State) + 1 < B) {i : ℕ} {b : Bool} (h : (Cslib.Reachability.Savitch.step (inputEdge ntm mode B w) (ConfigurationGraph.vertexWidth k B))^[i] (initRound ntm mode B w.length).2 = { stack := [], reg := Cslib.Reachability.Savitch.Reg.ret b }) :
                                                              b = sinkReach ntm mode B w

                                                              A returned round holds the value of its recursion.

                                                              theorem Turing.MultiTapeNTM.SquareSavitch.exists_run_returned {k : ℕ} {State : Type} [Fintype State] {ntm : MultiTapeNTM k Bool State} (w : List Bool) {mode : Bool} {B t₀ : ℕ} (hB : Fintype.card (Option State) + 1 < B) (h₀ : (machine ntm).run w t₀ = { counter := w.length, started := true, round := SimulationRound.ofRound (initRound ntm mode B w.length) }) :
                                                              ∃ (t : ℕ) (symbol : Option Bool), (machine ntm).run w t = { counter := w.length, started := true, round := SimulationRound.ofRound (((mode, B, w.length, symbol), ConfigurationGraph.vertexWidth k B), { stack := [], reg := Cslib.Reachability.Savitch.Reg.ret (sinkReach ntm mode B w) }) }

                                                              A round runs to its return: from the first state of a round, the machine runs the recursion until it returns the value sinkReach.

                                                              def Turing.MultiTapeNTM.SquareSavitch.RunState {k : ℕ} {State : Type} [Fintype State] {ntm : MultiTapeNTM k Bool State} (w : List Bool) (s : Runtime) :

                                                              The states of a run: counting the input, or a round of radix roundRadix State n j, after overflow rounds that found overflow at every earlier radix. An acceptance round has no reachable overflow at its radix.

                                                              Instances For
                                                                theorem Turing.MultiTapeNTM.SquareSavitch.runState_step {k : ℕ} {State : Type} [Fintype State] {ntm : MultiTapeNTM k Bool State} (w : List Bool) {s : Runtime} (h : RunState w s) :
                                                                RunState w ((machine ntm).step w s)

                                                                The machine keeps the states of a run.

                                                                theorem Turing.MultiTapeNTM.SquareSavitch.runState_run {k : ℕ} {State : Type} [Fintype State] {ntm : MultiTapeNTM k Bool State} (w : List Bool) (t : ℕ) :
                                                                RunState w ((machine ntm).run w t)

                                                                Every state of the run is a state of a run.

                                                                theorem Turing.MultiTapeNTM.SquareSavitch.answer_iff_of_halted {k : ℕ} {State : Type} [Fintype State] {ntm : MultiTapeNTM k Bool State} (w : List Bool) {s : Runtime} (h : RunState w s) (hh : halted s = true) :

                                                                A halted machine has decided acceptance.

                                                                theorem Turing.MultiTapeNTM.SquareSavitch.halted_or_next_round {k : ℕ} {State : Type} [Fintype State] {ntm : MultiTapeNTM k Bool State} (w : List Bool) {j t₀ : ℕ} (h₀ : (machine ntm).run w t₀ = { counter := w.length, started := true, round := SimulationRound.ofRound (initRound ntm true (ConfigurationGraph.roundRadix State w.length j) w.length) }) :
                                                                (∃ (t : ℕ), halted ((machine ntm).run w t) = true) ∨ OverflowReachable ntm (ConfigurationGraph.roundRadix State w.length j) w ∧ ∃ (t₁ : ℕ), (machine ntm).run w t₁ = { counter := w.length, started := true, round := SimulationRound.ofRound (initRound ntm true (ConfigurationGraph.roundRadix State w.length (j + 1)) w.length) }

                                                                A returned overflow round leads to a halted machine or to the overflow round of the next radix, after reachable overflow.

                                                                theorem Turing.MultiTapeNTM.SquareSavitch.exists_halted {k : ℕ} {State : Type} [Fintype State] {ntm : MultiTapeNTM k Bool State} (w : List Bool) {S : ℕ} (hs : ntm.RunsInSpace w S) :
                                                                ∃ (t : ℕ), halted ((machine ntm).run w t) = true

                                                                The machine halts on the inputs of a machine within some space bound.

                                                                The size of the states #

                                                                theorem Turing.MultiTapeNTM.SquareSavitch.le_of_overflowReachable {k : ℕ} {State : Type} [Fintype State] {ntm : MultiTapeNTM k Bool State} {w : List Bool} {S j : ℕ} (hs : ntm.RunsInSpace w S) (hlt : ∀ j' < j, OverflowReachable ntm (ConfigurationGraph.roundRadix State w.length j') w) :
                                                                j ≤ 4 * S + 1

                                                                A run within space S stays below round 4 * S + 1.

                                                                The states of the recursion satisfy the invariant of a run at depth W.

                                                                noncomputable def Turing.MultiTapeNTM.SquareSavitch.widthConst (k : ℕ) (State : Type) [Fintype State] :

                                                                The constant factor of the width of the vertices in the rounds of a run.

                                                                Instances For
                                                                  noncomputable def Turing.MultiTapeNTM.SquareSavitch.sizeConst (k : ℕ) (State : Type) [Fintype State] :

                                                                  The constant of the bound on the states of the machine.

                                                                  Instances For
                                                                    theorem Turing.MultiTapeNTM.SquareSavitch.length_encRuntime_le {k : ℕ} {State : Type} [Fintype State] {ntm : MultiTapeNTM k Bool State} {w : List Bool} {S : ℕ} (hs : ntm.RunsInSpace w S) {s : Runtime} (h : RunState w s) :
                                                                    (encRuntime s).length ≤ sizeConst k State * (S + w.length.log2 + 1) ^ 2

                                                                    The states of a run have O((S + log₂ n + 1) ^ 2) bits, for a machine within space S.

                                                                    The parts of the machine in linear space #

                                                                    The value of the source of the pending call, within a budget.

                                                                    Whether the recursion has returned, within a budget.

                                                                    The input position to read, in space linear in the state.

                                                                    theorem Turing.MultiTapeNTM.SquareSavitch.initRound_budget {k : ℕ} {State : Type} [Fintype State] (ntm : MultiTapeNTM k Bool State) {α : Type} {enc : α ↪ List Bool} {S : α → ℕ} {mode : α → Bool} {B n : α → ℕ} (hmode : MultiTapeTM.ComputableInSpace mode enc MultiTapeTM.encBool S) (hB : MultiTapeTM.ComputableInSpace B enc MultiTapeTM.encNat S) (hn : MultiTapeTM.ComputableInSpace n enc MultiTapeTM.encNat S) (hin : MultiTapeTM.BigOLe (fun (a : α) => (enc a).length) S) :
                                                                    MultiTapeTM.ComputableInSpace (fun (a : α) => initRound ntm (mode a) (B a) (n a)) enc (Cslib.Reachability.Savitch.encRound encParam) S

                                                                    The first state of a round, from the mode, the radix and the input length, within a budget.

                                                                    theorem Turing.MultiTapeNTM.SquareSavitch.startRadix_budget {State : Type} [Fintype State] {α : Type} {enc : α ↪ List Bool} {S n : α → ℕ} (hn : MultiTapeTM.ComputableInSpace n enc MultiTapeTM.encNat S) (hin : MultiTapeTM.BigOLe (fun (a : α) => (enc a).length) S) :

                                                                    The first radix, within a budget.

                                                                    theorem Turing.MultiTapeNTM.exists_decidableInTimeAndSpace_sq {α : Type} {enc : α ↪ List Bool} {A : Set α} {k : ℕ} {State : Type} [Finite State] {ntm : MultiTapeNTM k Bool State} {S : α → ℕ} (hA : ntm.RecognizesInSpace enc A S) :
                                                                    ∃ (t : α → ℕ) (c : ℕ), MultiTapeTM.DecidableInTimeAndSpace A enc t fun (a : α) => c * (S a + (enc a).length.log2 + 1) ^ 2

                                                                    Savitch's theorem [Sav70], for general space bounds. No constructibility is assumed: the machine tries growing bounds, as in Sipser's proof of Theorem 8.5 [Sip13]. A problem recognized by a nondeterministic machine whose computation paths on enc a visit at most S a work cells, and whose branches need not halt, is decided by a deterministic machine within space O((S a + log₂ |enc a| + 1) ^ 2): Savitch's midpoint recursion on the compact configuration graphs of the machine of growing radix (Turing.MultiTapeNTM.SquareSavitch.machine).