Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
8561629
feat: introduce NA for discussion
fmontesi Sep 29, 2025
cae4e0d
chore: rename Dfa to DFA and Lts to LTS
fmontesi Sep 29, 2025
69b0c1e
feat: introduce DA, plus some documentation for automata
fmontesi Sep 29, 2025
b1e5014
feat: move general defs and theorems from DFA to DA
fmontesi Sep 29, 2025
362ec6a
feat: add LTS.setImage, the image of a set of states
fmontesi Sep 30, 2025
40585d4
chore: rename LTS.Image and LTS.OutgoingLabels with lowercase initials
fmontesi Sep 30, 2025
33f0331
chore: fix casing of Sum.isLeft/RightP
fmontesi Oct 1, 2025
f113731
feat (LTS): union of two LTSs with the same state and label types
fmontesi Oct 1, 2025
bd0b568
feat: extension of LTS theory to deal with image transitions, and app…
fmontesi Oct 3, 2025
898d941
docs: alternative shapes for transitions in NA
fmontesi Oct 3, 2025
fee5bad
feat: add NFA and EpsilonNA
fmontesi Oct 3, 2025
d00c2fb
feat: EpsilonNA.toNAWithoutEpsilon
fmontesi Oct 3, 2025
a76afcb
feat (EpsilonNA): conversion of EpsilonNA into NA, with proof of corr…
fmontesi Oct 6, 2025
bdf5285
chore: Split automata theory translations into multiple files
fmontesi Oct 6, 2025
75f0bf0
chore: renaming to toNFA`
fmontesi Oct 6, 2025
a4eb319
chore: spacing
fmontesi Oct 6, 2025
87336de
Update Cslib/Computability/Automata/DFA.lean
fmontesi Oct 6, 2025
c71741a
Update Cslib/Computability/Automata/DFAToNFA.lean
fmontesi Oct 6, 2025
740c26c
Update Cslib/Computability/Automata/EpsilonNFAToNFA.lean
fmontesi Oct 6, 2025
f915549
Update Cslib/Computability/Automata/EpsilonNFAToNFA.lean
fmontesi Oct 6, 2025
b1f9cb2
Update Cslib/Computability/Automata/DFAToNFA.lean
fmontesi Oct 6, 2025
81cb3a1
Update Cslib/Computability/Automata/DFAToNFA.lean
fmontesi Oct 6, 2025
2b5ac8f
Apply suggestion from @chenson2018
fmontesi Oct 6, 2025
066a62b
Apply suggestion from @chenson2018
fmontesi Oct 6, 2025
0ff5f1a
Apply suggestion from @chenson2018
fmontesi Oct 6, 2025
a48173f
Apply suggestion from @chenson2018
fmontesi Oct 6, 2025
4b17e09
grind annotations
fmontesi Oct 6, 2025
ec94a20
scope all the grinds
fmontesi Oct 6, 2025
9a01e84
Move accept conditions around for better extensibility to omega autom…
fmontesi Oct 6, 2025
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
6 changes: 3 additions & 3 deletions Cslib.lean
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import Cslib.Foundations.Semantics.Lts.Basic
import Cslib.Foundations.Semantics.Lts.Bisimulation
import Cslib.Foundations.Semantics.Lts.TraceEq
import Cslib.Foundations.Semantics.LTS.Basic
import Cslib.Foundations.Semantics.LTS.Bisimulation
Copy link

Choose a reason for hiding this comment

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

[imports (comment with "bot fix style" to have the bot commit all style suggestions)] reported by reviewdog 🐶

Suggested change
import Cslib.Foundations.Semantics.LTS.Bisimulation
import Cslib.Computability.Automata.DA
import Cslib.Computability.Automata.DFA
import Cslib.Computability.Automata.DFAToNFA
import Cslib.Computability.Automata.EpsilonNFA
import Cslib.Computability.Automata.EpsilonNFAToNFA
import Cslib.Computability.Automata.NA
import Cslib.Computability.Automata.NFA
import Cslib.Computability.Automata.NFAToDFA
import Cslib.Foundations.Control.Monad.Free
import Cslib.Foundations.Control.Monad.Free.Effects
import Cslib.Foundations.Control.Monad.Free.Fold
import Cslib.Foundations.Data.FinFun
import Cslib.Foundations.Data.HasFresh
import Cslib.Foundations.Data.Relation
import Cslib.Foundations.Semantics.LTS.Bisimulation

import Cslib.Foundations.Semantics.LTS.TraceEq
import Cslib.Foundations.Data.Relation
Copy link

Choose a reason for hiding this comment

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

[imports (comment with "bot fix style" to have the bot commit all style suggestions)] reported by reviewdog 🐶

Suggested change
import Cslib.Foundations.Data.Relation
import Cslib.Foundations.Semantics.LTS.Simulation
import Cslib.Foundations.Data.Relation

import Cslib.Languages.CombinatoryLogic.Defs
import Cslib.Languages.CombinatoryLogic.Basic
Comment on lines 5 to 6
Copy link

Choose a reason for hiding this comment

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

[imports (comment with "bot fix style" to have the bot commit all style suggestions)] reported by reviewdog 🐶

Suggested change
import Cslib.Languages.CombinatoryLogic.Defs
import Cslib.Languages.CombinatoryLogic.Basic
import Cslib.Foundations.Semantics.ReductionSystem.Basic
import Cslib.Foundations.Syntax.HasAlphaEquiv
import Cslib.Foundations.Syntax.HasSubstitution
import Cslib.Foundations.Syntax.HasWellFormed
import Cslib.Languages.CCS.Basic
import Cslib.Languages.CCS.BehaviouralTheory
import Cslib.Languages.CCS.Semantics

17 changes: 17 additions & 0 deletions Cslib/Computability/Automata/DA.lean
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
/-
Copyright (c) 2025 Fabrizio Montesi. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Fabrizio Montesi
-/

import Cslib.Computability.Automata.NA

/-! # Deterministic Automaton

A Deterministic Automaton (DA) is an automaton defined by a transition function.
-/
structure DA (State : Type _) (Symbol : Type _) where
Copy link
Collaborator

Choose a reason for hiding this comment

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

Suggested change
structure DA (State : Type _) (Symbol : Type _) where
structure DA (State Symbol : Type*) where

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I still don't get what the advantage of Type* is given that Type _ (even by listing the identifiers before it) does the same thing and seems native?

Copy link
Collaborator

Choose a reason for hiding this comment

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

My opinion is that it is more readable and as a side benefit more compact. As is, you have to twice interpret an annotation and _, whereas with Type* you get one piece of syntax that says "all these types are in arbitrary universes". As this is a very stable piece of Mathlib syntax, I do not find an advantage in the native spelling.

Not a deal breaker for me, this can be considered personal preference.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I see what you mean, although I still find (State : Type _) (Symbol : Type _) to be less ambiguous. I'll mull over it.

/-- The initial state of the automaton. -/
start : State
/-- The transition function of the automaton. -/
tr : State → Symbol → State
61 changes: 61 additions & 0 deletions Cslib/Computability/Automata/DFA.lean
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
/-
Copyright (c) 2025 Fabrizio Montesi. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Fabrizio Montesi
-/

import Cslib.Computability.Automata.DA

set_option linter.style.longLine false in
/-! # Deterministic Finite-State Automata

A Deterministic Finite Automaton (DFA) is a finite-state machine that accepts or rejects
a finite string.

## References

* [J. E. Hopcroft, R. Motwani, J. D. Ullman, *Introduction to Automata Theory, Languages, and Computation*][Hopcroft2006]
-/

/-- A Deterministic Finite Automaton (DFA) consists of a labelled transition function
`tr` over finite sets of states and labels (called symbols), a starting state `start` and a finite
set of accepting states `accept`. -/
structure DFA (State : Type _) (Symbol : Type _) extends DA State Symbol where
Copy link
Collaborator

Choose a reason for hiding this comment

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

Suggested change
structure DFA (State : Type _) (Symbol : Type _) extends DA State Symbol where
structure DFA (State Symbol : Type*) extends DA State Symbol where

/-- The set of accepting states of the automaton. -/
accept : Set State
/-- The automaton is finite-state. -/
finite_state : Finite State
/-- The type of symbols (also called 'alphabet') is finite. -/
finite_symbol : Finite Symbol


namespace DFA

/-- Extended transition function.

Implementation note: compared to [Hopcroft2006], the definition consumes the input list of symbols
from the left (instead of the right), in order to match the way lists are constructed.
-/
@[scoped grind =]
def mtr (dfa : DFA State Symbol) (s : State) (xs : List Symbol) := xs.foldl dfa.tr s

@[scoped grind =]
theorem mtr_nil_eq {dfa : DFA State Symbol} : dfa.mtr s [] = s := by rfl

/-- A DFA accepts a string if there is a multi-step accepting derivative with that trace from
the start state. -/
@[scoped grind →]
def Accepts (dfa : DFA State Symbol) (xs : List Symbol) :=
dfa.mtr dfa.start xs ∈ dfa.accept

/-- The language of a DFA is the set of strings that it accepts. -/
@[scoped grind =]
def language (dfa : DFA State Symbol) : Set (List Symbol) :=
{ xs | dfa.Accepts xs }

/-- A string is accepted by a DFA iff it is in the language of the DFA. -/
@[scoped grind _=_]
theorem accepts_mem_language (dfa : DFA State Symbol) (xs : List Symbol) :
dfa.Accepts xs ↔ xs ∈ dfa.language := by rfl

end DFA
63 changes: 63 additions & 0 deletions Cslib/Computability/Automata/DFAToNFA.lean
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
/-
Copyright (c) 2025 Fabrizio Montesi. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Fabrizio Montesi
-/

import Cslib.Computability.Automata.DFA
import Cslib.Computability.Automata.NFA

/-! # Translation of DFA into NFA -/

namespace DFA
section NFA

/-- `DFA` is a special case of `NFA`. -/
@[scoped grind =]
def toNFA (dfa : DFA State Symbol) : NFA State Symbol where
start := {dfa.start}
accept := dfa.accept
Tr := fun s1 μ s2 => dfa.tr s1 μ = s2
finite_state := dfa.finite_state
finite_symbol := dfa.finite_symbol

@[scoped grind =]
lemma toNFA_start {dfa : DFA State Symbol} : dfa.toNFA.start = {dfa.start} := rfl

instance : Coe (DFA State Symbol) (NFA State Symbol) where
coe := toNFA

/-- `DA.toNA` correctly characterises transitions. -/
@[scoped grind =]
theorem toNA_tr {dfa : DFA State Symbol} :
dfa.toNFA.Tr s1 μ s2 ↔ dfa.tr s1 μ = s2 := by
rfl

/-- The transition system of a DA is deterministic. -/
@[scoped grind ⇒]
theorem toNFA_deterministic (dfa : DFA State Symbol) : dfa.toNFA.Deterministic := by
grind

/-- The transition system of a DA is image-finite. -/
@[scoped grind ⇒]
theorem toNFA_imageFinite (dfa : DFA State Symbol) : dfa.toNFA.ImageFinite :=
dfa.toNFA.deterministic_imageFinite dfa.toNFA_deterministic

/-- Characterisation of multistep transitions. -/
@[scoped grind =]
theorem toNFA_mtr {dfa : DFA State Symbol} :
dfa.toNFA.MTr s1 xs s2 ↔ dfa.mtr s1 xs = s2 := by
have : ∀ x, dfa.toNFA.Tr s1 x (dfa.tr s1 x) := by grind
constructor <;> intro h
case mp => induction h <;> grind
case mpr => induction xs generalizing s1 <;> grind

/-- The `NFA` constructed from a `DFA` has the same language. -/
@[scoped grind =]
theorem toNFA_language_eq {dfa : DFA State Symbol} :
dfa.toNFA.language = dfa.language := by
ext xs
refine ⟨?_, fun _ => ⟨dfa.start, ?_⟩⟩ <;> open NFA in grind

end NFA
end DFA
52 changes: 52 additions & 0 deletions Cslib/Computability/Automata/EpsilonNFA.lean
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
/-
Copyright (c) 2025 Fabrizio Montesi. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Fabrizio Montesi
-/

import Cslib.Computability.Automata.NA

/-! # Nondeterministic automata with ε-transitions. -/

/-- A nondeterministic finite automaton with ε-transitions (`εNFA`) is an `NA` with an `Option`
symbol type. The special symbol ε is represented by the `Option.none` case.

Internally, ε (`Option.none`) is treated as the `τ` label of the underlying transition system,
allowing for reusing the definitions and results on saturated transitions of `LTS` to deal with
ε-closure. -/
structure εNFA (State : Type _) (Symbol : Type _) extends NA State (Option Symbol) where
Copy link
Collaborator

Choose a reason for hiding this comment

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

Suggested change
structure εNFA (State : Type _) (Symbol : Type _) extends NA State (Option Symbol) where
structure εNFA (State Symbol : Type*) extends NA State (Option Symbol) where

Copy link

Choose a reason for hiding this comment

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

Instead of extending NA to obtain εNFA, it may be cleaner to have an εNA (namely, an NA that supports ε-transitions) and extend εNA to obtain εNFA. My comments about separating out the main part of the subset construction from NFA to NA also applies, mutatis mutandis, here. I think such a design would be more orthogonal than the current one.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I agree with both comments, though I'd have to test grind (seems to be obstructed a bit by structure extensions sometimes). I'll implement them in a separate PR when I have some time for this again, since it seems like a backwards compatible extension to what is here. (Or, if you like, feel free to submit one.)

/-- The set of accepting states of the automaton. -/
accept : Set State
/-- The automaton is finite-state. -/
finite_state : Finite State
/-- The type of symbols (also called 'alphabet') is finite. -/
finite_symbol : Finite Symbol

@[local grind =]
private instance : HasTau (Option α) := ⟨.none⟩

/-- The `ε`-closure of a set of states `S` is the set of states reachable by any state in `S`
by performing only `ε`-transitions. We use `LTS.τClosure` since `ε` (`Option.none`) is an instance
of `HasTau.τ`. -/
abbrev εNFA.εClosure (enfa : εNFA State Symbol) (S : Set State) := enfa.τClosure S

namespace εNFA

/-- An εNFA accepts a string if there is a saturated multistep accepting derivative with that trace
from the start state. -/
@[scoped grind]
def Accepts (enfa : εNFA State Symbol) (xs : List Symbol) :=
∃ s ∈ enfa.εClosure enfa.start, ∃ s' ∈ enfa.accept,
enfa.saturate.MTr s (xs.map (some ·)) s'

/-- The language of an εDA is the set of strings that it accepts. -/
@[scoped grind =]
def language (enfa : εNFA State Symbol) : Set (List Symbol) :=
{ xs | enfa.Accepts xs }

/-- A string is accepted by an εNFA iff it is in the language of the NA. -/
@[scoped grind =]
theorem accepts_mem_language (enfa : εNFA State Symbol) (xs : List Symbol) :
enfa.Accepts xs ↔ xs ∈ enfa.language := by rfl

end εNFA
55 changes: 55 additions & 0 deletions Cslib/Computability/Automata/EpsilonNFAToNFA.lean
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
/-
Copyright (c) 2025 Fabrizio Montesi. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Fabrizio Montesi
-/

import Cslib.Computability.Automata.EpsilonNFA
import Cslib.Computability.Automata.NFA

/-! # Translation of εNFA into NFA -/

/-- Converts an `LTS` with Option labels into an `LTS` on the carried label type, by removing all
ε-transitions. -/
@[grind]
Copy link
Collaborator

Choose a reason for hiding this comment

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

Based on the fact that you are having to use simp and rw wedged between grind is an indicator that something is preventing the annotations in this file from being useful.

private def LTS.noε (lts : LTS State (Option Label)) : LTS State Label where
Tr := fun s μ s' => lts.Tr s (some μ) s'

@[local grind]
private lemma LTS.noε_saturate_tr
{lts : LTS State (Option Label)} {h : μ = some μ'} :
lts.saturate.Tr s μ s' ↔ lts.saturate.noε.Tr s μ' s' := by
simp only [LTS.noε]
grind

namespace εNFA
section NFA

/-- Any εNFA can be converted into an NFA that does not use ε-transitions. -/
@[scoped grind]
def toNFA (enfa : εNFA State Symbol) : NFA State Symbol where
start := enfa.εClosure enfa.start
accept := enfa.accept
Tr := enfa.saturate.noε.Tr
finite_state := enfa.finite_state
finite_symbol := enfa.finite_symbol

@[scoped grind]
lemma LTS.noε_saturate_mTr
{lts : LTS State (Option Label)} :
lts.saturate.MTr s (μs.map (some ·)) = lts.saturate.noε.MTr s μs := by
ext s'
induction μs generalizing s <;> grind [<= LTS.MTr.stepL]


/-- Correctness of `toNFA`. -/
@[scoped grind]
theorem toNFA_language_eq {enfa : εNFA State Symbol} :
enfa.toNFA.language = enfa.language := by
ext xs
have : ∀ s s', enfa.saturate.MTr s (xs.map (some ·)) s' = enfa.saturate.noε.MTr s xs s' := by
simp [LTS.noε_saturate_mTr]
open NFA in grind

end NFA
end εNFA
19 changes: 19 additions & 0 deletions Cslib/Computability/Automata/NA.lean
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
/-
Copyright (c) 2025 Fabrizio Montesi. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Fabrizio Montesi
-/

import Cslib.Foundations.Semantics.LTS.Basic

/-! # Nondeterministic Automaton

A Nondeterministic Automaton (NA) is an automaton with a set of initial states.

This definition extends `LTS` and thus stores the transition system as a relation `Tr` of the form
`State → Symbol → State → Prop`. Note that you can also instantiate `Tr` by passing an argument of
type `State → Symbol → Set State`; it gets automatically expanded to the former shape.
-/
structure NA (State : Type _) (Symbol : Type _) extends LTS State Symbol where
Copy link
Collaborator

Choose a reason for hiding this comment

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

Suggested change
structure NA (State : Type _) (Symbol : Type _) extends LTS State Symbol where
structure NA (State Symbol : Type*) extends LTS State Symbol where

/-- The set of initial states of the automaton. -/
start : Set State
37 changes: 37 additions & 0 deletions Cslib/Computability/Automata/NFA.lean
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
/-
Copyright (c) 2025 Fabrizio Montesi. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Fabrizio Montesi
-/

import Cslib.Computability.Automata.NA

/-- A Nondeterministic Finite Automaton (NFA) is a nondeterministic automaton (NA)
over finite sets of states and symbols. -/
structure NFA (State : Type _) (Symbol : Type _) extends NA State Symbol where
Copy link
Collaborator

Choose a reason for hiding this comment

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

Suggested change
structure NFA (State : Type _) (Symbol : Type _) extends NA State Symbol where
structure NFA (State Symbol : Type*) extends NA State Symbol where

/-- The set of accepting states of the automaton. -/
accept : Set State
/-- The automaton is finite-state. -/
finite_state : Finite State
/-- The type of symbols (also called 'alphabet') is finite. -/
finite_symbol : Finite Symbol

namespace NFA

/-- An NFA accepts a string if there is a multi-step accepting derivative with that trace from
the start state. -/
@[scoped grind]
def Accepts (nfa : NFA State Symbol) (xs : List Symbol) :=
∃ s ∈ nfa.start, ∃ s' ∈ nfa.accept, nfa.MTr s xs s'

/-- The language of an NFA is the set of strings that it accepts. -/
@[scoped grind]
def language (nfa : NFA State Symbol) : Set (List Symbol) :=
{ xs | nfa.Accepts xs }

/-- A string is accepted by an NFA iff it is in the language of the NFA. -/
@[scoped grind]
theorem accepts_mem_language (nfa : NFA State Symbol) (xs : List Symbol) :
nfa.Accepts xs ↔ xs ∈ nfa.language := by rfl

end NFA
64 changes: 64 additions & 0 deletions Cslib/Computability/Automata/NFAToDFA.lean
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
/-
Copyright (c) 2025 Fabrizio Montesi. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Fabrizio Montesi
-/

import Cslib.Computability.Automata.DFA
import Cslib.Computability.Automata.NFA
import Mathlib.Data.Fintype.Powerset

/-! # Translation of NFA into DFA (subset construction) -/

namespace NFA
section SubsetConstruction

/-- Converts an `NFA` into a `DFA` using the subset construction. -/
@[scoped grind =]
def toDFA (nfa : NFA State Symbol) : DFA (Set State) Symbol := {
Copy link

Choose a reason for hiding this comment

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

Perhaps you can separate out the start and tr components to a NAtoDA.lean, so that other extensions of NA and DA for omega-automata can also use the results? Note that all the heavy-lifting in the proof of the subset construction involve only the start and tr components anyway.

start := nfa.start
accept := { S | ∃ s ∈ S, s ∈ nfa.accept }
tr := nfa.setImage
finite_state := by
haveI := nfa.finite_state
Copy link
Collaborator

Choose a reason for hiding this comment

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

Shouldn't we be able to infer this by putting an instance on NFA? Also I don't think have vs haveI makes a difference here, does it?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Not sure what you mean, could you elaborate?
(Re have vs haveI, nah, I don't think it makes a difference.)

Copy link
Collaborator

Choose a reason for hiding this comment

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

I meant that if NFA.{finite_state,finite_symbol} were made instances, the corresponding DFA fields could be inferred completely here. That seems to not quite work though...

infer_instance
finite_symbol := nfa.finite_symbol
}

/-- Characterisation of transitions in `NFA.toDFA` wrt transitions in the original NA. -/
@[scoped grind =]
theorem toDFA_mem_tr {nfa : NFA State Symbol} :
s' ∈ nfa.toDFA.tr S x ↔ ∃ s ∈ S, nfa.Tr s x s' := by
simp only [NFA.toDFA, LTS.setImage, Set.mem_iUnion, exists_prop]
grind

/-- Characterisation of multistep transitions in `NFA.toDFA` wrt multistep transitions in the
original NA. -/
@[scoped grind =]
theorem toDFA_mem_mtr {nfa : NFA State Symbol} :
s' ∈ nfa.toDFA.mtr S xs ↔ ∃ s ∈ S, nfa.MTr s xs s' := by
simp only [NFA.toDFA, DFA.mtr]
/- TODO: Grind does not catch a useful rewrite in the subset construction for automata

A very similar issue seems to occur in the proof of `NFA.toDFA_language_eq`.

labels: grind, lts, automata
-/
rw [← LTS.setImageMultistep_foldl_setImage]
grind

/-- Characterisation of multistep transitions in `NFA.toDFA` as image transitions in `LTS`. -/
@[scoped grind =]
theorem toDFA_mtr_setImageMultistep {nfa : NFA State Symbol} :
nfa.toDFA.mtr = nfa.setImageMultistep := by grind

/-- The `DFA` constructed from an `NFA` has the same language. -/
@[scoped grind =]
theorem toDFA_language_eq {nfa : NFA State Symbol} :
nfa.toDFA.language = nfa.language := by
ext xs
rw [← DFA.accepts_mem_language]
open DFA in grind

end SubsetConstruction
end NFA
Loading