Computable functions #
THIS FILE IS SYNCHRONIZED WITH MATHLIB4. Any changes to this file require a corresponding PR to mathlib4.
This file contains the definition of a Turing machine with some finiteness conditions (bundling the definition of TM2 in turing_machine.lean), a definition of when a TM gives a certain output (in a certain time), and the definition of computability (in polytime or any time function) of a function between two types that have an encoding (as in encoding.lean).
Main theorems #
id_computable_in_poly_time
: a TM + a proof it computes the identity on a type in polytime.id_computable
: a TM + a proof it computes the identity on a type.
Implementation notes #
To count the execution time of a Turing machine, we have decided to count the number of times the
step
function is used. Each step executes a statement (of type stmt); this is a function, and
generally contains multiple "fundamental" steps (pushing, popping, so on). However, as functions
only contain a finite number of executions and each one is executed at most once, this execution
time is up to multiplication by a constant the amount of fundamental steps.
- K : Type
- K_decidable_eq : decidable_eq self.K
- K_fin : fintype self.K
- k₀ : self.K
- k₁ : self.K
- Γ : self.K → Type
- Λ : Type
- main : self.Λ
- Λ_fin : fintype self.Λ
- σ : Type
- initial_state : self.σ
- σ_fin : fintype self.σ
- Γk₀_fin : fintype (self.Γ self.k₀)
- M : self.Λ → turing.TM2.stmt self.Γ self.Λ self.σ
A bundled TM2 (an equivalent of the classical Turing machine, defined starting from
the namespace turing.TM2
in turing_machine.lean
), with an input and output stack,
a main function, an initial state and some finiteness guarantees.
Instances for turing.fin_tm2
- turing.fin_tm2.has_sizeof_inst
- turing.inhabited_fin_tm2
Equations
Equations
- turing.fin_tm2.σ.inhabited tm = {default := tm.initial_state}
The type of statements (functions) corresponding to this TM.
Instances for turing.fin_tm2.stmt
The type of configurations (functions) corresponding to this TM.
Instances for turing.fin_tm2.cfg
Equations
- tm.inhabited_cfg = turing.TM2.cfg.inhabited tm.Γ tm.Λ tm.σ
The initial configuration corresponding to a list in the input alphabet.
The final configuration corresponding to a list in the output alphabet.
A "proof" of the fact that f eventually reaches b when repeatedly evaluated on a, remembering the number of steps it takes.
Instances for turing.evals_to
- turing.evals_to.has_sizeof_inst
- turing.inhabited_tm2_evals_to
- to_evals_to : turing.evals_to f a b
- steps_le_m : self.to_evals_to.steps ≤ m
A "proof" of the fact that f
eventually reaches b
in at most m
steps when repeatedly
evaluated on a
, remembering the number of steps it takes.
Instances for turing.evals_to_in_time
- turing.evals_to_in_time.has_sizeof_inst
- turing.inhabited_evals_to_in_time
Reflexivity of evals_to
in 0 steps.
Equations
- turing.evals_to.refl f a = {steps := 0, evals_in_steps := _}
Transitivity of evals_to
in the sum of the numbers of steps.
Equations
- turing.evals_to.trans f a b c h₁ h₂ = {steps := h₂.steps + h₁.steps, evals_in_steps := _}
Reflexivity of evals_to_in_time
in 0 steps.
Equations
- turing.evals_to_in_time.refl f a = {to_evals_to := turing.evals_to.refl f a, steps_le_m := _}
Transitivity of evals_to_in_time
in the sum of the numbers of steps.
Equations
- turing.evals_to_in_time.trans f m₁ m₂ a b c h₁ h₂ = {to_evals_to := turing.evals_to.trans f a b c h₁.to_evals_to h₂.to_evals_to, steps_le_m := _}
A proof of tm outputting l' when given l.
Equations
- turing.tm2_outputs tm l l' = turing.evals_to tm.step (turing.init_list tm l) (option.map (turing.halt_list tm) l')
Instances for turing.tm2_outputs
A proof of tm outputting l' when given l in at most m steps.
Equations
- turing.tm2_outputs_in_time tm l l' m = turing.evals_to_in_time tm.step (turing.init_list tm l) (option.map (turing.halt_list tm) l') m
Instances for turing.tm2_outputs_in_time
The forgetful map, forgetting the upper bound on the number of steps.
Equations
- tm : turing.fin_tm2
- input_alphabet : self.tm.Γ self.tm.k₀ ≃ Γ₀
- output_alphabet : self.tm.Γ self.tm.k₁ ≃ Γ₁
A Turing machine with input alphabet equivalent to Γ₀ and output alphabet equivalent to Γ₁.
Instances for turing.tm2_computable_aux
- turing.tm2_computable_aux.has_sizeof_inst
- turing.inhabited_tm2_computable_aux
- to_tm2_computable_aux : turing.tm2_computable_aux ea.to_encoding.Γ eb.to_encoding.Γ
- outputs_fun : Π (a : α), turing.tm2_outputs self.to_tm2_computable_aux.tm (list.map self.to_tm2_computable_aux.input_alphabet.inv_fun (ea.to_encoding.encode a)) (option.some (list.map self.to_tm2_computable_aux.output_alphabet.inv_fun (eb.to_encoding.encode (f a))))
A Turing machine + a proof it outputs f.
Instances for turing.tm2_computable
- turing.tm2_computable.has_sizeof_inst
- turing.inhabited_tm2_computable
- to_tm2_computable_aux : turing.tm2_computable_aux ea.to_encoding.Γ eb.to_encoding.Γ
- time : ℕ → ℕ
- outputs_fun : Π (a : α), turing.tm2_outputs_in_time self.to_tm2_computable_aux.tm (list.map self.to_tm2_computable_aux.input_alphabet.inv_fun (ea.to_encoding.encode a)) (option.some (list.map self.to_tm2_computable_aux.output_alphabet.inv_fun (eb.to_encoding.encode (f a)))) (self.time (ea.to_encoding.encode a).length)
A Turing machine + a time function + a proof it outputs f in at most time(len(input)) steps.
Instances for turing.tm2_computable_in_time
- turing.tm2_computable_in_time.has_sizeof_inst
- turing.inhabited_tm2_computable_in_time
- to_tm2_computable_aux : turing.tm2_computable_aux ea.to_encoding.Γ eb.to_encoding.Γ
- time : polynomial ℕ
- outputs_fun : Π (a : α), turing.tm2_outputs_in_time self.to_tm2_computable_aux.tm (list.map self.to_tm2_computable_aux.input_alphabet.inv_fun (ea.to_encoding.encode a)) (option.some (list.map self.to_tm2_computable_aux.output_alphabet.inv_fun (eb.to_encoding.encode (f a)))) (polynomial.eval (ea.to_encoding.encode a).length self.time)
A Turing machine + a polynomial time function + a proof it outputs f in at most time(len(input)) steps.
Instances for turing.tm2_computable_in_poly_time
- turing.tm2_computable_in_poly_time.has_sizeof_inst
- turing.inhabited_tm2_computable_in_poly_time
A forgetful map, forgetting the time bound on the number of steps.
Equations
- h.to_tm2_computable = {to_tm2_computable_aux := h.to_tm2_computable_aux, outputs_fun := λ (a : α), (h.outputs_fun a).to_tm2_outputs}
A forgetful map, forgetting that the time function is polynomial.
Equations
- h.to_tm2_computable_in_time = {to_tm2_computable_aux := h.to_tm2_computable_aux, time := λ (n : ℕ), polynomial.eval n h.time, outputs_fun := h.outputs_fun}
A Turing machine computing the identity on α.
Equations
- turing.id_computer ea = {K := unit, K_decidable_eq := λ (a b : unit), punit.decidable_eq a b, K_fin := punit.fintype, k₀ := punit.star, k₁ := punit.star, Γ := λ (_x : unit), ea.to_encoding.Γ, Λ := unit, main := punit.star, Λ_fin := punit.fintype, σ := unit, initial_state := punit.star, σ_fin := punit.fintype, Γk₀_fin := ea.Γ_fin, M := λ (_x : unit), turing.TM2.stmt.halt}
Equations
A proof that the identity map on α is computable in polytime.
Equations
- turing.id_computable_in_poly_time ea = {to_tm2_computable_aux := {tm := turing.id_computer ea, input_alphabet := equiv.cast _, output_alphabet := equiv.cast _}, time := 1, outputs_fun := λ (_x : α), {to_evals_to := {steps := 1, evals_in_steps := _}, steps_le_m := _}}
Equations
Equations
- turing.inhabited_evals_to_in_time = {default := turing.evals_to_in_time.refl (λ (_x : unit), option.some punit.star) punit.star}
Equations
- turing.inhabited_tm2_evals_to = {default := turing.evals_to.refl (λ (_x : unit), option.some punit.star) punit.star}
A proof that the identity map on α is computable in time.
A proof that the identity map on α is computable.