Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions Cslib.lean
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,9 @@ public import Cslib.Computability.Languages.MyhillNerode
public import Cslib.Computability.Languages.OmegaLanguage
public import Cslib.Computability.Languages.OmegaRegularLanguage
public import Cslib.Computability.Languages.RegularLanguage
public import Cslib.Computability.Machines.Turing.SingleTape.Defs
public import Cslib.Computability.Machines.Turing.SingleTape.Deterministic
public import Cslib.Computability.Machines.Turing.SingleTape.NonDeterministic
public import Cslib.Computability.URM.Basic
public import Cslib.Computability.URM.Computable
public import Cslib.Computability.URM.Defs
Expand Down
68 changes: 68 additions & 0 deletions Cslib/Computability/Machines/Turing/SingleTape/Defs.lean
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
/-
Copyright (c) 2026 Fabrizio Montesi. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Fabrizio Montesi, Bolton Bailey
-/

module

public import Cslib.Foundations.Data.BiTape

/-! # Basic definitions for Turing Machines (TMs) -/

@[expose] public section

namespace Cslib.Computability.Turing.SingleTape

/-- The transition labels used by a single-tape Turing Machine. -/
inductive TrLabel (Symbol : Type*)
/-- Read `x` from the tape. -/
| read (x : Symbol)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why does read need a parameter. Shouldn't read just return whatever symbol is on the thread?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This codifies the transition where the machine needs to read the symbol x to change states according to its transition relation. It's the usual thing in textbooks on TMs and automata, as well as labelled transition systems with 'observable actions'.

/-- Write `x` on the tape. -/
| write (x : Symbol)
/-- Move the head of the tape. -/
| move (d : Turing.Dir)
/-- Do nothing. -/
| skip

/-- Applies a transition label to a tape, returning `none` if it is not possible.
The input is taken as an `Option` to make the function composable. -/
def TrLabel.applyToTape [DecidableEq Symbol]
(otape : Option (Turing.BiTape Symbol)) (μ : TrLabel Symbol) :
Option (Turing.BiTape Symbol) :=
match μ, otape with
| read x, some tape => if x = tape.head then some tape else none

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is the tape an option type? We always operate on the tape don't we?

@fmontesi fmontesi Jun 30, 2026

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because I need to use this with List.foldl in the NTM defs, but if you have a better suggestion I'm happy to hear it.

| write x, some tape => some (tape.write x)
| move d, some tape => some (tape.move d)
| skip, some tape => some tape
| _, _ => none

@[scoped grind →]
theorem TrLabel.applyToTape_isSome [DecidableEq Symbol] {μ : TrLabel Symbol}
{ot : Option (Turing.BiTape Symbol)} (h : (μ.applyToTape ot).isSome) : ot.isSome := by
have ⟨t', ht'⟩ := Option.isSome_iff_exists.mp h
simp only [applyToTape] at ht'
grind [applyToTape]

@[scoped grind →]
theorem TrLabel.applyToTape_foldl_isSome [DecidableEq Symbol] {μs : List (TrLabel Symbol)}
{ot : Option (Turing.BiTape Symbol)} (h : (μs.foldl applyToTape ot).isSome) : ot.isSome := by
induction μs generalizing ot <;> grind

/-- Configuration of a single-tape Turing machine. -/
@[ext]
structure Cfg (State Symbol : Type*) where
/-- The state that the machine is in. -/
state : State
/-- Tape of the machine (memory). -/
tape : Turing.BiTape Symbol

/-- Helper builder for a configuration with a given tape content. -/
def Cfg.mk₁ (s : State) (xs : List Symbol) : Cfg State Symbol where
state := s
tape := Turing.BiTape.mk₁ xs

/-- The space used by a configuration is the space used by its tape. -/
def Cfg.spaceUsed (cfg : Cfg State Symbol) : ℕ := cfg.tape.spaceUsed
Comment thread
fmontesi marked this conversation as resolved.

end Cslib.Computability.Turing.SingleTape
123 changes: 123 additions & 0 deletions Cslib/Computability/Machines/Turing/SingleTape/NonDeterministic.lean
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
/-
Copyright (c) 2026 Fabrizio Montesi. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Fabrizio Montesi
-/

module

public import Cslib.Foundations.Relation.Defs
public import Cslib.Foundations.Data.RelatesInSteps
public import Cslib.Computability.Automata.NA.Basic
public import Cslib.Computability.Automata.Transducers.Transducer
public import Cslib.Foundations.Data.BiTape
public import Cslib.Computability.Machines.Turing.SingleTape.Defs

/-! # Single-Tape Nondeterministic Turing Machines (NTMs)

Nondeterministic Turing Machines (NTMs), defined as nondeterministic automata (`NA`) that act on a
bidirectional tape (`BiTape`).

## References

* [M. Sipser, *Introduction to Theory of Computation*][Sipser2013]
-/

@[expose] public section

namespace Cslib.Computability.Turing.SingleTape

open Automata

