Documentation

Complexitylib.Models.TuringMachine

Turing machines #

This file defines the library's base model of computation: multi-tape deterministic and nondeterministic Turing machines over a fixed four-symbol alphabet, with named input/work/output tapes. The model's shape follows Arora–Barak (Computational Complexity: A Modern Approach, Definitions 1.1–1.4 and 2.1), with the conventions below enforced structurally.

Main definitions #

Design notes #

inductive Complexity.Γ :

The tape alphabet Γ = {0, 1, □, ▷}.

Instances For
    @[implicit_reducible]
    Equations
    @[implicit_reducible]
    Equations
    inductive Complexity.Γw :

    The writable alphabet Γw = {0, 1, □}. The start symbol cannot be written by a transition function — this is enforced structurally by using Γw in the output of δ.

    Instances For
      @[implicit_reducible]
      Equations
      @[implicit_reducible]
      Equations
      @[implicit_reducible]
      Equations

      A writable symbol is never the left-end marker.

      Convert a boolean to an alphabet symbol.

      Equations
      Instances For

        A Boolean tape symbol is never the left-end marker.

        A Boolean tape symbol is never blank.

        Three-way tape head direction: left, right, or stay.

        Instances For
          @[implicit_reducible]
          Equations

          A one-sided infinite tape. Cell 0 is the leftmost cell and permanently contains . The head cannot move left of cell 0 (moving left at position 0 is a no-op via Nat subtraction). Writing at cell 0 is a no-op, preserving .

          • head :

            The head position; cell 0 is the leftmost cell.

          • cells : Γ

            The tape contents, one symbol per cell.

          Instances For
            theorem Complexity.Tape.ext {x y : Tape} (head : x.head = y.head) (cells : x.cells = y.cells) :
            x = y

            Read the symbol under the head.

            Equations
            Instances For

              Write a symbol at the head position. Writing at cell 0 is a no-op, preserving the start symbol .

              Equations
              Instances For
                theorem Complexity.Tape.write_head (t : Tape) (s : Γ) :
                (t.write s).head = t.head

                Writing changes tape contents but preserves the head position.

                Move the head according to a three-way direction. Moving left at position 0 stays at 0 (Nat subtraction saturates).

                Equations
                Instances For
                  theorem Complexity.Tape.move_cells (t : Tape) (d : Dir3) :
                  (t.move d).cells = t.cells

                  Moving changes the head position but preserves tape contents.

                  theorem Complexity.Tape.head_move_le (t : Tape) (d : Dir3) :
                  (t.move d).head t.head + 1

                  Moving changes the head position by at most one.

                  The tape contains output y : List Bool starting at cell 1: cells 1 through |y| match y, and cell |y| + 1 is blank. Output is the binary string written on the output tape after .

                  Equations
                  Instances For
                    theorem Complexity.Tape.hasOutput_congr {t₁ t₂ : Tape} (h : t₁.cells = t₂.cells) (y : List Bool) :
                    t₁.HasOutput y t₂.HasOutput y

                    HasOutput depends only on the tape cells, not the head position.

                    @[implicit_reducible]
                    Equations
                    @[reducible, inline]
                    abbrev Complexity.Tape.writeAndMove (t : Tape) (s : Γ) (d : Dir3) :

                    Write a symbol and move in one step.

                    Equations
                    Instances For

                      t.StartInvariant says the left-end marker sits at cell 0 and nowhere else — the standing shape of every tape reachable from an initial configuration, since writes exclude and cell 0 is immutable.

                      Equations
                      Instances For

                        Under the invariant, a head at position ≥ 1 never reads .

                        Writing (any Γw symbol) preserves the invariant.

                        Moving preserves the invariant (cells unchanged).

                        Writing a Γw symbol and moving preserves the invariant.

                        theorem Complexity.Tape.head_writeAndMove_le (t : Tape) (s : Γ) (d : Dir3) :
                        (t.writeAndMove s d).head t.head + 1

                        One write-and-move step advances the head by at most one.

                        def Complexity.Tape.init (contents : List Γ) :

                        Initialize a tape: at cell 0, contents at cells 1, 2, ..., elsewhere. Head starts at position 0 (on ).

                        Equations
                        Instances For
                          @[simp]
                          theorem Complexity.Tape.init_head (contents : List Γ) :
                          (init contents).head = 0

                          An initialized tape starts with its head on the left-end marker.

                          @[simp]
                          theorem Complexity.Tape.init_cells_zero (contents : List Γ) :
                          (init contents).cells 0 = Γ.start

                          Cell zero of an initialized tape is the left-end marker.

                          theorem Complexity.Tape.init_cells_succ (contents : List Γ) (i : ) :
                          (init contents).cells (i + 1) = contents[i]?.getD Γ.blank

                          Cell i + 1 of an initialized tape contains item i, or blank when i lies beyond the initialized contents.

                          theorem Complexity.Tape.init_cells_ge (contents : List Γ) (i : ) (h : contents.length i) :
                          (init contents).cells (i + 1) = Γ.blank

                          Cells beyond the initialized contents are blank.

                          @[simp]

                          Every positive-indexed cell of the empty initialized tape is blank.

                          No positive-indexed cell of the empty initialized tape is a start marker.

                          theorem Complexity.Tape.init_ofBool_cells_lt (contents : List Bool) (i : ) (h : i < contents.length) :
                          (init (List.map Γ.ofBool contents)).cells (i + 1) = Γ.ofBool contents[i]

                          Within the initialized Boolean contents, cell i + 1 stores bit i.

                          theorem Complexity.Tape.init_ofBool_cells_ge (contents : List Bool) (i : ) (h : contents.length i) :
                          (init (List.map Γ.ofBool contents)).cells (i + 1) = Γ.blank

                          Beyond the initialized Boolean contents, cell i + 1 is blank.

                          theorem Complexity.Tape.init_ofBool_cells_ne_start (contents : List Bool) (j : ) (hj : 1 j) :

                          No positive-indexed cell of a Boolean-initialized tape contains the left-end marker.

                          @[simp]

                          Moving an empty initialized tape to cell one reads blank.

                          A Boolean-initialized tape moved to its first data cell never reads the left-end marker.

                          theorem Complexity.Tape.StartInvariant.init (xs : List Γ) (hxs : axs, a Γ.start) :

                          An initialized tape whose contents avoid satisfies the invariant.

                          A Boolean-initialized tape satisfies the invariant.

                          The empty initialized tape satisfies the invariant.

                          After stepping onto cell 1 of an empty initialized tape, no positive cell holds the left-end marker.

                          Moving the head does not introduce a left-end marker in the positive cells of a Boolean-initialized tape.

                          @[reducible, inline]

                          A language is a set of binary strings.

                          Equations
                          Instances For
                            structure Complexity.Cfg (n : ) (Q : Type) :

                            A configuration of a Turing machine with n work tapes: a read-only input tape, n read-write work tapes, and a read-write output tape.

                            • state : Q

                              The current machine state.

                            • input : Tape

                              The read-only input tape.

                            • work : Fin nTape

                              The n read-write work tapes.

                            • output : Tape

                              The read-write output tape.

                            Instances For
                              @[reducible, inline]
                              abbrev Complexity.Cfg.init {Q : Type} {n : } (qstart : Q) (x : List Bool) :
                              Cfg n Q

                              Initial configuration for any TM: input on the input tape, all tapes start with .

                              Equations
                              • One or more equations did not get rendered due to their size.
                              Instances For
                                @[reducible, inline]
                                abbrev Complexity.Cfg.isHalted {Q : Type} {n : } (qhalt : Q) (c : Cfg n Q) :

                                A configuration is halted when its state equals the halt state.

                                Equations
                                Instances For
                                  def Complexity.Cfg.WithinAuxSpace {n : } {Q : Type} (c : Cfg n Q) (inputLength space : ) :

                                  The auxiliary-space bound for a configuration on an input of length inputLength. Work-tape cells through space are available, while the input itself and its first trailing blank are free; travel farther into the input tape's blank tail is charged against space.

                                  This predicate deliberately omits the output tape. It is suitable for function computation only when the machine also satisfies the one-way output discipline TM.IsTransducer.

                                  Equations
                                  Instances For
                                    def Complexity.Cfg.WithinDecisionSpace {n : } {Q : Type} (c : Cfg n Q) (inputLength space : ) :

                                    The space bound for a language-decider configuration. In addition to WithinAuxSpace, the output head is bounded by space + 1: cell 1 is the free verdict cell, and any farther two-way output-tape travel is charged.

                                    Equations
                                    Instances For
                                      structure Complexity.TM (n : ) :

                                      A deterministic Turing machine with n work tapes.

                                      The machine has a read-only input tape, n read-write work tapes, and a read-write output tape. The transition function reads Γ from all tape heads but writes only Γw (excluding ) to work and output tapes. Q is finite.

                                      • Q : Type

                                        The (finite) type of machine states.

                                      • decEq : DecidableEq self.Q
                                      • finQ : Fintype self.Q
                                      • qstart : self.Q

                                        The designated start state.

                                      • qhalt : self.Q

                                        The designated halt state.

                                      • δ : self.QΓ(Fin nΓ)Γself.Q × (Fin nΓw) × Γw × Dir3 × (Fin nDir3) × Dir3

                                        The transition function: from the current state and the symbols under the input, work, and output heads, produce the next state, the symbols to write on the work and output tapes, and a direction for every head.

                                      • δ_right_of_start (q : self.Q) (iHead : Γ) (wHeads : Fin nΓ) (oHead : Γ) : match self.δ q iHead wHeads oHead with | (fst, fst_1, fst_2, inDir, workDirs, outDir) => (iHead = Γ.startinDir = Dir3.right) (∀ (i : Fin n), wHeads i = Γ.startworkDirs i = Dir3.right) (oHead = Γ.startoutDir = Dir3.right)

                                        Reading the left-end marker forces that head to move right, so no head ever falls off the left edge.

                                      Instances For
                                        structure Complexity.NTM (n : ) :

                                        A nondeterministic Turing machine with two transition functions.

                                        The same structure is used for probabilistic TMs — only the acceptance criterion differs (existential for NTM, counting for PTM). Q is finite.

                                        Instances For
                                          def Complexity.TM.step {n : } (tm : TM n) (c : Cfg n tm.Q) :
                                          Option (Cfg n tm.Q)

                                          Step a deterministic TM by one step. Returns none if halted.

                                          Equations
                                          • One or more equations did not get rendered due to their size.
                                          Instances For
                                            @[reducible, inline]
                                            abbrev Complexity.TM.initCfg {n : } (tm : TM n) (x : List Bool) :
                                            Cfg n tm.Q

                                            Initial configuration: input on the input tape, all tapes start with .

                                            Equations
                                            Instances For
                                              @[reducible, inline]
                                              abbrev Complexity.TM.halted {n : } (tm : TM n) (c : Cfg n tm.Q) :

                                              A configuration is halted when its state is qhalt.

                                              Equations
                                              Instances For
                                                theorem Complexity.TM.state_ne_qhalt_of_step {n : } {tm : TM n} {c c' : Cfg n tm.Q} (h : tm.step c = some c') :

                                                If step returns some, the machine was not halted.

                                                def Complexity.TM.stepRel {n : } (tm : TM n) (c c' : Cfg n tm.Q) :

                                                One-step relation for a deterministic TM.

                                                Equations
                                                Instances For
                                                  def Complexity.TM.reaches {n : } (tm : TM n) :
                                                  Cfg n tm.QCfg n tm.QProp

                                                  Reflexive-transitive closure of the step relation.

                                                  Equations
                                                  Instances For
                                                    inductive Complexity.TM.reachesIn {n : } (tm : TM n) :
                                                    Cfg n tm.QCfg n tm.QProp

                                                    Reachability in exactly t steps.

                                                    Instances For
                                                      def Complexity.TM.Accepts {n : } (tm : TM n) (x : List Bool) :

                                                      DTM accepts x: reaches qhalt with output cell 1 (after ) = 1.

                                                      Equations
                                                      Instances For
                                                        def Complexity.TM.AcceptsInTime {n : } (tm : TM n) (x : List Bool) (T : ) :

                                                        DTM accepts x within T steps.

                                                        Equations
                                                        Instances For
                                                          def Complexity.TM.DecidesInTime {n : } (tm : TM n) (L : Language) (T : ) :

                                                          DTM decides L within time bound T(n): halts on all inputs within T(|x|) steps, outputting 1 for x ∈ L and 0 for x ∉ L.

                                                          Equations
                                                          • One or more equations did not get rendered due to their size.
                                                          Instances For
                                                            def Complexity.TM.ComputesInTime {n : } (tm : TM n) (f : List BoolList Bool) (T : ) :

                                                            DTM computes function f in time T(n): for every input x, the machine halts within T(|x|) steps with f(x) written on the output tape.

                                                            Equations
                                                            Instances For
                                                              def Complexity.TM.Computes {n : } (tm : TM n) (f : List BoolList Bool) :

                                                              DTM computes function f (existential version of ComputesInTime).

                                                              Equations
                                                              Instances For
                                                                def Complexity.TM.DecidesInSpace {n : } (tm : TM n) (L : Language) (S : ) :

                                                                DTM decides L using at most S(|x|) auxiliary space. Every reachable configuration has work heads at position at most S(|x|), input head at position at most |x| + S(|x|) + 1, and output head at position at most S(|x|) + 1. Thus the input region, its first trailing blank, and output verdict cell 1 are free, but neither infinite tape can become uncharged two-way workspace. The machine halts on all inputs with correct output.

                                                                Equations
                                                                • One or more equations did not get rendered due to their size.
                                                                Instances For
                                                                  def Complexity.TM.DecidesInTimeSpace {n : } (tm : TM n) (L : Language) (T S : ) :

                                                                  DTM decides L within time T(|x|) and space S(|x|) simultaneously: a single machine halts in bounded time with correct output, and every reachable configuration satisfies the honest auxiliary-space convention of Cfg.WithinDecisionSpace.

                                                                  Equations
                                                                  • One or more equations did not get rendered due to their size.
                                                                  Instances For

                                                                    The output tape head never moves left — the machine is a transducer. This prevents earlier output from being reread as workspace while allowing unbounded output length. ComputesInSpace requires this discipline; the decision-space predicates separately bound two-way output-head travel.

                                                                    Equations
                                                                    • One or more equations did not get rendered due to their size.
                                                                    Instances For
                                                                      def Complexity.TM.ComputesInSpace {n : } (tm : TM n) (f : List BoolList Bool) (S : ) :

                                                                      DTM computes function f using at most S(|x|) auxiliary space. Work-tape travel and input-head travel beyond the input's first trailing blank are bounded by Cfg.WithinAuxSpace. The output length is not bounded: instead, IsTransducer makes the output one-way so it cannot serve as read-write workspace.

                                                                      Equations
                                                                      • One or more equations did not get rendered due to their size.
                                                                      Instances For
                                                                        theorem Complexity.TM.reachesIn_trans {n : } (tm : TM n) {t₁ t₂ : } {c₁ c₂ c₃ : Cfg n tm.Q} (h₁ : tm.reachesIn t₁ c₁ c₂) (h₂ : tm.reachesIn t₂ c₂ c₃) :
                                                                        tm.reachesIn (t₁ + t₂) c₁ c₃

                                                                        Transitivity: if c₁ reaches c₂ in t₁ steps and c₂ reaches c₃ in t₂ steps, then c₁ reaches c₃ in t₁ + t₂ steps.

                                                                        theorem Complexity.TM.reaches_of_reachesIn {n : } {tm : TM n} {t : } {c c' : Cfg n tm.Q} (h : tm.reachesIn t c c') :
                                                                        tm.reaches c c'

                                                                        Bounded reachability implies unbounded reachability.

                                                                        theorem Complexity.TM.accepts_of_acceptsInTime {n : } {tm : TM n} {x : List Bool} {T : } (h : tm.AcceptsInTime x T) :
                                                                        tm.Accepts x

                                                                        AcceptsInTime implies Accepts — forget the time bound.

                                                                        theorem Complexity.TM.AcceptsInTime.mono {n : } {tm : TM n} {x : List Bool} {T T' : } (hle : T T') (h : tm.AcceptsInTime x T) :

                                                                        DTM acceptance is monotone in the time bound.

                                                                        theorem Complexity.TM.DecidesInTime.mono {n : } {tm : TM n} {L : Language} {T T' : } (hle : ∀ (m : ), T m T' m) (h : tm.DecidesInTime L T) :

                                                                        DTM decision is monotone under pointwise enlargement of the time bound.

                                                                        theorem Complexity.TM.ComputesInTime.mono {n : } {tm : TM n} {f : List BoolList Bool} {T T' : } (hle : ∀ (m : ), T m T' m) (h : tm.ComputesInTime f T) :

                                                                        DTM computation is monotone under pointwise enlargement of the time bound.

                                                                        def Complexity.NTM.trace {n : } (tm : NTM n) (T : ) :
                                                                        (Fin TBool)Cfg n tm.QCfg n tm.Q

                                                                        Execute an NTM for T steps with a fixed choice sequence. Stops early if the machine reaches qhalt.

                                                                        Equations
                                                                        • One or more equations did not get rendered due to their size.
                                                                        • tm.trace 0 x_3 x✝ = x✝
                                                                        Instances For
                                                                          @[reducible, inline]
                                                                          abbrev Complexity.NTM.initCfg {n : } (tm : NTM n) (x : List Bool) :
                                                                          Cfg n tm.Q

                                                                          Initial configuration: input on the input tape, all tapes start with .

                                                                          Equations
                                                                          Instances For
                                                                            @[reducible, inline]
                                                                            abbrev Complexity.NTM.halted {n : } (tm : NTM n) (c : Cfg n tm.Q) :

                                                                            A configuration is halted when its state is qhalt.

                                                                            Equations
                                                                            Instances For
                                                                              theorem Complexity.NTM.trace_halted {n : } (tm : NTM n) {c : Cfg n tm.Q} (T : ) (choices : Fin TBool) (h : tm.halted c) :
                                                                              tm.trace T choices c = c

                                                                              Once halted, the NTM trace stays at the same configuration regardless of the remaining choices.

                                                                              def Complexity.NTM.Accepts {n : } (tm : NTM n) (x : List Bool) :

                                                                              NTM accepts x: there exists a time bound and choice sequence leading to qhalt with output cell 1 = 1.

                                                                              Equations
                                                                              Instances For
                                                                                def Complexity.NTM.AcceptsInTime {n : } (tm : NTM n) (x : List Bool) (T : ) :

                                                                                NTM accepts x within T steps: there exists a choice sequence of length T leading to qhalt with output cell 1 = 1.

                                                                                Equations
                                                                                Instances For
                                                                                  theorem Complexity.NTM.accepts_of_acceptsInTime {n : } {tm : NTM n} {x : List Bool} {T : } (h : tm.AcceptsInTime x T) :
                                                                                  tm.Accepts x

                                                                                  AcceptsInTime implies Accepts — package the time bound existentially.

                                                                                  theorem Complexity.NTM.accepts_iff_exists_acceptsInTime {n : } {tm : NTM n} {x : List Bool} :
                                                                                  tm.Accepts x ∃ (T : ), tm.AcceptsInTime x T

                                                                                  Accepts is exactly ∃ T, AcceptsInTime x T.

                                                                                  theorem Complexity.NTM.trace_mono {n : } (tm : NTM n) {T T' : } (hle : T T') {choices : Fin TBool} {choices' : Fin T'Bool} {c : Cfg n tm.Q} (hagree : ∀ (i : Fin T), choices' i, = choices i) (h : tm.halted (tm.trace T choices c)) :
                                                                                  tm.trace T' choices' c = tm.trace T choices c

                                                                                  Running the NTM trace for more steps preserves the final configuration: if the machine halts within T steps and the extended choice sequence agrees with the original on the first T positions, the extra steps are no-ops.

                                                                                  theorem Complexity.NTM.AcceptsInTime.mono {n : } {tm : NTM n} {x : List Bool} {T T' : } (hle : T T') (h : tm.AcceptsInTime x T) :

                                                                                  NTM acceptance is monotone in the time bound: AcceptsInTime x T implies AcceptsInTime x T' for any T' ≥ T. Extra steps are no-ops once halted.

                                                                                  def Complexity.NTM.AllPathsHaltIn {n : } (tm : NTM n) (T : ) :

                                                                                  All computation paths of the NTM halt within T(|x|) steps, for every input x and every choice sequence. This is the core time-boundedness condition shared by DecidesInTime, BPTIME, and NTM.IsPPT.

                                                                                  Equations
                                                                                  Instances For
                                                                                    def Complexity.NTM.DecidesInTime {n : } (tm : NTM n) (L : Language) (T : ) :

                                                                                    NTM decides L within time bound T(n): all computation paths halt within T(|x|) steps, and accepting paths exist iff x ∈ L (AB Definition 2.1).

                                                                                    Equations
                                                                                    Instances For
                                                                                      theorem Complexity.NTM.AllPathsHaltIn.mono {n : } {tm : NTM n} {T T' : } (hle : ∀ (m : ), T m T' m) (h : tm.AllPathsHaltIn T) :

                                                                                      All-paths halting is monotone in the time bound: once halted, the extra steps are no-ops.

                                                                                      theorem Complexity.NTM.acceptsInTime_of_le_of_allPathsHaltIn {n : } {tm : NTM n} {T T' : } {x : List Bool} (hle : ∀ (m : ), T m T' m) (hN : tm.AllPathsHaltIn T) (h : tm.AcceptsInTime x (T' x.length)) :

                                                                                      With all paths halting within T, timed acceptance transfers DOWN from any pointwise-larger bound: by T(|x|) every path is already frozen.

                                                                                      theorem Complexity.NTM.DecidesInTime.mono {n : } {tm : NTM n} {L : Language} {T T' : } (hle : ∀ (m : ), T m T' m) (h : tm.DecidesInTime L T) :

                                                                                      Deciding within T transfers to any pointwise-larger bound T': halting is monotone, and acceptance transfers both ways (up by monotonicity, down by the all-paths-halt freeze).

                                                                                      noncomputable def Complexity.NTM.acceptCount {n : } (tm : NTM n) (x : List Bool) (T : ) :

                                                                                      Count of accepting choice sequences of length T.

                                                                                      Meaningful when the machine halts on all paths within T steps — use in conjunction with NTM.DecidesInTime or an explicit all-paths-halt hypothesis.

                                                                                      Equations
                                                                                      Instances For
                                                                                        noncomputable def Complexity.NTM.acceptProb {n : } (tm : NTM n) (x : List Bool) (T : ) :

                                                                                        Acceptance probability = |accepting paths| / 2^T.

                                                                                        Meaningful when the machine halts on all paths within T steps.

                                                                                        Equations
                                                                                        Instances For
                                                                                          noncomputable def Complexity.NTM.outputCount {n : } (tm : NTM n) (x : List Bool) (T : ) (y : List Bool) :

                                                                                          Count of choice sequences of length T on which the machine halts with output y (using Tape.HasOutput).

                                                                                          Meaningful when the machine halts on all paths within T steps.

                                                                                          Equations
                                                                                          Instances For
                                                                                            noncomputable def Complexity.NTM.outputProb {n : } (tm : NTM n) (x : List Bool) (T : ) (y : List Bool) :

                                                                                            Probability that the machine outputs y on input x = |output-matching paths| / 2^T.

                                                                                            Meaningful when the machine halts on all paths within T steps. This generalizes acceptProb from accept/reject to arbitrary output strings, as needed for cryptographic definitions.

                                                                                            Equations
                                                                                            Instances For
                                                                                              def Complexity.NTM.DecidesInSpace {n : } (tm : NTM n) (L : Language) (S : ) :

                                                                                              NTM decides L using at most S(|x|) auxiliary space. Every intermediate configuration on every path obeys Cfg.WithinDecisionSpace: work heads are bounded by S, the finite input plus first blank is free but farther input travel is charged, and only output verdict cell 1 is free. There exists a time bound within which all paths halt and decide correctly.

                                                                                              Equations
                                                                                              • One or more equations did not get rendered due to their size.
                                                                                              Instances For

                                                                                                The output tape head never moves left — the machine is a transducer. This prevents earlier output from being reread as workspace while allowing unbounded output length. Decision-space predicates separately bound two-way output-head travel.

                                                                                                Equations
                                                                                                • One or more equations did not get rendered due to their size.
                                                                                                Instances For
                                                                                                  def Complexity.TM.toNTM {n : } (tm : TM n) :
                                                                                                  NTM n

                                                                                                  Embed a DTM into an NTM by using the same transition for both choices.

                                                                                                  Equations
                                                                                                  Instances For