Computable functions
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 c.K
- K_fin : fintype c.K
- k₀ : c.K
- k₁ : c.K
- Γ : c.K → Type
- Λ : Type
- main : c.Λ
- Λ_fin : fintype c.Λ
- σ : Type
- initial_state : c.σ
- σ_fin : fintype c.σ
- Γk₀_fin : fintype (c.Γ c.k₀)
- M : c.Λ → turing.TM2.stmt c.Γ c.Λ c.σ
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.
Equations
- tm.decidable_eq = tm.K_decidable_eq
Equations
- tm.inhabited = {default := tm.initial_state}
The type of statements (functions) corresponding to this TM.
The type of configurations (functions) corresponding to this TM.
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.
- to_evals_to : turing.evals_to f a b
- steps_le_m : c.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.
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 a b c m₁ m₂ 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')
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
The forgetful map, forgetting the upper bound on the number of steps.
Equations
- to_tm2_computable_aux : turing.tm2_computable_aux ea.to_encoding.Γ eb.to_encoding.Γ
- outputs_fun : Π (a : α), turing.tm2_outputs c.to_tm2_computable_aux.tm (list.map c.to_tm2_computable_aux.input_alphabet.inv_fun (ea.to_encoding.encode a)) (some (list.map c.to_tm2_computable_aux.output_alphabet.inv_fun (eb.to_encoding.encode (f a))))
A Turing machine + a proof it outputs f.
- to_tm2_computable_aux : turing.tm2_computable_aux ea.to_encoding.Γ eb.to_encoding.Γ
- time : ℕ → ℕ
- outputs_fun : Π (a : α), turing.tm2_outputs_in_time c.to_tm2_computable_aux.tm (list.map c.to_tm2_computable_aux.input_alphabet.inv_fun (ea.to_encoding.encode a)) (some (list.map c.to_tm2_computable_aux.output_alphabet.inv_fun (eb.to_encoding.encode (f a)))) (c.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.
- to_tm2_computable_aux : turing.tm2_computable_aux ea.to_encoding.Γ eb.to_encoding.Γ
- time : polynomial ℕ
- outputs_fun : Π (a : α), turing.tm2_outputs_in_time c.to_tm2_computable_aux.tm (list.map c.to_tm2_computable_aux.input_alphabet.inv_fun (ea.to_encoding.encode a)) (some (list.map c.to_tm2_computable_aux.output_alphabet.inv_fun (eb.to_encoding.encode (f a)))) (polynomial.eval (ea.to_encoding.encode a).length c.time)
A Turing machine + a polynomial time function + a proof it outputs f in at most time(len(input)) steps.
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
- turing.inhabited_tm2_outputs = {default := (default (turing.tm2_outputs_in_time (turing.id_computer computability.fin_encoding_bool_bool) (list.map (equiv.cast turing.inhabited_tm2_outputs_in_time._proof_1).inv_fun [ff]) (some (list.map (equiv.cast turing.inhabited_tm2_outputs_in_time._proof_2).inv_fun [ff])) (polynomial.eval (computability.fin_encoding_bool_bool.to_encoding.encode ff).length (turing.id_computable_in_poly_time computability.fin_encoding_bool_bool).time))).to_tm2_outputs}
Equations
Equations
- turing.inhabited_tm2_evals_to = {default := turing.evals_to.refl (λ (_x : unit), 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.