Documentation

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

Nondeterministic query machines #

A query machine with one binary nondeterministic choice per step. An abstract state can be infinite; it is data to be encoded on work tapes, rather than native finite control. The input is read by position, with none returned beyond its end. Halted states self-loop.

Finite lists of choices describe paths at the proof level. They are not additional inputs or work tapes of the machine. Acceptance requires both halting and an accepting state.

Main definitions #

Main results #

References #

A decision-only query machine with one binary nondeterministic choice per step.

  • init : σ

    The initial state.

  • query : σ → ℕ

    The queried input position.

  • next : σ × Option Bool × Bool → σ

    The next state, given the current state, input answer and nondeterministic choice.

  • halted : σ → Bool

    Whether the state has halted.

  • accept : σ → Bool

    Whether a halted state accepts. This field is ignored before halting.

Instances For

    The input answer, none past the end of the input.

    Instances For
      def Turing.NondeterministicQueryMachine.step {σ : Type u_1} (M : NondeterministicQueryMachine σ) (input : List Bool) (s : σ) (choice : Bool) :
      σ

      A step selected by one choice; halted states are fixed.

      Instances For
        @[reducible, inline]

        The existential one-step relation, including halted self-loops.

        Instances For
          def Turing.NondeterministicQueryMachine.replay {σ : Type u_1} (M : NondeterministicQueryMachine σ) (input choices : List Bool) (s : σ) :
          σ

          Replay a finite sequence of choices from a supplied state.

          Instances For

            Run from the initial state with a finite sequence of choices.

            Instances For
              @[reducible, inline]

              Finite paths of the abstract step relation.

              Instances For

                A state reached by some finite branch.

                Instances For

                  Some finite branch halts and accepts.

                  Instances For

                    Every branch of exactly t abstract steps has halted.

                    Instances For

                      The same machine started in s. The compiler uses it to start each input in its own state.

                      Instances For
                        theorem Turing.NondeterministicQueryMachine.run_withInit {σ : Type u_1} (M : NondeterministicQueryMachine σ) (input : List Bool) (s : σ) (choices : List Bool) :
                        (M.withInit s).run input choices = M.replay input choices s
                        @[simp]
                        theorem Turing.NondeterministicQueryMachine.replay_nil {σ : Type u_1} (M : NondeterministicQueryMachine σ) (input : List Bool) (s : σ) :
                        M.replay input [] s = s
                        theorem Turing.NondeterministicQueryMachine.replay_cons {σ : Type u_1} (M : NondeterministicQueryMachine σ) (input : List Bool) (choice : Bool) (choices : List Bool) (s : σ) :
                        M.replay input (choice :: choices) s = M.replay input choices (M.step input s choice)
                        theorem Turing.NondeterministicQueryMachine.replay_append {σ : Type u_1} (M : NondeterministicQueryMachine σ) (input choices more : List Bool) (s : σ) :
                        M.replay input (choices ++ more) s = M.replay input more (M.replay input choices s)
                        theorem Turing.NondeterministicQueryMachine.run_append {σ : Type u_1} (M : NondeterministicQueryMachine σ) (input choices more : List Bool) :
                        M.run input (choices ++ more) = M.replay input more (M.run input choices)
                        theorem Turing.NondeterministicQueryMachine.step_of_halted {σ : Type u_1} (M : NondeterministicQueryMachine σ) (input : List Bool) {s : σ} (h : M.halted s = true) (choice : Bool) :
                        M.step input s choice = s
                        theorem Turing.NondeterministicQueryMachine.replay_of_halted {σ : Type u_1} (M : NondeterministicQueryMachine σ) (input : List Bool) {s : σ} (h : M.halted s = true) (choices : List Bool) :
                        M.replay input choices s = s

                        After halting, every further choice is ignored.

                        theorem Turing.NondeterministicQueryMachine.run_append_of_halted {σ : Type u_1} (M : NondeterministicQueryMachine σ) (input : List Bool) {choices : List Bool} (h : M.halted (M.run input choices) = true) (more : List Bool) :
                        M.run input (choices ++ more) = M.run input choices
                        theorem Turing.NondeterministicQueryMachine.exists_runPath_iff {σ : Type u_1} (M : NondeterministicQueryMachine σ) (input : List Bool) {s s' : σ} {n : ℕ} :
                        (∃ (p : M.RunPath input), RelSeries.head p = s ∧ p.length = n ∧ RelSeries.last p = s') ↔ ∃ (choices : List Bool), choices.length = n ∧ M.replay input choices s = s'

                        Every finite relational path is a choice replay of the same length, and conversely.

                        theorem Turing.NondeterministicQueryMachine.Reachable.step {σ : Type u_1} (M : NondeterministicQueryMachine σ) (input : List Bool) {s : σ} (h : M.Reachable input s) (choice : Bool) :
                        M.Reachable input (M.step input s choice)
                        theorem Turing.NondeterministicQueryMachine.HaltsWithin.mono {σ : Type u_1} (M : NondeterministicQueryMachine σ) (input : List Bool) {t t' : ℕ} (h : M.HaltsWithin input t) (ht : t ≤ t') :
                        M.HaltsWithin input t'

                        A common all-branches clock also bounds every longer branch.

                        theorem Turing.NondeterministicQueryMachine.accepts_iff_length {σ : Type u_1} (M : NondeterministicQueryMachine σ) (input : List Bool) {t : ℕ} (h : M.HaltsWithin input t) :
                        M.Accepts input ↔ ∃ (choices : List Bool), choices.length = t ∧ M.accept (M.run input choices) = true

                        Acceptance can be tested at the common clock: short branches are padded by halted self-loops, and longer branches already halted at the clock. The padding is proof-level data only.

                        theorem Turing.NondeterministicQueryMachine.run_take_of_haltsWithin {σ : Type u_1} (M : NondeterministicQueryMachine σ) (input : List Bool) {t : ℕ} (h : M.HaltsWithin input t) (choices : List Bool) :
                        M.run input (List.take t choices) = M.run input choices

                        A branch longer than the common clock has the same state as its clock-length prefix.

                        theorem Turing.NondeterministicQueryMachine.exists_bound_on_reachable {σ : Type u_1} (M : NondeterministicQueryMachine σ) (input : List Bool) {t : ℕ} (h : M.HaltsWithin input t) (cost : σ → ℕ) :
                        ∃ (bound : ℕ), ∀ (s : σ), M.Reachable input s → cost s ≤ bound

                        Any total local runtime has a common finite bound on all reachable states of an abstract machine with an all-branches clock. This maximum is proof-level data: it need not be computed by the simulator, encoded in a state, or stored on a tape.

                        Every branch of t steps from the supplied abstract state has halted.

                        Instances For
                          theorem Turing.NondeterministicQueryMachine.haltsFrom_of_reachable {σ : Type u_1} (M : NondeterministicQueryMachine σ) (input : List Bool) {t : ℕ} (h : M.HaltsWithin input t) {s : σ} (hs : M.Reachable input s) :
                          M.HaltsFrom input s t

                          A clock for the initial state is also a clock from every reachable state. The extra history only makes the complete branch longer than the original clock.

                          noncomputable def Turing.NondeterministicQueryMachine.remainingSteps {σ : Type u_1} (M : NondeterministicQueryMachine σ) (input : List Bool) (s : σ) :

                          The least all-branches halting clock from a state, or zero when no such clock exists. This is a ghost ranking function, not a counter stored by the native simulator.

                          Instances For
                            theorem Turing.NondeterministicQueryMachine.remainingSteps_spec {σ : Type u_1} (M : NondeterministicQueryMachine σ) (input : List Bool) {s : σ} (h : ∃ (t : ℕ), M.HaltsFrom input s t) :
                            M.HaltsFrom input s (M.remainingSteps input s)
                            theorem Turing.NondeterministicQueryMachine.remainingSteps_le {σ : Type u_1} (M : NondeterministicQueryMachine σ) (input : List Bool) {s : σ} {t : ℕ} (h : M.HaltsFrom input s t) :
                            M.remainingSteps input s ≤ t
                            theorem Turing.NondeterministicQueryMachine.remainingSteps_pos {σ : Type u_1} (M : NondeterministicQueryMachine σ) (input : List Bool) {s : σ} (h : ∃ (t : ℕ), M.HaltsFrom input s t) (hs : M.halted s = false) :
                            0 < M.remainingSteps input s
                            theorem Turing.NondeterministicQueryMachine.remainingSteps_step_lt {σ : Type u_1} (M : NondeterministicQueryMachine σ) (input : List Bool) {s : σ} (h : ∃ (t : ℕ), M.HaltsFrom input s t) (hs : M.halted s = false) (choice : Bool) :
                            M.remainingSteps input (M.step input s choice) < M.remainingSteps input s

                            The ghost clock strictly decreases on every branch from a running state. The native machine can therefore be proved terminating without computing or storing any runtime maximum.

                            Reusing the deterministic input pass #

                            Fixing the choice gives a deterministic query machine. This does not enumerate choices or store a witness: it supplies either of the two local transition routines.

                            Instances For
                              theorem Turing.NondeterministicQueryMachine.step_withChoice {σ : Type u_1} (M : NondeterministicQueryMachine σ) (input : List Bool) (choice : Bool) (s : σ) :
                              (M.withChoice choice).step input s = M.step input s choice

                              The deterministic input scan fetches exactly the abstract query answer.

                              The end of a deterministic pass performs the selected nondeterministic abstract step and resets the position counter and fetched answer.

                              Local computation and space bounds #

                              theorem Turing.NondeterministicQueryMachine.length_passState_le (input : List Bool) {σ : Type} {encS : σ ↪ List Bool} {s : σ} {j S c : ℕ} (hstate : (encS s).length ≤ c * S) (hlog : input.length.log2 + 1 ≤ S) (hj : j ≤ input.length) (answer : Option Bool) :
                              ((QueryMachine.Simulation.encPass encS) (s, j, answer)).length ≤ (2 * c + 6) * S

                              The encoded scan state fits in the abstract-state budget plus the binary input counter. This estimate is independent of the number of passes and of all earlier choices.

                              theorem Turing.NondeterministicQueryMachine.length_scanState_le (input : List Bool) {σ : Type} {encS : σ ↪ List Bool} {M : NondeterministicQueryMachine σ} {S c : ℕ} (hstate : ∀ (s : σ), M.Reachable input s → (encS s).length ≤ c * S) (hlog : input.length.log2 + 1 ≤ S) (choices : List Bool) {j : ℕ} (hj : j ≤ input.length) (answer : Option Bool) :
                              ((QueryMachine.Simulation.encPass encS) (M.run input choices, j, answer)).length ≤ (2 * c + 6) * S

                              Every abstract prefix state has the same space bound when the bound holds on reachable states. No choice history is included in the encoded state.