Computable functions #
This file contains the definition of a Turing machine with some finiteness conditions (bundling the definition of TM2 in TuringMachine.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 #
idComputableInPolyTime
: a TM + a proof it computes the identity on a type in polytime.idComputable
: 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.
A bundled TM2 (an equivalent of the classical Turing machine, defined starting from
the namespace Turing.TM2
in TuringMachine.lean
), with an input and output stack,
a main function, an initial state and some finiteness guarantees.
- K : Type
- kDecidableEq : DecidableEq self.K
- kFin : Fintype self.K
- k₀ : self.K
- k₁ : self.K
- Γ : self.K → Type
- Λ : Type
- main : self.Λ
- ΛFin : Fintype self.Λ
- σ : Type
- initialState : self.σ
- σFin : Fintype self.σ
- Γk₀Fin : Fintype (self.Γ self.k₀)
- m : self.Λ → Turing.TM2.Stmt self.Γ self.Λ self.σ
Instances For
Equations
- Turing.FinTM2.decidableEqK tm = tm.kDecidableEq
Equations
- Turing.FinTM2.inhabitedσ tm = { default := tm.initialState }
The type of statements (functions) corresponding to this TM.
Equations
- Turing.FinTM2.Stmt tm = Turing.TM2.Stmt tm.Γ tm.Λ tm.σ
Instances For
Equations
- Turing.FinTM2.inhabitedStmt tm = inferInstanceAs (Inhabited (Turing.TM2.Stmt tm.Γ tm.Λ tm.σ))
The type of configurations (functions) corresponding to this TM.
Equations
- Turing.FinTM2.Cfg tm = Turing.TM2.Cfg tm.Γ tm.Λ tm.σ
Instances For
Equations
- Turing.FinTM2.inhabitedCfg tm = Turing.TM2.Cfg.inhabited tm.Γ tm.Λ tm.σ
The step function corresponding to this TM.
Equations
- Turing.FinTM2.step tm = Turing.TM2.step tm.m
Instances For
The initial configuration corresponding to a list in the input alphabet.
Equations
Instances For
The final configuration corresponding to a list in the output alphabet.
Equations
Instances For
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
Reflexivity of EvalsTo
in 0 steps.
Equations
- Turing.EvalsTo.refl f a = { steps := 0, evals_in_steps := (_ : (flip bind f)^[0] (some a) = (flip bind f)^[0] (some a)) }
Instances For
Transitivity of EvalsTo
in the sum of the numbers of steps.
Equations
- Turing.EvalsTo.trans f a b c h₁ h₂ = { steps := h₂.steps + h₁.steps, evals_in_steps := (_ : (flip bind f)^[h₂.steps + h₁.steps] (some a) = c) }
Instances For
Reflexivity of EvalsToInTime
in 0 steps.
Equations
- Turing.EvalsToInTime.refl f a = { toEvalsTo := Turing.EvalsTo.refl f a, steps_le_m := Turing.EvalsToInTime.refl.proof_1 }
Instances For
Transitivity of EvalsToInTime
in the sum of the numbers of steps.
Equations
- Turing.EvalsToInTime.trans f m₁ m₂ a b c h₁ h₂ = { toEvalsTo := Turing.EvalsTo.trans f a b c h₁.toEvalsTo h₂.toEvalsTo, steps_le_m := (_ : h₂.steps + h₁.steps ≤ m₂ + m₁) }
Instances For
A proof of tm outputting l' when given l.
Equations
- Turing.TM2Outputs tm l l' = Turing.EvalsTo (Turing.FinTM2.step tm) (Turing.initList tm l) (Option.map (Turing.haltList tm) l')
Instances For
A proof of tm outputting l' when given l in at most m steps.
Equations
- Turing.TM2OutputsInTime tm l l' m = Turing.EvalsToInTime (Turing.FinTM2.step tm) (Turing.initList tm l) (Option.map (Turing.haltList tm) l') m
Instances For
The forgetful map, forgetting the upper bound on the number of steps.
Equations
- Turing.TM2OutputsInTime.toTM2Outputs h = h.toEvalsTo
Instances For
A Turing machine with input alphabet equivalent to Γ₀ and output alphabet equivalent to Γ₁.
- tm : Turing.FinTM2
- inputAlphabet : self.tm.Γ self.tm.k₀ ≃ Γ₀
- outputAlphabet : self.tm.Γ self.tm.k₁ ≃ Γ₁
Instances For
A Turing machine + a proof it outputs f.
- tm : Turing.FinTM2
- inputAlphabet : self.tm.Γ self.tm.k₀ ≃ ea.Γ
- outputAlphabet : self.tm.Γ self.tm.k₁ ≃ eb.Γ
- outputsFun : (a : α) → Turing.TM2Outputs self.tm (List.map self.inputAlphabet.invFun (ea.toEncoding.encode a)) (some (List.map self.outputAlphabet.invFun (eb.toEncoding.encode (f a))))
Instances For
A Turing machine + a time function + a proof it outputs f in at most time(len(input)) steps.
- tm : Turing.FinTM2
- inputAlphabet : self.tm.Γ self.tm.k₀ ≃ ea.Γ
- outputAlphabet : self.tm.Γ self.tm.k₁ ≃ eb.Γ
- outputsFun : (a : α) → Turing.TM2OutputsInTime self.tm (List.map self.inputAlphabet.invFun (ea.toEncoding.encode a)) (some (List.map self.outputAlphabet.invFun (eb.toEncoding.encode (f a)))) (self.time (List.length (ea.toEncoding.encode a)))
Instances For
A Turing machine + a polynomial time function + a proof it outputs f in at most time(len(input)) steps.
- tm : Turing.FinTM2
- inputAlphabet : self.tm.Γ self.tm.k₀ ≃ ea.Γ
- outputAlphabet : self.tm.Γ self.tm.k₁ ≃ eb.Γ
- time : Polynomial ℕ
- outputsFun : (a : α) → Turing.TM2OutputsInTime self.tm (List.map self.inputAlphabet.invFun (ea.toEncoding.encode a)) (some (List.map self.outputAlphabet.invFun (eb.toEncoding.encode (f a)))) (Polynomial.eval (List.length (ea.toEncoding.encode a)) self.time)
Instances For
A forgetful map, forgetting the time bound on the number of steps.
Equations
- Turing.TM2ComputableInTime.toTM2Computable h = { toTM2ComputableAux := h.toTM2ComputableAux, outputsFun := fun (a : α) => Turing.TM2OutputsInTime.toTM2Outputs (h.outputsFun a) }
Instances For
A forgetful map, forgetting that the time function is polynomial.
Equations
- Turing.TM2ComputableInPolyTime.toTM2ComputableInTime h = { toTM2ComputableAux := h.toTM2ComputableAux, time := fun (n : ℕ) => Polynomial.eval n h.time, outputsFun := h.outputsFun }
Instances For
A Turing machine computing the identity on α.
Equations
- Turing.idComputer ea = Turing.FinTM2.mk PUnit.unit PUnit.unit (fun (x : Unit) => ea.Γ) Unit PUnit.unit Unit PUnit.unit fun (x : Unit) => Turing.TM2.Stmt.halt
Instances For
Equations
- Turing.inhabitedFinTM2 = { default := Turing.idComputer default }
A proof that the identity map on α is computable in polytime.
Equations
- One or more equations did not get rendered due to their size.
Instances For
Equations
- Turing.inhabitedTM2ComputableInPolyTime = { default := Turing.idComputableInPolyTime default }
Equations
- Turing.inhabitedTM2OutputsInTime = { default := (Turing.idComputableInPolyTime Computability.finEncodingBoolBool).outputsFun false }
Equations
- Turing.inhabitedTM2Outputs = { default := Turing.TM2OutputsInTime.toTM2Outputs default }
Equations
- Turing.inhabitedEvalsToInTime = { default := Turing.EvalsToInTime.refl (fun (x : Unit) => some PUnit.unit) PUnit.unit }
Equations
- Turing.inhabitedTM2EvalsTo = { default := Turing.EvalsTo.refl (fun (x : Unit) => some PUnit.unit) PUnit.unit }
A proof that the identity map on α is computable in time.
Equations
Instances For
Equations
- Turing.inhabitedTM2ComputableInTime = { default := Turing.idComputableInTime default }
A proof that the identity map on α is computable.
Equations
Instances For
Equations
- Turing.inhabitedTM2Computable = { default := Turing.idComputable default }
Equations
- Turing.inhabitedTM2ComputableAux = { default := default.toTM2ComputableAux }