Documentation

Mathlib.Computability.Tape

Turing machine tapes #

This file defines the notion of a Turing machine tape, and the operations on it. A tape is a bidirectional infinite sequence of cells, each of which stores an element of a given alphabet Γ. All but finitely many of the cells are required to hold the blank symbol default : Γ.

Main definitions #

def Turing.BlankExtends {Γ : Type u_1} [Inhabited Γ] (l₁ l₂ : List Γ) :

The BlankExtends partial order holds of l₁ and l₂ if l₂ is obtained by adding blanks (default : Γ) to the end of l₁.

Equations
Instances For
    theorem Turing.BlankExtends.trans {Γ : Type u_1} [Inhabited Γ] {l₁ l₂ l₃ : List Γ} :
    Turing.BlankExtends l₁ l₂Turing.BlankExtends l₂ l₃Turing.BlankExtends l₁ l₃
    theorem Turing.BlankExtends.below_of_le {Γ : Type u_1} [Inhabited Γ] {l l₁ l₂ : List Γ} :
    Turing.BlankExtends l l₁Turing.BlankExtends l l₂l₁.length l₂.lengthTuring.BlankExtends l₁ l₂
    def Turing.BlankExtends.above {Γ : Type u_1} [Inhabited Γ] {l l₁ l₂ : List Γ} (h₁ : Turing.BlankExtends l l₁) (h₂ : Turing.BlankExtends l l₂) :
    { l' : List Γ // Turing.BlankExtends l₁ l' Turing.BlankExtends l₂ l' }

    Any two extensions by blank l₁,l₂ of l have a common join (which can be taken to be the longer of l₁ and l₂).

    Equations
    • h₁.above h₂ = if h : l₁.length l₂.length then l₂, else l₁,
    Instances For
      theorem Turing.BlankExtends.above_of_le {Γ : Type u_1} [Inhabited Γ] {l l₁ l₂ : List Γ} :
      Turing.BlankExtends l₁ lTuring.BlankExtends l₂ ll₁.length l₂.lengthTuring.BlankExtends l₁ l₂
      def Turing.BlankRel {Γ : Type u_1} [Inhabited Γ] (l₁ l₂ : List Γ) :

      BlankRel is the symmetric closure of BlankExtends, turning it into an equivalence relation. Two lists are related by BlankRel if one extends the other by blanks.

      Equations
      Instances For
        theorem Turing.BlankRel.refl {Γ : Type u_1} [Inhabited Γ] (l : List Γ) :
        theorem Turing.BlankRel.symm {Γ : Type u_1} [Inhabited Γ] {l₁ l₂ : List Γ} :
        Turing.BlankRel l₁ l₂Turing.BlankRel l₂ l₁
        theorem Turing.BlankRel.trans {Γ : Type u_1} [Inhabited Γ] {l₁ l₂ l₃ : List Γ} :
        Turing.BlankRel l₁ l₂Turing.BlankRel l₂ l₃Turing.BlankRel l₁ l₃
        def Turing.BlankRel.above {Γ : Type u_1} [Inhabited Γ] {l₁ l₂ : List Γ} (h : Turing.BlankRel l₁ l₂) :
        { l : List Γ // Turing.BlankExtends l₁ l Turing.BlankExtends l₂ l }

        Given two BlankRel lists, there exists (constructively) a common join.

        Equations
        • h.above = if hl : l₁.length l₂.length then l₂, else l₁,
        Instances For
          def Turing.BlankRel.below {Γ : Type u_1} [Inhabited Γ] {l₁ l₂ : List Γ} (h : Turing.BlankRel l₁ l₂) :
          { l : List Γ // Turing.BlankExtends l l₁ Turing.BlankExtends l l₂ }

          Given two BlankRel lists, there exists (constructively) a common meet.

          Equations
          • h.below = if hl : l₁.length l₂.length then l₁, else l₂,
          Instances For
            def Turing.BlankRel.setoid (Γ : Type u_1) [Inhabited Γ] :

            Construct a setoid instance for BlankRel.

            Equations
            Instances For
              def Turing.ListBlank (Γ : Type u_1) [Inhabited Γ] :
              Type u_1

              A ListBlank Γ is a quotient of List Γ by extension by blanks at the end. This is used to represent half-tapes of a Turing machine, so that we can pretend that the list continues infinitely with blanks.

              Equations
              Instances For
                @[reducible, inline]
                abbrev Turing.ListBlank.liftOn {Γ : Type u_1} [Inhabited Γ] {α : Sort u_2} (l : Turing.ListBlank Γ) (f : List Γα) (H : ∀ (a b : List Γ), Turing.BlankExtends a bf a = f b) :
                α

                A modified version of Quotient.liftOn' specialized for ListBlank, with the stronger precondition BlankExtends instead of BlankRel.

                Equations
                Instances For
                  def Turing.ListBlank.mk {Γ : Type u_1} [Inhabited Γ] :

                  The quotient map turning a List into a ListBlank.

                  Equations
                  Instances For
                    theorem Turing.ListBlank.induction_on {Γ : Type u_1} [Inhabited Γ] {p : Turing.ListBlank ΓProp} (q : Turing.ListBlank Γ) (h : ∀ (a : List Γ), p (Turing.ListBlank.mk a)) :
                    p q
                    def Turing.ListBlank.head {Γ : Type u_1} [Inhabited Γ] (l : Turing.ListBlank Γ) :
                    Γ

                    The head of a ListBlank is well defined.

                    Equations
                    Instances For
                      @[simp]
                      theorem Turing.ListBlank.head_mk {Γ : Type u_1} [Inhabited Γ] (l : List Γ) :
                      (Turing.ListBlank.mk l).head = l.headI

                      The tail of a ListBlank is well defined (up to the tail of blanks).

                      Equations
                      Instances For
                        @[simp]
                        theorem Turing.ListBlank.tail_mk {Γ : Type u_1} [Inhabited Γ] (l : List Γ) :
                        def Turing.ListBlank.cons {Γ : Type u_1} [Inhabited Γ] (a : Γ) (l : Turing.ListBlank Γ) :

                        We can cons an element onto a ListBlank.

                        Equations
                        Instances For
                          @[simp]
                          theorem Turing.ListBlank.head_cons {Γ : Type u_1} [Inhabited Γ] (a : Γ) (l : Turing.ListBlank Γ) :
                          @[simp]
                          theorem Turing.ListBlank.tail_cons {Γ : Type u_1} [Inhabited Γ] (a : Γ) (l : Turing.ListBlank Γ) :
                          @[simp]
                          theorem Turing.ListBlank.cons_head_tail {Γ : Type u_1} [Inhabited Γ] (l : Turing.ListBlank Γ) :
                          Turing.ListBlank.cons l.head l.tail = l

                          The cons and head/tail functions are mutually inverse, unlike in the case of List where this only holds for nonempty lists.

                          theorem Turing.ListBlank.exists_cons {Γ : Type u_1} [Inhabited Γ] (l : Turing.ListBlank Γ) :
                          ∃ (a : Γ) (l' : Turing.ListBlank Γ), l = Turing.ListBlank.cons a l'

                          The cons and head/tail functions are mutually inverse, unlike in the case of List where this only holds for nonempty lists.

                          def Turing.ListBlank.nth {Γ : Type u_1} [Inhabited Γ] (l : Turing.ListBlank Γ) (n : ) :
                          Γ

                          The n-th element of a ListBlank is well defined for all n : ℕ, unlike in a List.

                          Equations
                          • l.nth n = l.liftOn (fun (l : List Γ) => l.getI n)
                          Instances For
                            @[simp]
                            theorem Turing.ListBlank.nth_mk {Γ : Type u_1} [Inhabited Γ] (l : List Γ) (n : ) :
                            (Turing.ListBlank.mk l).nth n = l.getI n
                            @[simp]
                            theorem Turing.ListBlank.nth_zero {Γ : Type u_1} [Inhabited Γ] (l : Turing.ListBlank Γ) :
                            l.nth 0 = l.head
                            @[simp]
                            theorem Turing.ListBlank.nth_succ {Γ : Type u_1} [Inhabited Γ] (l : Turing.ListBlank Γ) (n : ) :
                            l.nth (n + 1) = l.tail.nth n
                            theorem Turing.ListBlank.ext {Γ : Type u_1} [i : Inhabited Γ] {L₁ L₂ : Turing.ListBlank Γ} :
                            (∀ (i_1 : ), L₁.nth i_1 = L₂.nth i_1)L₁ = L₂
                            def Turing.ListBlank.modifyNth {Γ : Type u_1} [Inhabited Γ] (f : ΓΓ) :

                            Apply a function to a value stored at the nth position of the list.

                            Equations
                            Instances For
                              theorem Turing.ListBlank.nth_modifyNth {Γ : Type u_1} [Inhabited Γ] (f : ΓΓ) (n i : ) (L : Turing.ListBlank Γ) :
                              (Turing.ListBlank.modifyNth f n L).nth i = if i = n then f (L.nth i) else L.nth i
                              structure Turing.PointedMap (Γ : Type u) (Γ' : Type v) [Inhabited Γ] [Inhabited Γ'] :
                              Type (max u v)

                              A pointed map of Inhabited types is a map that sends one default value to the other.

                              • f : ΓΓ'

                                The map underlying this instance.

                              • map_pt' : self.f default = default
                              Instances For
                                instance Turing.instInhabitedPointedMap {Γ : Type u_1} {Γ' : Type u_2} [Inhabited Γ] [Inhabited Γ'] :
                                Equations
                                instance Turing.instCoeFunPointedMapForall {Γ : Type u_1} {Γ' : Type u_2} [Inhabited Γ] [Inhabited Γ'] :
                                CoeFun (Turing.PointedMap Γ Γ') fun (x : Turing.PointedMap Γ Γ') => ΓΓ'
                                Equations
                                theorem Turing.PointedMap.mk_val {Γ : Type u_1} {Γ' : Type u_2} [Inhabited Γ] [Inhabited Γ'] (f : ΓΓ') (pt : f default = default) :
                                { f := f, map_pt' := pt }.f = f
                                @[simp]
                                theorem Turing.PointedMap.map_pt {Γ : Type u_1} {Γ' : Type u_2} [Inhabited Γ] [Inhabited Γ'] (f : Turing.PointedMap Γ Γ') :
                                @[simp]
                                theorem Turing.PointedMap.headI_map {Γ : Type u_1} {Γ' : Type u_2} [Inhabited Γ] [Inhabited Γ'] (f : Turing.PointedMap Γ Γ') (l : List Γ) :
                                (List.map f.f l).headI = f.f l.headI
                                def Turing.ListBlank.map {Γ : Type u_1} {Γ' : Type u_2} [Inhabited Γ] [Inhabited Γ'] (f : Turing.PointedMap Γ Γ') (l : Turing.ListBlank Γ) :

                                The map function on lists is well defined on ListBlanks provided that the map is pointed.

                                Equations
                                Instances For
                                  @[simp]
                                  @[simp]
                                  theorem Turing.ListBlank.head_map {Γ : Type u_1} {Γ' : Type u_2} [Inhabited Γ] [Inhabited Γ'] (f : Turing.PointedMap Γ Γ') (l : Turing.ListBlank Γ) :
                                  (Turing.ListBlank.map f l).head = f.f l.head
                                  @[simp]
                                  theorem Turing.ListBlank.tail_map {Γ : Type u_1} {Γ' : Type u_2} [Inhabited Γ] [Inhabited Γ'] (f : Turing.PointedMap Γ Γ') (l : Turing.ListBlank Γ) :
                                  @[simp]
                                  theorem Turing.ListBlank.nth_map {Γ : Type u_1} {Γ' : Type u_2} [Inhabited Γ] [Inhabited Γ'] (f : Turing.PointedMap Γ Γ') (l : Turing.ListBlank Γ) (n : ) :
                                  (Turing.ListBlank.map f l).nth n = f.f (l.nth n)
                                  def Turing.proj {ι : Type u_1} {Γ : ιType u_2} [(i : ι) → Inhabited (Γ i)] (i : ι) :
                                  Turing.PointedMap ((i : ι) → Γ i) (Γ i)

                                  The i-th projection as a pointed map.

                                  Equations
                                  • Turing.proj i = { f := fun (a : (i : ι) → Γ i) => a i, map_pt' := }
                                  Instances For
                                    theorem Turing.proj_map_nth {ι : Type u_1} {Γ : ιType u_2} [(i : ι) → Inhabited (Γ i)] (i : ι) (L : Turing.ListBlank ((i : ι) → Γ i)) (n : ) :
                                    (Turing.ListBlank.map (Turing.proj i) L).nth n = L.nth n i
                                    theorem Turing.ListBlank.map_modifyNth {Γ : Type u_1} {Γ' : Type u_2} [Inhabited Γ] [Inhabited Γ'] (F : Turing.PointedMap Γ Γ') (f : ΓΓ) (f' : Γ'Γ') (H : ∀ (x : Γ), F.f (f x) = f' (F.f x)) (n : ) (L : Turing.ListBlank Γ) :

                                    Append a list on the left side of a ListBlank.

                                    Equations
                                    Instances For
                                      @[simp]
                                      theorem Turing.ListBlank.append_mk {Γ : Type u_1} [Inhabited Γ] (l₁ l₂ : List Γ) :
                                      theorem Turing.ListBlank.append_assoc {Γ : Type u_1} [Inhabited Γ] (l₁ l₂ : List Γ) (l₃ : Turing.ListBlank Γ) :
                                      def Turing.ListBlank.flatMap {Γ : Type u_1} {Γ' : Type u_2} [Inhabited Γ] [Inhabited Γ'] (l : Turing.ListBlank Γ) (f : ΓList Γ') (hf : ∃ (n : ), f default = List.replicate n default) :

                                      The flatMap function on lists is well defined on ListBlanks provided that the default element is sent to a sequence of default elements.

                                      Equations
                                      Instances For
                                        @[deprecated Turing.ListBlank.flatMap (since := "2024-10-16")]
                                        def Turing.ListBlank.bind {Γ : Type u_1} {Γ' : Type u_2} [Inhabited Γ] [Inhabited Γ'] (l : Turing.ListBlank Γ) (f : ΓList Γ') (hf : ∃ (n : ), f default = List.replicate n default) :

                                        Alias of Turing.ListBlank.flatMap.


                                        The flatMap function on lists is well defined on ListBlanks provided that the default element is sent to a sequence of default elements.

                                        Equations
                                        Instances For
                                          @[simp]
                                          theorem Turing.ListBlank.flatMap_mk {Γ : Type u_1} {Γ' : Type u_2} [Inhabited Γ] [Inhabited Γ'] (l : List Γ) (f : ΓList Γ') (hf : ∃ (n : ), f default = List.replicate n default) :
                                          (Turing.ListBlank.mk l).flatMap f hf = Turing.ListBlank.mk (l.flatMap f)
                                          @[deprecated Turing.ListBlank.flatMap_mk (since := "2024-10-16")]
                                          theorem Turing.ListBlank.bind_mk {Γ : Type u_1} {Γ' : Type u_2} [Inhabited Γ] [Inhabited Γ'] (l : List Γ) (f : ΓList Γ') (hf : ∃ (n : ), f default = List.replicate n default) :
                                          (Turing.ListBlank.mk l).flatMap f hf = Turing.ListBlank.mk (l.flatMap f)

                                          Alias of Turing.ListBlank.flatMap_mk.

                                          @[simp]
                                          theorem Turing.ListBlank.cons_flatMap {Γ : Type u_1} {Γ' : Type u_2} [Inhabited Γ] [Inhabited Γ'] (a : Γ) (l : Turing.ListBlank Γ) (f : ΓList Γ') (hf : ∃ (n : ), f default = List.replicate n default) :
                                          (Turing.ListBlank.cons a l).flatMap f hf = Turing.ListBlank.append (f a) (l.flatMap f hf)
                                          @[deprecated Turing.ListBlank.cons_flatMap (since := "2024-10-16")]
                                          theorem Turing.ListBlank.cons_bind {Γ : Type u_1} {Γ' : Type u_2} [Inhabited Γ] [Inhabited Γ'] (a : Γ) (l : Turing.ListBlank Γ) (f : ΓList Γ') (hf : ∃ (n : ), f default = List.replicate n default) :
                                          (Turing.ListBlank.cons a l).flatMap f hf = Turing.ListBlank.append (f a) (l.flatMap f hf)

                                          Alias of Turing.ListBlank.cons_flatMap.

                                          structure Turing.Tape (Γ : Type u_1) [Inhabited Γ] :
                                          Type u_1

                                          The tape of a Turing machine is composed of a head element (which we imagine to be the current position of the head), together with two ListBlanks denoting the portions of the tape going off to the left and right. When the Turing machine moves right, an element is pulled from the right side and becomes the new head, while the head element is consed onto the left side.

                                          • head : Γ

                                            The current position of the head.

                                          • The portion of the tape going off to the left.

                                          • right : Turing.ListBlank Γ

                                            The portion of the tape going off to the right.

                                          Instances For
                                            Equations
                                            inductive Turing.Dir :

                                            A direction for the Turing machine move command, either left or right.

                                            Instances For
                                              Equations

                                              The "inclusive" left side of the tape, including both left and head.

                                              Equations
                                              Instances For

                                                The "inclusive" right side of the tape, including both right and head.

                                                Equations
                                                Instances For

                                                  Move the tape in response to a motion of the Turing machine. Note that T.move Dir.left makes T.left smaller; the Turing machine is moving left and the tape is moving right.

                                                  Equations
                                                  Instances For
                                                    def Turing.Tape.mk' {Γ : Type u_1} [Inhabited Γ] (L R : Turing.ListBlank Γ) :

                                                    Construct a tape from a left side and an inclusive right side.

                                                    Equations
                                                    Instances For
                                                      @[simp]
                                                      theorem Turing.Tape.mk'_left {Γ : Type u_1} [Inhabited Γ] (L R : Turing.ListBlank Γ) :
                                                      (Turing.Tape.mk' L R).left = L
                                                      @[simp]
                                                      theorem Turing.Tape.mk'_head {Γ : Type u_1} [Inhabited Γ] (L R : Turing.ListBlank Γ) :
                                                      (Turing.Tape.mk' L R).head = R.head
                                                      @[simp]
                                                      theorem Turing.Tape.mk'_right {Γ : Type u_1} [Inhabited Γ] (L R : Turing.ListBlank Γ) :
                                                      (Turing.Tape.mk' L R).right = R.tail
                                                      @[simp]
                                                      theorem Turing.Tape.mk'_right₀ {Γ : Type u_1} [Inhabited Γ] (L R : Turing.ListBlank Γ) :
                                                      (Turing.Tape.mk' L R).right₀ = R
                                                      @[simp]
                                                      theorem Turing.Tape.mk'_left_right₀ {Γ : Type u_1} [Inhabited Γ] (T : Turing.Tape Γ) :
                                                      Turing.Tape.mk' T.left T.right₀ = T
                                                      theorem Turing.Tape.exists_mk' {Γ : Type u_1} [Inhabited Γ] (T : Turing.Tape Γ) :
                                                      ∃ (L : Turing.ListBlank Γ) (R : Turing.ListBlank Γ), T = Turing.Tape.mk' L R
                                                      def Turing.Tape.mk₂ {Γ : Type u_1} [Inhabited Γ] (L R : List Γ) :

                                                      Construct a tape from a left side and an inclusive right side.

                                                      Equations
                                                      Instances For
                                                        def Turing.Tape.mk₁ {Γ : Type u_1} [Inhabited Γ] (l : List Γ) :

                                                        Construct a tape from a list, with the head of the list at the TM head and the rest going to the right.

                                                        Equations
                                                        Instances For
                                                          def Turing.Tape.nth {Γ : Type u_1} [Inhabited Γ] (T : Turing.Tape Γ) :
                                                          Γ

                                                          The nth function of a tape is integer-valued, with index 0 being the head, negative indexes on the left and positive indexes on the right. (Picture a number line.)

                                                          Equations
                                                          Instances For
                                                            @[simp]
                                                            theorem Turing.Tape.nth_zero {Γ : Type u_1} [Inhabited Γ] (T : Turing.Tape Γ) :
                                                            T.nth 0 = T.head
                                                            theorem Turing.Tape.right₀_nth {Γ : Type u_1} [Inhabited Γ] (T : Turing.Tape Γ) (n : ) :
                                                            T.right₀.nth n = T.nth n
                                                            @[simp]
                                                            theorem Turing.Tape.mk'_nth_nat {Γ : Type u_1} [Inhabited Γ] (L R : Turing.ListBlank Γ) (n : ) :
                                                            (Turing.Tape.mk' L R).nth n = R.nth n
                                                            @[simp]
                                                            theorem Turing.Tape.move_left_nth {Γ : Type u_1} [Inhabited Γ] (T : Turing.Tape Γ) (i : ) :
                                                            (Turing.Tape.move Turing.Dir.left T).nth i = T.nth (i - 1)
                                                            @[simp]
                                                            theorem Turing.Tape.move_right_nth {Γ : Type u_1} [Inhabited Γ] (T : Turing.Tape Γ) (i : ) :
                                                            (Turing.Tape.move Turing.Dir.right T).nth i = T.nth (i + 1)
                                                            @[simp]
                                                            theorem Turing.Tape.move_right_n_head {Γ : Type u_1} [Inhabited Γ] (T : Turing.Tape Γ) (i : ) :
                                                            ((Turing.Tape.move Turing.Dir.right)^[i] T).head = T.nth i
                                                            def Turing.Tape.write {Γ : Type u_1} [Inhabited Γ] (b : Γ) (T : Turing.Tape Γ) :

                                                            Replace the current value of the head on the tape.

                                                            Equations
                                                            Instances For
                                                              @[simp]
                                                              theorem Turing.Tape.write_self {Γ : Type u_1} [Inhabited Γ] (T : Turing.Tape Γ) :
                                                              Turing.Tape.write T.head T = T
                                                              @[simp]
                                                              theorem Turing.Tape.write_nth {Γ : Type u_1} [Inhabited Γ] (b : Γ) (T : Turing.Tape Γ) {i : } :
                                                              (Turing.Tape.write b T).nth i = if i = 0 then b else T.nth i
                                                              def Turing.Tape.map {Γ : Type u_1} {Γ' : Type u_2} [Inhabited Γ] [Inhabited Γ'] (f : Turing.PointedMap Γ Γ') (T : Turing.Tape Γ) :

                                                              Apply a pointed map to a tape to change the alphabet.

                                                              Equations
                                                              Instances For
                                                                @[simp]
                                                                theorem Turing.Tape.map_fst {Γ : Type u_1} {Γ' : Type u_2} [Inhabited Γ] [Inhabited Γ'] (f : Turing.PointedMap Γ Γ') (T : Turing.Tape Γ) :
                                                                (Turing.Tape.map f T).head = f.f T.head
                                                                @[simp]
                                                                theorem Turing.Tape.map_write {Γ : Type u_1} {Γ' : Type u_2} [Inhabited Γ] [Inhabited Γ'] (f : Turing.PointedMap Γ Γ') (b : Γ) (T : Turing.Tape Γ) :
                                                                theorem Turing.Tape.map_mk₂ {Γ : Type u_1} {Γ' : Type u_2} [Inhabited Γ] [Inhabited Γ'] (f : Turing.PointedMap Γ Γ') (L R : List Γ) :
                                                                theorem Turing.Tape.map_mk₁ {Γ : Type u_1} {Γ' : Type u_2} [Inhabited Γ] [Inhabited Γ'] (f : Turing.PointedMap Γ Γ') (l : List Γ) :