/-- A (single-tape) Nondeterministic Turing Machine (NTM) is a nondeterministic automaton equipped
with a set of accepting halting states. -/
structure SingleTapeNTM (State Symbol : Type*)
extends NA State (TrLabel Symbol) where
/-- The set of accepting states. -/
accept : Set State
/-- Proof that all accepting states are halting states. -/
accept_halting (hmem : s ∈ accept) : ¬∃ μ s', Tr s μ s'

variable {State Symbol : Type*}

namespace SingleTapeNTM

variable [DecidableEq Symbol]

/-- An NTM yields a small-step operational semantics on configurations, which codifies an execution
step. This formalises the 'yields' relation from [Sipser2013]. -/
def Yields (m : SingleTapeNTM State Symbol)
(c c' : Cfg State Symbol) : Prop :=
∃ μ, m.Tr c.state μ c'.state ∧ μ.applyToTape c.tape = c'.tape

@[scoped grind =]
theorem yields_tr {m : SingleTapeNTM State Symbol} :
m.Yields c c' ↔ ∃ μ, m.Tr c.state μ c'.state ∧ μ.applyToTape c.tape = c'.tape := by rfl

/-- Multistep execution of an NTM, defined as the reflexive and transitive closure of one-step
execution.
-/
def MYields (m : SingleTapeNTM State Symbol) := Relation.ReflTransGen m.Yields

open scoped LTS LTS.MTr TrLabel

/-- Characterisation of executions in terms of multistep transitions. -/
@[scoped grind =]
theorem mYields_mTr {m : SingleTapeNTM State Symbol} :
m.MYields c c' ↔ ∃ μs, m.MTr c.state μs c'.state ∧
μs.foldl TrLabel.applyToTape (some c.tape) = c'.tape := by
apply Iff.intro <;> intro h
case mp =>
induction h using Relation.ReflTransGen.head_induction_on
case refl =>
exists []
grind
case head _ c cb hred hmred ih =>
rcases ih with ⟨μs, hmtr, ih⟩
have ⟨μ, _⟩ := yields_tr.mp hred
exists μ :: μs
grind
case mpr =>
rcases h with ⟨μs, hmtr, h⟩
induction μs generalizing c
case nil =>
rw [show c = c' by grind [Cfg.ext]]
apply Relation.ReflTransGen.refl
case cons μ μs ih =>
cases hmtr
case stepL sb htr hmtr =>
have hat : ∀ (μ : TrLabel Symbol) t, (μ.applyToTape t).isSome → t.isSome := by grind
have ⟨tb, htb⟩ : ∃ tb, μ.applyToTape c.tape = some tb := by grind [Option.isSome_iff_exists]
let cb := {state := sb, tape := tb : Cfg State Symbol}
have hmyields : m.MYields cb c' := by grind
apply Relation.ReflTransGen.head (b := cb) (by grind)
simp only [MYields] at hmyields
grind

/-- An NTM is an acceptor of finite lists of symbols. -/
instance : Acceptor (SingleTapeNTM State Symbol) Symbol where
Accepts (m : SingleTapeNTM State Symbol) (xs : List Symbol) :=
∃ s ∈ m.start, ∃ c', c'.state ∈ m.accept ∧ m.MYields (Cfg.mk₁ s xs) c'

/-- The NTM `m` accepts `xs` in `n` execution steps. -/
def AcceptsInSteps (m : SingleTapeNTM State Symbol) (xs : List Symbol) (n : ℕ) : Prop :=
∃ s ∈ m.start, ∃ c', c'.state ∈ m.accept ∧ Relation.RelatesInSteps m.Yields (Cfg.mk₁ s xs) c' n

/-- The NTM `m` accepts `xs` in at most `n` execution steps. -/
def AcceptsInAtMostSteps (m : SingleTapeNTM State Symbol) (xs : List Symbol) (n : ℕ) : Prop :=
∃ k ≤ n, m.AcceptsInSteps xs k

/-- An NTM is a transducer of finite lists of symbols. -/
instance : Transducer (SingleTapeNTM State Symbol) Symbol Symbol where
Translates (m : SingleTapeNTM State Symbol) (xs ys : List Symbol) :=
∃ s ∈ m.start, ∃ c',
c'.state ∈ m.accept ∧
m.MYields (Cfg.mk₁ s xs) c' ∧
/- The following condition on output deviates from textbooks, in order to have the same
criterion as for deterministic TMs. We might want to revisit this in the future.
-/
c'.tape = Turing.BiTape.mk₁ ys

Comment thread
fmontesi marked this conversation as resolved.
end SingleTapeNTM

end Cslib.Computability.Turing.SingleTape
8 changes: 8 additions & 0 deletions references.bib
Original file line number Diff line number Diff line change
Expand Up @@ -476,3 +476,11 @@ @mastersthesis{Calisto2022
school = {Universidade do Minho},
year = {2022}
}

@book{Sipser2013,
author = {Sipser, Michael},
title = {Introduction to the Theory of Computation},
edition = {3rd},
publisher = {Cengage Learning},
year = {2013}
}
Loading