Documentation

Cslib.Computability.Machines.Turing.SingleTape.Deterministic

Single-Tape Turing Machines #

Defines a single-tape Turing machine for computing functions on List Symbol for finite alphabet Symbol.

Design #

Here are some design choices made in this file:

These machines have access to a single bidirectionally-infinite tape (BiTape) which uses symbols from Option Symbol.

The transition function of the machine takes a state and a tape alphabet character under the read-head (i.e. an Option Symbol) and returns a Stmt describing the tape action to take, as well as an optional new state to transition to (where none means halt).

We do not make the "halting state" a member of the state type for a few reasons:

We also include the possibility for non-movement actions, for convenience in composition of machines.

Important Declarations #

We define a number of structures related to Turing machine computation:

We also provide ways of constructing polynomial-runtime TMs

TODOs #

A Turing machine "statement" is just a Optional command to move left or right, and write a symbol (i.e. an Option Symbol, where none is the blank symbol) on the BiTape

  • symbol : Option Symbol

    The symbol to write at the current head position

  • movement : Option Turing.Dir

    The direction to move the tape head

Instances For
    @[instance_reducible]
    structure Cslib.Turing.SingleTapeTM (Symbol : Type) [Inhabited Symbol] [Fintype Symbol] :

    A single-tape Turing machine over the alphabet of Option Symbol (where none is the blank BiTape symbol).

    • State : Type

      type of state labels

    • stateFintype : Fintype self.State

      finiteness of the state type

    • q₀ : self.State

      Initial state

    • tr : self.State → Option Symbol → Stmt Symbol × Option self.State

      Transition function, mapping a state and a head symbol to a Stmt to invoke, and optionally the new state to transition to afterwards (none for halt)

    Instances For

      Configurations of a Turing Machine #

      This section defines the configurations of a Turing machine, the step function that lets the machine transition from one configuration to the next, and the intended initial and final configurations.

      @[instance_reducible]
      instance Cslib.Turing.SingleTapeTM.instInhabitedState {Symbol : Type} [Inhabited Symbol] [Fintype Symbol] (tm : SingleTapeTM Symbol) :
      @[instance_reducible]
      instance Cslib.Turing.SingleTapeTM.instFintypeState {Symbol : Type} [Inhabited Symbol] [Fintype Symbol] (tm : SingleTapeTM Symbol) :
      @[instance_reducible]
      structure Cslib.Turing.SingleTapeTM.Cfg {Symbol : Type} [Inhabited Symbol] [Fintype Symbol] (tm : SingleTapeTM Symbol) :

      The configurations of a Turing machine consist of: an Optional state (or none for the halting state), and a BiTape representing the tape contents.

      • state : Option tm.State

        the state of the TM (or none for the halting state)

      • BiTape : Turing.BiTape Symbol

        the BiTape contents

      Instances For
        @[instance_reducible]
        instance Cslib.Turing.SingleTapeTM.instInhabitedCfg {a✝ : Type} {a✝¹ : Inhabited a✝} {a✝² : Fintype a✝} {a✝³ : SingleTapeTM a✝} :
        Inhabited a✝³.Cfg
        def Cslib.Turing.SingleTapeTM.step {Symbol : Type} [Inhabited Symbol] [Fintype Symbol] (tm : SingleTapeTM Symbol) :
        tm.Cfg → Option tm.Cfg

        The step function corresponding to a SingleTapeTM.

        Instances For
          def Cslib.Turing.SingleTapeTM.initCfg {Symbol : Type} [Inhabited Symbol] [Fintype Symbol] (tm : SingleTapeTM Symbol) (s : List Symbol) :
          tm.Cfg

          The initial configuration corresponding to a list in the input alphabet. Note that the entries of the tape constructed by BiTape.mk₁ are all some values. This is to ensure that distinct lists map to distinct initial configurations.

          Instances For
            def Cslib.Turing.SingleTapeTM.haltCfg {Symbol : Type} [Inhabited Symbol] [Fintype Symbol] (tm : SingleTapeTM Symbol) (s : List Symbol) :
            tm.Cfg

            The final configuration corresponding to a list in the output alphabet. (We demand that the head halts at the leftmost position of the output.)

            Instances For
              def Cslib.Turing.SingleTapeTM.Cfg.spaceUsed {Symbol : Type} [Inhabited Symbol] [Fintype Symbol] (tm : SingleTapeTM Symbol) (cfg : tm.Cfg) :

              The space used by a configuration is the space used by its tape.

              Instances For
                theorem Cslib.Turing.SingleTapeTM.Cfg.spaceUsed_initCfg {Symbol : Type} [Inhabited Symbol] [Fintype Symbol] (tm : SingleTapeTM Symbol) (s : List Symbol) :
                spaceUsed tm (tm.initCfg s) = max 1 s.length
                theorem Cslib.Turing.SingleTapeTM.Cfg.spaceUsed_haltCfg {Symbol : Type} [Inhabited Symbol] [Fintype Symbol] (tm : SingleTapeTM Symbol) (s : List Symbol) :
                spaceUsed tm (tm.haltCfg s) = max 1 s.length
                theorem Cslib.Turing.SingleTapeTM.Cfg.spaceUsed_step {Symbol : Type} [Inhabited Symbol] [Fintype Symbol] {tm : SingleTapeTM Symbol} (cfg cfg' : tm.Cfg) (hstep : tm.step cfg = some cfg') :
                spaceUsed tm cfg' ≤ spaceUsed tm cfg + 1
                def Cslib.Turing.SingleTapeTM.TransitionRelation {Symbol : Type} [Inhabited Symbol] [Fintype Symbol] (tm : SingleTapeTM Symbol) (c₁ c₂ : tm.Cfg) :

                The TransitionRelation corresponding to a SingleTapeTM Symbol is defined by the step function, which maps a configuration to its next configuration, if it exists.

                Instances For
                  def Cslib.Turing.SingleTapeTM.Outputs {Symbol : Type} [Inhabited Symbol] [Fintype Symbol] (tm : SingleTapeTM Symbol) (l l' : List Symbol) :

                  A proof of tm outputting l' on input l.

                  Instances For
                    def Cslib.Turing.SingleTapeTM.OutputsWithinTime {Symbol : Type} [Inhabited Symbol] [Fintype Symbol] (tm : SingleTapeTM Symbol) (l l' : List Symbol) (m : ℕ) :

                    A proof of tm outputting l' on input l in at most m steps.

                    Instances For
                      theorem Cslib.Turing.SingleTapeTM.output_length_le_input_length_add_time {Symbol : Type} [Inhabited Symbol] [Fintype Symbol] (tm : SingleTapeTM Symbol) (l l' : List Symbol) (t : ℕ) (h : tm.OutputsWithinTime l l' t) :
                      l'.length ≤ max 1 l.length + t

                      This lemma bounds the size blow-up of the output of a Turing machine. It states that the increase in length of the output over the input is bounded by the runtime. This is important for guaranteeing that composition of polynomial time Turing machines remains polynomial time, as the input to the second machine is bounded by the output length of the first machine.

                      A Turing machine computing the identity.

                      Instances For
                        def Cslib.Turing.SingleTapeTM.compComputer {Symbol : Type} [Inhabited Symbol] [Fintype Symbol] (tm1 tm2 : SingleTapeTM Symbol) :

                        A Turing machine computing the composition of two other Turing machines.

                        If f and g are computed by Turing machines tm1 and tm2 then we can construct a Turing machine which computes g ∘ f by first running tm1 and then, when tm1 halts, transitioning to the start state of tm2 and running tm2.

                        Instances For

                          Composition Computer Lemmas #

                          theorem Cslib.Turing.SingleTapeTM.compComputer_q₀_eq {Symbol : Type} [Inhabited Symbol] [Fintype Symbol] (tm1 tm2 : SingleTapeTM Symbol) :

                          Time Computability #

                          This section defines the notion of time-bounded Turing Machines

                          structure Cslib.Turing.SingleTapeTM.TimeComputable {Symbol : Type} [Inhabited Symbol] [Fintype Symbol] (f : List Symbol → List Symbol) :

                          A Turing machine + a time function + a proof it outputs f in at most time(input.length) steps.

                          Instances For

                            The identity map on Symbol is computable in constant time.

                            Instances For
                              def Cslib.Turing.SingleTapeTM.TimeComputable.comp {Symbol : Type} [Inhabited Symbol] [Fintype Symbol] {f g : List Symbol → List Symbol} (hf : TimeComputable f) (hg : TimeComputable g) (h_mono : Monotone hg.timeBound) :

                              Time bounds for compComputer.

                              The compComputer of two machines which have time bounds is bounded by

                              • The time taken by the first machine on the input size
                              • added to the time taken by the second machine on the output size of the first machine (which is itself bounded by the time taken by the first machine)

                              Note that we require the time function of the second machine to be monotone; this is to ensure that if the first machine returns an output which is shorter than the maximum possible length of output for that input size, then the time bound for the second machine still holds for that shorter input to the second machine.

                              Instances For
                                def Cslib.Turing.SingleTapeTM.TimeComputable.withMonotoneBound {Symbol : Type} [Inhabited Symbol] [Fintype Symbol] {f : List Symbol → List Symbol} (hf : TimeComputable f) :

                                Convert a TimeComputable to one with a monotone time bound, by replacing the time bound t with partialSups t, i.e. n ↦ max (t 0) ⋯ (t n). The underlying machine is unchanged.

                                Instances For

                                  Polynomial Time Computability #

                                  This section defines polynomial time computable functions on Turing machines, and proves that:

                                  structure Cslib.Turing.SingleTapeTM.PolyTimeComputable {Symbol : Type} [Inhabited Symbol] [Fintype Symbol] (f : List Symbol → List Symbol) extends Cslib.Turing.SingleTapeTM.TimeComputable f :

                                  A Turing machine + a polynomial time function + a proof it outputs f in at most time(input.length) steps.

                                  Instances For

                                    A proof that the identity map on Symbol is computable in polytime.

                                    Instances For
                                      noncomputable def Cslib.Turing.SingleTapeTM.PolyTimeComputable.withMonotoneBound {Symbol : Type} [Inhabited Symbol] [Fintype Symbol] {f : List Symbol → List Symbol} (hf : PolyTimeComputable f) :

                                      Convert a PolyTimeComputable to one with a monotone time bound. The polynomial bound is unchanged, since polynomial evaluation over ℕ is monotone.

                                      Instances For
                                        noncomputable def Cslib.Turing.SingleTapeTM.PolyTimeComputable.comp {Symbol : Type} [Inhabited Symbol] [Fintype Symbol] {f g : List Symbol → List Symbol} (hf : PolyTimeComputable f) (hg : PolyTimeComputable g) :

                                        A proof that the composition of two polytime computable functions is polytime computable.

                                        The time bound of hg is first replaced by a monotone one via withMonotoneBound, so that no monotonicity assumption is required of the caller.

                                        Instances For